diff --git a/nuxt4/app/app.vue b/nuxt4/app/app.vue index c9a0350..2642a4d 100644 --- a/nuxt4/app/app.vue +++ b/nuxt4/app/app.vue @@ -14,11 +14,16 @@ -
- -
- - +
+ + + + +
+ +
+ + @@ -86,6 +91,7 @@
+
diff --git a/nuxt4/app/components/auth/ApplicationsList.vue b/nuxt4/app/components/auth/ApplicationsList.vue new file mode 100644 index 0000000..d1ad56a --- /dev/null +++ b/nuxt4/app/components/auth/ApplicationsList.vue @@ -0,0 +1,112 @@ + + + diff --git a/nuxt4/server/api/authentik/applications.ts b/nuxt4/server/api/authentik/applications.ts new file mode 100644 index 0000000..b494369 --- /dev/null +++ b/nuxt4/server/api/authentik/applications.ts @@ -0,0 +1,77 @@ +/** + * API endpoint para obtener las aplicaciones de Authentik + * Devuelve todas las aplicaciones disponibles + */ +export default defineEventHandler(async (event) => { + const config = useRuntimeConfig() + const headers = getRequestHeaders(event) + + // Obtener el username desde los headers de Authentik + const username = headers['x-authentik-username'] + const userGroups = headers['x-authentik-groups']?.split('|').filter(g => g.trim()) || [] + + if (!username) { + throw createError({ + statusCode: 401, + message: 'Usuario no autenticado' + }) + } + + // Obtener la URL y token de Authentik + const authentikUrl = config.authentikApiUrl || config.public.authentikUrl + const authentikToken = config.authentikApiToken + + if (!authentikToken) { + throw createError({ + statusCode: 500, + message: 'Token de Authentik no configurado' + }) + } + + try { + const response = await $fetch(`${authentikUrl}/api/v3/core/applications/`, { + headers: { + 'Authorization': `Bearer ${authentikToken}`, + 'Content-Type': 'application/json' + } + }) + + const apps = response as any + + // Filtrar aplicaciones basándose en grupos (si están definidos) + // Si la app no tiene grupos requeridos, está disponible para todos + const filteredApps = apps.results.filter((app: any) => { + // Si no hay launch_url, probablemente no sea una app accesible + if (!app.launch_url) return false + + // Si no tiene grupos definidos, está disponible para todos + if (!app.group || app.group.trim() === '') return true + + // Si el usuario es superuser, tiene acceso a todo + if (headers['x-authentik-is-superuser'] === 'true') return true + + // Verificar si el usuario tiene alguno de los grupos requeridos + const requiredGroups = app.group.split(',').map((g: string) => g.trim()) + return requiredGroups.some((reqGroup: string) => userGroups.includes(reqGroup)) + }) + + // Mapear a un formato más simple + return filteredApps.map((app: any) => ({ + pk: app.pk, + name: app.name, + slug: app.slug, + launchUrl: app.launch_url, + description: app.meta_description, + icon: app.meta_icon, + publisher: app.meta_publisher, + group: app.group, + openInNewTab: app.open_in_new_tab + })) + } catch (error: any) { + console.error('Error al obtener aplicaciones de Authentik:', error) + throw createError({ + statusCode: error.statusCode || 500, + message: error.message || 'Error al obtener las aplicaciones' + }) + } +})