fix(client): bridge same-origin proxy via Vite + dev token fallback — Patch 021
Cross-origin (5173 vs 4000) blocked the auth cookie from reaching the bridge — every /database slash command request 401'd silently. Two changes: 1. vite.config.ts: add /bridge -> http://localhost:4000 proxy with path rewrite + /bridge-events -> /api/events for SSE. Same-origin = browser sends the auth cookie automatically. 2. bridge-client.ts: resolveBridgeUrl() defaults to /bridge instead of absolute http://localhost:4000. Also adds a VITE_BRIDGE_TOKEN env fallback for dev (the bridge requires Bearer auth and the Docmost session cookie is HttpOnly so JS cannot read it). Patch 021.
This commit is contained in:
parent
5b512e6324
commit
aef912f9a4
2 changed files with 25 additions and 10 deletions
|
|
@ -17,17 +17,16 @@
|
||||||
|
|
||||||
import axios, { AxiosInstance } from "axios";
|
import axios, { AxiosInstance } from "axios";
|
||||||
|
|
||||||
/** Resolved bridge base URL: per-instance override > env var > default. */
|
/** Resolved bridge base URL: per-instance override > env var > same-origin proxy default.
|
||||||
|
*
|
||||||
|
* In dev, the Vite server proxies `/bridge/*` to `http://localhost:4000/*` (see vite.config.ts).
|
||||||
|
* Same-origin = the auth cookie is sent automatically without CORS gymnastics.
|
||||||
|
* In prod, set VITE_BRIDGE_URL at build time to an absolute URL behind your reverse proxy
|
||||||
|
* (or keep `/bridge` and proxy server-side).
|
||||||
|
*/
|
||||||
export function resolveBridgeUrl(bridgeUrlOverride?: string | null): string {
|
export function resolveBridgeUrl(bridgeUrlOverride?: string | null): string {
|
||||||
// Vite exposes import.meta.env at build time. The double cast is required
|
|
||||||
// because ImportMeta has no index signature in TypeScript's strict mode,
|
|
||||||
// but at runtime Vite replaces the env values.
|
|
||||||
const metaEnv = (import.meta as unknown as { env?: { VITE_BRIDGE_URL?: string } }).env;
|
const metaEnv = (import.meta as unknown as { env?: { VITE_BRIDGE_URL?: string } }).env;
|
||||||
return (
|
return bridgeUrlOverride ?? metaEnv?.VITE_BRIDGE_URL ?? "/bridge";
|
||||||
bridgeUrlOverride ??
|
|
||||||
metaEnv?.VITE_BRIDGE_URL ??
|
|
||||||
"http://localhost:4000"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Attempt to read the auth token from JS-accessible cookie or jotai storage. */
|
/** Attempt to read the auth token from JS-accessible cookie or jotai storage. */
|
||||||
|
|
@ -58,7 +57,11 @@ export function createBridgeClient(bridgeUrl: string): AxiosInstance {
|
||||||
});
|
});
|
||||||
|
|
||||||
instance.interceptors.request.use((config) => {
|
instance.interceptors.request.use((config) => {
|
||||||
const token = readTokenFromCookie();
|
// Priority: cookie token (prod) > VITE_BRIDGE_TOKEN env (dev fallback)
|
||||||
|
const cookieToken = readTokenFromCookie();
|
||||||
|
const metaEnv = (import.meta as unknown as { env?: { VITE_BRIDGE_TOKEN?: string } }).env;
|
||||||
|
const envToken = metaEnv?.VITE_BRIDGE_TOKEN;
|
||||||
|
const token = cookieToken || envToken;
|
||||||
if (token) {
|
if (token) {
|
||||||
config.headers["Authorization"] = `Bearer ${token}`;
|
config.headers["Authorization"] = `Bearer ${token}`;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ export default defineConfig(({ mode }) => {
|
||||||
BILLING_TRIAL_DAYS,
|
BILLING_TRIAL_DAYS,
|
||||||
POSTHOG_HOST,
|
POSTHOG_HOST,
|
||||||
POSTHOG_KEY,
|
POSTHOG_KEY,
|
||||||
|
VITE_BRIDGE_TOKEN,
|
||||||
} = loadEnv(mode, envPath, "");
|
} = loadEnv(mode, envPath, "");
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -31,6 +32,7 @@ export default defineConfig(({ mode }) => {
|
||||||
BILLING_TRIAL_DAYS,
|
BILLING_TRIAL_DAYS,
|
||||||
POSTHOG_HOST,
|
POSTHOG_HOST,
|
||||||
POSTHOG_KEY,
|
POSTHOG_KEY,
|
||||||
|
VITE_BRIDGE_TOKEN,
|
||||||
},
|
},
|
||||||
APP_VERSION: JSON.stringify(process.env.npm_package_version),
|
APP_VERSION: JSON.stringify(process.env.npm_package_version),
|
||||||
},
|
},
|
||||||
|
|
@ -70,6 +72,16 @@ export default defineConfig(({ mode }) => {
|
||||||
ws: true,
|
ws: true,
|
||||||
rewriteWsOrigin: true,
|
rewriteWsOrigin: true,
|
||||||
},
|
},
|
||||||
|
"/bridge": {
|
||||||
|
target: process.env.VITE_BRIDGE_PROXY_TARGET || "http://localhost:4000",
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: (p) => p.replace(/^\/bridge/, ""),
|
||||||
|
},
|
||||||
|
"/bridge-events": {
|
||||||
|
target: process.env.VITE_BRIDGE_PROXY_TARGET || "http://localhost:4000",
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: (p) => p.replace(/^\/bridge-events/, "/api/events"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue