Files
seguidorDeLotes/nuxt4-app/server/api/auth/authentik.get.ts
josedario87 b9ba7a80db
All checks were successful
build-and-deploy / build (push) Successful in 2m1s
build-and-deploy / deploy (push) Successful in 4s
Clean up codebase and prepare as template
Remove unused files and code:
- Delete test/debug endpoints (test.get.ts, public.get.ts, user.get.ts, debug-config backup)
- Remove unused OAuth wrapper (oauth-authentik.ts)
- Clean up debug console.log statements
- Simplify code comments

Fix TypeScript errors:
- Add @types/node dependency
- Create index.d.ts with User interface extension
- Fix UButton color props (red→error, gray→neutral)
- Add type assertions in protected.get.ts

Update documentation:
- Enhance README.md as template documentation
- Update SETUP.md with correct API routes (/api/auth/* instead of /auth/*)
- Add NUXT_OAUTH_AUTHENTIK_SERVER_URL_INTERNAL documentation
- Update endpoint documentation

This commit prepares the repository to be used as a template for future Nuxt 4 + Authentik OAuth projects.
2025-10-11 19:18:52 -06:00

83 lines
2.6 KiB
TypeScript

import { getQuery } from 'h3'
import { withQuery } from 'ufo'
/**
* OAuth Authentik Login Handler
* Handles OAuth flow: initial redirect and callback
*/
export default defineEventHandler(async (event) => {
const runtimeConfig = useRuntimeConfig(event)
const query = getQuery(event)
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'],
}
// 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()
})
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(' '),
}
)
return sendRedirect(event, authorizationUrl)
})