22 Commits
Author SHA1 Message Date
lockbitchat 60bf037ef9 Fix the desktop download buttons; release v5.5.4
CodeQL Analysis / Analyze CodeQL (push) Canceled after 0s
Deploy Application / deploy (push) Canceled after 0s
Mirror to Codeberg / mirror (push) Canceled after 0s
Mirror to PrivacyGuides / mirror (push) Canceled after 0s
The buttons still led to a dead GitHub page. 5.5.3 updated one of the two places
these links live — the platforms menu on the connection screen keeps its own
DOWNLOADS table, and it was missed, so it stayed on 0.1.0.

Why it looked like a working link that did nothing: the stale entries used
/releases/latest/download/<file>, and GitHub resolves `latest` by redirecting to
the newest tag. Once 0.3.0 shipped, a link written for 0.1.0 resolved to
/releases/download/v0.3.0/SecureBit.Chat_0.1.0_x64-setup.exe — a file that never
existed under that tag. The browser navigated to GitHub and downloaded nothing.

Both places now build their URLs from a DESKTOP_VERSION constant with the tag
pinned, so the version is written once per file and a link cannot silently
become invalid when a new release goes out.

Adds tests/desktop-download-links.test.mjs, which fails the build if this drifts
again: every source must derive URLs from that constant, /latest/ and hardcoded
versions in filenames are rejected, and each generated URL is fetched to prove
the asset exists. SKIP_NETWORK=1 skips the fetches offline.
2026-07-27 04:53:44 -04:00
lockbitchat 6152a77b51 security: fix SAS verification bypass and unauthenticated frame injection; release v5.5.2
CodeQL Analysis / Analyze CodeQL (push) Canceled after 0s
Deploy Application / deploy (push) Canceled after 0s
Mirror to Codeberg / mirror (push) Canceled after 0s
Mirror to PrivacyGuides / mirror (push) Canceled after 0s
A security review of the transport and verification layers. Every item is a fix
to how untrusted peer input is handled; no features changed.

- SAS verification could be bypassed. `verification_both_confirmed` is an
  unauthenticated frame on a channel that is not yet trusted, but it was taken as
  proof that both sides had compared their codes — so a peer who completed the
  signalling exchange could send it right after the data channel opened and drive
  the other side to a "verified" session while the user never looked at the code.
  It is now only an acknowledgement: refused unless this side already confirmed
  locally, and _setVerifiedStatus() independently rejects any SAS-based
  transition without a local confirmation. Holding ECDH-derived keys was never
  proof of identity — a MITM has those too.

- Unauthenticated frames could be injected into the chat. A bare
  {type:"message"} frame, a raw non-JSON frame and a binary frame were each
  decoded and rendered, bypassing decryption, the HMAC check and the verification
  gate; the injected text was indistinguishable from a genuine message. Chat
  content now reaches the UI only through the authenticated enhanced_message
  path.

- A peer could supply the verification code. `sas_code` announcements were
  adopted verbatim when no local SAS had been derived yet. They may now only
  corroborate the locally derived code.

- Anti-replay never ran. The sequence-number and AAD validators were defined on
  SecureKeyStorage instead of the connection manager, so every call site failed
  with a TypeError and the sliding replay window was dead code. Moved onto the
  manager, wired into the live chat path, and a missing or non-numeric sequence
  number now fails closed instead of sailing through the range checks.

- File transfers are gated on verification in both directions. Control frames are
  written straight to the data channel by the transfer system; sending was
  already gated, receiving now is too.

- Tighter CSP: connect-src and img-src no longer allow arbitrary https: hosts
  (nothing in the app talks to a third party), plus base-uri 'none'.

- The SAS is no longer written to logs, and is compared in constant time on every
  path. Fixed SecureMasterKeyManager.isUnlocked() testing a field renamed long
  ago, so it never actually gated anything.

- Fixed the header showing "Secure undefined%": getRealSecurityLevel() became
  reachable for the first time by the move above and returned only per-feature
  booleans, while the header renders `level` and `score` directly. It now runs
  the same verified scoring as every other consumer.

Adds regression tests for the verification gate, inbound frame authentication and
the security-level shape.
2026-07-27 00:10:29 -04:00
lockbitchat b3fcf54670 feat(webrtc): end-to-end encrypted voice & video calls with adaptive codecs
CodeQL Analysis / Analyze CodeQL (push) Canceled after 0s
Deploy Application / deploy (push) Canceled after 0s
Mirror to Codeberg / mirror (push) Canceled after 0s
Mirror to PrivacyGuides / mirror (push) Canceled after 0s
Add 1:1 voice and video calling over the existing SAS-verified peer
connection. Audio and video tracks ride the same RTCPeerConnection as the
chat, bundled onto one DTLS-SRTP transport, so media inherits the session's
end-to-end encryption. SDP offer/answer is renegotiated in-band over the
verified data channel — no signalling server, so the media's DTLS
fingerprints are authenticated end-to-end. Calls are gated on a connected,
SAS-verified session.

Codecs & adaptation:
- Opus tuned for lossy links (in-band FEC, DTX, RED redundancy); audio is
  bandwidth-prioritised and never throttled.
- VP9/AV1 single-encoding SVC with H.264/VP8 fallback; video degrades by
  spatial/temporal layer.
- Runtime NetworkAdaptationController trims video bitrate on loss/RTT and
  recovers as the link clears — no renegotiation. Live connection-quality
  indicator (Excellent/Good/Fair/Weak) in the call UI.

In-call controls: mute, camera on/off (voice→video upgrade in-band),
camera flip, minimize-to-widget, hang up, and accept/decline for incoming
calls. Production logging disabled (DEBUG_MODE=false); temporary call
diagnostic logger removed. Codec rationale in docs/webrtc-config.md.
2026-07-23 12:56:19 -04:00
lockbitchat c98a01b1d5 Add end-to-end encrypted voice messages; release v5.4.5
CodeQL Analysis / Analyze CodeQL (push) Canceled after 0s
Deploy Application / deploy (push) Canceled after 0s
Mirror to Codeberg / mirror (push) Canceled after 0s
Mirror to PrivacyGuides / mirror (push) Canceled after 0s
- Record voice notes in-browser, sent over the chunked AES-GCM file-transfer
  channel (per-file session key + signed SHA-256 integrity).
- Captured as PCM and encoded to WAV for universal playback (incl. iOS/Safari);
  auto-accepted and played inline from an in-memory blob, never written to disk.
- Composer mic button with live waveform + timer; desktop shows mic + send side
  by side, mobile swaps mic to send when typing.
- CSP media-src now allows blob: so recorded/received audio can play.
- Roadmap: Desktop Edition -> 5.0, new 5.5 'Secure Voice & Calls', later
  milestones shifted; version bumped to 5.4.5.
- Update README, docs (security/API/cryptography), and CHANGELOG.
2026-07-22 00:41:58 -04:00
lockbitchat 0e3e3a2974 Add multiple-session support: run several independent encrypted chats at once
CodeQL Analysis / Analyze CodeQL (push) Has been cancelled
Deploy Application / deploy (push) Has been cancelled
Mirror to Codeberg / mirror (push) Has been cancelled
Mirror to PrivacyGuides / mirror (push) Has been cancelled
Each conversation now runs its own WebRTC session with separate keys and SAS verification, so chats never mix. Adds a side panel to switch between open chats with unread badges, a New chat action that leaves existing chats connected, per-chat local labels stored only on this device, and an availability status (Available, Away, Busy, Invisible) shared end-to-end with connected peers. Also includes vendored Prism syntax highlighting, more reliable PWA update handling, and offline send queueing fixes. Version 4.10.0.
2026-06-26 00:00:13 -04:00
lockbitchat b39f9ecd2c release: v4.8.20 secure chat tools — completed, fixed and polished
CodeQL Analysis / Analyze CodeQL (push) Has been cancelled
Deploy Application / deploy (push) Has been cancelled
Mirror to Codeberg / mirror (push) Has been cancelled
Mirror to PrivacyGuides / mirror (push) Has been cancelled
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.
2026-06-19 02:58:03 -04:00
lockbitchat 15173a9278 release: v4.8.14 secure chat tools (code blocks, view-once, disappearing, unsend, panic)
CodeQL Analysis / Analyze CodeQL (push) Has been cancelled
Deploy Application / deploy (push) Has been cancelled
Mirror to Codeberg / mirror (push) Has been cancelled
Mirror to PrivacyGuides / mirror (push) Has been cancelled
New privacy-focused messaging controls in the composer:
- Code blocks: button wraps the message in a fenced block; both peers render a
  monospace code window with a copy button (clipboard auto-clears after ~30s).
  Window is built from sanitized text via React nodes — no new XSS surface.
- View-once: recipient sees a blurred bubble, reveals on tap, then it is wiped.
  Honestly cooperative (not screenshot-proof).
- Disappearing messages: optional 30s/5m/1h timer auto-deletes on both sides
  with a live countdown; incoming TTL clamped to [5s, 24h].
- Unsend (delete for everyone) via new MESSAGE_TYPES.message_delete control.
- Panic wipe: clears chat, wipes keys and disconnects (behind a confirm).

Transport:
- Per-message metadata (id / view-once / timer) travels inside the encrypted
  envelope, not in the sanitized text, so content cannot spoof these controls.
- _sanitizeMessageMeta whitelists + bounds metadata on send and receive.
- AAD/replay protection, SAS gate and receive-side DOMPurify are unchanged.

Adds tests/secure-chat-features.test.mjs (full suite: 17 files, all passing).
Bumps version to 4.8.14 across package.json, package-lock.json, manifest.json,
index.html, meta.json, README, SECURITY_DISCLAIMER, header and init banner.
2026-06-18 20:37:50 -04:00
lockbitchat 42be55aaeb fix(security): restore outgoing message integrity, add HSTS/Permissions-Policy
CodeQL Analysis / Analyze CodeQL (push) Has been cancelled
Deploy Application / deploy (push) Has been cancelled
Mirror to Codeberg / mirror (push) Has been cancelled
Mirror to PrivacyGuides / mirror (push) Has been cancelled
- Remove send-path keyword blocklist that silently rejected legitimate
  messages (e.g. "constructor", "global", "document.", literal "javascript:")
  without adding protection. XSS is enforced at the rendering boundary by the
  receive-side DOMPurify pass and by sanitizeMessage() before encryption.
- Preserve newlines/tabs/indentation in _sanitizeInputString; stop collapsing
  all whitespace which destroyed multi-line messages and code snippets.
- Stop logging raw AAD (sessionId + keyFingerprint) on validation failure;
  log length only, in both message and file-message AAD validators.
- Add Strict-Transport-Security (2y + preload) and Permissions-Policy
  (camera=self for QR, rest denied) to nginx.conf and .htaccess.
- Add tests/outgoing-message-integrity.test.mjs regression suite.
2026-06-18 16:48:29 -04:00
lockbitchat be1d02f1f7 release: v4.8.11 file transfer reliability fix
CodeQL Analysis / Analyze CodeQL (push) Has been cancelled
Deploy Application / deploy (push) Has been cancelled
Mirror to Codeberg / mirror (push) Has been cancelled
Mirror to PrivacyGuides / mirror (push) Has been cancelled
fix(file-transfer): size chunks under the 64KB SCTP message limit

Each 64KB chunk became a ~87KB AES-GCM+Base64 file_chunk message,
exceeding WebRTC's 64KB SCTP message-size floor. The consent handshake
(small messages) succeeded, but no chunk was ever delivered on Safari
and cross-browser connections whose SDP omits a=max-message-size, so
files never transferred. Send chunk size is now 16KB (~22KB on the
wire); inbound chunks up to 64KB stay accepted for backward compat.

fix(file-transfer): make MIME advisory, drive validation by extension

The client-supplied MIME type is easily spoofed and varies across
browsers/OSes, yet was a hard gate: files with an empty MIME or a
cross-OS variant (application/x-zip-compressed, image/jpg) were wrongly
rejected. Extension allow-list plus BLOCKED_EXTENSIONS is now the
boundary; a blatantly foreign MIME on a safe extension is still rejected
and per-type size limits still apply.
2026-06-16 18:24:29 -04:00
lockbitchat 7f2ecce57f feat: user-configurable STUN/TURN servers (advanced network settings)
- add iceServers.js: allowlist-based validation/normalization of user-supplied
  STUN/TURN URLs (rejects javascript:/data:/http/ws, control chars, enforces limits)
- add iceSettingsStore.js: opt-in persistence encrypted at rest with a
  non-extractable AES-GCM device key in IndexedDB; load/save/clear
- add IceServerSettings.jsx modal: public vs custom servers, JSON/line input,
  live validation, relay-only toggle, 'Test servers' connectivity check,
  save-on-device prompt, forget-saved action
- wire chosen servers/privacy mode into EnhancedSecureWebRTCManager construction
  (priority: custom > operator override > built-in defaults)
- entry point on the connection-creation screen next to the relay-only toggle
- add ice-servers-validation.test.mjs to the suite
2026-06-15 15:39:13 -04:00
lockbitchat d11f250257 release: v4.8.8 file transfer consent fix
CodeQL Analysis / Analyze CodeQL (push) Has been cancelled
Deploy Application / deploy (push) Has been cancelled
Mirror to Codeberg / mirror (push) Has been cancelled
Mirror to PrivacyGuides / mirror (push) Has been cancelled
Complete the mandatory receiver-consent gate that was wired in the
backend but never connected to the UI callback chain:

- Add the missing onIncomingFileRequest (4th) callback to
  setFileTransferCallbacks in app.jsx — its absence caused
  handleFileTransferStart to auto-reject every incoming file.
- Remove independent callback registration from FileTransferComponent;
  the component was overwriting app-level callbacks on mount and
  nulling all four on unmount, silently breaking progress/received/
  error handlers whenever the panel was hidden.
- Lift pendingIncomingFiles state to the root component so consent
  prompts are shown regardless of panel visibility; auto-open the
  panel on incoming request.
- Add getReceivedFileObjectURL / revokeReceivedFileObjectURL on
  EnhancedSecureWebRTCManager for download buttons in the panel.
- Update file-transfer-ui-cleanup regression test to match the new
  single-owner callback architecture.
- All 14 tests pass; clean production build.
2026-05-26 22:55:52 -04:00
lockbitchat 2468cb495e release: v4.8.7 WebRTC join reliability patch
CodeQL Analysis / Analyze CodeQL (push) Has been cancelled
Deploy Application / deploy (push) Has been cancelled
Mirror to Codeberg / mirror (push) Has been cancelled
Mirror to PrivacyGuides / mirror (push) Has been cancelled
2026-05-19 09:49:22 -04:00
lockbitchat 1cc873223a fix: stabilize manual WebRTC join flow
CodeQL Analysis / Analyze CodeQL (push) Has been cancelled
Deploy Application / deploy (push) Has been cancelled
Mirror to Codeberg / mirror (push) Has been cancelled
Mirror to PrivacyGuides / mirror (push) Has been cancelled
2026-05-18 19:49:57 -04:00
lockbitchat f2a4276b31 fix: remove untracked disconnect timer
CodeQL Analysis / Analyze CodeQL (push) Has been cancelled
Deploy Application / deploy (push) Has been cancelled
Mirror to Codeberg / mirror (push) Has been cancelled
Mirror to PrivacyGuides / mirror (push) Has been cancelled
2026-05-17 23:16:14 -04:00
lockbitchat 33f3764ec5 fix: synchronize WebRTC privacy mode state 2026-05-17 23:09:45 -04:00
lockbitchat a04a70eb97 fix: throttle inbound file chunks 2026-05-17 23:05:43 -04:00
lockbitchat 0fbcc240be fix: add inbound message rate limiting 2026-05-17 23:01:58 -04:00
lockbitchat 18022c6b68 fix: gate debug window hooks behind explicit flag 2026-05-17 22:58:21 -04:00
lockbitchat f71ff62417 fix: make WebRTC privacy mode explicit 2026-05-17 17:57:11 -04:00
lockbitchat ce48e8a851 fix: harden chat sanitization with DOMPurify 2026-05-17 17:52:36 -04:00
lockbitchat cc7f850e7d fix: bind SAS verification to DTLS fingerprint strings 2026-05-17 17:46:15 -04:00
lockbitchat 0a42aa13c3 release: prepare v4.8.5 security hardening release
CodeQL Analysis / Analyze CodeQL (push) Has been cancelled
Deploy Application / deploy (push) Has been cancelled
Mirror to Codeberg / mirror (push) Has been cancelled
Mirror to PrivacyGuides / mirror (push) Has been cancelled
2026-05-17 14:48:52 -04:00