import { getQuery } from 'h3' import { withQuery } from 'ufo' /** * OAuth Authentik Login Handler * Ruta: /api/auth/authentik * * Este endpoint inicia el flujo OAuth con Authentik */ export default defineEventHandler(async (event) => { const runtimeConfig = useRuntimeConfig(event) const query = getQuery(event) // Configuración de Authentik const config = { clientId: runtimeConfig.oauth.authentik.clientId, clientSecret: runtimeConfig.oauth.authentik.clientSecret, serverUrl: runtimeConfig.oauth.authentik.serverUrl, serverUrlInternal: runtimeConfig.oauth.authentik.serverUrlInternal || runtimeConfig.oauth.authentik.serverUrl, redirectURL: runtimeConfig.oauth.authentik.redirectURL, scope: ['openid', 'profile', 'email'], } console.log('OAuth Authentik - Iniciando flujo:', { serverUrl: config.serverUrl, serverUrlInternal: config.serverUrlInternal, redirectURL: config.redirectURL, hasCode: !!query.code }) // Handle OAuth callback if (query.code) { try { // Exchange code for tokens (usar URL interna para comunicación servidor-a-servidor) const tokenUrl = `${config.serverUrlInternal}/application/o/token/` const tokenResponse = await $fetch(tokenUrl, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: new URLSearchParams({ grant_type: 'authorization_code', client_id: config.clientId, client_secret: config.clientSecret, code: query.code as string, redirect_uri: config.redirectURL, }), }) const tokens = tokenResponse as any // Get user info (usar URL interna para comunicación servidor-a-servidor) const userInfoUrl = `${config.serverUrlInternal}/application/o/userinfo/` const user = await $fetch(userInfoUrl, { headers: { Authorization: `Bearer ${tokens.access_token}`, }, }) // Guardar información del usuario en la sesión await setUserSession(event, { user: { id: (user as any).sub, email: (user as any).email, name: (user as any).name || (user as any).preferred_username, username: (user as any).preferred_username, picture: (user as any).picture, groups: (user as any).groups || [] }, loggedInAt: Date.now() }) // Redirigir al dashboard después del login return sendRedirect(event, '/') } catch (error: any) { console.error('Authentik OAuth error:', error) return sendRedirect(event, '/?error=auth_failed') } } // Initial redirect to Authentik const authorizationUrl = withQuery( `${config.serverUrl}/application/o/authorize/`, { client_id: config.clientId, redirect_uri: config.redirectURL, response_type: 'code', scope: config.scope.join(' '), } ) console.log('Redirecting to:', authorizationUrl) return sendRedirect(event, authorizationUrl) })