marco.pms.web/src/router/ProtectedRoute.jsx

87 lines
2.1 KiB
JavaScript

import React, { useState, useEffect } from "react";
import { Navigate, Outlet } from "react-router-dom";
import { jwtDecode } from "jwt-decode";
import AuthRepository from "../repositories/AuthRepository";
import { removeSession } from "../utils/authUtils";
const isTokenExpired = (token) => {
if (!token) return true;
try {
const { exp } = jwtDecode(token);
return exp * 1000 < Date.now();
} catch {
return true;
}
};
const validateToken = async () => {
const token =
localStorage.getItem("jwtToken") ||
sessionStorage.getItem("jwtToken");
const refreshTokenStored =
localStorage.getItem("refreshToken") ||
sessionStorage.getItem("refreshToken");
if (!refreshTokenStored){
console.log("no refrh tokem");
removeSession()
return false
};
if (isTokenExpired(token)) {
return await attemptTokenRefresh(refreshTokenStored);
}
return true;
};
const attemptTokenRefresh = async (storedRefreshToken) => {
try {
const currentToken =
localStorage.getItem("jwtToken") ||
sessionStorage.getItem("jwtToken");
const response = await AuthRepository.refreshToken({
token: currentToken,
refreshToken: storedRefreshToken,
});
const { token: newToken, refreshToken: newRefreshToken } = response.data;
if (localStorage.getItem("jwtToken")) {
localStorage.setItem("jwtToken", newToken);
localStorage.setItem("refreshToken", newRefreshToken);
} else {
sessionStorage.setItem("jwtToken", newToken);
sessionStorage.setItem("refreshToken", newRefreshToken);
}
return true;
} catch (error) {
console.error("Token refresh failed:", error);
return false;
}
};
const ProtectedRoute = () => {
const [isAuthenticated, setIsAuthenticated] = useState(null);
useEffect(() => {
const checkAuth = async () => {
const valid = await validateToken();
setIsAuthenticated(valid);
};
checkAuth();
}, []);
if (isAuthenticated === null) {
return <div>Loading...</div>;
}
return isAuthenticated ? <Outlet /> : <Navigate to="/auth/login" replace />;
};
export default ProtectedRoute;