Device manager - prune client information events after remote sign out (#9874)

* prune client infromation events from old devices

* test client data pruning

* remove debug

* strict

* Update src/components/views/settings/devices/useOwnDevices.ts

Co-authored-by: Michael Weimann <michaelw@matrix.org>

* improvements from review

Co-authored-by: Michael Weimann <michaelw@matrix.org>
This commit is contained in:
Kerry 2023-01-10 19:01:50 +13:00 committed by GitHub
parent 4f0a5d1eb4
commit b1c32995c6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 80 additions and 15 deletions

View file

@ -46,6 +46,7 @@ import LogoutDialog from "../../../../../../src/components/views/dialogs/LogoutD
import { DeviceSecurityVariation, ExtendedDevice } from "../../../../../../src/components/views/settings/devices/types";
import { INACTIVE_DEVICE_AGE_MS } from "../../../../../../src/components/views/settings/devices/filter";
import SettingsStore from "../../../../../../src/settings/SettingsStore";
import { getClientInformationEventType } from "../../../../../../src/utils/device/clientInformation";
mockPlatformPeg();
@ -87,6 +88,7 @@ describe("<SessionManagerTab />", () => {
generateClientSecret: jest.fn(),
setDeviceDetails: jest.fn(),
getAccountData: jest.fn(),
deleteAccountData: jest.fn(),
doesServerSupportUnstableFeature: jest.fn().mockResolvedValue(true),
getPushers: jest.fn(),
setPusher: jest.fn(),
@ -182,6 +184,9 @@ describe("<SessionManagerTab />", () => {
],
});
// @ts-ignore mock
mockClient.store = { accountData: {} };
mockClient.getAccountData.mockReset().mockImplementation((eventType) => {
if (eventType.startsWith(LOCAL_NOTIFICATION_SETTINGS_PREFIX.name)) {
return new MatrixEvent({
@ -667,6 +672,47 @@ describe("<SessionManagerTab />", () => {
);
});
it("removes account data events for devices after sign out", async () => {
const mobileDeviceClientInfo = new MatrixEvent({
type: getClientInformationEventType(alicesMobileDevice.device_id),
content: {
name: "test",
},
});
// @ts-ignore setup mock
mockClient.store = {
// @ts-ignore setup mock
accountData: {
[mobileDeviceClientInfo.getType()]: mobileDeviceClientInfo,
},
};
mockClient.getDevices
.mockResolvedValueOnce({
devices: [alicesDevice, alicesMobileDevice, alicesOlderMobileDevice],
})
.mockResolvedValueOnce({
// refreshed devices after sign out
devices: [alicesDevice],
});
const { getByTestId, getByLabelText } = render(getComponent());
await act(async () => {
await flushPromises();
});
expect(mockClient.deleteAccountData).not.toHaveBeenCalled();
fireEvent.click(getByTestId("current-session-menu"));
fireEvent.click(getByLabelText("Sign out of all other sessions (2)"));
await confirmSignout(getByTestId);
// only called once for signed out device with account data event
expect(mockClient.deleteAccountData).toHaveBeenCalledTimes(1);
expect(mockClient.deleteAccountData).toHaveBeenCalledWith(mobileDeviceClientInfo.getType());
});
describe("other devices", () => {
const interactiveAuthError = { httpStatus: 401, data: { flows: [{ stages: ["m.login.password"] }] } };