Cypress: Add test to verify device after login (#11217)

* Run cypress test without `cryptoCallbacks`

* Add security phrase test

* Add security key test

* Fix type import

* Move new test in `verification.spec.ts`

* The nest tests work with the new crypto

* Fix import yupe
pull/28217/head
Florian Duros 2023-07-11 16:18:46 +02:00 committed by GitHub
parent a8f632ae19
commit 21a1bdf7b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 88 additions and 2 deletions

View File

@ -36,7 +36,11 @@ describe("Device verification", () => {
cy.window({ log: false }).should("have.property", "matrixcs");
// Create a new device for alice
cy.getBot(homeserver, { rustCrypto: true, bootstrapCrossSigning: true }).then((bot) => {
cy.getBot(homeserver, {
rustCrypto: true,
bootstrapCrossSigning: true,
bootstrapSecretStorage: true,
}).then((bot) => {
aliceBotClient = bot;
});
});
@ -87,6 +91,51 @@ describe("Device verification", () => {
checkDeviceIsCrossSigned();
});
it("Verify device during login with Security Phrase", () => {
logIntoElement(homeserver.baseUrl, aliceBotClient.getUserId(), aliceBotClient.__cypress_password);
// Select the security phrase
cy.get(".mx_AuthPage").within(() => {
cy.findByRole("button", { name: "Verify with Security Key or Phrase" }).click();
});
// Fill the passphrase
cy.get(".mx_Dialog").within(() => {
cy.get("input").type("new passphrase");
cy.contains(".mx_Dialog_primary:not([disabled])", "Continue").click();
});
cy.get(".mx_AuthPage").within(() => {
cy.findByRole("button", { name: "Done" }).click();
});
// Check that our device is now cross-signed
checkDeviceIsCrossSigned();
});
it("Verify device during login with Security Key", () => {
logIntoElement(homeserver.baseUrl, aliceBotClient.getUserId(), aliceBotClient.__cypress_password);
// Select the security phrase
cy.get(".mx_AuthPage").within(() => {
cy.findByRole("button", { name: "Verify with Security Key or Phrase" }).click();
});
// Fill the security key
cy.get(".mx_Dialog").within(() => {
cy.findByRole("button", { name: "use your Security Key" }).click();
cy.get("#mx_securityKey").type(aliceBotClient.__cypress_recovery_key.encodedPrivateKey);
cy.contains(".mx_Dialog_primary:not([disabled])", "Continue").click();
});
cy.get(".mx_AuthPage").within(() => {
cy.findByRole("button", { name: "Done" }).click();
});
// Check that our device is now cross-signed
checkDeviceIsCrossSigned();
});
it("Handle incoming verification request with SAS", () => {
logIntoElement(homeserver.baseUrl, aliceBotClient.getUserId(), aliceBotClient.__cypress_password);

View File

@ -17,6 +17,8 @@ limitations under the License.
/// <reference types="cypress" />
import type { ISendEventResponse, MatrixClient, Room } from "matrix-js-sdk/src/matrix";
import type { GeneratedSecretStorageKey } from "matrix-js-sdk/src/crypto-api";
import type { AddSecretStorageKeyOpts } from "matrix-js-sdk/src/secret-storage";
import { HomeserverInstance } from "../plugins/utils/homeserver";
import { Credentials } from "./homeserver";
import Chainable = Cypress.Chainable;
@ -47,6 +49,10 @@ interface CreateBotOpts {
* Whether to use the rust crypto impl. Defaults to false (for now!)
*/
rustCrypto?: boolean;
/**
* Whether or not to bootstrap the secret storage
*/
bootstrapSecretStorage?: boolean;
}
const defaultCreateBotOptions = {
@ -58,6 +64,7 @@ const defaultCreateBotOptions = {
export interface CypressBot extends MatrixClient {
__cypress_password: string;
__cypress_recovery_key: GeneratedSecretStorageKey;
}
declare global {
@ -143,6 +150,24 @@ function setupBotClient(
Object.assign(keys, k);
};
// Store the cached secret storage key and return it when `getSecretStorageKey` is called
let cachedKey: { keyId: string; key: Uint8Array };
const cacheSecretStorageKey = (keyId: string, keyInfo: AddSecretStorageKeyOpts, key: Uint8Array) => {
cachedKey = {
keyId,
key,
};
};
const getSecretStorageKey = () => Promise.resolve<[string, Uint8Array]>([cachedKey.keyId, cachedKey.key]);
const cryptoCallbacks = {
getCrossSigningKey,
saveCrossSigningKeys,
cacheSecretStorageKey,
getSecretStorageKey,
};
const cli = new win.matrixcs.MatrixClient({
baseUrl: homeserver.baseUrl,
userId: credentials.userId,
@ -151,7 +176,7 @@ function setupBotClient(
store: new win.matrixcs.MemoryStore(),
scheduler: new win.matrixcs.MatrixScheduler(),
cryptoStore: new win.matrixcs.MemoryCryptoStore(),
cryptoCallbacks: { getCrossSigningKey, saveCrossSigningKeys },
cryptoCallbacks,
});
if (opts.autoAcceptInvites) {
@ -192,6 +217,18 @@ function setupBotClient(
},
});
}
if (opts.bootstrapSecretStorage) {
const passphrase = "new passphrase";
const recoveryKey = await cli.getCrypto().createRecoveryKeyFromPassphrase(passphrase);
Object.assign(cli, { __cypress_recovery_key: recoveryKey });
await cli.getCrypto()!.bootstrapSecretStorage({
setupNewSecretStorage: true,
createSecretStorageKey: () => Promise.resolve(recoveryKey),
});
}
return cli;
},
);