fix(wave-2): audit fixes — account-data races, search-cache wipe, export, media
Web fixes from the Wave-2 bug-hunt (findings in LOTUS_TODO): - F1 (security): wipe the decrypted-plaintext search index on SERVER-FORCED logout too (token expiry / remote sign-out) — only manual logout did before. F4: the delete no longer reports success while onblocked (waits, 3s cap). - M1/M2 (data-loss): useBookmarks + useUserNotes account-data writes are now serialized at MODULE scope (single queue + latestRef per client, echo-driven), fixing the cross-instance lost-update clobber (useBookmarks mounts per message row, so a per-instance queue was insufficient — caught in review). - M6: room-history export gets a 200-page cap + Cancel + unmount-abort + correct date-range early-break (raw paginated ts). M4: image compression skips PNG (was flattening transparency to black), bakes EXIF orientation via createImageBitmap, .jpg-renames, and falls back to the original on decode failure instead of dropping the file. M5: MediaGallery lightbox opens the right item (shared thumb guard). M8: audio speed survives async decrypt. - Desktop web wiring: D2 badge sums leaf rooms only (space double-count, like the favicon fix); D3 useTauriDnd re-hydrates from get_tray_dnd on mount; D5 updater has a terminal state. Reviewed; M7 reverted (past-time clamp is an intentional, tested contract). tsc/eslint/prettier clean, build OK, 678 tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -70,6 +70,32 @@ Bug-hunt of the Tier-1 high-risk areas (notifications/unread/receipts, threads,
|
||||
|
||||
---
|
||||
|
||||
## 🔎 Audit findings — Wave 2 (2026-07)
|
||||
|
||||
Tier-2 bug-hunt (desktop/native, crypto/session/infra, messaging data) by 3 parallel agents. `[D#]`=desktop/native, `[F#]`=crypto/session/infra, `[M#]`=messaging.
|
||||
|
||||
**✅ FIXED (2026-07):**
|
||||
|
||||
- **🔴/security:** F1 (search-cache DECRYPTED plaintext never wiped on server-forced logout → now `deleteSearchCacheDatabase()` on that path); D1 (Linux no-sleep was totally broken — zbus inhibit bound to a dropped connection; now a long-lived connection in managed state); M1/M2 (bookmarks + user-notes account-data **lost-update** data-loss → serialized via `latestRef`+write-queue like `useReminders`).
|
||||
- **🟠:** M3 (reminder cross-instance race → hoisted the queue to module scope); M4 (image compression flattened transparent PNGs to black + stripped EXIF orientation → skip PNG, `createImageBitmap` orientation, `.jpg` rename); M6 (export "all" had unbounded pagination/OOM → 200-page cap + Cancel button + incremental `oldestTs`); D2 (desktop taskbar/Unity badge double-counted spaces — same as favicon N1 → leaf-only sum); D3 (tray DND desynced from `manualDndAtom` after reload → `get_tray_dnd` re-hydrate); F4 (search-cache delete falsely reported success while `onblocked` → wait for real delete, 3s cap).
|
||||
- **🟡:** M5 (MediaGallery lightbox opened the wrong item — index drift; shared `getThumbMxc` guard); M8 (audio playback-rate reset on async decrypt → re-apply on loadedmetadata/play); D5 (updater never relaunched → `app.restart()` + terminal UI state).
|
||||
|
||||
**⚠️ FLAGGED — product decision (not auto-changed):**
|
||||
|
||||
- **F2:** URL previews **default ON in encrypted rooms** (`settings.ts encUrlPreview: true`) → the homeserver fetches every link in an E2EE message (leaks E2EE link URLs to the server). This is the deliberate Lotus "URL Preview Default in Encrypted Rooms" feature — most clients default it OFF for privacy. **Your call whether to flip the default to `false`.**
|
||||
|
||||
**Won't-fix / by-design:** M7 (scheduledMessages clamps a past target to 1s — intentional + unit-tested; the modal already guards ≥60s).
|
||||
|
||||
**Still open (low tail / follow-ups):**
|
||||
|
||||
- **D4** cold-start deep link may navigate twice (idempotent; guard the argv path). **D6** WinRT rich-toast AUMID never registered → P5-41 quick-reply / P5-35 click-to-open are inert on Windows (falls back to plain toast) — a wiring task. **D7** Unity badge `application://cinny.desktop` id may not match the installed `.desktop` basename (runtime-verify on the `.deb`/AppImage).
|
||||
- **F3** session blob unconditionally wins over legacy keys even if legacy is fresher (downgrade-then-upgrade → stale token → forced re-login); **F5** OIDC refresh drops `expiresAt`/id-token claims on persist; **F6** server-forced logout leaves a stale token in the SW + skips issuer revocation (token already revoked server-side — minor).
|
||||
- **Nit:** ForwardMessageDialog doesn't strip `m.mentions` → forwarding can re-ping.
|
||||
|
||||
**Verified sound (spot-checks):** media-auth token only in the `Authorization` header (never a URL); `removeFallbackSession` clears all credential keys; session cross-tab sync; the opt-in search gate; `cryptoCallbacks`; SW precache (no stale SPA shell); Windows `SetThreadExecutionState` main-thread clear; native IPC surface matches end-to-end; GDI/COM/jumplist/thumbbar resource hygiene; `useReminders` serialization template; forward multi-select index alignment; KaTeX (`trust:false`, no XSS); `mathParse`; `searchCache` merge/coverage; ScheduleMessageModal local-tz + ≥60s guard; polls 2–10 bounds; edit-history pagination; `useLocalTime` DST.
|
||||
|
||||
---
|
||||
|
||||
## ✅ Done — Awaiting Verification
|
||||
|
||||
Built and gate-green; verify per [LOTUS_TESTING.md](./LOTUS_TESTING.md), then they graduate to LOTUS_FEATURES.md. (Open bugs + the verification backlog now live in this file and LOTUS_TESTING.md.)
|
||||
|
||||
Reference in New Issue
Block a user