diff --git a/frontend/vite.config.js b/frontend/vite.config.js index 1aca842..e8e5fe6 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -5,17 +5,50 @@ import vue from '@vitejs/plugin-vue' import { existsSync, renameSync, mkdirSync } from 'node:fs' import sirv from 'sirv' +// Auth host mode: when set, clients accessing the auth host get /auth/ at / and /auth/admin/ at /admin/ +const authHost = process.env.PASKIA_AUTH_HOST + export default defineConfig(({ command }) => ({ appType: 'mpa', publicDir: 'public', plugins: [ vue(), + // Auth host routing: rewrite paths when accessing dedicated auth host + // Must run before serve-examples to handle / correctly + authHost && { + name: 'auth-host-routing', + configureServer(server) { + server.middlewares.use((req, _res, next) => { + const host = req.headers.host?.split(':')[0] + // Check if request is coming to the auth host + if (host === authHost) { + // Only rewrite specific paths that should map to /auth/* + // Rewrite / and /index.html to /auth/ + if (req.url === '/' || req.url === '/index.html') { + req.url = '/auth/' + } + // Rewrite /admin/* to /auth/admin/* + else if (req.url.startsWith('/admin/') || req.url === '/admin') { + req.url = '/auth' + req.url + } + // Everything else (Vite paths, passphrase links, etc.) passes through unchanged + } + next() + }) + } + }, { name: 'serve-examples', configureServer(server) { const examplesDir = resolve(__dirname, '../examples') const serve = sirv(examplesDir, { dev: true }) server.middlewares.use((req, _res, next) => { + // Skip redirect to examples on auth host (handled by auth-host-routing) + const host = req.headers.host?.split(':')[0] + if (authHost && host === authHost) { + next() + return + } if (req.url === '/' || req.url === '/index.html') req.url = '/examples/' next() }) @@ -46,7 +79,7 @@ export default defineConfig(({ command }) => ({ } } } - ], + ].filter(Boolean), resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) } }, diff --git a/scripts/devserver.py b/scripts/devserver.py index f4db987..f2955c9 100755 --- a/scripts/devserver.py +++ b/scripts/devserver.py @@ -118,7 +118,7 @@ def parse_endpoint( return host, port, None, False -def run_vite(vite_url: str, vite_host: str | None, vite_port: int): +def run_vite(vite_url: str, vite_host: str | None, vite_port: int, auth_host: str | None = None): """Spawn the frontend dev server (deno, npm, or bunx) as a background process.""" devpath = Path(__file__).parent.parent / "frontend" if not (devpath / "package.json").exists(): @@ -160,7 +160,10 @@ def run_vite(vite_url: str, vite_host: str | None, vite_port: int): full_cmd = cmd + vite_args stderr.write(f">>> {' '.join([tool_name, *full_cmd[1:]])}\n") - vite_process = subprocess.Popen(full_cmd, cwd=str(devpath), shell=False) + vite_env = os.environ.copy() + if auth_host: + vite_env["PASKIA_AUTH_HOST"] = auth_host + vite_process = subprocess.Popen(full_cmd, cwd=str(devpath), shell=False, env=vite_env) except Exception as e: stderr.write( f"┃ ⚠️ Vite couldn't start: {e}\n" @@ -418,7 +421,7 @@ def main(): raise SystemExit(1) # Start Vite dev server - run_vite(vite_url, vite_host, vite_port) + run_vite(vite_url, vite_host, vite_port, args.auth_host) # Set dev mode with Vite URL in environment for subprocess env = os.environ.copy()