diff --git a/apps/visualizer/vite.config.ts b/apps/visualizer/vite.config.ts index 01ebb34..8c5fe11 100644 --- a/apps/visualizer/vite.config.ts +++ b/apps/visualizer/vite.config.ts @@ -7,6 +7,8 @@ import react from '@vitejs/plugin-react'; const DIR = path.dirname(fileURLToPath(import.meta.url)); const ROOT = path.resolve(DIR, '../..'); +type BasicAuth = { username: string; password: string }; + function readApiReadToken(): string | undefined { if (process.env.API_READ_TOKEN) return process.env.API_READ_TOKEN; const p = path.join(ROOT, 'tokens', 'read.json'); @@ -20,7 +22,40 @@ function readApiReadToken(): string | undefined { } } +function parseBasicAuth(value: string | undefined): BasicAuth | undefined { + const raw = String(value || '').trim(); + if (!raw) return undefined; + const idx = raw.indexOf(':'); + if (idx <= 0) return undefined; + const username = raw.slice(0, idx).trim(); + const password = raw.slice(idx + 1); + if (!username || !password) return undefined; + return { username, password }; +} + +function readProxyBasicAuth(): BasicAuth | undefined { + const fromEnv = parseBasicAuth(process.env.API_PROXY_BASIC_AUTH); + if (fromEnv) return fromEnv; + + const fileRaw = String(process.env.API_PROXY_BASIC_AUTH_FILE || '').trim(); + if (!fileRaw) return undefined; + + const p = path.isAbsolute(fileRaw) ? fileRaw : path.join(ROOT, fileRaw); + if (!fs.existsSync(p)) return undefined; + try { + const raw = fs.readFileSync(p, 'utf8'); + const json = JSON.parse(raw) as { username?: string; password?: string }; + const username = typeof json?.username === 'string' ? json.username.trim() : ''; + const password = typeof json?.password === 'string' ? json.password : ''; + if (!username || !password) return undefined; + return { username, password }; + } catch { + return undefined; + } +} + const apiReadToken = readApiReadToken(); +const proxyBasicAuth = readProxyBasicAuth(); export default defineConfig({ plugins: [react()], @@ -34,6 +69,13 @@ export default defineConfig({ 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}`); }); },