- Replaced custom MIT-NC license with GNU Affero General Public License v3
- Haven is now truly open source under an OSI-approved license
- AGPL copyleft ensures forks deployed as network services must release source
- Updated all license references across README, package.json, docs, website, and TOS
- Fixed bot/webhook pinned messages showing raw username instead of [BOT] prefix
- Replace all haven-app.com references with https://ancsemi.github.io/Haven/
- Delete website/CNAME (domain not owned)
- Fix desktop promo popup and banner links to point to website download section
- Sync docs/ from website/
- Include package-lock.json version bump to 2.3.0
Adds TURN_URL, TURN_SECRET, TURN_USERNAME, TURN_PASSWORD env vars.
New /api/ice-servers endpoint serves STUN + TURN config to authenticated clients.
Supports both coturn shared-secret (time-limited credentials) and static auth.
Client fetches ICE config on init and refreshes before each voice join.
Closes#37
Added:
- Discord history import Direct Connect (paste token, pick server, select channels)
- Discord history import File upload (DiscordChatExporter JSON/ZIP)
- Tabbed import modal (Upload File | Connect to Discord)
- Full server structure import (text, announcement, forum, media, threads)
- Forum tag resolution and display
- Discord avatar preservation (webhook_avatar column)
- Channel type indicators in import picker
Fixed:
- E2E key loss on password change (re-wraps key with new password)
- Scroll-to-bottom loop when images load while scrolled up
- ARM64 Docker support (#34)
Changed:
- Website, README, GUIDE updated with Discord import docs
- Version bumped to 2.0.0
- e2e.js: Don't generate new keys when server has existing encrypted key
but no password is available (token auto-login). Previously this silently
overwrote the server's public key, making all old messages unreadable.
- e2e.js: Added recoverWithPassword() for post-login key recovery.
- app.js: Show password recovery banner when E2E needs password unlock.
- app.js: Move lock icon from inside message-content to absolute-right
position in compact messages (was appearing LEFT of text).
- app.js: Remove redundant lock emoji from decrypt fallback text (e2eTag
span handles the icon display separately).
- style.css: .message-compact > .e2e-tag positioned absolute right.
Features:
- Automatic update detection: checks GitHub releases and shows a pulsing 'Update Available' pill in the header with one-click download
- Mobile input area: media buttons (image, file, emoji, GIF) now sit in their own row above the textbox so the input never gets cramped
- Mobile message actions: long-press (500ms) to show toolbar instead of tap, preventing accidental pin/edit/delete. Tap anywhere to dismiss
- Haptic feedback on mobile long-press (vibration API)
Bug fixes:
- Deleting the root message of a group no longer orphans subsequent compact messages the next message is promoted to full format with avatar and header
- Invisible status: server now sends per-socket customized user lists so invisible users appear offline to others
- DM section badge: now properly clears when all DMs are read
- Emoji search: added ~200 emoji keyword mappings for accurate search results
- Emoji picker: fixed scroll flicker caused by overflow-y:auto toggling scrollbar
- Sound upload: fixed bug where response wrapper broke custom sound loading
- Channel rename: DMs no longer show 'Unknown' after renaming channels or managing sub-channels
Other:
- Idle timer extended from 5 to 10 minutes
- Sub-channel styling: tighter spacing, deeper indent, smaller font
- /api/version endpoint for programmatic version queries
- Scramble effect: separated matrix rain from matrix scan lines into independent toggleable effects