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:
Florian Duros
2023-05-25 18:24:50 +00:00
committed by GitHub
co-authored by Richard van der Hoff
parent 5593872b7a
commit 8d77d6e4cc
4 changed files with 161 additions and 65 deletions
+59 -2
View File
@@ -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();
}