diff --git a/frontend/src/components/LoginView.vue b/frontend/src/components/LoginView.vue index a1a0d2c..a9eb444 100644 --- a/frontend/src/components/LoginView.vue +++ b/frontend/src/components/LoginView.vue @@ -31,7 +31,11 @@ const handleLogin = async () => { authStore.showMessage('Starting authentication...', 'info') await authStore.authenticate() authStore.showMessage('Authentication successful!', 'success', 2000) - authStore.currentView = 'profile' + if (location.pathname.startsWith('/auth/')) { + authStore.currentView = 'profile' + } else { + location.reload() + } } catch (error) { authStore.showMessage(`Authentication failed: ${error.message}`, 'error') } diff --git a/frontend/src/components/RegisterView.vue b/frontend/src/components/RegisterView.vue index 532c4a8..87bc9b6 100644 --- a/frontend/src/components/RegisterView.vue +++ b/frontend/src/components/RegisterView.vue @@ -5,7 +5,7 @@
{{ authStore.isLoading ? 'Registering...' : 'Register Passkey' }} diff --git a/frontend/src/utils/passkey.js b/frontend/src/utils/passkey.js index 0d98e3e..d4135d0 100644 --- a/frontend/src/utils/passkey.js +++ b/frontend/src/utils/passkey.js @@ -15,7 +15,7 @@ export async function register(url, options) { } export async function registerUser(user_name) { - return register('/auth/ws/new_user_registration', { user_name }) + return register('/auth/ws/register_new', { user_name }) } export async function registerCredential() { diff --git a/frontend/vite.config.js b/frontend/vite.config.js index 0749d1e..548dbc6 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -4,7 +4,7 @@ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // https://vite.dev/config/ -export default defineConfig({ +export default defineConfig(({ command, mode }) => ({ plugins: [ vue(), ], @@ -13,7 +13,7 @@ export default defineConfig({ '@': fileURLToPath(new URL('./src', import.meta.url)) }, }, - base: '/auth/', + base: command == 'build' ? '/auth/' : '/', server: { port: 3000, proxy: { @@ -29,4 +29,4 @@ export default defineConfig({ emptyOutDir: true, assetsDir: 'assets' } -}) +})) diff --git a/passkeyauth/main.py b/passkeyauth/main.py index 5e9c339..d470c26 100644 --- a/passkeyauth/main.py +++ b/passkeyauth/main.py @@ -15,11 +15,17 @@ from datetime import datetime from pathlib import Path from uuid import UUID, uuid4 -from fastapi import FastAPI, Request, Response, WebSocket, WebSocketDisconnect +from fastapi import ( + FastAPI, + Request, + Response, + WebSocket, + WebSocketDisconnect, +) from fastapi import ( Path as FastAPIPath, ) -from fastapi.responses import FileResponse, RedirectResponse +from fastapi.responses import FileResponse, JSONResponse, RedirectResponse from fastapi.staticfiles import StaticFiles from webauthn.helpers.exceptions import InvalidAuthenticationResponse @@ -204,7 +210,7 @@ async def register_chat( ) await ws.send_json(options) response = await ws.receive_json() - return passkey.reg_verify(response, challenge, user_id) + return passkey.reg_verify(response, challenge, user_id, origin=origin) @app.websocket("/auth/ws/authenticate") @@ -269,6 +275,27 @@ async def api_validate_token(request: Request): return await validate_token(request) +@app.get("/auth/forward-auth") +async def forward_authentication(request: Request): + """A verification endpoint to use with Caddy forward_auth or Nginx auth_request.""" + result = await validate_token(request) + if result.get("status") != "success": + # Serve the index.html of the authentication app if not authenticated + return FileResponse( + STATIC_DIR / "index.html", + status_code=401, + headers={"www-authenticate": "PrivateToken"}, + ) + + # If authenticated, return a success response + return JSONResponse( + result, + headers={ + "x-auth-user-id": result["user_id"], + }, + ) + + @app.post("/auth/logout") async def api_logout(response: Response): """Log out the current user by clearing the session cookie.""" @@ -315,20 +342,6 @@ async def reset_authentication( return response -@app.get("/auth/user-info-by-passphrase") -async def api_get_user_info_by_passphrase(token: str): - """Get user information using the passphrase.""" - reset_token = await db.get_reset_token(token) - if not reset_token: - return Response(content="Invalid or expired passphrase", status_code=403) - - user = await db.get_user_by_id(reset_token.user_id) - if not user: - return Response(content="User not found", status_code=404) - - return {"user_name": user.user_name} - - # Serve static files app.mount( "/auth/assets", StaticFiles(directory=STATIC_DIR / "assets"), name="static assets" diff --git a/passkeyauth/passkey.py b/passkeyauth/passkey.py index fe1722a..e3a85dc 100644 --- a/passkeyauth/passkey.py +++ b/passkeyauth/passkey.py @@ -141,11 +141,10 @@ class Passkey: Registration verification result """ credential = parse_registration_credential_json(response_json) - expected_origin = origin or self.origin registration = verify_registration_response( credential=credential, expected_challenge=expected_challenge, - expected_origin=expected_origin, + expected_origin=origin or self.origin, expected_rp_id=self.rp_id, ) return StoredCredential(