E2EE direct messages, the chat dock, the Messages module, the message WebSocket and its realtime registry, and the messages / message_keys tables (migration 0097; the downgrade restores the empty schema). Prod held two welcome notes, no message between people and one key — never used (owner decision, E34). WebSocket now has no owner module: the lint bans it everywhere. Privacy policy updated: it no longer promises E2EE for a feature that is gone.
93 lines
3.2 KiB
JSON
93 lines
3.2 KiB
JSON
{
|
|
"_comment": "One redaction contract for both logs: backend/app/logs.py redact() and frontend/src/lib/log.ts redact() must turn every `value` (under `key`) into `expected`. Both test suites run this file (backend tests/test_logs.py, frontend src/lib/log.contract.test.ts), so the two implementations cannot drift apart. Some cases prove a secret goes; others prove ordinary content (a search term, a Plex title, a chat line) is not mangled — what a LEVEL may carry is decided at the call site, not here.",
|
|
"cases": [
|
|
{
|
|
"name": "a password field is dropped whole",
|
|
"key": "",
|
|
"value": {
|
|
"email": "a@b.co",
|
|
"password": "hunter2",
|
|
"current_password": "x"
|
|
},
|
|
"expected": {
|
|
"email": "[email]",
|
|
"password": "[redacted]",
|
|
"current_password": "[redacted]"
|
|
}
|
|
},
|
|
{
|
|
"name": "a token under any spelling of the key, nested and in lists",
|
|
"key": "",
|
|
"value": {
|
|
"plex": { "plex_server_token": "abc", "Authorization": "Bearer z" },
|
|
"items": [{ "access_token": "t1" }, { "id": 3 }]
|
|
},
|
|
"expected": {
|
|
"plex": {
|
|
"plex_server_token": "[redacted]",
|
|
"Authorization": "[redacted]"
|
|
},
|
|
"items": [{ "access_token": "[redacted]" }, { "id": 3 }]
|
|
}
|
|
},
|
|
{
|
|
"name": "ciphertext, passphrases and cookies",
|
|
"key": "",
|
|
"value": {
|
|
"ciphertext": "AAAA",
|
|
"passphrase": "p",
|
|
"private_key": "k",
|
|
"cookies": "SID=1"
|
|
},
|
|
"expected": {
|
|
"ciphertext": "[redacted]",
|
|
"passphrase": "[redacted]",
|
|
"private_key": "[redacted]",
|
|
"cookies": "[redacted]"
|
|
}
|
|
},
|
|
{
|
|
"name": "a reset link and a verify fragment",
|
|
"key": "msg",
|
|
"value": "open https://app.example/#reset=QWErty123 or /?verify=abc&lang=hu",
|
|
"expected": "open https://app.example/#reset=[redacted] or /?verify=[redacted]&lang=hu"
|
|
},
|
|
{
|
|
"name": "an OAuth callback URL",
|
|
"key": "url",
|
|
"value": "/auth/callback?code=4/0Ab-xyz&state=s3cr3t&scope=email",
|
|
"expected": "/auth/callback?code=[redacted]&state=[redacted]&scope=email"
|
|
},
|
|
{
|
|
"name": "an email address inside a sentence",
|
|
"key": "message",
|
|
"value": "Invitation sent to Some.One+tag@mail.example.org.",
|
|
"expected": "Invitation sent to [email]."
|
|
},
|
|
{
|
|
"name": "a search term is kept (TRACE decides whether it is logged at all)",
|
|
"key": "q",
|
|
"value": "lo-fi beats to relax",
|
|
"expected": "lo-fi beats to relax"
|
|
},
|
|
{
|
|
"name": "a Plex title with an at-sign is not an address",
|
|
"key": "title",
|
|
"value": "Live @ Wembley 1986",
|
|
"expected": "Live @ Wembley 1986"
|
|
},
|
|
{
|
|
"name": "a chat line is text like any other; its only secret part is scrubbed",
|
|
"key": "body",
|
|
"value": "see you at 8, my mail is me@home.example",
|
|
"expected": "see you at 8, my mail is [email]"
|
|
},
|
|
{
|
|
"name": "non-text values pass through",
|
|
"key": "",
|
|
"value": { "status": 404, "ok": false, "ratio": 0.5, "none": null },
|
|
"expected": { "status": 404, "ok": false, "ratio": 0.5, "none": null }
|
|
}
|
|
]
|
|
}
|