import { defineNuxtRouteMiddleware, navigateTo } from '#app'; import type { RouteLocationNormalized } from 'vue-router'; import { useAuth } from '~/composables/useAuth'; export default defineNuxtRouteMiddleware(async (to: RouteLocationNormalized) => { console.log('🛡️ Auth middleware triggered for:', to.path); // Allow the login page to handle its own checks without redirection loops if (to.path === '/auth/login') { console.log('⏭️ Allowing access to Login page'); return; } // Check for authentication signal from successful login redirect FIRST // This must be checked before the root redirect logic const isAuthRedirect: boolean = to.query.authenticated === 'true'; if (isAuthRedirect) { console.log('🔐 Authentication redirect detected, allowing access to verify session'); // Don't redirect, let it proceed to auth verification below } else { // Check for bypass flag (from keyboard shortcut) if (process.client) { const bypassFlag = sessionStorage.getItem('bypassRootRedirect'); if (bypassFlag === 'true' && to.path === '/') { console.log('🔑 Bypass flag detected - allowing root access'); // Clear the flag immediately to prevent future bypasses sessionStorage.removeItem('bypassRootRedirect'); return; // Allow access without any redirect } } // Redirect root path to Login page (only if not authenticated redirect) if (to.path === '/') { console.log('🔄 Redirecting from root to Login page'); return navigateTo('/auth/login', { replace: true }); } } // On server-side during development, skip intensive checks // The cookie check will happen on client-side if (process.server && process.env.NODE_ENV === 'development') { if (isAuthRedirect) { console.log('⏭️ Server-side: Allowing authenticated redirect to pass through (dev mode)'); return; // Allow server-side render to proceed, client will verify } console.log('⏭️ Skipping intensive check on server-side during development'); useAuth(); return; } // Process the authentication redirect if (isAuthRedirect) { console.log('⏳ Client-side is processing a new login session, checking cookie...'); // Give the browser a moment to process the cookie from the redirect if (process.client) { await new Promise(resolve => setTimeout(resolve, 50)); } // Check authentication first before removing query parameter try { const { checkAuth } = useAuth(); console.log('🔍 Checking authentication after redirect...'); let user = await checkAuth(); // If not found, retry once more if (!user && process.client) { console.log('⚠️ Cookie not available yet, retrying...'); await new Promise(resolve => setTimeout(resolve, 150)); user = await checkAuth(); } if (user) { console.log('✅ User is authenticated after redirect:', user.name || user.preferred_username || user.email); // Remove query parameter and allow access await navigateTo({ path: to.path, query: {} }, { replace: true }); return; // Allow access } else { console.log('❌ Still no session after retry, redirecting to login'); return navigateTo('/auth/login'); } } catch (authError) { console.error('❌ Auth check failed after redirect:', authError); // Retry once if (process.client) { await new Promise(resolve => setTimeout(resolve, 150)); try { const { checkAuth } = useAuth(); const retryUser = await checkAuth(); if (retryUser) { console.log('✅ User authenticated on retry after error'); await navigateTo({ path: to.path, query: {} }, { replace: true }); return; } } catch (retryError) { console.error('❌ Retry also failed:', retryError); } } return navigateTo('/auth/login'); } } try { const { checkAuth } = useAuth(); console.log('🔍 Checking authentication status using useAuth...'); const user = await checkAuth(); if (user) { console.log('✅ User is authenticated:', user.name || user.preferred_username || user.email); return; } else { console.log('❌ No valid session found, redirecting to login'); return navigateTo('/auth/login'); } } catch (error) { console.error('❌ Auth middleware error:', error); console.log('🔄 Redirecting to login due to error'); return navigateTo('/auth/login'); } });