Remove call of MatrixClient.setDeviceVerified
This commit is contained in:
parent
95175caf0c
commit
ccc04de039
6 changed files with 4 additions and 514 deletions
|
@ -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: "<user-id> <device-id> <device-signing-key>",
|
||||
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<void> => {
|
||||
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: (
|
||||
<div>
|
||||
<p>{_t("slash_command|verify_success_description", { userId, deviceId })}</p>
|
||||
</div>
|
||||
),
|
||||
});
|
||||
})(),
|
||||
);
|
||||
}
|
||||
}
|
||||
return reject(this.getUsage());
|
||||
},
|
||||
category: CommandCategories.advanced,
|
||||
renderingTypes: [TimelineRenderingType.Room],
|
||||
}),
|
||||
new Command({
|
||||
command: "discardsession",
|
||||
description: _td("slash_command|discardsession"),
|
||||
|
|
|
@ -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 = (
|
||||
<div>
|
||||
<p>{text}</p>
|
||||
<div className="mx_DeviceVerifyDialog_cryptoSection">
|
||||
<ul>
|
||||
<li>
|
||||
<label>{_t("encryption|verification|manual_device_verification_device_name_label")}:</label>{" "}
|
||||
<span>{device.displayName}</span>
|
||||
</li>
|
||||
<li>
|
||||
<label>{_t("encryption|verification|manual_device_verification_device_id_label")}:</label>{" "}
|
||||
<span>
|
||||
<code>{device.deviceId}</code>
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
<label>{_t("encryption|verification|manual_device_verification_device_key_label")}:</label>{" "}
|
||||
<span>
|
||||
<code>
|
||||
<strong>{key}</strong>
|
||||
</code>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p>{_t("encryption|verification|manual_device_verification_footer")}</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<QuestionDialog
|
||||
title={_t("settings|sessions|verify_session")}
|
||||
description={body}
|
||||
button={_t("settings|sessions|verify_session")}
|
||||
onFinished={onLegacyFinished}
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -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"
|
||||
},
|
||||
|
|
|
@ -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<void> => {
|
||||
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 });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
<MatrixClientContext.Provider value={mockClient}>
|
||||
<ManualDeviceKeyVerificationDialog userId={userId} device={device} onFinished={onLegacyFinished} />
|
||||
</MatrixClientContext.Provider>,
|
||||
);
|
||||
}
|
||||
|
||||
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();
|
||||
});
|
||||
});
|
|
@ -1,231 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ManualDeviceKeyVerificationDialog should display the device 1`] = `
|
||||
<div>
|
||||
<div
|
||||
data-focus-guard="true"
|
||||
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-describedby="mx_Dialog_content"
|
||||
aria-labelledby="mx_BaseDialog_title"
|
||||
class="mx_QuestionDialog mx_Dialog_fixedWidth"
|
||||
data-focus-lock-disabled="false"
|
||||
role="dialog"
|
||||
>
|
||||
<div
|
||||
class="mx_Dialog_header"
|
||||
>
|
||||
<h1
|
||||
class="mx_Heading_h3 mx_Dialog_title"
|
||||
id="mx_BaseDialog_title"
|
||||
>
|
||||
Verify session
|
||||
</h1>
|
||||
</div>
|
||||
<div
|
||||
class="mx_Dialog_content"
|
||||
id="mx_Dialog_content"
|
||||
>
|
||||
<div>
|
||||
<p>
|
||||
Confirm by comparing the following with the User Settings in your other session:
|
||||
</p>
|
||||
<div
|
||||
class="mx_DeviceVerifyDialog_cryptoSection"
|
||||
>
|
||||
<ul>
|
||||
<li>
|
||||
<label>
|
||||
Session name
|
||||
:
|
||||
</label>
|
||||
|
||||
<span>
|
||||
my device
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
<label>
|
||||
Session ID
|
||||
:
|
||||
</label>
|
||||
|
||||
<span>
|
||||
<code>
|
||||
XYZ
|
||||
</code>
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
<label>
|
||||
Session key
|
||||
:
|
||||
</label>
|
||||
|
||||
<span>
|
||||
<code>
|
||||
<strong>
|
||||
ABCD EFGH
|
||||
</strong>
|
||||
</code>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p>
|
||||
If they don't match, the security of your communication may be compromised.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mx_Dialog_buttons"
|
||||
>
|
||||
<span
|
||||
class="mx_Dialog_buttons_row"
|
||||
>
|
||||
<button
|
||||
data-testid="dialog-cancel-button"
|
||||
type="button"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
class="mx_Dialog_primary"
|
||||
data-testid="dialog-primary-button"
|
||||
type="button"
|
||||
>
|
||||
Verify session
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Close dialog"
|
||||
class="mx_AccessibleButton mx_Dialog_cancelButton"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
data-focus-guard="true"
|
||||
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
|
||||
tabindex="0"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ManualDeviceKeyVerificationDialog should display the device of another user 1`] = `
|
||||
<div>
|
||||
<div
|
||||
data-focus-guard="true"
|
||||
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-describedby="mx_Dialog_content"
|
||||
aria-labelledby="mx_BaseDialog_title"
|
||||
class="mx_QuestionDialog mx_Dialog_fixedWidth"
|
||||
data-focus-lock-disabled="false"
|
||||
role="dialog"
|
||||
>
|
||||
<div
|
||||
class="mx_Dialog_header"
|
||||
>
|
||||
<h1
|
||||
class="mx_Heading_h3 mx_Dialog_title"
|
||||
id="mx_BaseDialog_title"
|
||||
>
|
||||
Verify session
|
||||
</h1>
|
||||
</div>
|
||||
<div
|
||||
class="mx_Dialog_content"
|
||||
id="mx_Dialog_content"
|
||||
>
|
||||
<div>
|
||||
<p>
|
||||
Confirm this user's session by comparing the following with their User Settings:
|
||||
</p>
|
||||
<div
|
||||
class="mx_DeviceVerifyDialog_cryptoSection"
|
||||
>
|
||||
<ul>
|
||||
<li>
|
||||
<label>
|
||||
Session name
|
||||
:
|
||||
</label>
|
||||
|
||||
<span>
|
||||
my device
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
<label>
|
||||
Session ID
|
||||
:
|
||||
</label>
|
||||
|
||||
<span>
|
||||
<code>
|
||||
XYZ
|
||||
</code>
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
<label>
|
||||
Session key
|
||||
:
|
||||
</label>
|
||||
|
||||
<span>
|
||||
<code>
|
||||
<strong>
|
||||
ABCD EFGH
|
||||
</strong>
|
||||
</code>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p>
|
||||
If they don't match, the security of your communication may be compromised.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mx_Dialog_buttons"
|
||||
>
|
||||
<span
|
||||
class="mx_Dialog_buttons_row"
|
||||
>
|
||||
<button
|
||||
data-testid="dialog-cancel-button"
|
||||
type="button"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
class="mx_Dialog_primary"
|
||||
data-testid="dialog-primary-button"
|
||||
type="button"
|
||||
>
|
||||
Verify session
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Close dialog"
|
||||
class="mx_AccessibleButton mx_Dialog_cancelButton"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
data-focus-guard="true"
|
||||
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
|
||||
tabindex="0"
|
||||
/>
|
||||
</div>
|
||||
`;
|
Loading…
Add table
Add a link
Reference in a new issue