mirror of
https://github.com/element-hq/element-web.git
synced 2025-12-28 07:14:20 +00:00
Fix e2e icons in CompleteSecurity & SetupEncryptionBody (#31521)
* Fix e2e icons in CompleteSecurity & SetupEncryptionBody Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Tests Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Prevent screenshot clash between tests Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
362e34513d
commit
7b024f956d
@ -130,53 +130,68 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => {
|
||||
await page.unrouteAll({ behavior: "ignoreErrors" });
|
||||
});
|
||||
|
||||
test("Verify device with QR code during login", async ({ page, app, credentials, homeserver }) => {
|
||||
// A mode 0x02 verification: "self-verifying in which the current device does not yet trust the master key"
|
||||
await logIntoElement(page, credentials);
|
||||
test(
|
||||
"Verify device with QR code during login",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, credentials, homeserver }) => {
|
||||
// A mode 0x02 verification: "self-verifying in which the current device does not yet trust the master key"
|
||||
await logIntoElement(page, credentials);
|
||||
|
||||
// Launch the verification request between alice and the bot
|
||||
const verificationRequest = await initiateAliceVerificationRequest(page);
|
||||
// Launch the verification request between alice and the bot
|
||||
const verificationRequest = await initiateAliceVerificationRequest(page);
|
||||
|
||||
const infoDialog = page.locator(".mx_InfoDialog");
|
||||
// feed the QR code into the verification request.
|
||||
const qrData = await readQrCode(infoDialog);
|
||||
const verifier = await verificationRequest.evaluateHandle(
|
||||
(request, qrData) => request.scanQRCode(new Uint8ClampedArray(qrData)),
|
||||
[...qrData],
|
||||
);
|
||||
const infoDialog = page.locator(".mx_InfoDialog");
|
||||
// feed the QR code into the verification request.
|
||||
const qrData = await readQrCode(infoDialog);
|
||||
await expect(page.locator(".mx_Dialog")).toMatchScreenshot("qr-code.png", {
|
||||
mask: [infoDialog.locator("img")],
|
||||
});
|
||||
const verifier = await verificationRequest.evaluateHandle(
|
||||
(request, qrData) => request.scanQRCode(new Uint8ClampedArray(qrData)),
|
||||
[...qrData],
|
||||
);
|
||||
|
||||
// Confirm that the bot user scanned successfully
|
||||
await expect(infoDialog.getByText("Confirm that you see a green shield on your other device")).toBeVisible();
|
||||
await infoDialog.getByRole("button", { name: "Yes, I see a green shield" }).click();
|
||||
await infoDialog.getByRole("button", { name: "Got it" }).click();
|
||||
// Confirm that the bot user scanned successfully
|
||||
await expect(
|
||||
infoDialog.getByText("Confirm that you see a green shield on your other device"),
|
||||
).toBeVisible();
|
||||
await expect(page.locator(".mx_Dialog")).toMatchScreenshot("confirm-green-shield.png");
|
||||
await infoDialog.getByRole("button", { name: "Yes, I see a green shield" }).click();
|
||||
await expect(page.locator(".mx_Dialog")).toMatchScreenshot("got-it.png");
|
||||
await infoDialog.getByRole("button", { name: "Got it" }).click();
|
||||
|
||||
// wait for the bot to see we have finished
|
||||
await verifier.evaluate((verifier) => verifier.verify());
|
||||
// wait for the bot to see we have finished
|
||||
await verifier.evaluate((verifier) => verifier.verify());
|
||||
|
||||
// the bot uploads the signatures asynchronously, so wait for that to happen
|
||||
await page.waitForTimeout(1000);
|
||||
// the bot uploads the signatures asynchronously, so wait for that to happen
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// our device should trust the bot device
|
||||
await app.client.evaluate(async (cli, aliceBotCredentials) => {
|
||||
const deviceStatus = await cli
|
||||
.getCrypto()!
|
||||
.getDeviceVerificationStatus(aliceBotCredentials.userId, aliceBotCredentials.deviceId);
|
||||
if (!deviceStatus.isVerified()) {
|
||||
throw new Error("Bot device was not verified after QR code verification");
|
||||
}
|
||||
}, aliceBotClient.credentials);
|
||||
// our device should trust the bot device
|
||||
await app.client.evaluate(async (cli, aliceBotCredentials) => {
|
||||
const deviceStatus = await cli
|
||||
.getCrypto()!
|
||||
.getDeviceVerificationStatus(aliceBotCredentials.userId, aliceBotCredentials.deviceId);
|
||||
if (!deviceStatus.isVerified()) {
|
||||
throw new Error("Bot device was not verified after QR code verification");
|
||||
}
|
||||
}, aliceBotClient.credentials);
|
||||
|
||||
// Check that our device is now cross-signed
|
||||
await checkDeviceIsCrossSigned(app);
|
||||
// Check that our device is now cross-signed
|
||||
await checkDeviceIsCrossSigned(app);
|
||||
|
||||
// Check that the current device is connected to key backup
|
||||
await checkDeviceIsConnectedKeyBackup(app, expectedBackupVersion, true);
|
||||
});
|
||||
// Check that the current device is connected to key backup
|
||||
await checkDeviceIsConnectedKeyBackup(app, expectedBackupVersion, true);
|
||||
},
|
||||
);
|
||||
|
||||
test("Verify device with Security Phrase during login", async ({ page, app, credentials, homeserver }) => {
|
||||
await logIntoElement(page, credentials);
|
||||
await enterRecoveryKeyAndCheckVerified(page, app, "new passphrase");
|
||||
});
|
||||
test(
|
||||
"Verify device with Security Phrase during login",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, credentials, homeserver }) => {
|
||||
await logIntoElement(page, credentials);
|
||||
await enterRecoveryKeyAndCheckVerified(page, app, "new passphrase", true);
|
||||
},
|
||||
);
|
||||
|
||||
test("Verify device with Recovery Key during login", async ({ page, app, credentials, homeserver }) => {
|
||||
const recoveryKey = (await aliceBotClient.getRecoveryKey()).encodedPrivateKey;
|
||||
@ -226,7 +241,12 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => {
|
||||
});
|
||||
|
||||
/** Helper for the three tests above which verify by recovery key */
|
||||
async function enterRecoveryKeyAndCheckVerified(page: Page, app: ElementAppPage, recoveryKey: string) {
|
||||
async function enterRecoveryKeyAndCheckVerified(
|
||||
page: Page,
|
||||
app: ElementAppPage,
|
||||
recoveryKey: string,
|
||||
screenshot = false,
|
||||
) {
|
||||
await page.getByRole("button", { name: "Use recovery key" }).click();
|
||||
|
||||
// Enter the recovery key
|
||||
@ -234,8 +254,12 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => {
|
||||
// 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.getByTitle("Recovery key").pressSequentially(recoveryKey);
|
||||
if (screenshot) {
|
||||
await expect(page.locator(".mx_Dialog").filter({ hasText: "Enter your recovery key" })).toMatchScreenshot(
|
||||
"recovery-key.png",
|
||||
);
|
||||
}
|
||||
await dialog.getByRole("button", { name: "Continue", disabled: false }).click();
|
||||
|
||||
await page.getByRole("button", { name: "Done" }).click();
|
||||
|
||||
// Check that our device is now cross-signed
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
@ -15,14 +15,14 @@ Please see LICENSE files in the repository root for full details.
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 4px;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mx_CompleteSecurity_heroIcon {
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mx_CompleteSecurity_skip {
|
||||
|
||||
@ -10,12 +10,14 @@ import React from "react";
|
||||
import { Glass } from "@vector-im/compound-web";
|
||||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import { SetupEncryptionStore, Phase } from "../../../stores/SetupEncryptionStore";
|
||||
import { Phase, SetupEncryptionStore } from "../../../stores/SetupEncryptionStore";
|
||||
import SetupEncryptionBody from "./SetupEncryptionBody";
|
||||
import AccessibleButton from "../../views/elements/AccessibleButton";
|
||||
import CompleteSecurityBody from "../../views/auth/CompleteSecurityBody";
|
||||
import AuthPage from "../../views/auth/AuthPage";
|
||||
import SdkConfig from "../../../SdkConfig";
|
||||
import E2EIcon from "../../views/rooms/E2EIcon.tsx";
|
||||
import { E2EStatus } from "../../../utils/ShieldUtils.ts";
|
||||
|
||||
interface IProps {
|
||||
onFinished: () => void;
|
||||
@ -67,13 +69,13 @@ export default class CompleteSecurity extends React.Component<IProps, IState> {
|
||||
} else if (phase === Phase.Intro) {
|
||||
// We don't specify an icon nor title since `SetupEncryptionBody` provides its own
|
||||
} else if (phase === Phase.Done) {
|
||||
icon = <span className="mx_CompleteSecurity_headerIcon mx_E2EIcon_verified" />;
|
||||
icon = <E2EIcon className="mx_CompleteSecurity_headerIcon" status={E2EStatus.Verified} hideTooltip />;
|
||||
title = _t("encryption|verification|after_new_login|device_verified");
|
||||
} else if (phase === Phase.ConfirmSkip) {
|
||||
icon = <span className="mx_CompleteSecurity_headerIcon mx_E2EIcon_warning" />;
|
||||
icon = <E2EIcon className="mx_CompleteSecurity_headerIcon" status={E2EStatus.Warning} hideTooltip />;
|
||||
title = _t("common|are_you_sure");
|
||||
} else if (phase === Phase.Busy) {
|
||||
icon = <span className="mx_CompleteSecurity_headerIcon mx_E2EIcon_warning" />;
|
||||
icon = <E2EIcon className="mx_CompleteSecurity_headerIcon" status={E2EStatus.Warning} hideTooltip />;
|
||||
title = _t("encryption|verification|after_new_login|verify_this_device");
|
||||
} else if (phase === Phase.Finished) {
|
||||
// SetupEncryptionBody will take care of calling onFinished, we don't need to do anything
|
||||
|
||||
@ -27,6 +27,8 @@ import { EncryptionCardButtons } from "../../views/settings/encryption/Encryptio
|
||||
import { EncryptionCardEmphasisedContent } from "../../views/settings/encryption/EncryptionCardEmphasisedContent";
|
||||
import ExternalLink from "../../views/elements/ExternalLink";
|
||||
import dispatcher from "../../../dispatcher/dispatcher";
|
||||
import E2EIcon from "../../views/rooms/E2EIcon.tsx";
|
||||
import { E2EStatus } from "../../../utils/ShieldUtils.ts";
|
||||
|
||||
interface IProps {
|
||||
onFinished: () => void;
|
||||
@ -228,7 +230,7 @@ export default class SetupEncryptionBody extends React.Component<IProps, IState>
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<div className="mx_CompleteSecurity_heroIcon mx_E2EIcon_verified" />
|
||||
<E2EIcon className="mx_CompleteSecurity_heroIcon" status={E2EStatus.Verified} hideTooltip />
|
||||
{message}
|
||||
<div className="mx_CompleteSecurity_actionRow">
|
||||
<AccessibleButton kind="primary" onClick={this.onDoneClick}>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user