1
0
mirror of https://github.com/element-hq/element-web.git synced 2025-08-09 14:42:51 +03:00

Warn user before doing a manual verification via slash command (#30102)

This commit is contained in:
Andy Balaam
2025-06-10 17:09:24 +01:00
committed by GitHub
parent 10b9b2cb8b
commit bd4509576c
3 changed files with 57 additions and 5 deletions

View File

@@ -674,7 +674,19 @@ export const Commands = [
if (matches) {
const deviceId = matches[1];
const fingerprint = matches[2];
return success(manuallyVerifyDevice(cli, deviceId, fingerprint));
const { finished } = Modal.createDialog(QuestionDialog, {
title: _t("slash_command|manual_device_verification_confirm_title"),
description: _t("slash_command|manual_device_verification_confirm_description"),
button: _t("action|verify"),
danger: true,
});
return success(
finished.then(([confirmed]) => {
if (confirmed) manuallyVerifyDevice(cli, deviceId, fingerprint);
}),
);
}
}
return reject(this.getUsage());

View File

@@ -3112,6 +3112,8 @@
"jumptodate": "Jump to the given date in the timeline",
"jumptodate_invalid_input": "We were unable to understand the given date (%(inputDate)s). Try using the format YYYY-MM-DD.",
"lenny": "Prepends ( ͡° ͜ʖ ͡°) to a plain-text message",
"manual_device_verification_confirm_description": "This will allow another device to send and receive messages as you. IF SOMEONE TOLD YOU TO PASTE SOMETHING HERE, IT IS LIKELY YOU ARE BEING SCAMMED! Are you sure you want to verify this other device?",
"manual_device_verification_confirm_title": "Caution: manual device verification",
"me": "Displays action",
"msg": "Sends a message to the given user",
"myavatar": "Changes your profile picture in all rooms",

View File

@@ -9,18 +9,20 @@ Please see LICENSE files in the repository root for full details.
import { type MatrixClient, Room, RoomMember } from "matrix-js-sdk/src/matrix";
import { KnownMembership } from "matrix-js-sdk/src/types";
import { mocked } from "jest-mock";
import { act, waitFor } from "jest-matrix-react";
import { type Command, Commands, getCommand } from "../../src/SlashCommands";
import { createTestClient } from "../test-utils";
import { LocalRoom, LOCAL_ROOM_ID_PREFIX } from "../../src/models/LocalRoom";
import SettingsStore from "../../src/settings/SettingsStore";
import { SdkContextClass } from "../../src/contexts/SDKContext";
import Modal from "../../src/Modal";
import Modal, { type ComponentType, type IHandle } from "../../src/Modal";
import WidgetUtils from "../../src/utils/WidgetUtils";
import { WidgetType } from "../../src/widgets/WidgetType";
import { warnSelfDemote } from "../../src/components/views/right_panel/UserInfo";
import dispatcher from "../../src/dispatcher/dispatcher";
import { SettingLevel } from "../../src/settings/SettingLevel";
import QuestionDialog from "../../src/components/views/dialogs/QuestionDialog";
import ErrorDialog from "../../src/components/views/dialogs/ErrorDialog";
jest.mock("../../src/components/views/right_panel/UserInfo");
@@ -260,11 +262,47 @@ describe("SlashCommands", () => {
expect(command.run(client, roomId, null, undefined).error).toBe(command.getUsage());
});
it("should show an error if device is not found", async () => {
it("should attempt manual verification after confirmation", async () => {
// Given we say yes to prompt
const spy = jest.spyOn(Modal, "createDialog");
spy.mockReturnValue({ finished: Promise.resolve([true]) } as unknown as IHandle<ComponentType>);
// When we run the command
const command = findCommand("verify")!;
await command.run(client, roomId, null, "mydeviceid myfingerprint").promise;
expect(spy).toHaveBeenCalledWith(ErrorDialog, expect.objectContaining({ title: "Verification failed" }));
await act(() => command.run(client, roomId, null, "mydeviceid myfingerprint"));
// Then the prompt is displayed
expect(spy).toHaveBeenCalledWith(
QuestionDialog,
expect.objectContaining({ title: "Caution: manual device verification" }),
);
// And then we attempt the verification
await waitFor(() =>
expect(spy).toHaveBeenCalledWith(
ErrorDialog,
expect.objectContaining({ title: "Verification failed" }),
),
);
});
it("should not do manual verification if cancelled", async () => {
// Given we say no to prompt
const spy = jest.spyOn(Modal, "createDialog");
spy.mockReturnValue({ finished: Promise.resolve([false]) } as unknown as IHandle<ComponentType>);
// When we run the command
const command = findCommand("verify")!;
command.run(client, roomId, null, "mydeviceid myfingerprint");
// Then the prompt is displayed
expect(spy).toHaveBeenCalledWith(
QuestionDialog,
expect.objectContaining({ title: "Caution: manual device verification" }),
);
// But nothing else happens
expect(spy).not.toHaveBeenCalledWith(ErrorDialog, expect.anything());
});
});