diff --git a/playwright/e2e/crypto/toasts.spec.ts b/playwright/e2e/crypto/toasts.spec.ts index 905a8fb1ed..5b80f822a0 100644 --- a/playwright/e2e/crypto/toasts.spec.ts +++ b/playwright/e2e/crypto/toasts.spec.ts @@ -29,7 +29,9 @@ test.describe("Key storage out of sync toast", () => { }); 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 + // We need to wait for there to be two toasts as the wait below won't work in isolation: + // playwright only evaluates the 'first()' call initially, not subsequent times it checks, so + // it would always be checking the same toast, even if another one is now the first. await expect(page.getByRole("alert")).toHaveCount(2); await expect(page.getByRole("alert").first()).toMatchScreenshot("key-storage-out-of-sync-toast.png"); diff --git a/playwright/e2e/crypto/utils.ts b/playwright/e2e/crypto/utils.ts index a317a2a215..0030dc02d0 100644 --- a/playwright/e2e/crypto/utils.ts +++ b/playwright/e2e/crypto/utils.ts @@ -221,6 +221,9 @@ export async function logIntoElement(page: Page, credentials: Credentials, secur await page.locator(".mx_AuthPage").getByRole("button", { name: "Verify with Recovery Key" }).click(); const useSecurityKey = page.locator(".mx_Dialog").getByRole("button", { name: "use your Recovery Key" }); + // If the user has set a recovery *passphrase*, they'll be prompted for that first and have to click + // through to enter the recovery key which is what we have here. If they haven't, they'll be prompted + // for a recovery key straight away. We click the button if it's there so this works in both cases. if (await useSecurityKey.isVisible()) { await useSecurityKey.click(); } diff --git a/src/components/views/dialogs/UserSettingsDialog.tsx b/src/components/views/dialogs/UserSettingsDialog.tsx index 6a94ae8842..4eb0a66f1a 100644 --- a/src/components/views/dialogs/UserSettingsDialog.tsx +++ b/src/components/views/dialogs/UserSettingsDialog.tsx @@ -50,6 +50,11 @@ import { EncryptionUserSettingsTab } from "../settings/tabs/user/EncryptionUserS interface IProps { initialTabId?: UserTab; showMsc4108QrCode?: boolean; + /** + * If `true`, the flow for a user to reset their encryption will be shown. In this case, `initialTabId` must be `UserTab.Encryption`. + * + * If false or undefined, show the tab as normal. + */ showResetIdentity?: boolean; sdkContext: SdkContextClass; onFinished(): void; @@ -92,7 +97,7 @@ 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 these props in state as changing tabs back and forth should clear it + // store these props in state as changing tabs back and forth should clear them const [showMsc4108QrCode, setShowMsc4108QrCode] = useState(props.showMsc4108QrCode); const [showResetIdentity, setShowResetIdentity] = useState(props.showResetIdentity); diff --git a/src/components/views/settings/encryption/ResetIdentityPanel.tsx b/src/components/views/settings/encryption/ResetIdentityPanel.tsx index 6c25985a22..9507e52872 100644 --- a/src/components/views/settings/encryption/ResetIdentityPanel.tsx +++ b/src/components/views/settings/encryption/ResetIdentityPanel.tsx @@ -31,8 +31,10 @@ interface ResetIdentityPanelProps { /** * 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"; diff --git a/src/components/views/settings/tabs/user/EncryptionUserSettingsTab.tsx b/src/components/views/settings/tabs/user/EncryptionUserSettingsTab.tsx index 3af555ed49..987b1d95b6 100644 --- a/src/components/views/settings/tabs/user/EncryptionUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/EncryptionUserSettingsTab.tsx @@ -37,7 +37,7 @@ import { DeleteKeyStoragePanel } from "../../encryption/DeleteKeyStoragePanel"; * This happens when the user has a recovery key and the user clicks on "Change recovery key" button of the RecoveryPanel. * - "set_recovery_key": The panel to show when the user is setting up their recovery key. * This happens when the user doesn't have a key a recovery key and the user clicks on "Set up recovery key" button of the RecoveryPanel. - * - "reset_identity_compromised": The panel to show when the user is resetting their identity, in te case where their key is compromised. + * - "reset_identity_compromised": The panel to show when the user is resetting their identity, in the case where their key is compromised. * - "reset_identity_forgot": The panel to show when the user is resetting their identity, in the case where they forgot their recovery key. * - "secrets_not_cached": The secrets are not cached locally. This can happen if we verified another device and secret-gossiping failed, or the other device itself lacked the secrets. * If the "set_up_encryption" and "secrets_not_cached" conditions are both filled, "set_up_encryption" prevails. @@ -55,9 +55,9 @@ export type State = | "secrets_not_cached" | "key_storage_delete"; -interface EncryptionUserSettingsTabProps { +interface Props { /** - * If the tab should start in a state other than the deasult + * If the tab should start in a state other than the default */ initialState?: State; } @@ -65,7 +65,7 @@ interface EncryptionUserSettingsTabProps { /** * The encryption settings tab. */ -export function EncryptionUserSettingsTab({ initialState = "loading" }: EncryptionUserSettingsTabProps): JSX.Element { +export function EncryptionUserSettingsTab({ initialState = "loading" }: Props): JSX.Element { const [state, setState] = useState(initialState); const checkEncryptionState = useCheckEncryptionState(state, setState); diff --git a/src/toasts/SetupEncryptionToast.ts b/src/toasts/SetupEncryptionToast.ts index 8a743dfe8b..1613c5b9c9 100644 --- a/src/toasts/SetupEncryptionToast.ts +++ b/src/toasts/SetupEncryptionToast.ts @@ -161,6 +161,7 @@ export const showToast = (kind: Kind): void => { const onSecondaryClick = (): void => { if (kind === Kind.KEY_STORAGE_OUT_OF_SYNC) { + // Open the user settings dialog to the encryption tab and start the flow to reset encryption const payload: OpenToTabPayload = { action: Action.ViewUserSettings, initialTabId: UserTab.Encryption,