The v0.1.4 Origin fix cleared only the first of two gates in /api/ws's
preHandler. The second, req.jwtVerify(), reads the HttpOnly cookie — which
tauri-plugin-websocket (a bare tungstenite client, no cookie jar) can never
send. Every desktop handshake 401'd and use-live-feed reconnected every 10s
(confirmed in the park-2 server log).
- routes/ws.ts: POST /api/ws/ticket (cookie + CSRF auth) mints a 30s,
single-use, in-memory ticket; the WS preHandler accepts it via an
x-ws-ticket header after the Origin check, then the same report:read
role check. Browser cookie path unchanged; JWT stays out of JS.
- platform-ws.ts: fetch a ticket before connect, send it with the Origin
header; connect failures now go through logClient (rate-limited).
- logger.ts: flush read the CSRF token from document.cookie, null on
desktop, so every desktop POST /api/logs 403'd and was dropped silently —
no desktop client log had ever reached app_logs. Stash moved to a
dependency-free lib/desktop-csrf.ts shared by api.ts and logger.ts.
- backend-config.ts: ConnectScreen probe uses the unauthenticated /health
(now also returns app: "parking-system") instead of accepting any 401.
- README: local-AppImage release gate — tauri dev runs at
http://localhost:5173, not tauri://localhost, so none of these
origin-dependent bugs reproduce there.
- wiki: new section + log entry; four citation corrections.
Requires the server image with this commit deployed before the new desktop
build connects (the ticket endpoint must exist).
Claude-Session: https://claude.ai/code/session_01FWncR69HgGPuei1dLrW3cU