test e2e: use encryption tab instead of Security & Settings tab in crypto.spec.ts (#29595)
* test(e2e crypto): use encryption tab instead of Security & Settings tab in crypto.spec.ts * test(e2e): remove wrong comment * test(e2e crypto): keep `downloadKeysForUsers` * test(e2e crypto): enter only password * test: fix typo
This commit is contained in:
@@ -8,14 +8,7 @@ Please see LICENSE files in the repository root for full details.
|
|||||||
|
|
||||||
import type { Page } from "@playwright/test";
|
import type { Page } from "@playwright/test";
|
||||||
import { expect, test } from "../../element-web-test";
|
import { expect, test } from "../../element-web-test";
|
||||||
import {
|
import { autoJoin, createSharedRoomWithUser, enableKeyBackup, verify } from "./utils";
|
||||||
autoJoin,
|
|
||||||
completeCreateSecretStorageDialog,
|
|
||||||
copyAndContinue,
|
|
||||||
createSharedRoomWithUser,
|
|
||||||
enableKeyBackup,
|
|
||||||
verify,
|
|
||||||
} from "./utils";
|
|
||||||
import { type Bot } from "../../pages/bot";
|
import { type Bot } from "../../pages/bot";
|
||||||
import { type ElementAppPage } from "../../pages/ElementAppPage";
|
import { type ElementAppPage } from "../../pages/ElementAppPage";
|
||||||
import { isDendrite } from "../../plugins/homeserver/dendrite";
|
import { isDendrite } from "../../plugins/homeserver/dendrite";
|
||||||
@@ -84,86 +77,43 @@ test.describe("Cryptography", function () {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const isDeviceVerified of [true, false]) {
|
/**
|
||||||
test.describe(`setting up secure key backup should work isDeviceVerified=${isDeviceVerified}`, () => {
|
* Verify that the `m.cross_signing.${keyType}` key is available on the account data on the server
|
||||||
/**
|
* @param keyType
|
||||||
* Verify that the `m.cross_signing.${keyType}` key is available on the account data on the server
|
*/
|
||||||
* @param keyType
|
async function verifyKey(app: ElementAppPage, keyType: "master" | "self_signing" | "user_signing") {
|
||||||
*/
|
const accountData: { encrypted: Record<string, Record<string, string>> } = await app.client.evaluate(
|
||||||
async function verifyKey(app: ElementAppPage, keyType: "master" | "self_signing" | "user_signing") {
|
(cli, keyType) => cli.getAccountDataFromServer(`m.cross_signing.${keyType}`),
|
||||||
const accountData: { encrypted: Record<string, Record<string, string>> } = await app.client.evaluate(
|
keyType,
|
||||||
(cli, keyType) => cli.getAccountDataFromServer(`m.cross_signing.${keyType}`),
|
);
|
||||||
keyType,
|
|
||||||
);
|
|
||||||
expect(accountData.encrypted).toBeDefined();
|
|
||||||
const keys = Object.keys(accountData.encrypted);
|
|
||||||
const key = accountData.encrypted[keys[0]];
|
|
||||||
expect(key.ciphertext).toBeDefined();
|
|
||||||
expect(key.iv).toBeDefined();
|
|
||||||
expect(key.mac).toBeDefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
test("by recovery code", async ({ page, app, user: aliceCredentials }) => {
|
expect(accountData.encrypted).toBeDefined();
|
||||||
// Verified the device
|
const keys = Object.keys(accountData.encrypted);
|
||||||
if (isDeviceVerified) {
|
const key = accountData.encrypted[keys[0]];
|
||||||
await app.client.bootstrapCrossSigning(aliceCredentials);
|
expect(key.ciphertext).toBeDefined();
|
||||||
}
|
expect(key.iv).toBeDefined();
|
||||||
|
expect(key.mac).toBeDefined();
|
||||||
await page.route("**/_matrix/client/v3/keys/signatures/upload", async (route) => {
|
|
||||||
// We delay this API otherwise the `Setting up keys` may happen too quickly and cause flakiness
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
||||||
await route.continue();
|
|
||||||
});
|
|
||||||
|
|
||||||
await app.settings.openUserSettings("Security & Privacy");
|
|
||||||
await page.getByRole("button", { name: "Set up Secure Backup" }).click();
|
|
||||||
|
|
||||||
await completeCreateSecretStorageDialog(page);
|
|
||||||
|
|
||||||
// Verify that the SSSS keys are in the account data stored in the server
|
|
||||||
await verifyKey(app, "master");
|
|
||||||
await verifyKey(app, "self_signing");
|
|
||||||
await verifyKey(app, "user_signing");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("by passphrase", async ({ page, app, user: aliceCredentials }) => {
|
|
||||||
// Verified the device
|
|
||||||
if (isDeviceVerified) {
|
|
||||||
await app.client.bootstrapCrossSigning(aliceCredentials);
|
|
||||||
}
|
|
||||||
|
|
||||||
await app.settings.openUserSettings("Security & Privacy");
|
|
||||||
await page.getByRole("button", { name: "Set up Secure Backup" }).click();
|
|
||||||
|
|
||||||
const dialog = page.locator(".mx_Dialog");
|
|
||||||
// Select passphrase option
|
|
||||||
await dialog.getByText("Enter a Security Phrase").click();
|
|
||||||
await dialog.getByRole("button", { name: "Continue" }).click();
|
|
||||||
|
|
||||||
// Fill passphrase input
|
|
||||||
await dialog.locator("input").fill("new passphrase for setting up a secure key backup");
|
|
||||||
await dialog.locator(".mx_Dialog_primary:not([disabled])", { hasText: "Continue" }).click();
|
|
||||||
// Confirm passphrase
|
|
||||||
await dialog.locator("input").fill("new passphrase for setting up a secure key backup");
|
|
||||||
await dialog.locator(".mx_Dialog_primary:not([disabled])", { hasText: "Continue" }).click();
|
|
||||||
|
|
||||||
await copyAndContinue(page);
|
|
||||||
|
|
||||||
await expect(dialog.getByText("Secure Backup successful")).toBeVisible();
|
|
||||||
await dialog.getByRole("button", { name: "Done" }).click();
|
|
||||||
await expect(dialog.getByText("Secure Backup successful")).not.toBeVisible();
|
|
||||||
|
|
||||||
// Verify that the SSSS keys are in the account data stored in the server
|
|
||||||
await verifyKey(app, "master");
|
|
||||||
await verifyKey(app, "self_signing");
|
|
||||||
await verifyKey(app, "user_signing");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("Setting up key backup by recovery key", async ({ page, app, user: aliceCredentials }) => {
|
||||||
|
await app.client.bootstrapCrossSigning(aliceCredentials);
|
||||||
|
|
||||||
|
await enableKeyBackup(app);
|
||||||
|
|
||||||
|
// Wait for the cross signing keys to be uploaded
|
||||||
|
// Waiting for "Change the recovery key" button ensure that all the secrets are uploaded and cached locally
|
||||||
|
const encryptionTab = await app.settings.openUserSettings("Encryption");
|
||||||
|
await expect(encryptionTab.getByRole("button", { name: "Change recovery key" })).toBeVisible();
|
||||||
|
|
||||||
|
// Verify that the SSSS keys are in the account data stored in the server
|
||||||
|
await verifyKey(app, "master");
|
||||||
|
await verifyKey(app, "self_signing");
|
||||||
|
await verifyKey(app, "user_signing");
|
||||||
|
});
|
||||||
|
|
||||||
test("Can reset cross-signing keys", async ({ page, app, user: aliceCredentials }) => {
|
test("Can reset cross-signing keys", async ({ page, app, user: aliceCredentials }) => {
|
||||||
await app.client.bootstrapCrossSigning(aliceCredentials);
|
await app.client.bootstrapCrossSigning(aliceCredentials);
|
||||||
const secretStorageKey = await enableKeyBackup(app);
|
await enableKeyBackup(app);
|
||||||
|
|
||||||
// Fetch the current cross-signing keys
|
// Fetch the current cross-signing keys
|
||||||
async function fetchMasterKey() {
|
async function fetchMasterKey() {
|
||||||
@@ -177,18 +127,15 @@ test.describe("Cryptography", function () {
|
|||||||
return k;
|
return k;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const masterKey1 = await fetchMasterKey();
|
const masterKey1 = await fetchMasterKey();
|
||||||
|
|
||||||
// Find the "reset cross signing" button, and click it
|
// Find "the Reset cryptographic identity" button
|
||||||
await app.settings.openUserSettings("Security & Privacy");
|
const encryptionTab = await app.settings.openUserSettings("Encryption");
|
||||||
await page.locator("div.mx_CrossSigningPanel_buttonRow").getByRole("button", { name: "Reset" }).click();
|
await encryptionTab.getByRole("button", { name: "Reset cryptographic identity" }).click();
|
||||||
|
|
||||||
// Confirm
|
// Confirm
|
||||||
await page.getByRole("button", { name: "Clear cross-signing keys" }).click();
|
await encryptionTab.getByRole("button", { name: "Continue" }).click();
|
||||||
|
|
||||||
// Enter the 4S key
|
|
||||||
await page.getByPlaceholder("Recovery Key").fill(secretStorageKey);
|
|
||||||
await page.getByRole("button", { name: "Continue" }).click();
|
|
||||||
|
|
||||||
// Enter the password
|
// Enter the password
|
||||||
await page.getByPlaceholder("Password").fill(aliceCredentials.password);
|
await page.getByPlaceholder("Password").fill(aliceCredentials.password);
|
||||||
@@ -198,9 +145,6 @@ test.describe("Cryptography", function () {
|
|||||||
const masterKey2 = await fetchMasterKey();
|
const masterKey2 = await fetchMasterKey();
|
||||||
expect(masterKey1).not.toEqual(masterKey2);
|
expect(masterKey1).not.toEqual(masterKey2);
|
||||||
}).toPass();
|
}).toPass();
|
||||||
|
|
||||||
// The dialog should have gone away
|
|
||||||
await expect(page.locator(".mx_Dialog")).toHaveCount(1);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test(
|
test(
|
||||||
|
|||||||
Reference in New Issue
Block a user