Files
Hotel-Booking/Frontend/src/features/auth/components/AdminRoute.tsx
Iliyan Angelov 62c1fe5951 updates
2025-12-01 06:50:10 +02:00

73 lines
2.1 KiB
TypeScript

import React, { useEffect } from 'react';
import { Navigate } from 'react-router-dom';
import useAuthStore from '../../../store/useAuthStore';
import { useAuthModal } from '../contexts/AuthModalContext';
interface AdminRouteProps {
children: React.ReactNode;
}
/**
* SECURITY NOTE: This component performs CLIENT-SIDE authorization checks only.
* These checks are for UX purposes (showing/hiding UI elements).
*
* ALL authorization must be enforced server-side. Client-side checks can be bypassed
* by modifying localStorage or browser DevTools. The backend API must validate
* user roles and permissions for every request.
*/
const AdminRoute: React.FC<AdminRouteProps> = ({
children
}) => {
const { isAuthenticated, userInfo, isLoading } = useAuthStore();
const { openModal } = useAuthModal();
// SECURITY: Client-side role check - backend must also validate
useEffect(() => {
if (!isLoading && !isAuthenticated) {
openModal('login');
}
}, [isLoading, isAuthenticated, openModal]);
if (isLoading) {
return (
<div
className="min-h-screen flex items-center
justify-center bg-gray-50"
>
<div className="text-center">
<div
className="animate-spin rounded-full h-12 w-12
border-b-2 border-indigo-600 mx-auto"
/>
<p className="mt-4 text-gray-600">
Authenticating...
</p>
</div>
</div>
);
}
if (!isAuthenticated) {
return null; // Modal will be shown by AuthModalManager
}
// SECURITY: Client-side role check - MUST be validated server-side
// This check can be bypassed by modifying localStorage
const isAdmin = userInfo?.role === 'admin';
if (!isAdmin) {
// Redirect to appropriate dashboard based on role
if (userInfo?.role === 'staff') {
return <Navigate to="/staff/dashboard" replace />;
} else if (userInfo?.role === 'accountant') {
return <Navigate to="/accountant/dashboard" replace />;
}
return <Navigate to="/" replace />;
}
return <>{children}</>;
};
export default AdminRoute;