From fda5b2497a5b1eeeab4cf73ec779eb672dc15673 Mon Sep 17 00:00:00 2001 From: josedario87 Date: Sun, 12 Oct 2025 03:06:08 -0600 Subject: [PATCH] =?UTF-8?q?fix:=20mejorar=20detecci=C3=B3n=20de=20p=C3=A9r?= =?UTF-8?q?dida=20de=20autenticaci=C3=B3n=20con=20Authentik?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Detectar errores "Failed to fetch" y "no response" como pérdida de auth - Mejor logging para debugging de cambios de estado - Manejar correctamente redirects 302 de Authentik en fetch --- components/AuthIndicator.client.vue | 23 +++++++++++++++++---- composables/useAuth.ts | 31 ++++++++++++++++++++++------- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/components/AuthIndicator.client.vue b/components/AuthIndicator.client.vue index 8136a1f..bedbfe0 100644 --- a/components/AuthIndicator.client.vue +++ b/components/AuthIndicator.client.vue @@ -66,8 +66,16 @@ watch(() => musicStore.error, (error, oldError) => { if (error && error !== oldError) { console.log('[AuthIndicator] Music store error detected:', error) - if (error.includes('401') || error.includes('403') || - error.includes('Unauthorized') || error.includes('Forbidden')) { + // Detectar errores de autenticación (múltiples formas) + const isAuthError = + error.includes('401') || + error.includes('403') || + error.includes('Unauthorized') || + error.includes('Forbidden') || + error.includes('Failed to fetch') || // Authentik redirect genera esto + error.includes('no response') // Nuxt $fetch sin respuesta + + if (isAuthError) { // Auth error detected - mark as unauthenticated immediately console.log('[AuthIndicator] Auth error detected, updating status') markUnauthenticated() @@ -80,8 +88,15 @@ watch(() => musicStore.loading, (loading, wasLoading) => { if (wasLoading && !loading && musicStore.error) { // Terminó de cargar con error, verificar si es de auth const error = musicStore.error - if (error.includes('401') || error.includes('403') || - error.includes('Unauthorized') || error.includes('Forbidden')) { + const isAuthError = + error.includes('401') || + error.includes('403') || + error.includes('Unauthorized') || + error.includes('Forbidden') || + error.includes('Failed to fetch') || + error.includes('no response') + + if (isAuthError) { markUnauthenticated() } } diff --git a/composables/useAuth.ts b/composables/useAuth.ts index 84efc6f..e687f3e 100644 --- a/composables/useAuth.ts +++ b/composables/useAuth.ts @@ -48,20 +48,37 @@ export const useAuth = () => { console.log('[Auth] Status changed:', isAuthenticated.value ? 'authenticated' : 'unauthenticated') } } catch (error: any) { - // TypeError: Failed to fetch = probablemente redirect de Authentik (no autenticado) - // o error de red real + // Con redirect: 'error', cualquier redirect (302) genera "Failed to fetch" + // Authentik redirige a login cuando no estás autenticado = 302 console.warn('[Auth] Check failed:', error.message) - // Si el error es por redirect (Authentik intenta redirigir a login), no estamos autenticados - if (error.message && error.message.includes('redirect')) { - const wasAuthenticated = isAuthenticated.value + const wasAuthenticated = isAuthenticated.value + + // "Failed to fetch" con redirect: 'error' configurado = sesión expirada + // Authentik intenta redirigir (302) pero fetch lo rechaza y genera error + if (error.message && error.message.includes('Failed to fetch')) { + console.log('[Auth] Failed to fetch detected - marking as unauthenticated') isAuthenticated.value = false authChecked.value = true if (wasAuthenticated) { - console.log('[Auth] Status changed: unauthenticated (redirect detected)') + console.log('[Auth] Status changed: authenticated → unauthenticated (Authentik redirect detected)') + } else { + console.log('[Auth] Confirmed unauthenticated state') } + } else if (error.name === 'TypeError' && error.message.includes('fetch')) { + // Otro tipo de TypeError fetch = también probablemente redirect + console.log('[Auth] TypeError fetch detected - marking as unauthenticated') + isAuthenticated.value = false + authChecked.value = true + if (wasAuthenticated) { + console.log('[Auth] Status changed: authenticated → unauthenticated (fetch error)') + } else { + console.log('[Auth] Confirmed unauthenticated state') + } + } else { + // Otro tipo de error (timeout, etc) - mantener estado actual + console.log('[Auth] Network error (not auth related), maintaining current state:', error.name) } - // Si no, mantenemos el estado actual (puede ser error de red temporal) lastCheckTime.value = now } finally {