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!
pull/28217/head
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> => {