Add cypress test for verifying a new device via SAS (#10940)
* Add WIP Sas cross-signing test * Login after bot creation * Figuring out how to make it work in ci * Wait for `r0/login` to be called before bot creation * Make waitForVerificationRequest automatically accept requests ... thereby making the `acceptVerificationRequest` helper redundant * Clean up `deviceIsCrossSigned` * combine `handleVerificationRequest` and `verifyEmojiSas` * get rid of a layer ... it adds no value * fix bad merge * minor cleanups to new test * Move `logIntoElement` to utils module * use `logIntoElement` function * Avoid intercept * Avoid `CryptoTestContext` --------- Co-authored-by: Richard van der Hoff <richard@matrix.org>
This commit is contained in:
co-authored by
Richard van der Hoff
parent
5593872b7a
commit
8d77d6e4cc
@@ -21,15 +21,16 @@ import type { VerificationRequest } from "matrix-js-sdk/src/crypto/verification/
|
||||
export type EmojiMapping = [emoji: string, name: string];
|
||||
|
||||
/**
|
||||
* wait for the given client to receive an incoming verification request
|
||||
* wait for the given client to receive an incoming verification request, and automatically accept it
|
||||
*
|
||||
* @param cli - matrix client we expect to receive a request
|
||||
*/
|
||||
export function waitForVerificationRequest(cli: MatrixClient): Promise<VerificationRequest> {
|
||||
return new Promise<VerificationRequest>((resolve) => {
|
||||
const onVerificationRequestEvent = (request: VerificationRequest) => {
|
||||
const onVerificationRequestEvent = async (request: VerificationRequest) => {
|
||||
// @ts-ignore CryptoEvent is not exported to window.matrixcs; using the string value here
|
||||
cli.off("crypto.verification.request", onVerificationRequestEvent);
|
||||
await request.accept();
|
||||
resolve(request);
|
||||
};
|
||||
// @ts-ignore
|
||||
@@ -62,3 +63,59 @@ export function handleVerificationRequest(request: VerificationRequest): Promise
|
||||
verifier.verify();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the user has published cross-signing keys, and that the user's device has been cross-signed.
|
||||
*/
|
||||
export function checkDeviceIsCrossSigned(): void {
|
||||
let userId: string;
|
||||
let myDeviceId: string;
|
||||
cy.window({ log: false })
|
||||
.then((win) => {
|
||||
// Get the userId and deviceId of the current user
|
||||
const cli = win.mxMatrixClientPeg.get();
|
||||
const accessToken = cli.getAccessToken()!;
|
||||
const homeserverUrl = cli.getHomeserverUrl();
|
||||
myDeviceId = cli.getDeviceId();
|
||||
userId = cli.getUserId();
|
||||
return cy.request({
|
||||
method: "POST",
|
||||
url: `${homeserverUrl}/_matrix/client/v3/keys/query`,
|
||||
headers: { Authorization: `Bearer ${accessToken}` },
|
||||
body: { device_keys: { [userId]: [] } },
|
||||
});
|
||||
})
|
||||
.then((res) => {
|
||||
// there should be three cross-signing keys
|
||||
expect(res.body.master_keys[userId]).to.have.property("keys");
|
||||
expect(res.body.self_signing_keys[userId]).to.have.property("keys");
|
||||
expect(res.body.user_signing_keys[userId]).to.have.property("keys");
|
||||
|
||||
// and the device should be signed by the self-signing key
|
||||
const selfSigningKeyId = Object.keys(res.body.self_signing_keys[userId].keys)[0];
|
||||
|
||||
expect(res.body.device_keys[userId][myDeviceId]).to.exist;
|
||||
|
||||
const myDeviceSignatures = res.body.device_keys[userId][myDeviceId].signatures[userId];
|
||||
expect(myDeviceSignatures[selfSigningKeyId]).to.exist;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill in the login form in element with the given creds
|
||||
*/
|
||||
export function logIntoElement(homeserverUrl: string, username: string, password: string) {
|
||||
cy.visit("/#/login");
|
||||
|
||||
// select homeserver
|
||||
cy.findByRole("button", { name: "Edit" }).click();
|
||||
cy.findByRole("textbox", { name: "Other homeserver" }).type(homeserverUrl);
|
||||
cy.findByRole("button", { name: "Continue" }).click();
|
||||
|
||||
// wait for the dialog to go away
|
||||
cy.get(".mx_ServerPickerDialog").should("not.exist");
|
||||
|
||||
cy.findByRole("textbox", { name: "Username" }).type(username);
|
||||
cy.findByPlaceholderText("Password").type(password);
|
||||
cy.findByRole("button", { name: "Sign in" }).click();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user