ui-nyla/src/auth/ProtectedRoute.tsx
2025-05-14 12:39:45 +02:00

75 lines
No EOL
2.2 KiB
TypeScript

import { useMsal } from "@azure/msal-react";
import { Navigate, useLocation } from "react-router-dom";
import { ReactNode, useEffect, useState } from "react";
interface ProtectedRouteProps {
children: ReactNode;
redirectPath?: string;
}
export const ProtectedRoute = ({
children,
redirectPath = "/login"
}: ProtectedRouteProps) => {
const { accounts } = useMsal();
const location = useLocation();
const [isChecking, setIsChecking] = useState(true);
const [isAuthenticated, setIsAuthenticated] = useState(false);
useEffect(() => {
const checkAuthentication = async () => {
try {
// Check for MSAL authentication
const hasMsalAccount = accounts.length > 0;
// Check for backend token
const authData = localStorage.getItem('auth_data');
let hasBackendToken = false;
if (authData) {
try {
const parsedAuthData = JSON.parse(authData);
hasBackendToken = !!parsedAuthData.accessToken;
} catch (e) {
console.error('Error parsing auth data:', e);
}
}
// User is authenticated if either method is valid
setIsAuthenticated(hasMsalAccount || hasBackendToken);
if (hasBackendToken) {
console.log('Authenticated with backend token');
} else if (hasMsalAccount) {
console.log('Authenticated with MSAL');
}
} catch (error) {
console.error('Error checking authentication:', error);
setIsAuthenticated(false);
} finally {
setIsChecking(false);
}
};
// Small delay to ensure MSAL is initialized
const timer = setTimeout(() => {
checkAuthentication();
}, 100);
return () => clearTimeout(timer);
}, [accounts]);
// If still checking, show loading
if (isChecking) {
return <div>Checking authentication...</div>;
}
// Check if user is authenticated through either method
if (!isAuthenticated) {
console.log("No valid authentication found, redirecting to login");
return <Navigate to={redirectPath} state={{ from: location }} replace />;
}
console.log("User is authenticated, rendering protected content");
return <>{children}</>;
};