diff --git a/help4bis-claude-notes/current-state.md b/help4bis-claude-notes/current-state.md index 96f0666..3997316 100644 --- a/help4bis-claude-notes/current-state.md +++ b/help4bis-claude-notes/current-state.md @@ -1,51 +1,63 @@ -## M8Chat App2 — Current State (2026-04-10) +## M8Chat App2 — Current State (2026-04-11) -Custom Flutter Matrix chat client (v1.2.0) deployed to app2.m8chat.au for testing. -Production (app.m8chat.au) still runs the old FluffyChat fork — DO NOT deploy there. +Custom Flutter Matrix chat client deployed to app2.m8chat.au. Replaces the FluffyChat fork (app.m8chat.au). Built on Matrix Dart SDK 0.33.0, LiveKit for video, Olm for E2EE. + +### What was built/changed this session + +1. **Jitsi Conference tab** — 4th bottom nav tab for joining conf.m8chat.au meetings +2. **Help tab** — 5th bottom nav tab with troubleshooting guides, account management links +3. **Auth rewrite (v2.0.0)** — fresh login every session on web, no credential persistence +4. **SSSS/cross-signing/key backup** — full security setup dialog (Bootstrap flow) +5. **Key restore dialog** — enter recovery key to download Megolm keys from backup +6. **Authenticated media (v2.0.0)** — switched to /_matrix/client/v1/media/download/ (Synapse 1.151.0 froze old endpoint) +7. **LiveKit E2EE** — CallE2EEManager for m.rtc.encryption_keys key exchange, COOP/COEP headers +8. **Hangup fix** — sends {} to clear call.member state event +9. **Cleaned up 24 ghost devices** for try user (DB direct delete) ### What works -- **Chat messaging** — rooms list, timeline, send/receive, reactions, replies, file upload, typing indicators -- **E2EE (Olm/Megolm)** — Olm loads in browser, device keys upload, messages encrypt/decrypt between app2 and Element -- **Spaces** — expandable space list with child rooms -- **User search** — search Matrix user directory, start DMs -- **Jitsi conferencing** — lazy-loaded iframe, no-login required -- **LiveKit video/audio calls** — JWT fetch works, WebRTC connects, video+audio publish to LiveKit SFU -- **Session persistence** — credentials in flutter_secure_storage, events in MatrixSdkDatabase (IndexedDB) -- **Brave browser** — app loads and works (Olm included, graceful fallback if WASM blocked) +- Login/logout flow (fresh every session) +- Room list with avatars (authenticated media endpoint) +- Chat messaging (text) +- Encrypted message display (lock icon for undecryptable) +- Security setup (SSSS + cross-signing + key backup creation) +- Key restore from backup +- Jitsi conference joining (Conference tab) +- Help tab with troubleshooting content +- Spaces view +- Profile with security settings -### What is broken / incomplete -- **Video call rendering — SCRAMBLED VIDEO from Element X**: Root cause identified. Element X sends media with `encryption: GCM` (AES-GCM frame encryption). App2 sends `encryption: NONE`. The LiveKit Flutter SDK needs E2EE frame encryption enabled to decrypt Element X video. This is the #1 priority fix. -- **Incoming call detection**: App listens for old m.call.invite events. Element X sends MSC3401 call.member state events. Incoming calls from Element X to app2 are not detected. -- **Avatar 404s**: ~10 room avatars return 404 on legacy /_matrix/media/v3/download/ path. Server may require authenticated media. -- **Rooms list spam**: debugPrint in rooms_repository.dart dumps all 15 rooms to console on every sync. Needs removal. -- **Old ghost devices**: 20 devices for @try user, 5 without keys (from pre-Olm builds). Should be cleaned up server-side. -- **Red exclamation mark in Element**: Try device is unverified (no cross-signing). Cosmetic — requires manual verification or Phase 2 cross-signing. -- **Profile screen**: E2EE status shows dynamically but notifications/cross-signing are placeholders. +### What's broken / untested +- **Video calls (E2EE interop)** — COOP/COEP headers added, E2EE re-enabled, but NOT YET TESTED. May still show scrambled video if key exchange doesn't interop with Element X's m.rtc.encryption_keys format. +- **Hangup termination** — Changed to send {} but NOT YET TESTED whether Element X recognises it. +- **Incoming call detection** — Not implemented. No MSC3401 state event listener. +- **Avatar 404s in cached/old data** — sync_persistence_service caches URLs; stale URLs may linger in IndexedDB +- **Ghost devices accumulate** — each web login creates a new device. No cleanup mechanism. +- **Rooms provider fires excessively** — console shows room list logged 15+ times per sync cycle (performance) +- **Noto font warning** — emoji characters in room names can't render (missing font asset) ### Key file paths -- **Project root**: /srv/wp-dev/pwa-sites/m8chat-app2/ -- **Web entry**: web/index.html (Olm load + fallback + Flutter bootstrap) -- **App config**: lib/core/config/app_config.dart (server URLs, version 1.2.0) -- **Matrix client**: lib/core/network/matrix_client.dart (MatrixSdkDatabase provider) -- **Auth flow**: lib/core/auth/auth_notifier.dart + lib/features/auth/data/auth_repository.dart -- **LiveKit service**: lib/features/calls/data/livekit_service.dart (JWT fetch, MatrixRTC state events) -- **Call screen**: lib/features/calls/presentation/call_screen.dart (video rendering) -- **Call controller**: lib/features/calls/presentation/call_controller.dart (state machine) -- **Chat repo**: lib/features/chat/data/chat_repository.dart (timeline, send, react, redact) -- **Jitsi service**: lib/features/jitsi/data/jitsi_web_service.dart (lazy script load) -- **Build output**: build/web/ (flutter build web --release) +| File | Version | Purpose | +|------|---------|---------| +| lib/core/auth/auth_notifier.dart | 2.0.0 | Auth state machine — fresh login, no restore | +| lib/core/auth/secure_storage.dart | 2.0.0 | Minimal — only stores device ID (currently unused) | +| lib/core/config/app_config.dart | 2.0.0 | Server URLs, app name/version | +| lib/shared/utils/mxc_url.dart | 2.0.0 | Authenticated media URL resolution | +| lib/features/calls/data/livekit_service.dart | 1.4.0 | LiveKit connect/disconnect with E2EE | +| lib/features/calls/data/call_e2ee.dart | 1.0.0 | E2EE key exchange via m.rtc.encryption_keys | +| lib/features/profile/presentation/security_setup_dialog.dart | 1.0.0 | SSSS Bootstrap driver | +| lib/features/profile/presentation/key_restore_dialog.dart | 1.0.0 | Recovery key input + loadAllKeys | +| lib/features/help/presentation/help_tab.dart | 1.1.0 | In-app help content | +| lib/features/jitsi/presentation/conference_tab.dart | 1.0.0 | Jitsi meeting join UI | +| lib/features/rooms/presentation/rooms_screen.dart | 1.3.0 | 5-tab bottom nav | -### Server infrastructure (chat.m8chat.au) -- Synapse 1.151.0 (healthy, 86 active users) -- LiveKit 1.10.1 + lk-jwt-service (both healthy) -- Element Web 1.12.15, Element Call -- PostgreSQL on host (user: synapse_user, pass: kijPt4cPWkoaZk8BVm, db: synapse) -- LiveKit WSS URL: wss://matrix.m8chat.au/livekit/ -- JWT endpoint: https://matrix.m8chat.au/_matrix/livekit/jwt/sfu/get +### Server configuration +- **COOP/COEP headers** added to ~/public_html/app2.m8chat.au/.htaccess +- Synapse 1.151.0 on chat.m8chat.au (PostgreSQL, SQLite was wrong assumption) +- LiveKit 1.10.1 on chat.m8chat.au +- lk-jwt-service for MatrixRTC JWT at /_matrix/livekit/jwt/sfu/get -### Deployment -- **Target**: app2.m8chat.au (NOT app.m8chat.au) -- **SSH**: m8chat@app.m8chat.au:2233 (key: ~/.ssh/m8chat_prod), path: public_html/app2.m8chat.au/ -- **Build**: cd /srv/wp-dev/pwa-sites/m8chat-app2 && flutter build web --release -- **Deploy**: rsync -avz --delete --exclude='.htaccess' --exclude='.ftpquota' -e "ssh -p 2233 -i ~/.ssh/m8chat_prod" build/web/ m8chat@app.m8chat.au:public_html/app2.m8chat.au/ -- **Backup on server**: public_html/app2.m8chat.au_backup_20260410_*.tar.gz +### Known technical debt +- call_e2ee.dart imported but E2EE interop with Element X not verified +- secure_storage.dart exists but device ID save/load is unused (removed to fix keys/upload 400) +- key_restore_dialog.dart is separate from security_setup_dialog.dart — could be consolidated +- Rooms provider rebuilds too frequently (every sync tick) \ No newline at end of file