Skip to content

EW: Modernize the recovery key input modal #29819

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 23, 2025
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
9 changes: 4 additions & 5 deletions playwright/e2e/crypto/device-verification.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*

Check failure on line 1 in playwright/e2e/crypto/device-verification.spec.ts

View workflow job for this annotation

GitHub Actions / Run Tests [Chrome] 1/6

[Chrome] › playwright/e2e/crypto/device-verification.spec.ts:121:9 › Device verification › Verify device with QR code during login @no-webkit

2) [Chrome] › playwright/e2e/crypto/device-verification.spec.ts:121:9 › Device verification › Verify device with QR code during login @no-webkit Error: apiRequestContext.fetch: Target page, context or browser has been closed Call log: - → POST http://localhost:39441/_synapse/admin/v1/register - user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.7103.25 Safari/537.36 - accept: */* - accept-encoding: gzip,deflate,br - content-type: application/json - content-length: 311 at Api.request (/home/runner/work/element-web/element-web/node_modules/@element-hq/element-web-playwright-common/lib/utils/api.js:28:41) at StartedSynapseContainer.registerUserInternal (/home/runner/work/element-web/element-web/node_modules/@element-hq/element-web-playwright-common/lib/testcontainers/synapse.js:287:42) at Object.credentials (/home/runner/work/element-web/element-web/node_modules/@element-hq/element-web-playwright-common/lib/fixtures/user.js:16:29)
Copyright 2024 New Vector Ltd.
Copyright 2023 The Matrix.org Foundation C.I.C.

Expand Down Expand Up @@ -93,7 +93,7 @@
await page.route("**/_matrix/client/v3/sendToDevice/m.secret.request/**", async (route) => {
await route.fulfill({ json: {} });
await new Promise((f) => setTimeout(f, 1000));
await route.fetch();

Check failure on line 96 in playwright/e2e/crypto/device-verification.spec.ts

View workflow job for this annotation

GitHub Actions / Run Tests [Chrome] 1/6

[Chrome] › playwright/e2e/crypto/device-verification.spec.ts:121:9 › Device verification › Verify device with QR code during login @no-webkit

2) [Chrome] › playwright/e2e/crypto/device-verification.spec.ts:121:9 › Device verification › Verify device with QR code during login @no-webkit Error: "route.fetch: Test ended." while running route callback. Consider awaiting `await page.unrouteAll({ behavior: 'ignoreErrors' })` before the end of the test to ignore remaining routes in flight. 94 | await route.fulfill({ json: {} }); 95 | await new Promise((f) => setTimeout(f, 1000)); > 96 | await route.fetch(); | ^ 97 | }); 98 | 99 | await logIntoElement(page, credentials); at /home/runner/work/element-web/element-web/playwright/e2e/crypto/device-verification.spec.ts:96:25
});

await logIntoElement(page, credentials);
Expand Down Expand Up @@ -169,8 +169,8 @@

// Fill the passphrase
const dialog = page.locator(".mx_Dialog");
await dialog.locator("input").fill("new passphrase");
await dialog.locator(".mx_Dialog_primary:not([disabled])", { hasText: "Continue" }).click();
await dialog.locator("textarea").fill("new passphrase");
await dialog.getByRole("button", { name: "Continue", disabled: false }).click();

await page.locator(".mx_AuthPage").getByRole("button", { name: "Done" }).click();

Expand All @@ -190,10 +190,9 @@

// Fill the recovery key
const dialog = page.locator(".mx_Dialog");
await dialog.getByRole("button", { name: "use your Recovery Key" }).click();
const aliceRecoveryKey = await aliceBotClient.getRecoveryKey();
await dialog.locator("#mx_securityKey").fill(aliceRecoveryKey.encodedPrivateKey);
await dialog.locator(".mx_Dialog_primary:not([disabled])", { hasText: "Continue" }).click();
await dialog.locator("textarea").fill(aliceRecoveryKey.encodedPrivateKey);
await dialog.getByRole("button", { name: "Continue", disabled: false }).click();

await page.locator(".mx_AuthPage").getByRole("button", { name: "Done" }).click();

Expand Down
6 changes: 3 additions & 3 deletions playwright/e2e/crypto/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,8 @@ export async function logIntoElement(page: Page, credentials: Credentials, secur
await useSecurityKey.click();
}
// Fill in the recovery key
await page.locator(".mx_Dialog").locator('input[type="password"]').fill(securityKey);
await page.locator(".mx_Dialog_primary:not([disabled])", { hasText: "Continue" }).click();
await page.locator(".mx_Dialog").locator("textarea").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('input[type="password"]').fill(securityKey);
await app.page.locator(".mx_Dialog").locator("textarea").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
1 change: 1 addition & 0 deletions res/css/_common.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,7 @@ legend {
.mx_Dialog_nonDialogButton,
.mx_AccessibleButton,
.mx_IdentityServerPicker button,
.mx_AccessSecretStorageDialog button,
[class|="maplibregl"]
),
.mx_Dialog_buttons button:not(.mx_Dialog_nonDialogButton, .mx_AccessibleButton),
Expand Down
110 changes: 8 additions & 102 deletions res/css/views/dialogs/security/_AccessSecretStorageDialog.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -7,62 +7,14 @@ Please see LICENSE files in the repository root for full details.
*/

.mx_AccessSecretStorageDialog {
.mx_AccessSecretStorageDialog_titleWithIcon {
&::before {
content: "";
display: inline-block;
width: 24px;
height: 24px;
margin-inline-end: $spacing-8;
position: relative;
top: 5px;
background-color: $primary-content;
}

&.mx_AccessSecretStorageDialog_resetBadge::before {
/* The image isn't capable of masking, so we use a background instead. */
background-image: url("@vector-im/compound-design-tokens/icons/error-solid.svg");
background-size: 24px;
background-color: transparent;
}

&.mx_AccessSecretStorageDialog_secureBackupTitle::before {
mask-image: url("$(res)/img/feather-customised/secure-backup.svg");
}

&.mx_AccessSecretStorageDialog_securePhraseTitle::before {
mask-image: url("$(res)/img/feather-customised/secure-phrase.svg");
}
&.mx_EncryptionCard {
/* override some styles that we don't need */
border: 0px none;
box-shadow: none;
padding: 0px;
}

.mx_AccessSecretStorageDialog_primaryContainer {
.mx_AccessSecretStorageDialog_passPhraseInput {
width: 300px;
border: 1px solid $accent;
border-radius: 5px;
}

.mx_AccessSecretStorageDialog_keyStatus {
height: 30px;
}

.mx_AccessSecretStorageDialog_recoveryKeyEntry {
display: flex;
align-items: center;

.mx_AccessSecretStorageDialog_recoveryKeyEntry_textInput {
flex-grow: 1;
}

.mx_AccessSecretStorageDialog_recoveryKeyEntry_entryControlSeparatorText {
margin: $spacing-16;
}

.mx_AccessSecretStorageDialog_recoveryKeyEntry_fileInput {
display: none;
}
}

.mx_AccessSecretStorageDialog_recoveryKeyFeedback {
&::before {
content: "";
Expand All @@ -76,15 +28,6 @@ Please see LICENSE files in the repository root for full details.
margin-inline-end: 5px;
}

&.mx_AccessSecretStorageDialog_recoveryKeyFeedback--valid {
color: $accent;

&::before {
mask-image: url("@vector-im/compound-design-tokens/icons/check.svg");
background-color: $accent;
}
}

&.mx_AccessSecretStorageDialog_recoveryKeyFeedback--invalid {
color: $alert;

Expand All @@ -94,46 +37,9 @@ Please see LICENSE files in the repository root for full details.
}
}
}
}

.mx_Dialog_buttons {
$spacingStart: $spacing-24; /* 16px icon + 8px padding */

text-align: initial;
display: flex;
flex-flow: column;
gap: 14px;

.mx_Dialog_buttons_additive {
float: none;

.mx_AccessSecretStorageDialog_reset {
position: relative;
padding-inline-start: $spacingStart;
/* To avoid bold styling inherent with <strong> elements */
font-weight: inherit;

&::before {
content: "";
display: inline-block;
position: absolute;
height: 16px;
width: 16px;
left: 0;
top: 2px; /* alignment */
background-image: url("@vector-im/compound-design-tokens/icons/error-solid.svg");
background-size: contain;
}

.mx_AccessSecretStorageDialog_reset_link {
color: $alert;
}
}
}

.mx_Dialog_buttons_row {
gap: $spacing-16; /* TODO: needs normalization */
padding-inline-start: $spacingStart;
}
}
.mx_EncryptionCard_buttons {
margin-top: var(--cpd-space-20x);
}
}
Loading
Loading