Device manage - handle sessions that don't support encryption (#9717)

* add handling for unverifiable sessions

* test

* update types for filtervariation

* strict fixes

* avoid setting up cross signing in device man tests
This commit is contained in:
Kerry 2022-12-09 10:52:00 +13:00 committed by GitHub
parent 6150b86421
commit 888e69f39a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 200 additions and 105 deletions

View file

@ -255,12 +255,23 @@ describe('<SessionManagerTab />', () => {
});
it('sets device verification status correctly', async () => {
mockClient.getDevices.mockResolvedValue({ devices: [alicesDevice, alicesMobileDevice] });
mockClient.getDevices.mockResolvedValue({ devices:
[alicesDevice, alicesMobileDevice, alicesOlderMobileDevice],
});
mockClient.getStoredDevice.mockImplementation((_userId, deviceId) => new DeviceInfo(deviceId));
mockCrossSigningInfo.checkDeviceTrust
// alices device is trusted
.mockReturnValueOnce(new DeviceTrustLevel(true, true, false, false))
// alices mobile device is not
.mockReturnValueOnce(new DeviceTrustLevel(false, false, false, false));
.mockImplementation((_userId, { deviceId }) => {
// alices device is trusted
if (deviceId === alicesDevice.device_id) {
return new DeviceTrustLevel(true, true, false, false);
}
// alices mobile device is not
if (deviceId === alicesMobileDevice.device_id) {
return new DeviceTrustLevel(false, false, false, false);
}
// alicesOlderMobileDevice does not support encryption
throw new Error('encryption not supported');
});
const { getByTestId } = render(getComponent());
@ -268,8 +279,20 @@ describe('<SessionManagerTab />', () => {
await flushPromises();
});
expect(mockCrossSigningInfo.checkDeviceTrust).toHaveBeenCalledTimes(2);
expect(getByTestId(`device-tile-${alicesDevice.device_id}`)).toMatchSnapshot();
expect(mockCrossSigningInfo.checkDeviceTrust).toHaveBeenCalledTimes(3);
expect(
getByTestId(`device-tile-${alicesDevice.device_id}`)
.querySelector('[aria-label="Verified"]'),
).toBeTruthy();
expect(
getByTestId(`device-tile-${alicesMobileDevice.device_id}`)
.querySelector('[aria-label="Unverified"]'),
).toBeTruthy();
// sessions that dont support encryption use unverified badge
expect(
getByTestId(`device-tile-${alicesOlderMobileDevice.device_id}`)
.querySelector('[aria-label="Unverified"]'),
).toBeTruthy();
});
it('extends device with client information when available', async () => {
@ -489,7 +512,7 @@ describe('<SessionManagerTab />', () => {
if (deviceId === alicesDevice.device_id) {
return new DeviceTrustLevel(true, true, false, false);
}
throw new Error('everything else unverified');
return new DeviceTrustLevel(false, false, false, false);
});
const { getByTestId } = render(getComponent());
@ -507,6 +530,38 @@ describe('<SessionManagerTab />', () => {
expect(modalSpy).toHaveBeenCalled();
});
it('does not allow device verification on session that do not support encryption', async () => {
mockClient.getDevices.mockResolvedValue({ devices: [alicesDevice, alicesMobileDevice] });
mockClient.getStoredDevice.mockImplementation((_userId, deviceId) => new DeviceInfo(deviceId));
mockCrossSigningInfo.checkDeviceTrust
.mockImplementation((_userId, { deviceId }) => {
// current session verified = able to verify other sessions
if (deviceId === alicesDevice.device_id) {
return new DeviceTrustLevel(true, true, false, false);
}
// but alicesMobileDevice doesn't support encryption
throw new Error('encryption not supported');
});
const {
getByTestId,
queryByTestId,
} = render(getComponent());
await act(async () => {
await flushPromises();
});
toggleDeviceDetails(getByTestId, alicesMobileDevice.device_id);
// no verify button
expect(queryByTestId(`verification-status-button-${alicesMobileDevice.device_id}`)).toBeFalsy();
expect(
getByTestId(`device-detail-${alicesMobileDevice.device_id}`)
.getElementsByClassName('mx_DeviceSecurityCard'),
).toMatchSnapshot();
});
it('refreshes devices after verifying other device', async () => {
const modalSpy = jest.spyOn(Modal, 'createDialog');
@ -518,7 +573,7 @@ describe('<SessionManagerTab />', () => {
if (deviceId === alicesDevice.device_id) {
return new DeviceTrustLevel(true, true, false, false);
}
throw new Error('everything else unverified');
return new DeviceTrustLevel(false, false, false, false);
});
const { getByTestId } = render(getComponent());

View file

@ -1,5 +1,43 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<SessionManagerTab /> Device verification does not allow device verification on session that do not support encryption 1`] = `
HTMLCollection [
<div
class="mx_DeviceSecurityCard"
>
<div
class="mx_DeviceSecurityCard_icon Unverified"
>
<div
height="16"
width="16"
/>
</div>
<div
class="mx_DeviceSecurityCard_content"
>
<p
class="mx_DeviceSecurityCard_heading"
>
Unverified session
</p>
<p
class="mx_DeviceSecurityCard_description"
>
This session doesn't support encryption and thus can't be verified.
<div
class="mx_AccessibleButton mx_LearnMore_button mx_AccessibleButton_hasKind mx_AccessibleButton_kind_link_inline"
role="button"
tabindex="0"
>
Learn more
</div>
</p>
</div>
</div>,
]
`;
exports[`<SessionManagerTab /> Sign out Signs out of current device 1`] = `
<div
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_danger_inline"
@ -345,68 +383,3 @@ exports[`<SessionManagerTab /> goes to filtered list from security recommendatio
</div>
</div>
`;
exports[`<SessionManagerTab /> sets device verification status correctly 1`] = `
<div
class="mx_DeviceTile mx_DeviceTile_interactive"
data-testid="device-tile-alices_device"
>
<div
class="mx_DeviceTypeIcon"
>
<div
class="mx_DeviceTypeIcon_deviceIconWrapper"
>
<div
aria-label="Unknown session type"
class="mx_DeviceTypeIcon_deviceIcon"
role="img"
/>
</div>
<div
aria-label="Verified"
class="mx_DeviceTypeIcon_verificationIcon verified"
role="img"
/>
</div>
<div
class="mx_DeviceTile_info"
>
<h4
class="mx_Heading_h4"
>
Alices device
</h4>
<div
class="mx_DeviceTile_metadata"
>
<span
data-testid="device-metadata-isVerified"
>
Verified
</span>
·
<span
data-testid="device-metadata-deviceId"
>
alices_device
</span>
</div>
</div>
<div
class="mx_DeviceTile_actions"
>
<div
aria-label="Show details"
class="mx_AccessibleButton mx_DeviceExpandDetailsButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_icon"
data-testid="current-session-toggle-details"
role="button"
tabindex="0"
>
<div
class="mx_DeviceExpandDetailsButton_icon"
/>
</div>
</div>
</div>
`;