'use client'; import React, { ReactNode, useEffect } from 'react'; import { useRouter } from 'next/navigation'; import { useAuth } from '@/contexts/AuthContext'; import { KEYCLOAK_REDIRECTS } from '@/config/keycloak'; import LoadingSpinner from '@/components/ui/LoadingSpinner'; // Props pour le composant de route protégée interface ProtectedRouteProps { children: ReactNode; requiredRoles?: string[]; requiredPermissions?: string[]; requireAnyRole?: boolean; // Si true, l'utilisateur doit avoir au moins un des rôles requis requireAllRoles?: boolean; // Si true, l'utilisateur doit avoir tous les rôles requis requireAnyPermission?: boolean; // Si true, l'utilisateur doit avoir au moins une des permissions requises requireAllPermissions?: boolean; // Si true, l'utilisateur doit avoir toutes les permissions requises fallbackComponent?: ReactNode; redirectTo?: string; showUnauthorized?: boolean; } // Composant de route protégée const ProtectedRoute: React.FC = ({ children, requiredRoles = [], requiredPermissions = [], requireAnyRole = true, requireAllRoles = false, requireAnyPermission = true, requireAllPermissions = false, fallbackComponent, redirectTo, showUnauthorized = true, }) => { const router = useRouter(); const { isAuthenticated, isLoading, user, hasRole, hasAnyRole, hasPermission, login } = useAuth(); // Vérification de l'authentification et des autorisations useEffect(() => { if (isLoading) return; // Si l'utilisateur n'est pas authentifié if (!isAuthenticated) { if (redirectTo) { router.push(redirectTo); } else { // Rediriger vers la page de connexion login(); } return; } // Si l'utilisateur est authentifié mais n'a pas les rôles requis if (requiredRoles.length > 0 && user) { let hasRequiredRoles = false; if (requireAllRoles) { // L'utilisateur doit avoir tous les rôles requis hasRequiredRoles = requiredRoles.every(role => hasRole(role)); } else if (requireAnyRole) { // L'utilisateur doit avoir au moins un des rôles requis hasRequiredRoles = hasAnyRole(requiredRoles); } if (!hasRequiredRoles) { if (redirectTo) { router.push(redirectTo); } else { router.push(KEYCLOAK_REDIRECTS.FORBIDDEN); } return; } } // Si l'utilisateur est authentifié mais n'a pas les permissions requises if (requiredPermissions.length > 0 && user) { let hasRequiredPermissions = false; if (requireAllPermissions) { // L'utilisateur doit avoir toutes les permissions requises hasRequiredPermissions = requiredPermissions.every(permission => hasPermission(permission)); } else if (requireAnyPermission) { // L'utilisateur doit avoir au moins une des permissions requises hasRequiredPermissions = requiredPermissions.some(permission => hasPermission(permission)); } if (!hasRequiredPermissions) { if (redirectTo) { router.push(redirectTo); } else { router.push(KEYCLOAK_REDIRECTS.FORBIDDEN); } return; } } }, [ isAuthenticated, isLoading, user, requiredRoles, requiredPermissions, requireAnyRole, requireAllRoles, requireAnyPermission, requireAllPermissions, redirectTo, router, hasRole, hasAnyRole, hasPermission, login, ]); // Affichage pendant le chargement if (isLoading) { return (
); } // Si l'utilisateur n'est pas authentifié if (!isAuthenticated) { if (fallbackComponent) { return <>{fallbackComponent}; } return (

Authentification requise

Vous devez être connecté pour accéder à cette page.

); } // Vérification des rôles if (requiredRoles.length > 0 && user) { let hasRequiredRoles = false; if (requireAllRoles) { hasRequiredRoles = requiredRoles.every(role => hasRole(role)); } else if (requireAnyRole) { hasRequiredRoles = hasAnyRole(requiredRoles); } if (!hasRequiredRoles) { if (fallbackComponent) { return <>{fallbackComponent}; } if (showUnauthorized) { return (

Accès non autorisé

Vous n'avez pas les permissions nécessaires pour accéder à cette page.

Rôles requis: {requiredRoles.join(', ')}

Vos rôles: {user.roles.join(', ')}

); } return null; } } // Vérification des permissions if (requiredPermissions.length > 0 && user) { let hasRequiredPermissions = false; if (requireAllPermissions) { hasRequiredPermissions = requiredPermissions.every(permission => hasPermission(permission)); } else if (requireAnyPermission) { hasRequiredPermissions = requiredPermissions.some(permission => hasPermission(permission)); } if (!hasRequiredPermissions) { if (fallbackComponent) { return <>{fallbackComponent}; } if (showUnauthorized) { return (

Permissions insuffisantes

Vous n'avez pas les permissions nécessaires pour accéder à cette page.

Permissions requises: {requiredPermissions.join(', ')}

Vos permissions: {user.permissions.join(', ')}

); } return null; } } // Si toutes les vérifications passent, afficher le contenu return <>{children}; }; export default ProtectedRoute;