fix(notifications): don't badge/notify stale device-verification requests

In-room verification requests arrive as m.room.message with
msgtype 'm.key.verification.request', so isNotificationEvent() counted them
(type is m.room.message). A stale/old request at the tail of a DM therefore
re-lit the room's unread dot — and could fire a toast/OS notification — on every
fresh sync (app update / CTRL+F5 cache clear); opening the room only cleared it
via the local read-receipt echo, so it returned on the next reload.

Exclude that msgtype from isNotificationEvent so verification control messages
never drive unread/notifications (mirrors the existing member/redaction/edit
exclusions). The rest of the verification flow already uses distinct event types
that aren't notification events.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 12:10:33 -04:00
co-authored by Claude Opus 4.8
parent 013f113bc2
commit 07b0c410ab
2 changed files with 31 additions and 0 deletions
+22
View File
@@ -357,6 +357,28 @@ test('isNotificationEvent accepts message/sticker but rejects member, redacted,
),
false,
);
// Device-verification requests (m.room.message + this msgtype) are crypto
// control messages — must NOT count as unread/notify (stale-request nag fix).
assert.equal(
isNotificationEvent(
mockEvent({
getType: () => 'm.room.message',
getContent: () => ({ msgtype: 'm.key.verification.request' }),
}),
),
false,
);
// Regression guard: a normal text message still notifies.
assert.equal(
isNotificationEvent(
mockEvent({
getType: () => 'm.room.message',
getContent: () => ({ msgtype: 'm.text', body: 'hi' }),
}),
),
true,
);
});
// --- roomHaveNotification / getUnreadInfo --------------------------------