diff --git a/package.json b/package.json index fd966458..48d61678 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "ioredis": "^5.4.1", "joi": "^17.6.0", "jsonwebtoken": "^9.0.2", + "jwt-decode": "^4.0.0", "loglevel": "^1.8.0", "loglevel-plugin-remote": "^0.6.8", "maxun-core": "^0.0.3", @@ -46,7 +47,7 @@ "moment-timezone": "^0.5.45", "node-cron": "^3.0.3", "pg": "^8.13.0", - "playwright": "^1.20.1", + "playwright": "^1.48.2", "playwright-extra": "^4.3.6", "posthog-node": "^4.2.1", "prismjs": "^1.28.0", diff --git a/src/context/auth.tsx b/src/context/auth.tsx index 1b99686a..10b1039c 100644 --- a/src/context/auth.tsx +++ b/src/context/auth.tsx @@ -1,6 +1,7 @@ import { useReducer, createContext, useEffect } from 'react'; import axios from 'axios'; import { useNavigate } from 'react-router-dom'; +import { jwtDecode } from "jwt-decode"; import { apiUrl } from "../apiConfig"; interface AuthProviderProps { @@ -50,10 +51,33 @@ const AuthProvider = ({ children }: AuthProviderProps) => { const navigate = useNavigate(); axios.defaults.withCredentials = true; + // Function to handle logout + const logoutUser = () => { + dispatch({ type: 'LOGOUT' }); + window.localStorage.removeItem('user'); + navigate('/login'); + }; + + // Function to check token expiration + const checkTokenExpiration = (token: string) => { + const decodedToken: any = jwtDecode(token); + const currentTime = Date.now(); + const tokenExpiryTime = decodedToken.exp * 1000; // Convert to milliseconds + const timeUntilExpiry = tokenExpiryTime - currentTime; + + if (timeUntilExpiry > 0) { + setTimeout(logoutUser, timeUntilExpiry); // Auto-logout when token expires + } else { + logoutUser(); // Immediately logout if token is expired + } + }; + useEffect(() => { const storedUser = window.localStorage.getItem('user'); if (storedUser) { - dispatch({ type: 'LOGIN', payload: JSON.parse(storedUser) }); + const userData = JSON.parse(storedUser); + dispatch({ type: 'LOGIN', payload: userData }); + checkTokenExpiration(userData.token); // Check if token is still valid } }, []); @@ -69,9 +93,7 @@ const AuthProvider = ({ children }: AuthProviderProps) => { .get(`${apiUrl}/auth/logout`) .then(() => { console.log('/401 error > logout'); - dispatch({ type: 'LOGOUT' }); - window.localStorage.removeItem('user'); - navigate('/login'); + logoutUser(); }) .catch((err) => { console.error('AXIOS INTERCEPTORS ERROR:', err);