Adds the Double Ratchet (Signal's design) on top of the existing ECDH session
keys, so message protection no longer rests on one set of keys lasting the whole
conversation. Every message gets its own key, derived through a one-way function
and discarded after use, and each change of direction introduces a fresh ECDH
key pair that re-keys the session root.
The ratchet needed no handshake change: both peers already hold each other's
authenticated ECDH public key, and the safety code compared during verification
covers exactly those keys. Its root is derived from the existing shared secret
through its own branch of the key schedule.
Support is negotiated in the invitation and response and used only when both
sides have it; a peer on an earlier release falls back to per-session keys. The
security panel reports which of the two is actually in force.
Out-of-order delivery is supported within fixed bounds (512 skipped keys per
chain, 1024 retained, five-minute expiry), and inbound frames are authenticated
before any ratchet state is committed, so a malformed frame cannot desynchronise
a live session.
Also in this release:
- Verification is enforced as a gate, not a label: control frames (reconnection
signalling, call setup, message deletion, delivery receipts) are acted on only
after both peers have compared the safety code, and verified state is set in a
single guarded place.
- Chat content reaches the interface through one authenticated path; an older,
weaker inbound path was retired.
- The security panel measures what it displays — several checks previously
returned a fixed result and now exercise the subsystem they describe.
- Invitation data is no longer kept in local storage, and entries left by earlier
versions are cleared on first launch.
- View-once and disappearing messages no longer place their text in system
notifications.
- Shared-secret buffers are overwritten once derivation completes; scanned QR
codes are decompressed with a size limit; voice notes are validated against
audio type and size budgets before skipping the consent prompt; the master
password is collected by the app rather than a browser dialog.
- Connection setup no longer fails on networks where STUN/TURN are unreachable:
it proceeds as soon as usable candidates exist and only waits while there are
none.
Test suite grows from 27 to 41 files, covering forward secrecy, post-compromise
re-keying, out-of-order delivery across ratchet steps, the skipped-key bounds,
tamper resistance, negotiation fallback, and byte-level key-derivation
compatibility with 5.6.0.
Completes the messaging controls from v4.8.14 and fixes the bug that made them
appear broken for recipients.
Fixed:
- Per-message metadata was silently dropped for recipients. NotificationIntegration
wrapped onMessage and deliverMessageToUI with 2-arg shims that called the
originals without the 3rd argument (meta); with notifications enabled, view-once,
disappearing timers and unsend all failed on the receiving side. Both wrappers
now forward all arguments. Added tests/notification-meta-forwarding.test.mjs.
- Chat would not open after SAS: composer props were threaded into the wrong
component (EnhancedConnectionSetup vs EnhancedChatInterface) -> ReferenceError
nowTick on the verified re-render. Props moved to the chat component.
Changed:
- Code blocks: lightweight dependency-free syntax highlighting via React nodes
(no innerHTML/remote scripts); code mode expands the input; copy auto-clears
the clipboard after ~30s.
- View-once: configurable visible-after-open time (5s/15s/30s/1m) via meta.onceTtl.
- Disappearing timer: duration picker (Off/30s/5m/1h) instead of click-cycling.
- Composer toolbar moved next to "Send files"; borderless buttons, brand-orange
active state; pickers open upward and are mobile-friendly.
- Sender bubble background lightened to rgba(249,115,22,0.05).
Removed:
- Panic wipe button (disconnect already wipes keys and clears session state).
Transport unchanged: per-message metadata travels inside the encrypted envelope,
whitelisted/bounded by _sanitizeMessageMeta. Full suite: 19 files, all passing.
Docs (README, CHANGELOG) updated; version bumped to 4.8.20.
- Update version to v4.7.53
- Add Desktop Edition documentation (Windows, macOS, Linux)
- Update roadmap with all versions and dates
- Add mobile apps information (Q1 2026)
- Expand security and development sections
- Update URLs to securebit.chat domain
- Guarded all Notification API usage to avoid ReferenceError on iOS Safari.
- Set default permission to 'denied' when Notification is undefined.
- Added early return in notification flow when Notifications API is unavailable.
- Wrapped Notification.permission, requestPermission(), and new Notification(...) with typeof checks.
- Updated SecureNotificationManager and app.jsx to degrade gracefully.
- Verified build passes and chat loads correctly on iOS without notifications.
- Added SecureNotificationManager with cross-browser support (Chrome, Firefox, Safari, Edge)
- Integrated WebRTC message notifications with tab visibility detection
- Implemented XSS protection, URL validation, and rate limiting
- Notifications shown only when chat tab is inactive
- Enforced HTTPS and user gesture requirements