Hide recovery key when prompting for verification (#30471)
* Separate security_key_title from security_key_label since they differ in designs See https://www.figma.com/design/ZodBLtGnKmRTGJo5SGLnH3/ER-137--Excluding-Insecure-Devices?node-id=92-8818&t=02JILBe2n7sx7ljU-1 In parallel with this, I have updated security_key_title in localazy. * Hide recovery key on entry screen after login
This commit is contained in:
@@ -209,7 +209,7 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => {
|
||||
const dialog = page.locator(".mx_Dialog");
|
||||
// We use `pressSequentially` here to make sure that the FocusLock isn't causing us any problems
|
||||
// (cf https://github.com/element-hq/element-web/issues/30089)
|
||||
await dialog.locator("textarea").pressSequentially(recoveryKey);
|
||||
await dialog.getByTitle("Recovery key").pressSequentially(recoveryKey);
|
||||
await dialog.getByRole("button", { name: "Continue", disabled: false }).click();
|
||||
|
||||
await page.getByRole("button", { name: "Done" }).click();
|
||||
|
||||
@@ -228,7 +228,7 @@ export async function logIntoElement(page: Page, credentials: Credentials, secur
|
||||
await useSecurityKey.click();
|
||||
}
|
||||
// Fill in the recovery key
|
||||
await page.locator(".mx_Dialog").locator("textarea").fill(securityKey);
|
||||
await page.locator(".mx_Dialog").getByTitle("Recovery key").fill(securityKey);
|
||||
await page.getByRole("button", { name: "Continue", disabled: false }).click();
|
||||
await page.getByRole("button", { name: "Done" }).click();
|
||||
}
|
||||
@@ -263,7 +263,7 @@ export async function verifySession(app: ElementAppPage, securityKey: string) {
|
||||
const settings = await app.settings.openUserSettings("Encryption");
|
||||
await settings.getByRole("button", { name: "Verify this device" }).click();
|
||||
await app.page.getByRole("button", { name: "Verify with Recovery Key" }).click();
|
||||
await app.page.locator(".mx_Dialog").locator("textarea").fill(securityKey);
|
||||
await app.page.locator(".mx_Dialog").getByTitle("Recovery key").fill(securityKey);
|
||||
await app.page.getByRole("button", { name: "Continue", disabled: false }).click();
|
||||
await app.page.getByRole("button", { name: "Done" }).click();
|
||||
await app.settings.closeDialog();
|
||||
|
||||
@@ -15,6 +15,23 @@ Please see LICENSE files in the repository root for full details.
|
||||
}
|
||||
|
||||
.mx_AccessSecretStorageDialog_primaryContainer {
|
||||
.mx_AccessSecretStorageDialog_recoveryKeyEntry {
|
||||
/*
|
||||
* Be specific here to avoid "margin: 9px" from _common.pcss
|
||||
*/
|
||||
:not(.mx_textinput):not(.mx_Field):not(.mx_no_textinput) {
|
||||
input {
|
||||
/*
|
||||
* From figma: https://www.figma.com/design/ZodBLtGnKmRTGJo5SGLnH3/ER-137--Excluding-Insecure-Devices?node-id=102-43729&t=QmewENUd7f6Tmw9U-1
|
||||
*/
|
||||
width: 448px;
|
||||
height: 70px;
|
||||
margin: 0px;
|
||||
border: 1px solid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_AccessSecretStorageDialog_recoveryKeyFeedback {
|
||||
&::before {
|
||||
content: "";
|
||||
|
||||
@@ -6,14 +6,13 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { Button } from "@vector-im/compound-web";
|
||||
import { Button, PasswordInput } from "@vector-im/compound-web";
|
||||
import LockSolidIcon from "@vector-im/compound-design-tokens/assets/web/icons/lock-solid";
|
||||
import { debounce } from "lodash";
|
||||
import classNames from "classnames";
|
||||
import React, { type ChangeEvent, type FormEvent } from "react";
|
||||
import { type SecretStorage } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import Field from "../../elements/Field";
|
||||
import { Flex } from "../../../../shared-components/utils/Flex";
|
||||
import { _t } from "../../../../languageHandler";
|
||||
import { EncryptionCard } from "../../settings/encryption/EncryptionCard";
|
||||
@@ -53,7 +52,7 @@ interface IState {
|
||||
* Access Secure Secret Storage by requesting the user's passphrase.
|
||||
*/
|
||||
export default class AccessSecretStorageDialog extends React.PureComponent<IProps, IState> {
|
||||
private inputRef = React.createRef<HTMLTextAreaElement>();
|
||||
private inputRef = React.createRef<HTMLInputElement>();
|
||||
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
@@ -119,7 +118,7 @@ export default class AccessSecretStorageDialog extends React.PureComponent<IProp
|
||||
});
|
||||
}
|
||||
|
||||
private onRecoveryKeyChange = (ev: ChangeEvent<HTMLTextAreaElement>): void => {
|
||||
private onRecoveryKeyChange = (ev: ChangeEvent<HTMLInputElement>): void => {
|
||||
this.setState({
|
||||
recoveryKey: ev.target.value,
|
||||
});
|
||||
@@ -181,17 +180,14 @@ export default class AccessSecretStorageDialog extends React.PureComponent<IProp
|
||||
autoComplete="off"
|
||||
>
|
||||
<div className="mx_AccessSecretStorageDialog_recoveryKeyEntry">
|
||||
<Field
|
||||
inputRef={this.inputRef}
|
||||
element="textarea"
|
||||
rows={2}
|
||||
cols={45}
|
||||
<PasswordInput
|
||||
ref={this.inputRef}
|
||||
id="mx_securityKey"
|
||||
label={_t("encryption|access_secret_storage_dialog|security_key_title")}
|
||||
title={_t("encryption|access_secret_storage_dialog|security_key_label")}
|
||||
placeholder={_t("encryption|access_secret_storage_dialog|security_key_label")}
|
||||
value={this.state.recoveryKey}
|
||||
onChange={this.onRecoveryKeyChange}
|
||||
autoFocus={true}
|
||||
forceValidity={this.state.recoveryKeyCorrect ?? undefined}
|
||||
autoComplete="off"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -920,6 +920,7 @@
|
||||
},
|
||||
"privacy_warning": "Make sure nobody can see this screen!",
|
||||
"restoring": "Restoring keys from backup",
|
||||
"security_key_label": "Recovery key",
|
||||
"security_key_title": "Recovery key"
|
||||
},
|
||||
"bootstrap_title": "Setting up keys",
|
||||
|
||||
@@ -31,7 +31,7 @@ describe("AccessSecretStorageDialog", () => {
|
||||
|
||||
const enterRecoveryKey = async (valueToEnter: string = recoveryKey): Promise<void> => {
|
||||
await act(async () => {
|
||||
fireEvent.change(screen.getByRole("textbox"), {
|
||||
fireEvent.change(screen.getByTitle("Recovery key"), {
|
||||
target: {
|
||||
value: valueToEnter,
|
||||
},
|
||||
@@ -67,7 +67,7 @@ describe("AccessSecretStorageDialog", () => {
|
||||
renderComponent({ onFinished, checkPrivateKey });
|
||||
|
||||
// check that the input field is focused
|
||||
expect(screen.getByRole("textbox")).toHaveFocus();
|
||||
expect(screen.getByTitle("Recovery key")).toHaveFocus();
|
||||
|
||||
await enterRecoveryKey();
|
||||
await submitDialog();
|
||||
@@ -111,7 +111,7 @@ describe("AccessSecretStorageDialog", () => {
|
||||
renderComponent({ checkPrivateKey, keyInfo });
|
||||
|
||||
await enterRecoveryKey();
|
||||
expect(screen.getByRole("textbox")).toHaveValue(recoveryKey);
|
||||
expect(screen.getByTitle("Recovery key")).toHaveValue(recoveryKey);
|
||||
|
||||
await expect(screen.findByText("The recovery key you entered is not correct.")).resolves.toBeInTheDocument();
|
||||
expect(screen.getByText("Continue")).toHaveAttribute("aria-disabled", "true");
|
||||
|
||||
Reference in New Issue
Block a user