A hardening release: transfers never lie about success, failures are visible instead of silent, and the browser only ever runs code the app shipped.
Security
- Strict CSP —
script-src 'self', no'unsafe-inline'; all inline scripts and handlers eliminated. - Filenames from the wire are sanitized (path separators, control chars,
./..) before reaching zip entries orContent-Disposition. - Null-prototype file/peer registries close a prototype-pollution hole via crafted peer ids.
- HSTS added to the Caddyfile.
Transfer reliability
- Failed sends no longer strand the receiver — sender-side failures (read/send errors, removed file, dropped peer) now notify the receiver, which tears down with a clear message instead of spinning forever.
- Integrity verification — downloads finalize only when the received byte count matches the announced size; corrupt or truncated streams show as failures.
Protocol & fixes
- Strict payload validation on all signaling messages; malformed
Hostvariants rejected. - TURN credential JWTs decoded as base64url (previous decoder failed on
-/_). - Room URLs copied and QR-encoded via
textContent— no more corruption on URLs containing&. - App boot survives an unreachable API; leave-page confirmation works in Safari.
Upgrading
docker compose pull && docker compose up -dNo new ports or environment variables.
Full changelog: v4.0.0...v4.1.0