feat(desktop): runtime-configurable backend server address
The desktop shell is one generic .deb/.AppImage distributed via mca/public_releases, not built per-booth, but the backend origin was baked in at build time (VITE_API_BASE, hardcoded to http://127.0.0.1:3000) — the same installer could never point at a different appliance without a rebuild. Adds ConnectScreen (shown before Login in Tauri when no backend is saved), backed by tauri-plugin-store persisting the operator-entered URL across restarts. CSP's connect-src tightens to 'self' only — all backend traffic already routes through tauri-plugin-http/websocket, which run Rust-side and are outside connect-src's reach anyway — and the real access boundary moves to capabilities/default.json's http:default scope, wildcarded so an operator-chosen host is actually reachable. Adds a "Change server" control in Setup (desktop-only) to repoint an already-configured install. While tracing the desktop auth path for this: tauri-plugin-http's fetch() runs through Rust's reqwest, which keeps its own cookie jar separate from the webview, so document.cookie on tauri://localhost never sees the parking_csrf cookie the server sets (open upstream bug, tauri-apps/tauri#13045/#11518). This means the desktop app has likely been silently sending no CSRF header on every mutation since the shell was first built — pre-existing, independent of this change. Fixed by having sessionView() (routes/auth.ts) also echo the CSRF value in the login/me JSON body; the desktop client stashes it in memory and echoes that instead of reading document.cookie. assertCsrf() itself is untouched. Verified end-to-end against a real LAN-bound dev server: login returns a csrfToken matching the cookie, a mutation using the body-sourced token in X-CSRF-Token succeeds (200), and the same mutation without it still correctly 403s.
This commit is contained in:
+24
@@ -2817,3 +2817,27 @@ version ("it's offering v0.1.4, so I must be on v0.1.3"). Added DesktopVersionBa
|
||||
existing server-side VersionBadge in router.tsx, using @tauri-apps/api's getVersion() (the real
|
||||
running app version, synced to the git tag at build time by release.yml). No-ops in a browser.
|
||||
Full detail on [[desktop-shell-tauri]].
|
||||
|
||||
## [2026-09-04] feat | Desktop backend origin is now runtime-configurable (was build-time)
|
||||
|
||||
The desktop shell is one generic .deb/.AppImage distributed via mca/public_releases — not built
|
||||
per-booth — but VITE_API_BASE was a build-time env var hardcoded to http://127.0.0.1:3000, so the
|
||||
same installer could only ever talk to a server on its own machine. Added ConnectScreen (shown
|
||||
before Login in Tauri when no backend is saved), backed by tauri-plugin-store persisting the
|
||||
operator-entered URL across restarts; origin.ts's API_BASE became a runtime-settable `let`. CSP's
|
||||
connect-src tightened to 'self' only (all backend traffic already went through
|
||||
tauri-plugin-http/websocket, which run Rust-side and are outside connect-src's reach anyway); the
|
||||
real boundary moved to capabilities/default.json's http:default scope, wildcarded to any host so
|
||||
the operator-chosen address is actually reachable. Added a "Change server" control (Setup nav,
|
||||
desktop-only) that clears the saved URL and reloads back to ConnectScreen.
|
||||
|
||||
While tracing the desktop auth path for this, found a pre-existing (not newly introduced) bug:
|
||||
tauri-plugin-http's fetch() runs through Rust's reqwest, which keeps its own cookie jar separate
|
||||
from the webview — document.cookie on tauri://localhost never sees the parking_csrf cookie the
|
||||
server sets (open upstream bug, tauri-apps/tauri#13045/#11518), so the desktop app has likely been
|
||||
silently sending no CSRF header on every mutation since the shell was first built, regardless of
|
||||
which host it targeted. Fixed by having sessionView() (routes/auth.ts) also echo the same csrf
|
||||
value in the login/me JSON body; the desktop client stashes it in memory and echoes that instead of
|
||||
reading document.cookie. assertCsrf() itself is untouched — the cookie is still what's verified,
|
||||
and reqwest was already sending it correctly; this only fixes how the desktop client *learns* the
|
||||
value. Full detail (including the exact CSP/capability tradeoffs) on [[desktop-shell-tauri]].
|
||||
|
||||
Reference in New Issue
Block a user