# Lotus Chat — Bug Report & Technical Audit **Date:** June 2026 This document tracks identified bugs, edge cases, and architectural discrepancies found during the audit of the Lotus Chat codebase. Recommended fixes are provided for each item. --- ## 🛡️ Critical Security & Privacy Regressions ### 1. E2EE Bypass in Media Gallery Downloads **File:** `src/app/features/room/MediaGallery.tsx` (Line 855) **Status:** **CRITICAL** * **Issue:** The "Download" button in the Files tab uses `mxcUrlToHttp` directly and clicks an `` link. * **Impact:** In encrypted rooms, this downloads the encrypted ciphertext rather than the decrypted file. Users cannot open the downloaded files. * **Recommended Fix:** 1. Check if the event is encrypted. 2. If encrypted, use the `decryptAttachment` logic (similar to `useDecryptedMediaUrl`) to decrypt the file in memory. 3. Use `file-saver` or a Blob URL to trigger the download of the decrypted plaintext. ### 2. Privacy Leak in URL Previews **File:** `src/app/components/url-preview/UrlPreviewCard.tsx` (Line 1655) **Status:** **PRIVACY RISK** * **Issue:** Generic URL preview cards fetch favicons directly from `https://www.google.com/s2/favicons?domain=...`. * **Impact:** This leaks the user's browsing/chat activity (domains of links they see) to Google. It bypasses the "proxied through Matrix" privacy standard. * **Recommended Fix:** Use the proxy URL returned by the Matrix `/_matrix/media/v3/preview_url` endpoint instead of contacting Google directly. --- ## 🚩 Functional & Logic Bugs ### 1. Presence Updater Reverts Status Updates **File:** `src/app/hooks/usePresenceUpdater.ts` (Line 20) **Status:** High Priority * **Issue:** The `storedStatus` variable is captured once when the `useEffect` starts. * **Impact:** If a user updates their status message in the Profile settings, the presence updater hook continues to use the *old* status message from its closure. Every time the user moves their mouse/activity, the hook sends `setOnline` with the stale status, reverting the user's change. * **Recommended Fix:** 1. Read the status from `localStorage` inside the `setOnline`/`setUnavailable` functions rather than at the top of the effect. ### 2. Audio Playback Rate Reset **File:** `src/app/components/message/content/AudioContent.tsx` (Line 97) **Status:** UX Bug * **Issue:** The `playbackRate` is set in a `useEffect` that only depends on `[playbackSpeed]`. * **Impact:** If a user selects a playback speed *before* the audio blob has finished loading, the `