diff --git a/API.md b/API.md index cce7e90..bec5b2c 100644 --- a/API.md +++ b/API.md @@ -48,7 +48,7 @@ Always under `/auth/api/` (even on auth host): | Method | Path | Description | |--------|------|-------------| -| GET | `/auth/restricted` | Authentication UI for iframe embedding (supports `?mode=login` or `?mode=reauth`) | +| GET | `/auth/restricted/` | Authentication UI for iframe embedding (supports `?mode=login` or `?mode=reauth`) | |--------|------|-------------| | POST | `/auth/api/validate` | Validate & (conditionally) renew session | | GET | `/auth/api/forward` | Auth proxy endpoint for reverse proxies (204 or 4xx) | diff --git a/examples/restricted-api.html b/examples/restricted-api.html index 759fd2d..60fc2af 100644 --- a/examples/restricted-api.html +++ b/examples/restricted-api.html @@ -111,7 +111,7 @@ iframe.title = 'Authentication'; document.body.appendChild(iframe); } - iframe.src = '/auth/restricted?mode=login'; + iframe.src = '/auth/restricted/?mode=login'; showStatus('Login mode loaded - for users who are not authenticated', 'info'); } @@ -123,7 +123,7 @@ iframe.title = 'Authentication'; document.body.appendChild(iframe); } - iframe.src = '/auth/restricted?mode=reauth'; + iframe.src = '/auth/restricted/?mode=reauth'; showStatus('Reauth mode loaded - for additional verification of authenticated users', 'info'); } @@ -133,7 +133,7 @@ iframe = document.createElement('iframe'); iframe.id = 'auth-iframe'; iframe.title = 'Authentication'; - iframe.src = '/auth/restricted'; + iframe.src = '/auth/restricted/'; document.body.appendChild(iframe); iframeInitialized = true; } diff --git a/frontend/auth/App.vue b/frontend/auth/App.vue index 54016f7..4494bce 100644 --- a/frontend/auth/App.vue +++ b/frontend/auth/App.vue @@ -57,7 +57,7 @@ function showAuthIframe() { authIframe = document.createElement('iframe') authIframe.id = 'auth-iframe' authIframe.title = 'Authentication' - authIframe.src = '/auth/restricted?mode=login' + authIframe.src = '/auth/restricted/?mode=login' document.body.appendChild(authIframe) loadingMessage.value = 'Authentication required...' } diff --git a/frontend/auth/admin/AdminApp.vue b/frontend/auth/admin/AdminApp.vue index 8274d7c..71341b4 100644 --- a/frontend/auth/admin/AdminApp.vue +++ b/frontend/auth/admin/AdminApp.vue @@ -330,7 +330,7 @@ function showAuthIframe() { authIframe = document.createElement('iframe') authIframe.id = 'auth-iframe' authIframe.title = 'Authentication' - authIframe.src = '/auth/restricted?mode=login' + authIframe.src = '/auth/restricted/?mode=login' document.body.appendChild(authIframe) loadingMessage.value = 'Authentication required...' } diff --git a/frontend/vite.config.js b/frontend/vite.config.js index 61c8175..40f7190 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -2,7 +2,7 @@ import { fileURLToPath, URL } from 'node:url' import { defineConfig } from 'vite' import { resolve } from 'node:path' import vue from '@vitejs/plugin-vue' -import { readFileSync, existsSync, statSync, renameSync, mkdirSync } from 'node:fs' +import { existsSync, renameSync, mkdirSync } from 'node:fs' export default defineConfig(({ command }) => ({ appType: 'mpa', @@ -45,53 +45,19 @@ export default defineConfig(({ command }) => ({ allow: ['..'] }, proxy: { - '/': { - target: 'http://localhost:4402', - bypass: (req) => { - const url = req.url?.split('?')[0] - - // Root and examples served by Vite - if (url === '/' || url === '') return '/../examples/index.html' - if (url === '/examples' || url === '/examples/') return '/../examples/index.html' - if (url?.startsWith('/examples/')) return `/../examples${url.slice(9)}` - - // Let other proxies handle their routes - return null - } + // Only proxy these two specific backend API paths + '/auth/api': { + target: 'http://localhost:4402' }, - '/auth/': { + '/auth/ws': { target: 'http://localhost:4402', - ws: true, - bypass: (req) => { - const url = req.url?.split('?')[0] - // Backend handles /auth/api/* and /auth/ws/* (no bypass - let proxy handle) - if (url?.startsWith('/auth/api/') || url?.startsWith('/auth/ws/')) return null - // Vite serves all assets - if (url?.startsWith('/auth/assets/')) return url - // Vite serves main app routes - if (url === '/auth' || url === '/auth/') return '/auth/index.html' - if (url === '/auth/admin' || url === '/auth/admin/') return '/auth/admin/index.html' - if (url === '/auth/restricted' || url === '/auth/restricted/') return '/auth/restricted/index.html' - if (url?.startsWith('/auth/') && /^\/auth\/([a-z]+\.)+[a-z]+\/?/.test(url)) return "/int/reset/index.html" - // Vite serves source files (for HMR and dev) - if (url?.startsWith('/auth/') && /\.(js|vue|css|ts|jsx|tsx|json)$/.test(url)) return url - return null - } - }, - '/int/': { - target: 'http://localhost:4402', - bypass: (req) => { - const url = req.url?.split('?')[0] - // Vite serves /int/ apps - if (url === '/int/host' || url === '/int/host/') return '/int/host/index.html' - if (url === '/int/reset' || url === '/int/reset/' || url?.match(/^\/int\/reset\/([a-z]+\.){4}[a-z]+\/?$/)) return '/int/reset/index.html' - if (url === '/int/forward' || url === '/int/forward/') return '/int/forward/index.html' - if (url?.startsWith('/int/')) return url - return null - } + ws: true } } }, + preview: { + port: 4403 + }, build: { outDir: '../passkey/frontend-build', emptyOutDir: true, diff --git a/passkey/fastapi/mainapp.py b/passkey/fastapi/mainapp.py index dbf18a4..2b24128 100644 --- a/passkey/fastapi/mainapp.py +++ b/passkey/fastapi/mainapp.py @@ -61,7 +61,7 @@ app.mount( ) -@app.get("/auth/restricted") +@app.get("/auth/restricted/") async def restricted_view(): """Serve the restricted/authentication UI for iframe embedding.""" return FileResponse(frontend.file("auth", "restricted", "index.html"))