fix(dev): enable Vite session auth proxy
This commit is contained in:
@@ -9,6 +9,11 @@ const ROOT = path.resolve(DIR, '../..');
|
||||
|
||||
type BasicAuth = { username: string; password: string };
|
||||
|
||||
function stripTrailingSlashes(p: string): string {
|
||||
const out = p.replace(/\/+$/, '');
|
||||
return out || '/';
|
||||
}
|
||||
|
||||
function readApiReadToken(): string | undefined {
|
||||
if (process.env.API_READ_TOKEN) return process.env.API_READ_TOKEN;
|
||||
const p = path.join(ROOT, 'tokens', 'read.json');
|
||||
@@ -56,30 +61,98 @@ function readProxyBasicAuth(): BasicAuth | undefined {
|
||||
|
||||
const apiReadToken = readApiReadToken();
|
||||
const proxyBasicAuth = readProxyBasicAuth();
|
||||
const apiProxyTarget = process.env.API_PROXY_TARGET || 'http://localhost:8787';
|
||||
|
||||
function parseUrl(v: string): URL | undefined {
|
||||
try {
|
||||
return new URL(v);
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
const apiProxyTargetUrl = parseUrl(apiProxyTarget);
|
||||
const apiProxyTargetPath = stripTrailingSlashes(apiProxyTargetUrl?.pathname || '/');
|
||||
const apiProxyTargetEndsWithApi = apiProxyTargetPath.endsWith('/api');
|
||||
|
||||
function inferUiProxyTarget(apiTarget: string): string | undefined {
|
||||
try {
|
||||
const u = new URL(apiTarget);
|
||||
const p = stripTrailingSlashes(u.pathname || '/');
|
||||
if (!p.endsWith('/api')) return undefined;
|
||||
const basePath = p.slice(0, -'/api'.length) || '/';
|
||||
u.pathname = basePath;
|
||||
u.search = '';
|
||||
u.hash = '';
|
||||
const out = u.toString();
|
||||
return out.endsWith('/') ? out.slice(0, -1) : out;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
const uiProxyTarget =
|
||||
process.env.FRONTEND_PROXY_TARGET ||
|
||||
process.env.UI_PROXY_TARGET ||
|
||||
process.env.AUTH_PROXY_TARGET ||
|
||||
inferUiProxyTarget(apiProxyTarget) ||
|
||||
(apiProxyTargetUrl && apiProxyTargetPath === '/' ? stripTrailingSlashes(apiProxyTargetUrl.toString()) : undefined);
|
||||
|
||||
function applyProxyBasicAuth(proxyReq: any) {
|
||||
if (!proxyBasicAuth) return false;
|
||||
const b64 = Buffer.from(`${proxyBasicAuth.username}:${proxyBasicAuth.password}`, 'utf8').toString('base64');
|
||||
proxyReq.setHeader('Authorization', `Basic ${b64}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
function rewriteSetCookieForLocalDevHttp(proxyRes: any) {
|
||||
const v = proxyRes?.headers?.['set-cookie'];
|
||||
if (!v) return;
|
||||
const rewrite = (cookie: string) => {
|
||||
let out = cookie.replace(/;\s*secure\b/gi, '');
|
||||
out = out.replace(/;\s*domain=[^;]+/gi, '');
|
||||
out = out.replace(/;\s*samesite=none\b/gi, '; SameSite=Lax');
|
||||
return out;
|
||||
};
|
||||
proxyRes.headers['set-cookie'] = Array.isArray(v) ? v.map(rewrite) : rewrite(String(v));
|
||||
}
|
||||
|
||||
const proxy: Record<string, any> = {
|
||||
'/api': {
|
||||
target: apiProxyTarget,
|
||||
changeOrigin: true,
|
||||
rewrite: (p: string) => (apiProxyTargetEndsWithApi ? p.replace(/^\/api/, '') : p),
|
||||
configure: (p: any) => {
|
||||
p.on('proxyReq', (proxyReq: any) => {
|
||||
if (applyProxyBasicAuth(proxyReq)) return;
|
||||
if (apiReadToken) proxyReq.setHeader('Authorization', `Bearer ${apiReadToken}`);
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
if (uiProxyTarget) {
|
||||
for (const prefix of ['/whoami', '/auth', '/logout']) {
|
||||
proxy[prefix] = {
|
||||
target: uiProxyTarget,
|
||||
changeOrigin: true,
|
||||
configure: (p: any) => {
|
||||
p.on('proxyReq', (proxyReq: any) => {
|
||||
applyProxyBasicAuth(proxyReq);
|
||||
});
|
||||
p.on('proxyRes', (proxyRes: any) => {
|
||||
rewriteSetCookieForLocalDevHttp(proxyRes);
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
server: {
|
||||
port: 5173,
|
||||
strictPort: true,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: process.env.API_PROXY_TARGET || 'http://localhost:8787',
|
||||
changeOrigin: true,
|
||||
rewrite: (p) => p.replace(/^\/api/, ''),
|
||||
configure: (proxy) => {
|
||||
proxy.on('proxyReq', (proxyReq) => {
|
||||
if (proxyBasicAuth) {
|
||||
const b64 = Buffer.from(`${proxyBasicAuth.username}:${proxyBasicAuth.password}`, 'utf8').toString(
|
||||
'base64'
|
||||
);
|
||||
proxyReq.setHeader('Authorization', `Basic ${b64}`);
|
||||
return;
|
||||
}
|
||||
if (apiReadToken) proxyReq.setHeader('Authorization', `Bearer ${apiReadToken}`);
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
proxy,
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user