From 159acefb5e6b9cf5d5eaad7eff8d458745756fd2 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 4 Feb 2025 17:40:31 +0000 Subject: [PATCH 1/2] Wire up the "Forgot recovery key" button for the "Key storage out of sync" toast (#29138) * Wire up the "Forgot recovery key" button for the "Key storage out of sync" toast * Unused import & fix test * Test 'forgot' variant * Fix dependencies * Add more toast tests * Unused import * Test initialState in Encryption Tab * Let's see if github has any more luck running this test than me * Working playwright test with screenshot * year * Convert playwright test to use the bot client * Disambiguate Co-authored-by: Florian Duros * Add doc & do other part of rename * Split out into custom hook * Fix tests --------- Co-authored-by: Florian Duros (cherry picked from commit 9657d39cd6f5f9a2555717b510155bcaed8bfa23) --- playwright/e2e/crypto/toasts.spec.ts | 54 ++++++ playwright/e2e/crypto/utils.ts | 5 + .../key-storage-out-of-sync-toast-linux.png | Bin 0 -> 19162 bytes .../views/dialogs/UserSettingsDialog.tsx | 14 +- .../encryption/ResetIdentityPanel.tsx | 19 +- .../tabs/user/EncryptionUserSettingsTab.tsx | 55 ++++-- src/i18n/strings/en_EN.json | 1 + src/toasts/SetupEncryptionToast.ts | 27 ++- .../views/dialogs/UserSettingsDialog-test.tsx | 6 +- .../encryption/ResetIdentityPanel-test.tsx | 11 +- .../ResetIdentityPanel-test.tsx.snap | 180 ++++++++++++++++++ .../user/EncryptionUserSettingsTab-test.tsx | 17 +- .../toasts/SetupEncryptionToast-test.tsx | 35 +++- 13 files changed, 389 insertions(+), 35 deletions(-) create mode 100644 playwright/e2e/crypto/toasts.spec.ts create mode 100644 playwright/snapshots/crypto/toasts.spec.ts/key-storage-out-of-sync-toast-linux.png diff --git a/playwright/e2e/crypto/toasts.spec.ts b/playwright/e2e/crypto/toasts.spec.ts new file mode 100644 index 00000000000..7763cc29c21 --- /dev/null +++ b/playwright/e2e/crypto/toasts.spec.ts @@ -0,0 +1,54 @@ +/* + * 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 "../../element-web-test"; +import { createBot, deleteCachedSecrets, logIntoElement } from "./utils"; + +test.describe("Key storage out of sync toast", () => { + let recoveryKey: GeneratedSecretStorageKey; + + test.beforeEach(async ({ page, homeserver, credentials }) => { + const res = await createBot(page, homeserver, credentials); + recoveryKey = res.recoveryKey; + + await logIntoElement(page, credentials, recoveryKey.encodedPrivateKey); + + await deleteCachedSecrets(page); + + // We won't be prompted for crypto setup unless we have an e2e room, so make one + await page.getByRole("button", { name: "Add room" }).click(); + await page.getByRole("menuitem", { name: "New room" }).click(); + await page.getByRole("textbox", { name: "Name" }).fill("Test room"); + await page.getByRole("button", { name: "Create room" }).click(); + }); + + test("should prompt for recovery key if 'enter recovery key' pressed", { tag: "@screenshot" }, async ({ page }) => { + // Need to wait for 2 to appear since playwright only evaluates 'first()' initially, so the waiting won't work + await expect(page.getByRole("alert")).toHaveCount(2); + await expect(page.getByRole("alert").first()).toMatchScreenshot("key-storage-out-of-sync-toast.png"); + + await page.getByRole("button", { name: "Enter recovery key" }).click(); + await page.locator(".mx_Dialog").getByRole("button", { name: "use your Security Key" }).click(); + + await page.getByRole("textbox", { name: "Security key" }).fill(recoveryKey.encodedPrivateKey); + await page.getByRole("button", { name: "Continue" }).click(); + + await expect(page.getByRole("button", { name: "Enter recovery key" })).not.toBeVisible(); + }); + + test("should open settings to reset flow if 'forgot recovery key' pressed", async ({ page, app, credentials }) => { + await expect(page.getByRole("button", { name: "Enter recovery key" })).toBeVisible(); + + await page.getByRole("button", { name: "Forgot recovery key?" }).click(); + + await expect( + page.getByRole("heading", { name: "Forgot your recovery key? You’ll need to reset your identity." }), + ).toBeVisible(); + }); +}); diff --git a/playwright/e2e/crypto/utils.ts b/playwright/e2e/crypto/utils.ts index 6753ae651c3..d4e276094fc 100644 --- a/playwright/e2e/crypto/utils.ts +++ b/playwright/e2e/crypto/utils.ts @@ -214,6 +214,11 @@ export async function logIntoElement(page: Page, credentials: Credentials, secur // if a securityKey was given, verify the new device if (securityKey !== undefined) { await page.locator(".mx_AuthPage").getByRole("button", { name: "Verify with Security Key" }).click(); + + const useSecurityKey = page.locator(".mx_Dialog").getByRole("button", { name: "use your Security Key" }); + if (await useSecurityKey.isVisible()) { + await useSecurityKey.click(); + } // Fill in the security key await page.locator(".mx_Dialog").locator('input[type="password"]').fill(securityKey); await page.locator(".mx_Dialog_primary:not([disabled])", { hasText: "Continue" }).click(); diff --git a/playwright/snapshots/crypto/toasts.spec.ts/key-storage-out-of-sync-toast-linux.png b/playwright/snapshots/crypto/toasts.spec.ts/key-storage-out-of-sync-toast-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..8e335bd2323b56429f8b03fdbcefd5ed77e9d6f2 GIT binary patch literal 19162 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 literal 0 HcmV?d00001 diff --git a/src/components/views/dialogs/UserSettingsDialog.tsx b/src/components/views/dialogs/UserSettingsDialog.tsx index 75739a7f454..5203c9b0599 100644 --- a/src/components/views/dialogs/UserSettingsDialog.tsx +++ b/src/components/views/dialogs/UserSettingsDialog.tsx @@ -50,6 +50,7 @@ import { EncryptionUserSettingsTab } from "../settings/tabs/user/EncryptionUserS interface IProps { initialTabId?: UserTab; showMsc4108QrCode?: boolean; + showResetIdentity?: boolean; sdkContext: SdkContextClass; onFinished(): void; } @@ -91,8 +92,9 @@ function titleForTabID(tabId: UserTab): React.ReactNode { export default function UserSettingsDialog(props: IProps): JSX.Element { const voipEnabled = useSettingValue(UIFeature.Voip); const mjolnirEnabled = useSettingValue("feature_mjolnir"); - // store this prop in state as changing tabs back and forth should clear it + // store these props in state as changing tabs back and forth should clear it const [showMsc4108QrCode, setShowMsc4108QrCode] = useState(props.showMsc4108QrCode); + const [showResetIdentity, setShowResetIdentity] = useState(props.showResetIdentity); const getTabs = (): NonEmptyArray> => { const tabs: Tab[] = []; @@ -184,7 +186,12 @@ export default function UserSettingsDialog(props: IProps): JSX.Element { ); tabs.push( - new Tab(UserTab.Encryption, _td("settings|encryption|title"), , ), + new Tab( + UserTab.Encryption, + _td("settings|encryption|title"), + , + , + ), ); if (showLabsFlags() || SettingsStore.getFeatureSettingNames().some((k) => SettingsStore.getBetaInfo(k))) { @@ -219,8 +226,9 @@ export default function UserSettingsDialog(props: IProps): JSX.Element { const [activeTabId, _setActiveTabId] = useActiveTabWithDefault(getTabs(), UserTab.Account, props.initialTabId); const setActiveTabId = (tabId: UserTab): void => { _setActiveTabId(tabId); - // Clear this so switching away from the tab and back to it will not show the QR code again + // Clear these so switching away from the tab and back to it will not show the QR code again setShowMsc4108QrCode(false); + setShowResetIdentity(false); }; const [activeToast, toastRack] = useActiveToast(); diff --git a/src/components/views/settings/encryption/ResetIdentityPanel.tsx b/src/components/views/settings/encryption/ResetIdentityPanel.tsx index c9113e9fe70..b0a6b3fbf27 100644 --- a/src/components/views/settings/encryption/ResetIdentityPanel.tsx +++ b/src/components/views/settings/encryption/ResetIdentityPanel.tsx @@ -25,12 +25,21 @@ interface ResetIdentityPanelProps { * Called when the cancel button is clicked or when we go back in the breadcrumbs. */ onCancelClick: () => void; + + /** + * The variant of the panel to show. We show more warnings in the 'compromised' variant (no use in showing a user this + * warning if they have to reset because they no longer have their key) + * "compromised" is shown when the user chooses 'reset' explicitly in settings, usually because they believe their + * identity has been compromised. + * "forgot" is shown when the user has just forgotten their passphrase. + */ + variant: "compromised" | "forgot"; } /** * The panel for resetting the identity of the current user. */ -export function ResetIdentityPanel({ onCancelClick, onFinish }: ResetIdentityPanelProps): JSX.Element { +export function ResetIdentityPanel({ onCancelClick, onFinish, variant }: ResetIdentityPanelProps): JSX.Element { const matrixClient = useMatrixClientContext(); return ( @@ -44,7 +53,11 @@ export function ResetIdentityPanel({ onCancelClick, onFinish }: ResetIdentityPan
@@ -59,7 +72,7 @@ export function ResetIdentityPanel({ onCancelClick, onFinish }: ResetIdentityPan {_t("settings|encryption|advanced|breadcrumb_third_description")} - {_t("settings|encryption|advanced|breadcrumb_warning")} + {variant === "compromised" && {_t("settings|encryption|advanced|breadcrumb_warning")}}
+
    +
  1. + + Encryption + +
  2. +
  3. + + Reset encryption + +
  4. +
+ +
+
+
+ + + +
+

+ Forgot your recovery key? You’ll need to reset your identity. +

+
+
+
    +
  • + + Your account details, contacts, preferences, and chat list will be kept +
  • +
  • + + You will lose any message history that’s stored only on the server +
  • +
  • + + You will need to verify all your existing devices and contacts again +
  • +
+
+ +
+ +`; + exports[` should reset the encryption when the continue button is clicked 1`] = `