From ccc04de039037072fcbc9bfcebbd36ccac14f4c1 Mon Sep 17 00:00:00 2001 From: Florian Duros Date: Thu, 28 Nov 2024 12:28:53 +0100 Subject: [PATCH 1/7] Remove call of `MatrixClient.setDeviceVerified` --- src/SlashCommands.tsx | 64 ----- .../ManualDeviceKeyVerificationDialog.tsx | 90 ------- src/i18n/strings/en_EN.json | 13 - src/verification.ts | 16 +- ...ManualDeviceKeyVerificationDialog-test.tsx | 104 -------- ...lDeviceKeyVerificationDialog-test.tsx.snap | 231 ------------------ 6 files changed, 4 insertions(+), 514 deletions(-) delete mode 100644 src/components/views/dialogs/ManualDeviceKeyVerificationDialog.tsx delete mode 100644 test/unit-tests/components/views/dialogs/ManualDeviceKeyVerificationDialog-test.tsx delete mode 100644 test/unit-tests/components/views/dialogs/__snapshots__/ManualDeviceKeyVerificationDialog-test.tsx.snap diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx index 5fc4d8c3576..b739cec12fc 100644 --- a/src/SlashCommands.tsx +++ b/src/SlashCommands.tsx @@ -49,7 +49,6 @@ import VoipUserMapper from "./VoipUserMapper"; import { htmlSerializeFromMdIfNeeded } from "./editor/serialize"; import { leaveRoomBehaviour } from "./utils/leave-behaviour"; import { MatrixClientPeg } from "./MatrixClientPeg"; -import { getDeviceCryptoInfo } from "./utils/crypto/deviceInfo"; import { isCurrentLocalRoom, reject, singleMxcUpload, success, successSync } from "./slash-commands/utils"; import { deop, op } from "./slash-commands/op"; import { CommandCategories } from "./slash-commands/interface"; @@ -658,69 +657,6 @@ export const Commands = [ category: CommandCategories.admin, renderingTypes: [TimelineRenderingType.Room], }), - new Command({ - command: "verify", - args: " ", - description: _td("slash_command|verify"), - runFn: function (cli, roomId, threadId, args) { - if (args) { - const matches = args.match(/^(\S+) +(\S+) +(\S+)$/); - if (matches) { - const userId = matches[1]; - const deviceId = matches[2]; - const fingerprint = matches[3]; - - return success( - (async (): Promise => { - const device = await getDeviceCryptoInfo(cli, userId, deviceId); - if (!device) { - throw new UserFriendlyError("slash_command|verify_unknown_pair", { - userId, - deviceId, - cause: undefined, - }); - } - const deviceTrust = await cli.getCrypto()?.getDeviceVerificationStatus(userId, deviceId); - - if (deviceTrust?.isVerified()) { - if (device.getFingerprint() === fingerprint) { - throw new UserFriendlyError("slash_command|verify_nop"); - } else { - throw new UserFriendlyError("slash_command|verify_nop_warning_mismatch"); - } - } - - if (device.getFingerprint() !== fingerprint) { - const fprint = device.getFingerprint(); - throw new UserFriendlyError("slash_command|verify_mismatch", { - fprint, - userId, - deviceId, - fingerprint, - cause: undefined, - }); - } - - await cli.setDeviceVerified(userId, deviceId, true); - - // Tell the user we verified everything - Modal.createDialog(InfoDialog, { - title: _t("slash_command|verify_success_title"), - description: ( -
-

{_t("slash_command|verify_success_description", { userId, deviceId })}

-
- ), - }); - })(), - ); - } - } - return reject(this.getUsage()); - }, - category: CommandCategories.advanced, - renderingTypes: [TimelineRenderingType.Room], - }), new Command({ command: "discardsession", description: _td("slash_command|discardsession"), diff --git a/src/components/views/dialogs/ManualDeviceKeyVerificationDialog.tsx b/src/components/views/dialogs/ManualDeviceKeyVerificationDialog.tsx deleted file mode 100644 index 76e7580e018..00000000000 --- a/src/components/views/dialogs/ManualDeviceKeyVerificationDialog.tsx +++ /dev/null @@ -1,90 +0,0 @@ -/* -Copyright 2024 New Vector Ltd. -Copyright 2020 The Matrix.org Foundation C.I.C. -Copyright 2019 New Vector Ltd -Copyright 2019 Michael Telatynski <7t3chguy@gmail.com> -Copyright 2017 Vector Creations Ltd -Copyright 2016 OpenMarket Ltd - -SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only -Please see LICENSE files in the repository root for full details. -*/ - -import React, { useCallback } from "react"; -import { Device } from "matrix-js-sdk/src/matrix"; - -import * as FormattingUtils from "../../../utils/FormattingUtils"; -import { _t } from "../../../languageHandler"; -import QuestionDialog from "./QuestionDialog"; -import { MatrixClientPeg } from "../../../MatrixClientPeg"; - -interface IManualDeviceKeyVerificationDialogProps { - userId: string; - device: Device; - onFinished(confirm?: boolean): void; -} - -export function ManualDeviceKeyVerificationDialog({ - userId, - device, - onFinished, -}: IManualDeviceKeyVerificationDialogProps): JSX.Element { - const mxClient = MatrixClientPeg.safeGet(); - - const onLegacyFinished = useCallback( - (confirm: boolean) => { - if (confirm) { - mxClient.setDeviceVerified(userId, device.deviceId, true); - } - onFinished(confirm); - }, - [mxClient, userId, device, onFinished], - ); - - let text; - if (mxClient?.getUserId() === userId) { - text = _t("encryption|verification|manual_device_verification_self_text"); - } else { - text = _t("encryption|verification|manual_device_verification_user_text"); - } - - const fingerprint = device.getFingerprint(); - const key = fingerprint && FormattingUtils.formatCryptoKey(fingerprint); - const body = ( -
-

{text}

-
-
    -
  • - {" "} - {device.displayName} -
  • -
  • - {" "} - - {device.deviceId} - -
  • -
  • - {" "} - - - {key} - - -
  • -
-
-

{_t("encryption|verification|manual_device_verification_footer")}

-
- ); - - return ( - - ); -} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 50ca4ae1e42..3eb092cad23 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -957,12 +957,6 @@ "incoming_sas_dialog_waiting": "Waiting for partner to confirm…", "incoming_sas_user_dialog_text_1": "Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.", "incoming_sas_user_dialog_text_2": "Verifying this user will mark their session as trusted, and also mark your session as trusted to them.", - "manual_device_verification_device_id_label": "Session ID", - "manual_device_verification_device_key_label": "Session key", - "manual_device_verification_device_name_label": "Session name", - "manual_device_verification_footer": "If they don't match, the security of your communication may be compromised.", - "manual_device_verification_self_text": "Confirm by comparing the following with the User Settings in your other session:", - "manual_device_verification_user_text": "Confirm this user's session by comparing the following with their User Settings:", "no_key_or_device": "It looks like you don't have a Security Key or any other devices you can verify against. This device will not be able to access old encrypted messages. In order to verify your identity on this device, you'll need to reset your verification keys.", "no_support_qr_emoji": "The device you are trying to verify doesn't support scanning a QR code or emoji verification, which is what %(brand)s supports. Try with a different client.", "other_party_cancelled": "The other party cancelled the verification.", @@ -3044,13 +3038,6 @@ "upgraderoom": "Upgrades a room to a new version", "upgraderoom_permission_error": "You do not have the required permissions to use this command.", "usage": "Usage", - "verify": "Verifies a user, session, and pubkey tuple", - "verify_mismatch": "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!", - "verify_nop": "Session already verified!", - "verify_nop_warning_mismatch": "WARNING: session already verified, but keys do NOT MATCH!", - "verify_success_description": "The signing key you provided matches the signing key you received from %(userId)s's session %(deviceId)s. Session marked as verified.", - "verify_success_title": "Verified key", - "verify_unknown_pair": "Unknown (user, session) pair: (%(userId)s, %(deviceId)s)", "view": "Views room with given address", "whois": "Displays information about a user" }, diff --git a/src/verification.ts b/src/verification.ts index e446186f802..2e7abed950f 100644 --- a/src/verification.ts +++ b/src/verification.ts @@ -15,7 +15,6 @@ import { RightPanelPhases } from "./stores/right-panel/RightPanelStorePhases"; import { accessSecretStorage } from "./SecurityManager"; import UntrustedDeviceDialog from "./components/views/dialogs/UntrustedDeviceDialog"; import { IDevice } from "./components/views/right_panel/UserInfo"; -import { ManualDeviceKeyVerificationDialog } from "./components/views/dialogs/ManualDeviceKeyVerificationDialog"; import RightPanelStore from "./stores/right-panel/RightPanelStore"; import { IRightPanelCardState } from "./stores/right-panel/RightPanelStoreIPanelState"; import { findDMForUser } from "./utils/dm/findDMForUser"; @@ -48,17 +47,10 @@ export async function verifyDevice(matrixClient: MatrixClient, user: User, devic user, device, onFinished: async (action): Promise => { - if (action === "sas") { - const verificationRequestPromise = matrixClient - .getCrypto() - ?.requestDeviceVerification(user.userId, device.deviceId); - setRightPanel({ member: user, verificationRequestPromise }); - } else if (action === "legacy") { - Modal.createDialog(ManualDeviceKeyVerificationDialog, { - userId: user.userId, - device, - }); - } + const verificationRequestPromise = matrixClient + .getCrypto() + ?.requestDeviceVerification(user.userId, device.deviceId); + setRightPanel({ member: user, verificationRequestPromise }); }, }); } diff --git a/test/unit-tests/components/views/dialogs/ManualDeviceKeyVerificationDialog-test.tsx b/test/unit-tests/components/views/dialogs/ManualDeviceKeyVerificationDialog-test.tsx deleted file mode 100644 index cb01b346dee..00000000000 --- a/test/unit-tests/components/views/dialogs/ManualDeviceKeyVerificationDialog-test.tsx +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2024 New Vector Ltd. - * Copyright 2023 The Matrix.org Foundation C.I.C. - * - * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only - * Please see LICENSE files in the repository root for full details. - */ - -import React from "react"; -import { render, screen } from "jest-matrix-react"; -import { Device, MatrixClient } from "matrix-js-sdk/src/matrix"; - -import { stubClient } from "../../../../test-utils"; -import { ManualDeviceKeyVerificationDialog } from "../../../../../src/components/views/dialogs/ManualDeviceKeyVerificationDialog"; -import MatrixClientContext from "../../../../../src/contexts/MatrixClientContext"; - -describe("ManualDeviceKeyVerificationDialog", () => { - let mockClient: MatrixClient; - - function renderDialog(userId: string, device: Device, onLegacyFinished: (confirm: boolean) => void) { - return render( - - - , - ); - } - - beforeEach(() => { - mockClient = stubClient(); - }); - - it("should display the device", () => { - // When - const deviceId = "XYZ"; - const device = new Device({ - userId: mockClient.getUserId()!, - deviceId, - displayName: "my device", - algorithms: [], - keys: new Map([[`ed25519:${deviceId}`, "ABCDEFGH"]]), - }); - const { container } = renderDialog(mockClient.getUserId()!, device, jest.fn()); - - // Then - expect(container).toMatchSnapshot(); - }); - - it("should display the device of another user", () => { - // When - const userId = "@alice:example.com"; - const deviceId = "XYZ"; - const device = new Device({ - userId, - deviceId, - displayName: "my device", - algorithms: [], - keys: new Map([[`ed25519:${deviceId}`, "ABCDEFGH"]]), - }); - const { container } = renderDialog(userId, device, jest.fn()); - - // Then - expect(container).toMatchSnapshot(); - }); - - it("should call onFinished and matrixClient.setDeviceVerified", () => { - // When - const deviceId = "XYZ"; - const device = new Device({ - userId: mockClient.getUserId()!, - deviceId, - displayName: "my device", - algorithms: [], - keys: new Map([[`ed25519:${deviceId}`, "ABCDEFGH"]]), - }); - const onFinished = jest.fn(); - renderDialog(mockClient.getUserId()!, device, onFinished); - - screen.getByRole("button", { name: "Verify session" }).click(); - - // Then - expect(onFinished).toHaveBeenCalledWith(true); - expect(mockClient.setDeviceVerified).toHaveBeenCalledWith(mockClient.getUserId(), deviceId, true); - }); - - it("should call onFinished and not matrixClient.setDeviceVerified", () => { - // When - const deviceId = "XYZ"; - const device = new Device({ - userId: mockClient.getUserId()!, - deviceId, - displayName: "my device", - algorithms: [], - keys: new Map([[`ed25519:${deviceId}`, "ABCDEFGH"]]), - }); - const onFinished = jest.fn(); - renderDialog(mockClient.getUserId()!, device, onFinished); - - screen.getByRole("button", { name: "Cancel" }).click(); - - // Then - expect(onFinished).toHaveBeenCalledWith(false); - expect(mockClient.setDeviceVerified).not.toHaveBeenCalled(); - }); -}); diff --git a/test/unit-tests/components/views/dialogs/__snapshots__/ManualDeviceKeyVerificationDialog-test.tsx.snap b/test/unit-tests/components/views/dialogs/__snapshots__/ManualDeviceKeyVerificationDialog-test.tsx.snap deleted file mode 100644 index 1186f06f386..00000000000 --- a/test/unit-tests/components/views/dialogs/__snapshots__/ManualDeviceKeyVerificationDialog-test.tsx.snap +++ /dev/null @@ -1,231 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`ManualDeviceKeyVerificationDialog should display the device 1`] = ` -
-
-