From 86d8b06da91cb6f1b231277a821bc12481f4cbfb Mon Sep 17 00:00:00 2001 From: Gustavo Madeira Santana Date: Fri, 27 Mar 2026 21:40:49 -0400 Subject: [PATCH] Matrix: preserve strict DM SAS fallback --- .../matrix/src/matrix/monitor/events.test.ts | 54 +++++++++++++++++-- .../src/matrix/monitor/verification-events.ts | 16 +++++- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/extensions/matrix/src/matrix/monitor/events.test.ts b/extensions/matrix/src/matrix/monitor/events.test.ts index 17696597042..fddba44af24 100644 --- a/extensions/matrix/src/matrix/monitor/events.test.ts +++ b/extensions/matrix/src/matrix/monitor/events.test.ts @@ -30,6 +30,7 @@ function createHarness(params?: { storeAllowFrom?: string[]; accountDataByType?: Record; joinedMembersByRoom?: Record; + getJoinedRoomsError?: Error; memberStateByRoomUser?: Record>; verifications?: Array<{ id: string; @@ -91,9 +92,11 @@ function createHarness(params?: { params?.joinedMembersByRoom?.[roomId] ?? ["@bot:example.org", "@alice:example.org"], ), getJoinedRooms: vi.fn(async () => - Object.keys(params?.joinedMembersByRoom ?? {}).length > 0 - ? Object.keys(params?.joinedMembersByRoom ?? {}) - : ["!room:example.org"], + params?.getJoinedRoomsError + ? await Promise.reject(params.getJoinedRoomsError) + : Object.keys(params?.joinedMembersByRoom ?? {}).length > 0 + ? Object.keys(params?.joinedMembersByRoom ?? {}) + : ["!room:example.org"], ), getAccountData: vi.fn( async (eventType: string) => @@ -1091,6 +1094,51 @@ describe("registerMatrixMonitorEvents verification routing", () => { expect(bodies.some((body) => body.includes("SAS decimal: 1111 2222 3333"))).toBe(false); }); + it("preserves strict-room SAS fallback when active DM inspection cannot resolve a room", async () => { + const { sendMessage, roomEventListener } = createHarness({ + joinedMembersByRoom: { + "!dm:example.org": ["@alice:example.org", "@bot:example.org"], + }, + getJoinedRoomsError: new Error("temporary joined-room lookup failure"), + verifications: [ + { + id: "verification-active", + transactionId: "$different-flow-id", + otherUserId: "@alice:example.org", + updatedAt: new Date("2026-02-25T21:43:54.000Z").toISOString(), + phaseName: "started", + phase: 3, + pending: true, + sas: { + decimal: [6158, 1986, 3513], + emoji: [ + ["🎁", "Gift"], + ["🌍", "Globe"], + ["🐴", "Horse"], + ], + }, + }, + ], + }); + + roomEventListener("!dm:example.org", { + event_id: "$start-active", + sender: "@alice:example.org", + type: "m.key.verification.start", + origin_server_ts: Date.now(), + content: { + "m.relates_to": { event_id: "$req-active" }, + }, + }); + + await vi.waitFor(() => { + const bodies = (sendMessage.mock.calls as unknown[][]).map((call) => + String((call[1] as { body?: string } | undefined)?.body ?? ""), + ); + expect(bodies.some((body) => body.includes("SAS decimal: 6158 1986 3513"))).toBe(true); + }); + }); + it("prefers the active verification for the current DM when multiple active summaries exist", async () => { const { sendMessage, roomEventListener } = createHarness({ joinedMembersByRoom: { diff --git a/extensions/matrix/src/matrix/monitor/verification-events.ts b/extensions/matrix/src/matrix/monitor/verification-events.ts index b905d71a120..9ee51db2977 100644 --- a/extensions/matrix/src/matrix/monitor/verification-events.ts +++ b/extensions/matrix/src/matrix/monitor/verification-events.ts @@ -223,7 +223,21 @@ async function resolveVerificationSummaryForSignal( client, remoteUserId: params.senderId, }).catch(() => null); - if (trimMaybeString(inspection?.activeRoomId) !== params.roomId) { + const activeRoomId = trimMaybeString(inspection?.activeRoomId); + if (activeRoomId) { + if (activeRoomId !== params.roomId) { + return null; + } + } else if ( + !(await isStrictDirectRoom({ + client, + roomId: params.roomId, + remoteUserId: params.senderId, + })) + ) { + // If we cannot determine a canonical active DM, preserve the older + // strict-room fallback so transient m.direct or joined-room read failures + // do not suppress SAS notices for the current DM. return null; }