Strip mentions from forwarded messages (#30884)
* strip mentions from forwarded messages fixes element-hq/element-web#30883 * call attachMentions() for empty m.mentions in forwarded messages As there is no EditorModel, attachMentions() currently does nothing * fix lint and typecheck * update test "should be navigable using arrow keys" * update test "forwards pin drop event" add empty mentions to expected content * add doc to transformEvent() & elaborate on attachMentions() * add test "strips mentions from forwarded messages" * fix lint * update source of `attachMentions()` import --------- Co-authored-by: David Baker <dbkr@users.noreply.github.com>
This commit is contained in:
@@ -57,6 +57,7 @@ import {
|
|||||||
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
|
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
|
||||||
import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
|
import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
|
||||||
import { OverflowTileView } from "../rooms/OverflowTileView";
|
import { OverflowTileView } from "../rooms/OverflowTileView";
|
||||||
|
import { attachMentions } from "../../../utils/messages";
|
||||||
|
|
||||||
const AVATAR_SIZE = 30;
|
const AVATAR_SIZE = 30;
|
||||||
|
|
||||||
@@ -178,7 +179,18 @@ const Entry: React.FC<IEntryProps<any>> = ({ room, type, content, matrixClient:
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const transformEvent = (event: MatrixEvent): { type: string; content: IContent } => {
|
/**
|
||||||
|
* Transform content of a MatrixEvent before forwarding:
|
||||||
|
* 1. Strip all relations.
|
||||||
|
* 2. Convert location events into a static pin-drop location share,
|
||||||
|
* and remove description from self-location shares.
|
||||||
|
* 3. Pass through attachMentions() to strip mentions (as no EditorModel is present to recalculate from).
|
||||||
|
*
|
||||||
|
* @param event - The MatrixEvent to transform.
|
||||||
|
* @param userId - Current user MXID (passed through to attachMentions()).
|
||||||
|
* @returns The transformed event type and content.
|
||||||
|
*/
|
||||||
|
const transformEvent = (event: MatrixEvent, userId: string): { type: string; content: IContent } => {
|
||||||
const {
|
const {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
"m.relates_to": _, // strip relations - in future we will attach a relation pointing at the original event
|
"m.relates_to": _, // strip relations - in future we will attach a relation pointing at the original event
|
||||||
@@ -213,6 +225,13 @@ const transformEvent = (event: MatrixEvent): { type: string; content: IContent }
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mentions can leak information about the context of the original message,
|
||||||
|
// so pass through attachMentions() to recalculate mentions.
|
||||||
|
// Currently, this strips all mentions (forces an empty m.mentions),
|
||||||
|
// as there is no EditorModel to parse pills from.
|
||||||
|
// Future improvements could actually recalculate mentions based on the message body.
|
||||||
|
attachMentions(userId, content, null, undefined);
|
||||||
|
|
||||||
return { type, content };
|
return { type, content };
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -223,7 +242,7 @@ const ForwardDialog: React.FC<IProps> = ({ matrixClient: cli, event, permalinkCr
|
|||||||
cli.getProfileInfo(userId).then((info) => setProfileInfo(info));
|
cli.getProfileInfo(userId).then((info) => setProfileInfo(info));
|
||||||
}, [cli, userId]);
|
}, [cli, userId]);
|
||||||
|
|
||||||
const { type, content } = transformEvent(event);
|
const { type, content } = transformEvent(event, userId);
|
||||||
|
|
||||||
// For the message preview we fake the sender as ourselves
|
// For the message preview we fake the sender as ourselves
|
||||||
const mockEvent = new MatrixEvent({
|
const mockEvent = new MatrixEvent({
|
||||||
|
|||||||
@@ -153,8 +153,9 @@ describe("ForwardDialog", () => {
|
|||||||
|
|
||||||
await userEvent.keyboard("[Enter]");
|
await userEvent.keyboard("[Enter]");
|
||||||
expect(mockClient.sendEvent).toHaveBeenCalledWith("A", "m.room.message", {
|
expect(mockClient.sendEvent).toHaveBeenCalledWith("A", "m.room.message", {
|
||||||
body: "Hello world!",
|
"body": "Hello world!",
|
||||||
msgtype: "m.text",
|
"msgtype": "m.text",
|
||||||
|
"m.mentions": {},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -248,6 +249,37 @@ describe("ForwardDialog", () => {
|
|||||||
expect(secondButton.getAttribute("aria-disabled")).toBeFalsy();
|
expect(secondButton.getAttribute("aria-disabled")).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("strips mentions from forwarded messages", async () => {
|
||||||
|
const messageWithMention = mkEvent({
|
||||||
|
type: "m.room.message",
|
||||||
|
room: sourceRoom,
|
||||||
|
user: "@bob:example.org",
|
||||||
|
content: {
|
||||||
|
"msgtype": "m.text",
|
||||||
|
"body": "Hi @alice:example.org",
|
||||||
|
"m.mentions": {
|
||||||
|
user_ids: ["@alice:example.org"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
event: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { container } = mountForwardDialog(messageWithMention);
|
||||||
|
const roomId = "a";
|
||||||
|
|
||||||
|
// Click the send button.
|
||||||
|
act(() => {
|
||||||
|
const sendButton = container.querySelector(".mx_ForwardList_sendButton");
|
||||||
|
fireEvent.click(sendButton!);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Expected content should have mentions empty.
|
||||||
|
expect(mockClient.sendEvent).toHaveBeenCalledWith(roomId, messageWithMention.getType(), {
|
||||||
|
...messageWithMention.getContent(),
|
||||||
|
"m.mentions": {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("Location events", () => {
|
describe("Location events", () => {
|
||||||
// 14.03.2022 16:15
|
// 14.03.2022 16:15
|
||||||
const now = 1647270879403;
|
const now = 1647270879403;
|
||||||
@@ -357,11 +389,12 @@ describe("ForwardDialog", () => {
|
|||||||
|
|
||||||
sendToFirstRoom(container);
|
sendToFirstRoom(container);
|
||||||
|
|
||||||
expect(mockClient.sendEvent).toHaveBeenCalledWith(
|
const expectedContent = {
|
||||||
roomId,
|
...pinDropLocationEvent.getContent(),
|
||||||
pinDropLocationEvent.getType(),
|
"m.mentions": {}, // Add mentions (explicitly set to empty)
|
||||||
pinDropLocationEvent.getContent(),
|
};
|
||||||
);
|
|
||||||
|
expect(mockClient.sendEvent).toHaveBeenCalledWith(roomId, pinDropLocationEvent.getType(), expectedContent);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user