fix(desktop): route fetch + WebSocket through native Tauri plugins (mixed-content)
Build desktop / desktop (push) Successful in 4m33s
Build & push images / images (push) Successful in 2m50s
CI / check (push) Successful in 43s
Release desktop / bundle (push) Successful in 5m13s

Fixing VITE_API_BASE got login to build a correct absolute URL, but it still
failed with WebKit's generic "Load failed" — WebKitGTK treats tauri://localhost
as a secure origin, so http://127.0.0.1:3000 (and ws://) from inside it is
blocked as mixed content, a WebKit limitation CSP's connect-src can't override.

Added tauri-plugin-http (genuine fetch() drop-in, wired via a new
platformFetch() in origin.ts, used by api.ts + logger.ts) and
tauri-plugin-websocket (not a drop-in — adapted behind a native-WebSocket-
shaped interface in the new platform-ws.ts so use-live-feed.ts needed no
changes). Both route through Tauri's Rust side instead of the webview's own
fetch/WebSocket. Capabilities scoped to 127.0.0.1:3000/localhost:3000, matching
the existing CSP allowlist.
This commit is contained in:
2026-09-03 14:57:45 +02:00
parent 276b048fa9
commit 439b11d16d
13 changed files with 776 additions and 16 deletions
+2 -2
View File
@@ -6,7 +6,7 @@
// wiki/entities/local-jwt-auth.md.
import { logFailedRequest } from "./lib/logger.js";
import { apiUrl } from "./lib/origin.js";
import { apiUrl, platformFetch } from "./lib/origin.js";
import type { AppLogRecord, ValidationLine, ValidationMode } from "@parking/shared";
const CSRF_COOKIE = "parking_csrf";
@@ -28,7 +28,7 @@ export async function apiFetch<T>(path: string, init: RequestInit = {}): Promise
const csrf = readCookie(CSRF_COOKIE);
if (csrf) headers.set(CSRF_HEADER, csrf);
}
const res = await fetch(apiUrl(path), { ...init, headers, credentials: "include" });
const res = await platformFetch(apiUrl(path), { ...init, headers, credentials: "include" });
if (!res.ok) {
const msg = (await res.json().catch(() => ({}))) as { error?: string; problems?: string[]; [k: string]: unknown };
const error = msg.error ?? `${path}: ${res.status}`;