0.2.1
Vault Rooms 0.2.1
Pinned TLS/WSS for the embedded and standalone relay, safe in-place upgrades from any v0.1 database shape, and a raft of sync-reliability and Obsidian review fixes.
Added
- Pinned TLS/WSS. New embedded servers self-manage a private CA + leaf certificate and listen HTTPS/WSS only; invites carry the server's identity (SPKI pin) so a client verifies the server before ever sending credentials. The standalone relay supports pinned or OS-trusted TLS via
TLS_MODE. - Identity rotation. Signed, replay-protected rotation records let an owner rotate the server's TLS identity without breaking already-paired clients. A client that can't verify the rotation chain shows a blocking "pin mismatch" and never sends credentials over an unverified connection.
- Legacy plaintext migration. Existing v0.1 installs get an owner-controlled upgrade path (normal or strict mode) to pinned TLS, with a dual-stack transition window before the plaintext listener is closed for good.
- LAN share reachability. The panel automatically probes the advertised LAN URL after every start/migrate/rotate and blocks creating invites when it's unreachable, instead of only warning after the fact.
Changed
- v0.1 database upgrades are more robust: a shares-only legacy schema (no
roomstable) now migrates instead of failing outright, and the one-time backup (relay.sqlite.bak-v1) is written atomically and tolerates a corrupted/foreign file at that path instead of permanently blocking startup. - REST file writes/deletes now enforce the same
sync:pushpermission the WebSocket path already required, closing a gap where the two transports could disagree on an ACL deny.
Fixed
- Live sync could silently stop delivering updates for a room if the connection dropped between subscribing and receiving its first snapshot - subscriptions now persist across reconnects instead of being dropped.
- A token-rotation race during plaintext-to-TLS migration could make the client think its access was revoked and abandon the migrated connection.
- A slow or failed pinned-transport retry could leave two live sockets on the same connection, causing duplicate applies of remote changes.
- One file failing to read during snapshot reconciliation no longer aborts reconciliation of every other file in that snapshot.
- An unauthenticated WebSocket connection could hold a connection slot indefinitely; the relay now times it out after 10 seconds.
- Obsidian community review findings resolved:
createDiv()/createSpan()used instead ofcreateEl("div"/"span"), and the standalone CLI's startup banner (bound URLs, TLS identity, bootstrap PIN) no longer goes throughconsole.log.