// src/app/core/guards/auth.guard.ts import { inject } from '@angular/core'; import { CanActivateFn, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { AuthService } from '../services/auth.service'; import { RoleService } from '../services/role.service'; import { map, catchError, of, tap, switchMap } from 'rxjs'; export const authGuard: CanActivateFn = (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { const authService = inject(AuthService); const roleService = inject(RoleService); const router = inject(Router); console.log('🔐 AuthGuard check for:', state.url); // Attendre que l'initialisation soit terminée return authService.getInitializedState().pipe( switchMap(initialized => { if (!initialized) { console.log('⏳ AuthService pas encore initialisé, attente...'); return of(false); // Bloquer en attendant l'initialisation } // Vérifier l'authentification if (authService.isAuthenticated()) { return of(checkRoleAccess(route, roleService, router, state.url)); } // Tentative de rafraîchissement du token const refreshToken = authService.getRefreshToken(); if (refreshToken) { console.log('🔄 Token expiré, tentative de rafraîchissement...'); return authService.refreshToken().pipe( tap(() => { console.log('✅ Token rafraîchi avec succès'); roleService.refreshRoles(); }), map(() => checkRoleAccess(route, roleService, router, state.url)), catchError((error) => { console.error('❌ Échec du rafraîchissement du token:', error); authService.logout().subscribe(); return of(redirectToLogin(router, state.url, 'session_expired')); }) ); } // Redirection vers login console.log('🔒 Redirection vers login depuis:', state.url); return of(redirectToLogin(router, state.url, 'not_authenticated')); }), catchError(error => { console.error('❌ Erreur dans le guard d\'auth:', error); return of(redirectToLogin(router, state.url, 'not_authenticated')); }) ); } /** * Vérifie l'accès basé sur les rôles requis */ function checkRoleAccess( route: ActivatedRouteSnapshot, roleService: RoleService, router: Router, currentUrl: string ): boolean { const requiredRoles = route.data?.['roles'] as string[]; if (!requiredRoles || requiredRoles.length === 0) { console.log('✅ Accès autorisé (aucun rôle requis):', currentUrl); return true; } const hasRequiredRole = roleService.hasAnyRole(requiredRoles); const currentUserRoles = roleService.getCurrentUserRoles(); if (hasRequiredRole) { console.log('✅ Accès autorisé avec rôles:', currentUrl); console.log(' Rôles requis:', requiredRoles); console.log(' Rôles actuels:', currentUserRoles); return true; } console.warn('❌ Accès refusé: rôles insuffisants'); console.warn(' URL demandée:', currentUrl); console.warn(' Rôles requis:', requiredRoles); console.warn(' Rôles actuels:', currentUserRoles); // Rediriger vers la page non autorisée router.navigate(['/unauthorized'], { queryParams: { requiredRoles: requiredRoles.join(','), currentRoles: currentUserRoles.join(','), attemptedUrl: currentUrl }, replaceUrl: true }); return false; } /** * Redirige vers la page de login avec les paramètres appropriés */ function redirectToLogin( router: Router, returnUrl: string, reason: 'not_authenticated' | 'session_expired' ): boolean { const queryParams: any = { returnUrl: returnUrl, reason: reason }; // Message spécifique selon la raison if (reason === 'session_expired') { queryParams.message = 'Votre session a expiré. Veuillez vous reconnecter.'; } router.navigate(['/auth/sign-in'], { queryParams, replaceUrl: true }); return false; }