[eric] desktop: renderer self-heals a stale backend port, fixes the post-signin CORS wall

This commit is contained in:
ciregenz
2026-06-10 17:37:57 -07:00
parent f38f478486
commit 0bf2eb37f6
2 changed files with 38 additions and 1 deletions
+6
View File
@@ -22,6 +22,12 @@ contextBridge.exposeInMainWorld('__OPENSWARM_PORT__', port);
contextBridge.exposeInMainWorld('openswarm', {
getBackendPort: () => port,
// Fresh re-query of the LIVE backend port (not the cached preload value).
// Used by the renderer to self-heal if its cached port ever resolved wrong
// (raced null -> 8324, or backend on a fallback port because 8324 was held).
getBackendPortLive: () => {
try { return ipcRenderer.sendSync('get-backend-port-sync'); } catch (_) { return port; }
},
getWebviewPreloadPath: () => webviewPreloadPath,
// Per-install auth token required for WS + HTTP calls to the
+32 -1
View File
@@ -1,4 +1,14 @@
const port = (window as any).__OPENSWARM_PORT__ || 8324;
const _w = window as any;
// Prefer the preload-injected port; if it's missing (preload raced the backend
// port being picked), re-query the live value before falling back to 8324. The
// bare 8324 guess is wrong on any machine where the backend landed on a fallback
// port (e.g. 8324 was held by a leftover backend); see the self-heal below.
const port =
_w.__OPENSWARM_PORT__ ||
(_w.openswarm && typeof _w.openswarm.getBackendPortLive === 'function'
? _w.openswarm.getBackendPortLive()
: 0) ||
8324;
const host = window.location.hostname || 'localhost';
export const API_BASE = `http://${host}:${port}/api`;
@@ -46,6 +56,25 @@ export function ensureAuthToken(): Promise<string> {
return _authTokenPromise;
}
// Self-heal: if our backend calls start failing with a network error (the
// renderer is pinned to a stale/wrong port), re-query the live port and reload
// once onto it. Guarded to one attempt per page-load and only when the live
// port actually differs, so a genuinely-down backend can't cause a reload loop.
let _portHealTried = false;
function _maybeHealBackendPort(): void {
if (_portHealTried) return;
try {
const ow = (window as any).openswarm;
const live = ow && typeof ow.getBackendPortLive === 'function' ? ow.getBackendPortLive() : null;
if (typeof live === 'number' && live > 0 && live !== port) {
_portHealTried = true;
window.location.reload();
}
} catch {
/* never let a heal attempt throw into the fetch path */
}
}
// Global fetch interceptor: attaches bearer for our API + dedupes/caches GETs in a 1s window.
// Cache is keyed `METHOD URL`, GET-only (mutations pass through); non-2xx never cached.
const _inflightFetches = new Map<string, Promise<Response>>();
@@ -117,6 +146,8 @@ function _installAuthFetchInterceptor() {
_inflightFetches.delete(cacheKey);
}
} catch {
// A network failure reaching our backend may mean we're on a stale port.
_maybeHealBackendPort();
return originalFetch(input, init);
}
};