You've already forked element-web
mirror of
https://github.com/element-hq/element-web.git
synced 2025-08-08 03:42:14 +03:00
Encryption tab: hide Advanced
section when the key storage is out of sync (#29129)
* fix(encryption tab): hide the advanced section when the secrets are not cached locally The secret verification is now made at the level of `EncryptionUserSettingsTab` instead at the `RecoveryPanel` level. In the `EncryptionUserSettingsTab`, we decide to only display `RecoveryPanelOutOfSync` in case of uncached secrets. `RecoveryPanelOutOfSync` is simplified version of `RecoveryPanel` handling only the `secrets_not_cached` case. * refactor(encryption tab): simplify the `RecoveryPanel` without having to handle the missing secrets * test(encryption tab): move test about cached secrets in `EncryptionUserSettingsTab-test.tsx` * test(encryption tab): move e2e test which are testing all the encryption tab in `encryption-tab.spec.ts * refactor(encryption tab): move `RecoveryPanelOutOfSync` in its own file - fix typos - call onFinish after accessSecretStorage - onFinish doesn't need to be asynchronous * doc(encryption tab): improve documentation when the secrets are not cached locally * test(encryption tab): improve test documentation and naming * doc(encryption tab): improve `RecoveryPanelOutOfSync` documentation
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { GeneratedSecretStorageKey } from "matrix-js-sdk/src/crypto-api";
|
||||
|
||||
import { test, expect } from ".";
|
||||
import {
|
||||
checkDeviceIsConnectedKeyBackup,
|
||||
checkDeviceIsCrossSigned,
|
||||
createBot,
|
||||
deleteCachedSecrets,
|
||||
verifySession,
|
||||
} from "../../crypto/utils";
|
||||
|
||||
test.describe("Encryption tab", () => {
|
||||
test.use({
|
||||
displayName: "Alice",
|
||||
});
|
||||
|
||||
let recoveryKey: GeneratedSecretStorageKey;
|
||||
let expectedBackupVersion: string;
|
||||
|
||||
test.beforeEach(async ({ page, homeserver, credentials }) => {
|
||||
// The bot bootstraps cross-signing, creates a key backup and sets up a recovery key
|
||||
const res = await createBot(page, homeserver, credentials);
|
||||
recoveryKey = res.recoveryKey;
|
||||
expectedBackupVersion = res.expectedBackupVersion;
|
||||
});
|
||||
|
||||
test(
|
||||
"should show a 'Verify this device' button if the device is unverified",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, util }) => {
|
||||
const dialog = await util.openEncryptionTab();
|
||||
const content = util.getEncryptionTabContent();
|
||||
|
||||
// The user's device is in an unverified state, therefore the only option available to them here is to verify it
|
||||
const verifyButton = dialog.getByRole("button", { name: "Verify this device" });
|
||||
await expect(verifyButton).toBeVisible();
|
||||
await expect(content).toMatchScreenshot("verify-device-encryption-tab.png");
|
||||
await verifyButton.click();
|
||||
|
||||
await util.verifyDevice(recoveryKey);
|
||||
|
||||
await expect(content).toMatchScreenshot("default-tab.png", {
|
||||
mask: [content.getByTestId("deviceId"), content.getByTestId("sessionKey")],
|
||||
});
|
||||
|
||||
// Check that our device is now cross-signed
|
||||
await checkDeviceIsCrossSigned(app);
|
||||
|
||||
// Check that the current device is connected to key backup
|
||||
// The backup decryption key should be in cache also, as we got it directly from the 4S
|
||||
await checkDeviceIsConnectedKeyBackup(app, expectedBackupVersion, true);
|
||||
},
|
||||
);
|
||||
|
||||
// Test what happens if the cross-signing secrets are in secret storage but are not cached in the local DB.
|
||||
//
|
||||
// This can happen if we verified another device and secret-gossiping failed, or the other device itself lacked the secrets.
|
||||
// We simulate this case by deleting the cached secrets in the indexedDB.
|
||||
test(
|
||||
"should prompt to enter the recovery key when the secrets are not cached locally",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, util }) => {
|
||||
await verifySession(app, "new passphrase");
|
||||
// We need to delete the cached secrets
|
||||
await deleteCachedSecrets(page);
|
||||
|
||||
await util.openEncryptionTab();
|
||||
// We ask the user to enter the recovery key
|
||||
const dialog = util.getEncryptionTabContent();
|
||||
const enterKeyButton = dialog.getByRole("button", { name: "Enter recovery key" });
|
||||
await expect(enterKeyButton).toBeVisible();
|
||||
await expect(dialog).toMatchScreenshot("out-of-sync-recovery.png");
|
||||
await enterKeyButton.click();
|
||||
|
||||
// Fill the recovery key
|
||||
await util.enterRecoveryKey(recoveryKey);
|
||||
await expect(dialog).toMatchScreenshot("default-tab.png", {
|
||||
mask: [dialog.getByTestId("deviceId"), dialog.getByTestId("sessionKey")],
|
||||
});
|
||||
|
||||
// Check that our device is now cross-signed
|
||||
await checkDeviceIsCrossSigned(app);
|
||||
|
||||
// Check that the current device is connected to key backup
|
||||
// The backup decryption key should be in cache also, as we got it directly from the 4S
|
||||
await checkDeviceIsConnectedKeyBackup(app, expectedBackupVersion, true);
|
||||
},
|
||||
);
|
||||
});
|
Reference in New Issue
Block a user