Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion playwright/e2e/crypto/device-verification.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions playwright/e2e/crypto/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down Expand Up @@ -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();
Expand Down
17 changes: 17 additions & 0 deletions res/css/views/dialogs/security/_AccessSecretStorageDialog.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -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: "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
});
Expand Down Expand Up @@ -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>
Expand Down
1 change: 1 addition & 0 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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");
Expand Down
Loading