Two competing local-cache implementations exist. lib/messageCache.ts correctly encrypts messages at rest with AES-GCM before storing in IndexedDB, but is never imported anywhere. The implementation in live use, lib/search/db.ts, stores full decrypted-message objects — including plaintext content — directly in IndexedDB with no encryption. IndexedDB is queryable by any script running in the page's origin (including a compromised extension or XSS payload), so this is a direct at-rest confidentiality violation.
Acceptance criteria:
- The live local cache (
lib/search/db.ts) encrypts message content before writing to IndexedDB and decrypts on read
- The cache-encryption key is derived from something not publicly recoverable (e.g. the now-correctly-persisted identity private key material), never from the public key alone
lib/messageCache.ts is either deleted (if search/db.ts absorbs its logic) or becomes the single canonical implementation — not left as a second parallel unused module
- A test confirms inspecting raw IndexedDB store contents directly never reveals plaintext message content
Two competing local-cache implementations exist.
lib/messageCache.tscorrectly encrypts messages at rest with AES-GCM before storing in IndexedDB, but is never imported anywhere. The implementation in live use,lib/search/db.ts, stores full decrypted-message objects — including plaintext content — directly in IndexedDB with no encryption. IndexedDB is queryable by any script running in the page's origin (including a compromised extension or XSS payload), so this is a direct at-rest confidentiality violation.Acceptance criteria:
lib/search/db.ts) encrypts message content before writing to IndexedDB and decrypts on readlib/messageCache.tsis either deleted (ifsearch/db.tsabsorbs its logic) or becomes the single canonical implementation — not left as a second parallel unused module