@@ -92,6 +92,17 @@ export function scrubMatrixUrl(url: string): string {
9292 . replace ( / \/ % 2 3 [ ^ / ? # \s ] * / gi, '/[ROOM_ALIAS]' )
9393 // URL-encoded event IDs as bare path segments: /%24eventId (%24 = $)
9494 . replace ( / \/ % 2 4 [ ^ / ? # \s ] * / gi, '/[EVENT_ID]' )
95+ // ── Opaque Matrix IDs with percent-encoded colon (%3A) ─────────────────────────
96+ // Catches device IDs, filter tokens, and other bare Matrix IDs that lack a sigil
97+ // prefix but still follow the localpart%3Aserver pattern in URL paths.
98+ // e.g. /Gj3Wy2D8gAi8jTIyR%3Asable.moe (decoded: Gj3Wy2D8gAi8jTIyR:sable.moe)
99+ . replace ( / \/ [ A - Z a - z 0 - 9 + / _ - ] { 5 , } % 3 A [ A - Z a - z 0 - 9 . _ - ] + [ ^ / ? # \s ] * / gi, '/[MATRIX_ID]' )
100+ // ── Long opaque base64url path segments (access tokens, crypto keys, push tokens) ─
101+ // Catches 30+ character base64url strings that appear as standalone path segments.
102+ // These are typically Curve25519 keys, MSC3575 session tokens, or push endpoints.
103+ // e.g. /vI02CuiDNpaYEhUIVLbqE8vdKqm2ZwqIR5Y6NwNY_Rg/
104+ // Runs last so earlier patterns already replaced known Matrix IDs.
105+ . replace ( / \/ [ A - Z a - z 0 - 9 + / _ - ] { 30 , } ( \/ | $ ) / g, '/[REDACTED]$1' )
95106 // ── Preview URL endpoint ────────────────────────────────────────────────────────
96107 // The ?url= query parameter on preview_url contains the full external URL being
97108 // previewed — strip the entire query string so browsing habits cannot be inferred.
0 commit comments