Add flat route files with dot notation
All checks were successful
build-and-deploy / build (push) Successful in 30s
build-and-deploy / deploy (push) Successful in 3s

- Add server/routes/auth.authentik.get.ts
- Add server/routes/auth.logout.get.ts
- Test if dot notation creates nested routes /auth/authentik
- Keep auth/ folder as backup
This commit is contained in:
2025-10-11 17:52:38 -06:00
parent 986d127c03
commit 2dbd2222af
2 changed files with 103 additions and 0 deletions

View File

@@ -0,0 +1,93 @@
import { getQuery } from 'h3'
import { withQuery } from 'ufo'
import { defu } from 'defu'
/**
* OAuth Authentik Login Handler
* Ruta: /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,
redirectURL: runtimeConfig.oauth.authentik.redirectURL,
scope: ['openid', 'profile', 'email'],
}
console.log('OAuth Authentik - Iniciando flujo:', {
serverUrl: config.serverUrl,
redirectURL: config.redirectURL,
hasCode: !!query.code
})
// Handle OAuth callback
if (query.code) {
try {
// Exchange code for tokens
const tokenUrl = `${config.serverUrl}/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
const userInfoUrl = `${config.serverUrl}/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?message=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)
})

View File

@@ -0,0 +1,10 @@
/**
* Logout Handler
* Ruta: /auth/logout
*
* Limpia la sesión del usuario y redirige a la página de inicio
*/
export default defineEventHandler(async (event) => {
await clearUserSession(event)
return sendRedirect(event, '/')
})