Add 'Iniciar Sesión' button to toasts when session is not active. Clicking the button reloads the page, triggering Authentik redirect to login flow. Also increased toast timeout from 5s to 10s to give users more time to see and click the login button.
141 lines
4.5 KiB
TypeScript
141 lines
4.5 KiB
TypeScript
/**
|
|
* Composable para leer información de usuario de Authentik
|
|
* Los headers son inyectados por Authentik Proxy Outpost
|
|
*/
|
|
export const useAuthentik = () => {
|
|
// Leer headers en el servidor y almacenarlos en state
|
|
const authentikUser = useState('authentikUser', () => {
|
|
// Solo en el servidor, leer los headers
|
|
if (process.server) {
|
|
const headers = useRequestHeaders()
|
|
|
|
const username = headers['x-authentik-username']
|
|
const email = headers['x-authentik-email']
|
|
const name = headers['x-authentik-name']
|
|
const groups = headers['x-authentik-groups']
|
|
const uid = headers['x-authentik-uid']
|
|
|
|
// Si no hay username, el usuario no está autenticado
|
|
if (!username) {
|
|
return null
|
|
}
|
|
|
|
return {
|
|
username,
|
|
email,
|
|
name,
|
|
groups: groups ? groups.split('|') : [],
|
|
uid,
|
|
// Generar avatar URL usando UI Avatars
|
|
avatar: `https://ui-avatars.com/api/?name=${encodeURIComponent(name || username)}&background=random&size=128`
|
|
}
|
|
}
|
|
|
|
return null
|
|
})
|
|
|
|
const user = computed(() => authentikUser.value)
|
|
const isAuthenticated = computed(() => !!user.value)
|
|
|
|
const logout = () => {
|
|
// Logout completo: invalida la sesión de Authentik completamente
|
|
// Esto cierra sesión en todas las aplicaciones
|
|
const authentikUrl = useRuntimeConfig().public.authentikUrl || 'https://authentik.nucleoriofrio.com'
|
|
navigateTo(`${authentikUrl}/flows/-/default/invalidation/`, { external: true })
|
|
}
|
|
|
|
const goToProfile = () => {
|
|
// URL de perfil de Authentik
|
|
const authentikUrl = useRuntimeConfig().public.authentikUrl || 'https://authentik.nucleoriofrio.com'
|
|
navigateTo(`${authentikUrl}/if/user/`, { external: true, open: { target: '_blank' } })
|
|
}
|
|
|
|
const checkSessionStatus = async () => {
|
|
const toast = useToast()
|
|
|
|
// Mostrar toast de "verificando..."
|
|
toast.add({
|
|
title: 'Verificando sesión...',
|
|
description: 'Consultando estado en Authentik',
|
|
color: 'info',
|
|
icon: 'i-heroicons-arrow-path',
|
|
timeout: 2000
|
|
})
|
|
|
|
try {
|
|
// Consultar el endpoint de API que verifica contra Authentik
|
|
const response = await $fetch('/api/auth/status')
|
|
|
|
if (response.authenticated && response.user) {
|
|
// Sesión activa en Authentik
|
|
toast.add({
|
|
title: 'Sesión Activa',
|
|
description: `Conectado como: ${response.user.name || response.user.username}`,
|
|
color: 'success',
|
|
icon: 'i-heroicons-check-circle',
|
|
timeout: 5000
|
|
})
|
|
} else {
|
|
// Sin sesión en Authentik
|
|
toast.add({
|
|
title: 'Sin Sesión',
|
|
description: 'No hay sesión activa en Authentik',
|
|
color: 'warning',
|
|
icon: 'i-heroicons-exclamation-triangle',
|
|
timeout: 10000,
|
|
actions: [{
|
|
label: 'Iniciar Sesión',
|
|
click: () => {
|
|
// Recargar la página forzará a Authentik a redirigir al login
|
|
window.location.reload()
|
|
}
|
|
}]
|
|
})
|
|
}
|
|
} catch (error) {
|
|
// Si el error es por redirect de Authentik (CORS/fetch error), significa que no hay sesión
|
|
// Authentik redirige a login cuando no hay sesión válida, causando error CORS en fetch
|
|
const errorMessage = error?.message || error?.toString() || ''
|
|
const isCorsOrRedirectError = errorMessage.includes('Failed to fetch') ||
|
|
errorMessage.includes('CORS') ||
|
|
error?.statusCode === 302
|
|
|
|
if (isCorsOrRedirectError) {
|
|
// Interpretar como sesión expirada/inválida
|
|
toast.add({
|
|
title: 'Sin Sesión',
|
|
description: 'No hay sesión activa en Authentik',
|
|
color: 'warning',
|
|
icon: 'i-heroicons-exclamation-triangle',
|
|
timeout: 10000,
|
|
actions: [{
|
|
label: 'Iniciar Sesión',
|
|
click: () => {
|
|
// Recargar la página forzará a Authentik a redirigir al login
|
|
window.location.reload()
|
|
}
|
|
}]
|
|
})
|
|
} else {
|
|
// Error real de red o servidor
|
|
toast.add({
|
|
title: 'Error',
|
|
description: 'No se pudo verificar el estado de la sesión',
|
|
color: 'error',
|
|
icon: 'i-heroicons-x-circle',
|
|
timeout: 5000
|
|
})
|
|
}
|
|
console.error('Error checking session status:', error)
|
|
}
|
|
}
|
|
|
|
return {
|
|
user,
|
|
isAuthenticated,
|
|
logout,
|
|
goToProfile,
|
|
checkSessionStatus
|
|
}
|
|
}
|