diff --git a/src/components/views/settings/encryption/ResetIdentityPanel.tsx b/src/components/views/settings/encryption/ResetIdentityPanel.tsx index 747b22fd59d..0f360a165a4 100644 --- a/src/components/views/settings/encryption/ResetIdentityPanel.tsx +++ b/src/components/views/settings/encryption/ResetIdentityPanel.tsx @@ -5,11 +5,11 @@ * Please see LICENSE files in the repository root for full details. */ -import { Breadcrumb, Button, VisualList, VisualListItem } from "@vector-im/compound-web"; +import { Breadcrumb, Button, InlineSpinner, VisualList, VisualListItem } from "@vector-im/compound-web"; import CheckIcon from "@vector-im/compound-design-tokens/assets/web/icons/check"; import InfoIcon from "@vector-im/compound-design-tokens/assets/web/icons/info"; import ErrorIcon from "@vector-im/compound-design-tokens/assets/web/icons/error-solid"; -import React, { type MouseEventHandler } from "react"; +import React, { useState, type MouseEventHandler } from "react"; import { _t } from "../../../../languageHandler"; import { EncryptionCard } from "./EncryptionCard"; @@ -44,6 +44,10 @@ interface ResetIdentityPanelProps { export function ResetIdentityPanel({ onCancelClick, onFinish, variant }: ResetIdentityPanelProps): JSX.Element { const matrixClient = useMatrixClientContext(); + // After the user clicks "Continue", we disable the button so it can't be + // clicked again, and warn the user not to close the window. + const [inProgress, setInProgress] = useState(false); + return ( <> - + {inProgress ? ( + + + {_t("settings|encryption|advanced|do_not_close_warning")} + + + ) : ( + + )} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 624beab0b88..06d869fc3be 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2479,6 +2479,7 @@ "breadcrumb_title_forgot": "Forgot your recovery key? You’ll need to reset your identity.", "breadcrumb_warning": "Only do this if you believe your account has been compromised.", "details_title": "Encryption details", + "do_not_close_warning": "Do not close this window until the reset is finished", "export_keys": "Export keys", "import_keys": "Import keys", "other_people_device_description": "By default in encrypted rooms, do not send encrypted messages to anyone until you’ve verified them", diff --git a/test/unit-tests/components/views/settings/encryption/ResetIdentityPanel-test.tsx b/test/unit-tests/components/views/settings/encryption/ResetIdentityPanel-test.tsx index 7b3095b5b46..b0928191ac4 100644 --- a/test/unit-tests/components/views/settings/encryption/ResetIdentityPanel-test.tsx +++ b/test/unit-tests/components/views/settings/encryption/ResetIdentityPanel-test.tsx @@ -7,6 +7,7 @@ import React from "react"; import { type MatrixClient } from "matrix-js-sdk/src/matrix"; +import { sleep } from "matrix-js-sdk/src/utils"; import { render, screen } from "jest-matrix-react"; import userEvent from "@testing-library/user-event"; @@ -30,7 +31,22 @@ describe("", () => { ); expect(asFragment()).toMatchSnapshot(); - await user.click(screen.getByRole("button", { name: "Continue" })); + // We need to pause the reset so that we can check that it's providing + // feedback to the user that something is happening. + let resolveResetEncryption; + const resetEncryptionPromise: Promise = new Promise((resolve) => { + resolveResetEncryption = resolve; + }); + jest.spyOn(matrixClient.getCrypto()!, "resetEncryption").mockImplementation(() => { + return resetEncryptionPromise; + }); + + const continueButton = screen.getByRole("button", { name: "Continue" }); + await user.click(continueButton); + expect(asFragment()).toMatchSnapshot(); + resolveResetEncryption!(); + await sleep(0); + expect(matrixClient.getCrypto()!.resetEncryption).toHaveBeenCalled(); expect(onFinish).toHaveBeenCalled(); }); diff --git a/test/unit-tests/components/views/settings/encryption/__snapshots__/ResetIdentityPanel-test.tsx.snap b/test/unit-tests/components/views/settings/encryption/__snapshots__/ResetIdentityPanel-test.tsx.snap index ce4f8b16abc..e8c0e64bb6d 100644 --- a/test/unit-tests/components/views/settings/encryption/__snapshots__/ResetIdentityPanel-test.tsx.snap +++ b/test/unit-tests/components/views/settings/encryption/__snapshots__/ResetIdentityPanel-test.tsx.snap @@ -159,6 +159,7 @@ exports[` should display the 'forgot recovery key' variant class="mx_EncryptionCard_buttons" > +
    +
  1. + + Encryption + +
  2. +
  3. + + Reset encryption + +
  4. +
+ +
+
+
+ + + +
+

+ Are you sure you want 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 +
  • +
+ + Only do this if you believe your account has been compromised. + +
+
+ +
+ + Do not close this window until the reset is finished + +
+
+
+ +`; diff --git a/test/unit-tests/components/views/settings/tabs/user/__snapshots__/EncryptionUserSettingsTab-test.tsx.snap b/test/unit-tests/components/views/settings/tabs/user/__snapshots__/EncryptionUserSettingsTab-test.tsx.snap index 5268748d668..c8e6701e0d0 100644 --- a/test/unit-tests/components/views/settings/tabs/user/__snapshots__/EncryptionUserSettingsTab-test.tsx.snap +++ b/test/unit-tests/components/views/settings/tabs/user/__snapshots__/EncryptionUserSettingsTab-test.tsx.snap @@ -333,6 +333,7 @@ exports[` should display the reset identity panel w class="mx_EncryptionCard_buttons" >