Files
antrean-operasi/middleware/auth.ts
2026-02-02 08:13:15 +07:00

123 lines
4.6 KiB
TypeScript

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');
}
});