Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Cypress: Use Rust crypto for the bot user in verification tests (#11173)
Browse files Browse the repository at this point in the history
* 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!
  • Loading branch information
richvdh authored Jul 7, 2023
1 parent 8924bd2 commit 1a75d5d
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 63 deletions.
4 changes: 2 additions & 2 deletions cypress/e2e/crypto/crypto.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
12 changes: 6 additions & 6 deletions cypress/e2e/crypto/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
}

Expand All @@ -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();
});
}

Expand Down Expand Up @@ -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());
});
});
});
Expand Down
6 changes: 3 additions & 3 deletions cypress/e2e/crypto/verification.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
});
});
Expand Down Expand Up @@ -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);
Expand Down
114 changes: 62 additions & 52 deletions cypress/support/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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 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 },
});
const saveCrossSigningKeys = (k: Record<string, Uint8Array>) => {
Object.assign(keys, k);
};

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);
}
if (opts.autoAcceptInvites) {
cli.on(win.matrixcs.RoomMemberEvent.Membership, (event, member) => {
if (member.membership === "invite" && member.userId === cli.getUserId()) {
cli.joinRoom(member.roomId);
}
});
}

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.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,
});
}
})
.then(() => cli),
// extra timeout, as this sometimes takes a while
{ timeout: 30_000 },
);
});
},
});
}
return cli;
},
);
}

Cypress.Commands.add("getBot", (homeserver: HomeserverInstance, opts: CreateBotOpts): Chainable<CypressBot> => {
Expand Down

0 comments on commit 1a75d5d

Please sign in to comment.