87 lines
2.1 KiB
JavaScript
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;
|