From 5c8b14c53e17b321da7f3cae7cc0cd0c28949cb1 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Mon, 4 Mar 2024 16:24:08 +0000 Subject: [PATCH] Fix requests for senders to submit auto-rageshakes (#12304) If auto-rageshake-on-UISI is enabled, then when we get a UISI we send the sender a to-device message asking them to also rageshake. Unfortunately, the logic to do so has been broken since c30b263. Also a few other minor cleanups while we're here. --- src/stores/AutoRageshakeStore.ts | 31 ++++++++++++++-- test/stores/AutoRageshakeStore-test.ts | 49 ++++++++++++++------------ 2 files changed, 55 insertions(+), 25 deletions(-) diff --git a/src/stores/AutoRageshakeStore.ts b/src/stores/AutoRageshakeStore.ts index 0a2c1a6d7d9..7ac00452087 100644 --- a/src/stores/AutoRageshakeStore.ts +++ b/src/stores/AutoRageshakeStore.ts @@ -14,8 +14,17 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { ClientEvent, MatrixEvent, MatrixEventEvent, SyncStateData, SyncState } from "matrix-js-sdk/src/matrix"; +import { + ClientEvent, + MatrixEvent, + MatrixEventEvent, + SyncStateData, + SyncState, + ToDeviceMessageId, +} from "matrix-js-sdk/src/matrix"; import { sleep } from "matrix-js-sdk/src/utils"; +import { v4 as uuidv4 } from "uuid"; +import { logger } from "matrix-js-sdk/src/logger"; import SdkConfig from "../SdkConfig"; import sendBugReport from "../rageshake/submit-rageshake"; @@ -108,20 +117,28 @@ export default class AutoRageshakeStore extends AsyncStoreWithClient { const now = new Date().getTime(); if (now - this.state.lastRageshakeTime < RAGESHAKE_INTERVAL) { + logger.info( + `Not sending recipient-side autorageshake for event ${ev.getId()}/session ${sessionId}: last rageshake was too recent`, + ); return; } await this.updateState({ lastRageshakeTime: now }); + const senderUserId = ev.getSender()!; const eventInfo = { event_id: ev.getId(), room_id: ev.getRoomId(), session_id: sessionId, device_id: wireContent.device_id, - user_id: ev.getSender()!, + user_id: senderUserId, sender_key: wireContent.sender_key, }; + logger.info(`Sending recipient-side autorageshake for event ${ev.getId()}/session ${sessionId}`); + // XXX: the rageshake server returns the URL for the github issue... which is typically absent for + // auto-uisis, because we've disabled creation of GH issues for them. So the `recipient_rageshake` + // field is broken. const rageshakeURL = await sendBugReport(SdkConfig.get().bug_report_endpoint_url, { userText: "Auto-reporting decryption error (recipient)", sendLogs: true, @@ -133,10 +150,11 @@ export default class AutoRageshakeStore extends AsyncStoreWithClient { const messageContent = { ...eventInfo, recipient_rageshake: rageshakeURL, + [ToDeviceMessageId]: uuidv4(), }; this.matrixClient?.sendToDevice( AUTO_RS_REQUEST, - new Map([["messageContent.user_id", new Map([[messageContent.device_id, messageContent]])]]), + new Map([[senderUserId, new Map([[messageContent.device_id, messageContent]])]]), ); } } @@ -158,6 +176,9 @@ export default class AutoRageshakeStore extends AsyncStoreWithClient { const now = new Date().getTime(); if (now - this.state.lastRageshakeTime > RAGESHAKE_INTERVAL) { await this.updateState({ lastRageshakeTime: now }); + logger.info( + `Sending sender-side autorageshake for event ${messageContent["event_id"]}/session ${messageContent["session_id"]}`, + ); await sendBugReport(SdkConfig.get().bug_report_endpoint_url, { userText: `Auto-reporting decryption error (sender)\nRecipient rageshake: ${recipientRageshake}`, sendLogs: true, @@ -168,6 +189,10 @@ export default class AutoRageshakeStore extends AsyncStoreWithClient { auto_uisi: JSON.stringify(messageContent), }, }); + } else { + logger.info( + `Not sending sender-side autorageshake for event ${messageContent["event_id"]}/session ${messageContent["session_id"]}: last rageshake was too recent`, + ); } } diff --git a/test/stores/AutoRageshakeStore-test.ts b/test/stores/AutoRageshakeStore-test.ts index c4709dfbd0e..52c14d8cdb8 100644 --- a/test/stores/AutoRageshakeStore-test.ts +++ b/test/stores/AutoRageshakeStore-test.ts @@ -32,6 +32,8 @@ jest.mock("../../src/rageshake/submit-rageshake"); jest.mock("../../src/stores/WidgetStore"); jest.mock("../../src/stores/widgets/WidgetLayoutStore"); +const TEST_SENDER = "@sender@example.com"; + describe("AutoRageshakeStore", () => { const roomId = "!room:example.com"; let client: MatrixClient; @@ -59,7 +61,7 @@ describe("AutoRageshakeStore", () => { event: true, content: {}, room: roomId, - user: client.getSafeUserId(), + user: TEST_SENDER, type: EventType.RoomMessage, }); jest.spyOn(utdEvent, "isDecryptionFailure").mockReturnValue(true); @@ -81,29 +83,32 @@ describe("AutoRageshakeStore", () => { jest.advanceTimersByTime(5500); }); - it("should send a rageshake", () => { - expect(mocked(client).sendToDevice.mock.calls).toMatchInlineSnapshot( - ` + it("should send a to-device message", () => { + expect(mocked(client).sendToDevice.mock.calls).toEqual([ [ - [ "im.vector.auto_rs_request", - Map { - "messageContent.user_id" => Map { - undefined => { - "device_id": undefined, - "event_id": "utd_event_id", - "recipient_rageshake": undefined, - "room_id": "!room:example.com", - "sender_key": undefined, - "session_id": undefined, - "user_id": "@userId:matrix.org", - }, - }, - }, - ], - ] - `.replace("utd_event_id", utdEvent.getId()!), - ); + new Map([ + [ + TEST_SENDER, + new Map([ + [ + undefined, + { + "device_id": undefined, + "event_id": utdEvent.getId(), + "org.matrix.msgid": expect.any(String), + "recipient_rageshake": undefined, + "room_id": "!room:example.com", + "sender_key": undefined, + "session_id": undefined, + "user_id": TEST_SENDER, + }, + ], + ]), + ], + ]), + ], + ]); }); }); });