Skip to content

Commit 1bc6117

Browse files
committed
In force-verify mode, prevent bypassing by cancelling device verification
1 parent e44ca88 commit 1bc6117

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

playwright/e2e/login/login-consent.spec.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,43 @@ test.describe("Login", () => {
258258

259259
await expect(h1.locator(".mx_CompleteSecurity_skip")).toHaveCount(0);
260260
});
261+
262+
test("Continues to show verification prompt after cancelling device verification", async ({
263+
page,
264+
homeserver,
265+
request,
266+
credentials,
267+
}) => {
268+
// Fake a different device, so we need to verify this one
269+
console.log(`uid ${credentials.userId} body`, DEVICE_SIGNING_KEYS_BODY);
270+
const res = await request.post(
271+
`${homeserver.baseUrl}/_matrix/client/v3/keys/device_signing/upload`,
272+
{
273+
headers: { Authorization: `Bearer ${credentials.accessToken}` },
274+
data: DEVICE_SIGNING_KEYS_BODY,
275+
},
276+
);
277+
if (res.status() / 100 !== 2) {
278+
console.log("Uploading dummy keys failed", await res.json());
279+
}
280+
expect(res.status() / 100).toEqual(2);
281+
282+
// Load the page and see that we are asked to verify
283+
await page.goto("/");
284+
await login(page, homeserver, credentials);
285+
let h1 = page.getByRole("heading", { name: "Verify this device", level: 1 });
286+
await expect(h1).toBeVisible();
287+
288+
// Click "Verify with another device"
289+
await page.getByRole("button", { name: "Verify with another device" }).click();
290+
291+
// Cancel the new dialog
292+
await page.getByRole("button", { name: "Close dialog" }).click();
293+
294+
// Check that we are still being asked to verify
295+
h1 = page.getByRole("heading", { name: "Verify this device", level: 1 });
296+
await expect(h1).toBeVisible();
297+
});
261298
});
262299
});
263300
});

src/components/structures/MatrixChat.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2003,8 +2003,17 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
20032003
};
20042004

20052005
// complete security / e2e setup has finished
2006-
private onCompleteSecurityE2eSetupFinished = (): void => {
2007-
// This is async but we making this function async to wait for it isn't useful
2006+
private onCompleteSecurityE2eSetupFinished = async (): Promise<void> => {
2007+
const forceVerify = await this.shouldForceVerification();
2008+
if (forceVerify) {
2009+
const isVerified = await MatrixClientPeg.safeGet().getCrypto()?.isCrossSigningReady();
2010+
if (!isVerified) {
2011+
// We must verify but we haven't yet verified - don't continue logging in
2012+
return;
2013+
}
2014+
}
2015+
2016+
// (This is async but we making this function async to wait for it isn't useful)
20082017
this.onShowPostLoginScreen().catch((e) => {
20092018
logger.error("Exception showing post-login screen", e);
20102019
});

0 commit comments

Comments
 (0)