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.
pull/28217/head
Richard van der Hoff 2024-03-04 16:24:08 +00:00 committed by GitHub
parent c3e0535be9
commit 5c8b14c53e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 55 additions and 25 deletions

View File

@ -14,8 +14,17 @@ See the License for the specific language governing permissions and
limitations under the License. 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 { 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 SdkConfig from "../SdkConfig";
import sendBugReport from "../rageshake/submit-rageshake"; import sendBugReport from "../rageshake/submit-rageshake";
@ -108,20 +117,28 @@ export default class AutoRageshakeStore extends AsyncStoreWithClient<IState> {
const now = new Date().getTime(); const now = new Date().getTime();
if (now - this.state.lastRageshakeTime < RAGESHAKE_INTERVAL) { 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; return;
} }
await this.updateState({ lastRageshakeTime: now }); await this.updateState({ lastRageshakeTime: now });
const senderUserId = ev.getSender()!;
const eventInfo = { const eventInfo = {
event_id: ev.getId(), event_id: ev.getId(),
room_id: ev.getRoomId(), room_id: ev.getRoomId(),
session_id: sessionId, session_id: sessionId,
device_id: wireContent.device_id, device_id: wireContent.device_id,
user_id: ev.getSender()!, user_id: senderUserId,
sender_key: wireContent.sender_key, 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, { const rageshakeURL = await sendBugReport(SdkConfig.get().bug_report_endpoint_url, {
userText: "Auto-reporting decryption error (recipient)", userText: "Auto-reporting decryption error (recipient)",
sendLogs: true, sendLogs: true,
@ -133,10 +150,11 @@ export default class AutoRageshakeStore extends AsyncStoreWithClient<IState> {
const messageContent = { const messageContent = {
...eventInfo, ...eventInfo,
recipient_rageshake: rageshakeURL, recipient_rageshake: rageshakeURL,
[ToDeviceMessageId]: uuidv4(),
}; };
this.matrixClient?.sendToDevice( this.matrixClient?.sendToDevice(
AUTO_RS_REQUEST, 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<IState> {
const now = new Date().getTime(); const now = new Date().getTime();
if (now - this.state.lastRageshakeTime > RAGESHAKE_INTERVAL) { if (now - this.state.lastRageshakeTime > RAGESHAKE_INTERVAL) {
await this.updateState({ lastRageshakeTime: now }); 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, { await sendBugReport(SdkConfig.get().bug_report_endpoint_url, {
userText: `Auto-reporting decryption error (sender)\nRecipient rageshake: ${recipientRageshake}`, userText: `Auto-reporting decryption error (sender)\nRecipient rageshake: ${recipientRageshake}`,
sendLogs: true, sendLogs: true,
@ -168,6 +189,10 @@ export default class AutoRageshakeStore extends AsyncStoreWithClient<IState> {
auto_uisi: JSON.stringify(messageContent), 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`,
);
} }
} }

View File

@ -32,6 +32,8 @@ jest.mock("../../src/rageshake/submit-rageshake");
jest.mock("../../src/stores/WidgetStore"); jest.mock("../../src/stores/WidgetStore");
jest.mock("../../src/stores/widgets/WidgetLayoutStore"); jest.mock("../../src/stores/widgets/WidgetLayoutStore");
const TEST_SENDER = "@sender@example.com";
describe("AutoRageshakeStore", () => { describe("AutoRageshakeStore", () => {
const roomId = "!room:example.com"; const roomId = "!room:example.com";
let client: MatrixClient; let client: MatrixClient;
@ -59,7 +61,7 @@ describe("AutoRageshakeStore", () => {
event: true, event: true,
content: {}, content: {},
room: roomId, room: roomId,
user: client.getSafeUserId(), user: TEST_SENDER,
type: EventType.RoomMessage, type: EventType.RoomMessage,
}); });
jest.spyOn(utdEvent, "isDecryptionFailure").mockReturnValue(true); jest.spyOn(utdEvent, "isDecryptionFailure").mockReturnValue(true);
@ -81,29 +83,32 @@ describe("AutoRageshakeStore", () => {
jest.advanceTimersByTime(5500); jest.advanceTimersByTime(5500);
}); });
it("should send a rageshake", () => { it("should send a to-device message", () => {
expect(mocked(client).sendToDevice.mock.calls).toMatchInlineSnapshot( expect(mocked(client).sendToDevice.mock.calls).toEqual([
`
[ [
[
"im.vector.auto_rs_request", "im.vector.auto_rs_request",
Map { new Map([
"messageContent.user_id" => Map { [
undefined => { TEST_SENDER,
"device_id": undefined, new Map([
"event_id": "utd_event_id", [
"recipient_rageshake": undefined, undefined,
"room_id": "!room:example.com", {
"sender_key": undefined, "device_id": undefined,
"session_id": undefined, "event_id": utdEvent.getId(),
"user_id": "@userId:matrix.org", "org.matrix.msgid": expect.any(String),
}, "recipient_rageshake": undefined,
}, "room_id": "!room:example.com",
}, "sender_key": undefined,
], "session_id": undefined,
] "user_id": TEST_SENDER,
`.replace("utd_event_id", utdEvent.getId()!), },
); ],
]),
],
]),
],
]);
}); });
}); });
}); });