Skip to content

Commit

Permalink
Use new labels when changing the recovery key
Browse files Browse the repository at this point in the history
  • Loading branch information
florianduros committed Jan 10, 2025
1 parent 0a52b7c commit e5dea48
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 19 deletions.
8 changes: 5 additions & 3 deletions playwright/e2e/settings/encryption-user-tab/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,19 @@ class Helpers {
/**
* Get the security key from the clipboard and fill in the input field
* Then click on the finish button
* @param title - The title of the dialog
* @param confirmButtonLabel - The label of the confirm button
* @param screenshot
*/
async confirmRecoveryKey(screenshot: `${string}.png`) {
async confirmRecoveryKey(title: string, confirmButtonLabel: string, screenshot: `${string}.png`) {
const dialog = this.getEncryptionTabContent();
await expect(dialog.getByText("Enter your recovery key to confirm")).toBeVisible();
await expect(dialog.getByText(title, { exact: true })).toBeVisible();
await expect(dialog).toMatchScreenshot(screenshot);

const handle = await this.page.evaluateHandle(() => navigator.clipboard.readText());
const clipboardContent = await handle.jsonValue();
await dialog.getByRole("textbox").fill(clipboardContent);
await dialog.getByRole("button", { name: "Finish set up" }).click();
await dialog.getByRole("button", { name: confirmButtonLabel }).click();
await expect(dialog).toMatchScreenshot("default-recovery.png");
}
}
12 changes: 10 additions & 2 deletions playwright/e2e/settings/encryption-user-tab/recovery.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,11 @@ test.describe("Recovery section in Encryption tab", () => {
await dialog.getByRole("button", { name: "Continue" }).click();

// Confirm the recovery key
await util.confirmRecoveryKey("change-key-2-encryption-tab.png");
await util.confirmRecoveryKey(
"Enter your new recovery key",
"Confirm new recovery key",
"change-key-2-encryption-tab.png",
);
},
);

Expand Down Expand Up @@ -102,7 +106,11 @@ test.describe("Recovery section in Encryption tab", () => {
await dialog.getByRole("button", { name: "Continue" }).click();

// Confirm the recovery key
await util.confirmRecoveryKey("set-up-key-3-encryption-tab.png");
await util.confirmRecoveryKey(
"Enter your recovery key to confirm",
"Finish set up",
"set-up-key-3-encryption-tab.png",
);

// The recovery key is now set up and the user can change it
await expect(dialog.getByRole("button", { name: "Change recovery key" })).toBeVisible();
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 36 additions & 9 deletions src/components/views/settings/encryption/ChangeRecoveryKey.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,15 @@ import { withSecretStorageKeyCache } from "../../../../SecurityManager";
* - `inform_user`: The user is informed about the recovery key.
* - `save_key_setup_flow`: The user is asked to save the new recovery key during the setup flow.
* - `save_key_change_flow`: The user is asked to save the new recovery key during the change key flow.
* - `confirm`: The user is asked to confirm the new recovery key.
* - `confirm_key_setup_flow`: The user is asked to confirm the new recovery key during the set up flow.
* - `confirm_key_change_flow`: The user is asked to confirm the new recovery key during the change key flow.
*/
type State = "inform_user" | "save_key_setup_flow" | "save_key_change_flow" | "confirm";
type State =
| "inform_user"
| "save_key_setup_flow"
| "save_key_change_flow"
| "confirm_key_setup_flow"
| "confirm_key_change_flow";

interface ChangeRecoveryKeyProps {
/**
Expand Down Expand Up @@ -89,12 +95,19 @@ export function ChangeRecoveryKey({
<KeyPanel
// encodedPrivateKey is always defined, the optional typing is incorrect
recoveryKey={recoveryKey.encodedPrivateKey!}
onConfirmClick={() => setState("confirm")}
onConfirmClick={() =>
setState((currentState) =>
currentState === "save_key_change_flow"
? "confirm_key_change_flow"
: "confirm_key_setup_flow",
)
}
onCancelClick={onCancelClick}
/>
);
break;
case "confirm":
case "confirm_key_setup_flow":
case "confirm_key_change_flow":
// Ask the user to enter the recovery key they just save to confirm it.
content = (
<KeyForm
Expand All @@ -120,6 +133,11 @@ export function ChangeRecoveryKey({
logger.error("Failed to bootstrap secret storage", e);
}
}}
submitButtonLabel={
state === "confirm_key_setup_flow"
? _t("settings|encryption|recovery|set_up_recovery_confirm_button")
: _t("settings|encryption|recovery|change_recovery_confirm_button")
}
/>
);
}
Expand Down Expand Up @@ -181,10 +199,15 @@ function getLabels(state: State): Labels {
title: _t("settings|encryption|recovery|change_recovery_key_title"),
description: _t("settings|encryption|recovery|change_recovery_key_description"),
};
case "confirm":
case "confirm_key_setup_flow":
return {
title: _t("settings|encryption|recovery|confirm_title"),
description: _t("settings|encryption|recovery|confirm_description"),
title: _t("settings|encryption|recovery|set_up_recovery_confirm_title"),
description: _t("settings|encryption|recovery|set_up_recovery_confirm_description"),
};
case "confirm_key_change_flow":
return {
title: _t("settings|encryption|recovery|change_recovery_confirm_title"),
description: _t("settings|encryption|recovery|change_recovery_confirm_description"),
};
}
}
Expand Down Expand Up @@ -279,14 +302,18 @@ interface KeyFormProps {
* The recovery key to confirm.
*/
recoveryKey: string;
/**
* The label for the submit button.
*/
submitButtonLabel: string;
}

/**
* The form to confirm the recovery key.
* The finish button is disabled until the key is filled and valid.
* The entered key is valid if it matches the recovery key.
*/
function KeyForm({ onCancelClick, onSubmit, recoveryKey }: KeyFormProps): JSX.Element {
function KeyForm({ onCancelClick, onSubmit, recoveryKey, submitButtonLabel }: KeyFormProps): JSX.Element {
// Undefined by default, as the key is not filled yet
const [isKeyValid, setIsKeyValid] = useState<boolean>();
const isKeyInvalidAndFilled = isKeyValid === false;
Expand Down Expand Up @@ -316,7 +343,7 @@ function KeyForm({ onCancelClick, onSubmit, recoveryKey }: KeyFormProps): JSX.El
)}
</Field>
<div className="mx_ChangeRecoveryKey_footer">
<Button disabled={!isKeyValid}>{_t("settings|encryption|recovery|confirm_finish")}</Button>
<Button disabled={!isKeyValid}>{submitButtonLabel}</Button>
<Button kind="tertiary" onClick={onCancelClick}>
{_t("action|cancel")}
</Button>
Expand Down
11 changes: 7 additions & 4 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -2472,19 +2472,22 @@
"device_not_verified_title": "Device not verified",
"dialog_title": "<strong>Settings:</strong> Encryption",
"recovery": {
"change_recovery_confirm_button": "Confirm new recovery key",
"change_recovery_confirm_description": "Enter your new recovery key below to finish. Your old one will no longer work.",
"change_recovery_confirm_title": "Enter your new recovery key",
"change_recovery_key": "Change recovery key",
"change_recovery_key_description": "Get a new recovery key if you've lost your existing one. After changing your recovery key, your old one will no longer work.",
"change_recovery_key_description": "Write down this new recovery key somewhere safe. Then click Continue to confirm the change.",
"change_recovery_key_title": "Change recovery key?",
"confirm_description": "Enter the recovery key shown on the previous screen to finish setting up recovery.",
"confirm_finish": "Finish set up",
"confirm_title": "Enter your recovery key to confirm",
"description": "Recover your cryptographic identity and message history with a recovery key if you’ve lost all your existing devices.",
"enter_key_error": "The recovery key you entered is not correct.",
"enter_recovery_key": "Enter recovery key",
"key_storage_warning": "Your key storage is out of sync. Click the button below to fix the problem.",
"save_key_description": "Do not share this with anyone!",
"save_key_title": "Recovery key",
"set_up_recovery": "Set up recovery",
"set_up_recovery_confirm_button": "Finish set up",
"set_up_recovery_confirm_description": "Enter the recovery key shown on the previous screen to finish setting up recovery.",
"set_up_recovery_confirm_title": "Enter your recovery key to confirm",
"set_up_recovery_description": "Your key storage is protected by a recovery key. If you need a new recovery key after setup, you can recreate it by selecting ‘%(changeRecoveryKeyButton)s’.",
"set_up_recovery_save_key_description": "Write down this recovery key somewhere safe, like a password manager, encrypted note, or a physical safe.",
"set_up_recovery_save_key_title": "Save your recovery key somewhere safe",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ exports[`<ChangeRecoveryKey /> flow to change the recovery key should display th
Change recovery key?
</h2>
<span>
Get a new recovery key if you've lost your existing one. After changing your recovery key, your old one will no longer work.
Write down this new recovery key somewhere safe. Then click Continue to confirm the change.
</span>
</div>
<div
Expand Down

0 comments on commit e5dea48

Please sign in to comment.