Skip to content

Commit 9ad239f

Browse files
uhoregrichvdh
andauthored
"Verify this device" redesign (#30596)
* add variant of ResetIdentityBody for when the user has no verif. methods * no longer distinguish between the using having a passphrase or not * use vertical stack of buttons via EncryptionCard and update wording * swap logic order to match rendering order * use the same dialog when no verification options available * make it agree with the design more * allow signing out on initial login * apply styling changes and remove duplicate elements * fix and add tests * add missing snapshot * Apply suggestions from code review Co-authored-by: Richard van der Hoff <[email protected]> * use a boolean property to disable blurring instead of adding a class * change string identifiers * apply changes from review -- simplify logic * change class name to avoid confusion --------- Co-authored-by: Richard van der Hoff <[email protected]>
1 parent 1e0cdf7 commit 9ad239f

File tree

23 files changed

+583
-208
lines changed

23 files changed

+583
-208
lines changed

playwright/e2e/crypto/dehydration.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ test.describe("Dehydration", () => {
3838
// Reset the identity key
3939
const settings = await app.settings.openUserSettings("Encryption");
4040
await settings.getByRole("button", { name: "Verify this device" }).click();
41-
await page.getByRole("button", { name: "Proceed with reset" }).click();
41+
await page.getByRole("button", { name: "Can't confirm?" }).click();
4242
await page.getByRole("button", { name: "Continue" }).click();
4343

4444
// Set up recovery
@@ -106,7 +106,7 @@ test.describe("Dehydration", () => {
106106
await logIntoElement(page, credentials);
107107

108108
// Oh no, we forgot our recovery key - reset our identity
109-
await page.locator(".mx_AuthPage").getByRole("button", { name: "Reset all" }).click();
109+
await page.locator(".mx_AuthPage").getByRole("button", { name: "Can't confirm" }).click();
110110
await expect(
111111
page.getByRole("heading", { name: "Are you sure you want to reset your identity?" }),
112112
).toBeVisible();

playwright/e2e/crypto/device-verification.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => {
3636
expectedBackupVersion = res.expectedBackupVersion;
3737
});
3838

39-
// Click the "Verify with another device" button, and have the bot client auto-accept it.
39+
// Click the "Use another device" button, and have the bot client auto-accept it.
4040
async function initiateAliceVerificationRequest(page: Page): Promise<JSHandle<VerificationRequest>> {
4141
// alice bot waits for verification request
4242
const promiseVerificationRequest = waitForVerificationRequest(aliceBotClient);
4343

44-
// Click on "Verify with another device"
45-
await page.locator(".mx_AuthPage").getByRole("button", { name: "Verify with another device" }).click();
44+
// Click on "Use another device"
45+
await page.locator(".mx_AuthPage").getByRole("button", { name: "Use another device" }).click();
4646

4747
// alice bot responds yes to verification request from alice
4848
return promiseVerificationRequest;
@@ -203,7 +203,7 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => {
203203

204204
/** Helper for the three tests above which verify by recovery key */
205205
async function enterRecoveryKeyAndCheckVerified(page: Page, app: ElementAppPage, recoveryKey: string) {
206-
await page.getByRole("button", { name: "Verify with Recovery Key or Phrase" }).click();
206+
await page.getByRole("button", { name: "Use recovery key" }).click();
207207

208208
// Enter the recovery key
209209
const dialog = page.locator(".mx_Dialog");

playwright/e2e/crypto/utils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,9 @@ export async function logIntoElement(page: Page, credentials: Credentials) {
224224
export async function logIntoElementAndVerify(page: Page, credentials: Credentials, recoveryKey: string) {
225225
await logIntoElement(page, credentials);
226226

227-
await page.locator(".mx_AuthPage").getByRole("button", { name: "Verify with Recovery Key" }).click();
227+
await page.locator(".mx_AuthPage").getByRole("button", { name: "Use recovery key" }).click();
228228

229-
const useSecurityKey = page.locator(".mx_Dialog").getByRole("button", { name: "use your Recovery Key" });
229+
const useSecurityKey = page.locator(".mx_Dialog").getByRole("button", { name: "Use recovery key" });
230230
// If the user has set a recovery *passphrase*, they'll be prompted for that first and have to click
231231
// through to enter the recovery key which is what we have here. If they haven't, they'll be prompted
232232
// for a recovery key straight away. We click the button if it's there so this works in both cases.
@@ -272,7 +272,7 @@ export async function logOutOfElement(page: Page, discardKeys: boolean = false)
272272
export async function verifySession(app: ElementAppPage, securityKey: string) {
273273
const settings = await app.settings.openUserSettings("Encryption");
274274
await settings.getByRole("button", { name: "Verify this device" }).click();
275-
await app.page.getByRole("button", { name: "Verify with Recovery Key" }).click();
275+
await app.page.getByRole("button", { name: "Use recovery key" }).click();
276276
await app.page.locator(".mx_Dialog").getByTitle("Recovery key").fill(securityKey);
277277
await app.page.getByRole("button", { name: "Continue", disabled: false }).click();
278278
await app.page.getByRole("button", { name: "Done" }).click();

playwright/e2e/login/login-consent.spec.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ test.describe("Login", () => {
186186
await page.goto("/");
187187
await login(page, homeserver, credentials);
188188

189-
await expect(page.getByRole("heading", { name: "Verify this device", level: 1 })).toBeVisible();
189+
await expect(page.getByRole("heading", { name: "Confirm your identity", level: 2 })).toBeVisible();
190190

191191
await expect(page.getByRole("button", { name: "Skip verification for now" })).toBeVisible();
192192
});
@@ -219,7 +219,7 @@ test.describe("Login", () => {
219219
await page.goto("/");
220220
await login(page, homeserver, credentials);
221221

222-
await expect(page.getByRole("heading", { name: "Verify this device", level: 1 })).toBeVisible();
222+
await expect(page.getByRole("heading", { name: "Confirm your identity", level: 2 })).toBeVisible();
223223

224224
await expect(page.getByRole("button", { name: "Skip verification for now" })).toBeVisible();
225225
});
@@ -254,10 +254,10 @@ test.describe("Login", () => {
254254
await page.goto("/");
255255
await login(page, homeserver, credentials);
256256

257-
const h1 = page.getByRole("heading", { name: "Verify this device", level: 1 });
258-
await expect(h1).toBeVisible();
257+
const h2 = page.getByRole("heading", { name: "Confirm your identity", level: 2 });
258+
await expect(h2).toBeVisible();
259259

260-
await expect(h1.locator(".mx_CompleteSecurity_skip")).toHaveCount(0);
260+
await expect(h2.locator(".mx_CompleteSecurity_skip")).toHaveCount(0);
261261
});
262262

263263
test("Continues to show verification prompt after cancelling device verification", async ({
@@ -274,18 +274,18 @@ test.describe("Login", () => {
274274
// Load the page and see that we are asked to verify
275275
await page.goto("/#/welcome");
276276
await login(page, homeserver, credentials);
277-
let h1 = page.getByRole("heading", { name: "Verify this device", level: 1 });
278-
await expect(h1).toBeVisible();
277+
let h2 = page.getByRole("heading", { name: "Confirm your identity", level: 2 });
278+
await expect(h2).toBeVisible();
279279

280-
// Click "Verify with another device"
281-
await page.getByRole("button", { name: "Verify with another device" }).click();
280+
// Click "Use another device"
281+
await page.getByRole("button", { name: "Use another device" }).click();
282282

283283
// Cancel the new dialog
284284
await page.getByRole("button", { name: "Close dialog" }).click();
285285

286286
// Check that we are still being asked to verify
287-
h1 = page.getByRole("heading", { name: "Verify this device", level: 1 });
288-
await expect(h1).toBeVisible();
287+
h2 = page.getByRole("heading", { name: "Confirm your identity", level: 2 });
288+
await expect(h2).toBeVisible();
289289
});
290290
});
291291

@@ -303,18 +303,18 @@ test.describe("Login", () => {
303303
await page.goto("/");
304304
await login(page, homeserver, credentials);
305305

306-
await expect(page.getByRole("heading", { name: "Verify this device", level: 1 })).toBeVisible();
306+
await expect(page.getByRole("heading", { name: "Confirm your identity", level: 2 })).toBeVisible();
307307

308308
// Start the reset process
309-
await page.getByRole("button", { name: "Proceed with reset" }).click();
309+
await page.getByRole("button", { name: "Can't confirm?" }).click();
310310

311311
// First try cancelling and restarting
312312
await page.getByRole("button", { name: "Cancel" }).click();
313-
await page.getByRole("button", { name: "Proceed with reset" }).click();
313+
await page.getByRole("button", { name: "Can't confirm?" }).click();
314314

315315
// Then click outside the dialog and restart
316316
await page.getByRole("link", { name: "Powered by Matrix" }).click({ force: true });
317-
await page.getByRole("button", { name: "Proceed with reset" }).click();
317+
await page.getByRole("button", { name: "Can't confirm?" }).click();
318318

319319
// Finally we actually continue
320320
await page.getByRole("button", { name: "Continue" }).click();

playwright/e2e/oidc/oidc-native.spec.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ test.describe("OIDC Native", { tag: ["@no-firefox", "@no-webkit"] }, () => {
129129
await page.getByRole("button", { name: "Continue" }).click();
130130
await page.getByRole("button", { name: "Continue" }).click();
131131

132-
// We should be in (we see an error because we have no recovery key).
133-
await expect(page.getByText("Unable to verify this device")).toBeVisible();
132+
// We should be in
133+
await expect(page.getByText("Confirm your identity")).toBeVisible();
134134
});
135135

136136
test.describe("with force_verification on", () => {
@@ -162,7 +162,7 @@ test.describe("OIDC Native", { tag: ["@no-firefox", "@no-webkit"] }, () => {
162162
await page.getByRole("button", { name: "Continue" }).click();
163163

164164
// We should be being warned that we need to verify (but we can't)
165-
await expect(page.getByText("Unable to verify this device")).toBeVisible();
165+
await expect(page.getByText("Confirm your identity")).toBeVisible();
166166

167167
// And there should be no way to close this prompt
168168
await expect(page.getByRole("button", { name: "Skip verification for now" })).not.toBeVisible();
@@ -210,7 +210,7 @@ test.describe("OIDC Native", { tag: ["@no-firefox", "@no-webkit"] }, () => {
210210
await expect(page.getByRole("button", { name: "Skip verification for now" })).not.toBeVisible();
211211

212212
// When we start verifying with another device
213-
await page.getByRole("button", { name: "Verify with another device" }).click();
213+
await page.getByRole("button", { name: "Use another device" }).click();
214214

215215
// And then cancel it
216216
await page.getByRole("button", { name: "Close dialog" }).click();
@@ -227,7 +227,7 @@ test.describe("OIDC Native", { tag: ["@no-firefox", "@no-webkit"] }, () => {
227227
* Perform interactive emoji verification for a new device.
228228
*/
229229
async function verifyUsingOtherDevice(deviceToVerifyPage: Page, alreadyVerifiedDevicePage: Page) {
230-
await deviceToVerifyPage.getByRole("button", { name: "Verify with another device" }).click();
230+
await deviceToVerifyPage.getByRole("button", { name: "Use another device" }).click();
231231
await alreadyVerifiedDevicePage.getByRole("button", { name: "Verify session" }).click();
232232
await alreadyVerifiedDevicePage.getByRole("button", { name: "Start" }).click();
233233
await alreadyVerifiedDevicePage.getByRole("button", { name: "They match" }).click();

playwright/e2e/settings/encryption-user-tab/encryption-tab.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,15 +160,15 @@ test.describe("Encryption tab", () => {
160160

161161
// We will reset our identity
162162
await settings.getByRole("button", { name: "Verify this device" }).click();
163-
await page.getByRole("button", { name: "Proceed with reset" }).click();
163+
await page.getByRole("button", { name: "Can't confirm?" }).click();
164164

165165
// First try cancelling and restarting
166166
await page.getByRole("button", { name: "Cancel" }).click();
167-
await page.getByRole("button", { name: "Proceed with reset" }).click();
167+
await page.getByRole("button", { name: "Can't confirm?" }).click();
168168

169169
// Then click outside the dialog and restart
170170
await page.locator("li").filter({ hasText: "Encryption" }).click({ force: true });
171-
await page.getByRole("button", { name: "Proceed with reset" }).click();
171+
await page.getByRole("button", { name: "Can't confirm?" }).click();
172172

173173
// Finally we actually continue
174174
await page.getByRole("button", { name: "Continue" }).click();

playwright/e2e/settings/encryption-user-tab/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class Helpers {
4343
*/
4444
async verifyDevice(recoveryKey: GeneratedSecretStorageKey) {
4545
// Select the security phrase
46-
await this.page.getByRole("button", { name: "Verify with Recovery Key" }).click();
46+
await this.page.getByRole("button", { name: "Use recovery key" }).click();
4747
await this.enterRecoveryKey(recoveryKey);
4848
await this.page.getByRole("button", { name: "Done" }).click();
4949
}

res/css/structures/auth/_SetupEncryptionBody.pcss

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,6 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
66
Please see LICENSE files in the repository root for full details.
77
*/
88

9-
.mx_SetupEncryptionBody_reset {
10-
color: $light-fg-color;
11-
margin-top: $font-14px;
12-
13-
.mx_SetupEncryptionBody_reset_link {
14-
&.mx_AccessibleButton_kind_link_inline {
15-
color: $alert;
16-
}
17-
}
9+
.mx_SetupEncryptionBody {
10+
width: 600px;
1811
}

res/css/views/auth/_AuthPage.pcss

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ Please see LICENSE files in the repository root for full details.
1919
display: flex;
2020
margin: 100px auto auto;
2121
border-radius: 4px;
22-
box-shadow: 0 2px 4px 0 rgb(0, 0, 0, 0.33);
2322
background-color: $authpage-modal-bg-color;
2423

2524
@media only screen and (max-height: 768px) {
@@ -29,4 +28,9 @@ Please see LICENSE files in the repository root for full details.
2928
@media only screen and (max-width: 480px) {
3029
margin-top: 0;
3130
}
31+
32+
/* Apply a blurred shadow around the modal */
33+
&.mx_AuthPage_modal_withBlur {
34+
box-shadow: 0 2px 4px 0 rgb(0, 0, 0, 0.33);
35+
}
3236
}

res/css/views/auth/_CompleteSecurityBody.pcss

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@ Please see LICENSE files in the repository root for full details.
88
*/
99

1010
.mx_CompleteSecurityBody {
11-
width: 600px;
1211
color: $authpage-primary-color;
1312
background-color: $background;
1413
border-radius: 4px;
15-
padding: 20px;
14+
padding: 20px 20px 60px 20px;
1615
box-sizing: border-box;
1716

1817
h2 {

0 commit comments

Comments
 (0)