Cypress: Use Rust crypto for the bot user in verification tests (#11173)

* Cypress: `crypto.verification.request` -> `crypto.verificationRequestReceived`

matrix-org/matrix-js-sdk#3514 deprecated crypto.verification.request.

* Cypress: `beginKeyVerification` -> `startVerification`

matrix-org/matrix-js-sdk#3528 deprecated beginKeyVerification

* simplify `setupBotClient`

no functional change here, just combining the various `cy.wrap()`ed things into
a single async func

* Cypress: Use Rust crypto for the bot user in verification tests

We can already start using the Rust crypto implementation for the "bot" user in
the verification tests!
This commit is contained in:
Richard van der Hoff 2023-07-07 17:56:53 +01:00 committed by GitHub
parent 8924bd26fa
commit 1a75d5d869
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 75 additions and 65 deletions

View file

@ -116,9 +116,9 @@ const verify = function (this: CryptoTestContext) {
// this requires creating a DM, so can take a while. Give it a longer timeout.
cy.findByRole("button", { name: "Verify by emoji", timeout: 30000 }).click();
cy.wrap(bobsVerificationRequestPromise).then((request: VerificationRequest) => {
cy.wrap(bobsVerificationRequestPromise).then(async (request: VerificationRequest) => {
// the bot user races with the Element user to hit the "verify by emoji" button
const verifier = request.beginKeyVerification("m.sas.v1");
const verifier = await request.startVerification("m.sas.v1");
doTwoWaySasVerification(verifier);
});
cy.findByRole("button", { name: "They match" }).click();

View file

@ -28,13 +28,11 @@ export type EmojiMapping = [emoji: string, name: string];
export function waitForVerificationRequest(cli: MatrixClient): Promise<VerificationRequest> {
return new Promise<VerificationRequest>((resolve) => {
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
cli.on("crypto.verification.request", onVerificationRequestEvent);
// @ts-ignore CryptoEvent is not exported to window.matrixcs; using the string value here
cli.once("crypto.verificationRequestReceived", onVerificationRequestEvent);
});
}
@ -59,7 +57,6 @@ export function handleSasVerification(verifier: Verifier): Promise<EmojiMapping[
// @ts-ignore as above, avoiding reference to VerifierEvent
verifier.on("show_sas", onShowSas);
verifier.verify();
});
}
@ -134,7 +131,10 @@ export function doTwoWaySasVerification(verifier: Verifier): void {
cy.wrap(emojiPromise).then((emojis: EmojiMapping[]) => {
cy.get(".mx_VerificationShowSas_emojiSas_block").then((emojiBlocks) => {
emojis.forEach((emoji: EmojiMapping, index: number) => {
expect(emojiBlocks[index].textContent.toLowerCase()).to.eq(emoji[0] + emoji[1]);
// VerificationShowSas munges the case of the emoji descriptions returned by the js-sdk before
// displaying them. Once we drop support for legacy crypto, that code can go away, and so can the
// case-munging here.
expect(emojiBlocks[index].textContent.toLowerCase()).to.eq(emoji[0] + emoji[1].toLowerCase());
});
});
});

View file

@ -36,7 +36,7 @@ describe("Device verification", () => {
cy.window({ log: false }).should("have.property", "matrixcs");
// Create a new device for alice
cy.getBot(homeserver, { bootstrapCrossSigning: true }).then((bot) => {
cy.getBot(homeserver, { rustCrypto: true, bootstrapCrossSigning: true }).then((bot) => {
aliceBotClient = bot;
});
});
@ -71,9 +71,9 @@ describe("Device verification", () => {
// Handle emoji SAS verification
cy.get(".mx_InfoDialog").within(() => {
cy.get<VerificationRequest>("@verificationRequest").then((request: VerificationRequest) => {
cy.get<VerificationRequest>("@verificationRequest").then(async (request: VerificationRequest) => {
// the bot chooses to do an emoji verification
const verifier = request.beginKeyVerification("m.sas.v1");
const verifier = await request.startVerification("m.sas.v1");
// Handle emoji request and check that emojis are matching
doTwoWaySasVerification(verifier);

View file

@ -43,6 +43,10 @@ interface CreateBotOpts {
* Whether or not to generate cross-signing keys
*/
bootstrapCrossSigning?: boolean;
/**
* Whether to use the rust crypto impl. Defaults to false (for now!)
*/
rustCrypto?: boolean;
}
const defaultCreateBotOptions = {
@ -125,66 +129,72 @@ function setupBotClient(
opts: CreateBotOpts,
): Chainable<MatrixClient> {
opts = Object.assign({}, defaultCreateBotOptions, opts);
return cy.window({ log: false }).then((win) => {
const keys = {};
return cy.window({ log: false }).then(
// extra timeout, as this sometimes takes a while
{ timeout: 30_000 },
async (win): Promise<MatrixClient> => {
const keys = {};
const getCrossSigningKey = (type: string) => {
return keys[type];
};
const getCrossSigningKey = (type: string) => {
return keys[type];
};
const saveCrossSigningKeys = (k: Record<string, Uint8Array>) => {
Object.assign(keys, k);
};
const saveCrossSigningKeys = (k: Record<string, Uint8Array>) => {
Object.assign(keys, k);
};
const cli = new win.matrixcs.MatrixClient({
baseUrl: homeserver.baseUrl,
userId: credentials.userId,
deviceId: credentials.deviceId,
accessToken: credentials.accessToken,
store: new win.matrixcs.MemoryStore(),
scheduler: new win.matrixcs.MatrixScheduler(),
cryptoStore: new win.matrixcs.MemoryCryptoStore(),
cryptoCallbacks: { getCrossSigningKey, saveCrossSigningKeys },
});
if (opts.autoAcceptInvites) {
cli.on(win.matrixcs.RoomMemberEvent.Membership, (event, member) => {
if (member.membership === "invite" && member.userId === cli.getUserId()) {
cli.joinRoom(member.roomId);
}
const cli = new win.matrixcs.MatrixClient({
baseUrl: homeserver.baseUrl,
userId: credentials.userId,
deviceId: credentials.deviceId,
accessToken: credentials.accessToken,
store: new win.matrixcs.MemoryStore(),
scheduler: new win.matrixcs.MatrixScheduler(),
cryptoStore: new win.matrixcs.MemoryCryptoStore(),
cryptoCallbacks: { getCrossSigningKey, saveCrossSigningKeys },
});
}
if (!opts.startClient) {
return cy.wrap(cli);
}
return cy.wrap(
cli
.initCrypto()
.then(() => cli.setGlobalErrorOnUnknownDevices(false))
.then(() => cli.startClient())
.then(async () => {
if (opts.bootstrapCrossSigning) {
await cli.bootstrapCrossSigning({
authUploadDeviceSigningKeys: async (func) => {
await func({
type: "m.login.password",
identifier: {
type: "m.id.user",
user: credentials.userId,
},
password: credentials.password,
});
},
});
if (opts.autoAcceptInvites) {
cli.on(win.matrixcs.RoomMemberEvent.Membership, (event, member) => {
if (member.membership === "invite" && member.userId === cli.getUserId()) {
cli.joinRoom(member.roomId);
}
})
.then(() => cli),
// extra timeout, as this sometimes takes a while
{ timeout: 30_000 },
);
});
});
}
if (!opts.startClient) {
return cli;
}
if (opts.rustCrypto) {
await cli.initRustCrypto({ useIndexedDB: false });
} else {
await cli.initCrypto();
}
cli.setGlobalErrorOnUnknownDevices(false);
await cli.startClient();
if (opts.bootstrapCrossSigning) {
// XXX: workaround https://github.com/matrix-org/matrix-rust-sdk/issues/2193
// wait for out device list to be available, as a proxy for the device keys having been uploaded.
await cli.getCrypto()!.getUserDeviceInfo([credentials.userId]);
await cli.getCrypto()!.bootstrapCrossSigning({
authUploadDeviceSigningKeys: async (func) => {
await func({
type: "m.login.password",
identifier: {
type: "m.id.user",
user: credentials.userId,
},
password: credentials.password,
});
},
});
}
return cli;
},
);
}
Cypress.Commands.add("getBot", (homeserver: HomeserverInstance, opts: CreateBotOpts): Chainable<CypressBot> => {