diff --git a/src/people/utils/TokenRefresh.tsx b/src/people/utils/TokenRefresh.tsx index a80ca511..cf2a51ea 100644 --- a/src/people/utils/TokenRefresh.tsx +++ b/src/people/utils/TokenRefresh.tsx @@ -3,33 +3,81 @@ import { observer } from 'mobx-react-lite'; import { Button, Modal } from '../../components/common'; import { useStores } from '../../store'; -let timeout; +interface TokenExpiring { + expired: boolean; + message: string; +} function TokenRefresh() { const { main, ui } = useStores(); const [show, setShow] = useState(false); - useEffect(() => { - timeout = setTimeout(async () => { - if ((ui.meInfo, ui.meInfo?.tribe_jwt)) { - const res = await main.refreshJwt(); - if (res && res.jwt) { - ui.setMeInfo({ ...ui.meInfo, tribe_jwt: res.jwt }); - } else { - console.log('Token refresh failed, logging out!', res); - ui.setMeInfo(null); - ui.setSelectedPerson(0); - ui.setSelectingPerson(0); - setShow(true); - // run this to reset state - main.getPeople(); - } + // Function to decode a JWT token + const decodeJWT = (token: any) => { + const parts = token.split('.'); + + if (parts.length !== 3) { + throw new Error('Invalid JWT token'); + } + + const payload = parts[1]; + const decodedPayload = atob(payload); + return JSON.parse(decodedPayload); + }; + + // Function to check if the token has expired or is within an hour of expiring + const isTokenExpiring = (token: any): TokenExpiring => { + try { + const payload = decodeJWT(token); + + if (!payload.exp) { + throw new Error('Token does not contain an expiration time'); + } + + console.log('Payload ===', payload); + + const currentTime = Math.floor(Date.now() / 1000); // Current time in seconds + const expiryTime = payload.exp; // Expiry time in seconds + const oneHour = 3600; // One hour in seconds + + if (expiryTime < currentTime) { + return { expired: true, message: 'Token has already expired' }; + } + + if (expiryTime - currentTime <= oneHour) { + return { expired: true, message: 'Token will expire within an hour' }; } - }, 6000); - return function cleanup() { - clearTimeout(timeout); - }; + return { expired: false, message: 'Token is valid and not expiring soon' }; + } catch (error: any) { + return { expired: true, message: `Error decoding token: ${error.message}` }; + } + }; + + useEffect(() => { + setInterval( + async () => { + if ((ui.meInfo, ui.meInfo?.tribe_jwt)) { + const tokenExpireCheck = isTokenExpiring(ui.meInfo?.tribe_jwt); + console.log('TOken Expired Check', tokenExpireCheck); + if (tokenExpireCheck.expired) { + const res = await main.refreshJwt(); + if (res && res.jwt) { + ui.setMeInfo({ ...ui.meInfo, tribe_jwt: res.jwt }); + } else { + console.log('Token refresh failed, logging out!', res); + ui.setMeInfo(null); + ui.setSelectedPerson(0); + ui.setSelectingPerson(0); + setShow(true); + // run this to reset state + main.getPeople(); + } + } + } + }, + 1000 * 60 * 60 + ); }, [main, ui]); return ( diff --git a/src/people/widgetViews/WorkspaceMission.tsx b/src/people/widgetViews/WorkspaceMission.tsx index a82584aa..b87293a1 100644 --- a/src/people/widgetViews/WorkspaceMission.tsx +++ b/src/people/widgetViews/WorkspaceMission.tsx @@ -309,7 +309,7 @@ const WorkspaceMission = () => { const [modalType, setModalType] = useState('add'); const [featureModal, setFeatureModal] = useState(false); const [features, setFeatures] = useState([]); - const [featuresCount, setFeaturesCount] = useState(0); + const [featuresCount] = useState(0); const [isOpenUserManage, setIsOpenUserManage] = useState(false); const [users, setUsers] = useState([]); const [displayUserRepoOptions, setDisplayUserRepoOptions] = useState>({}); diff --git a/src/store/main.ts b/src/store/main.ts index cb258496..759b7169 100644 --- a/src/store/main.ts +++ b/src/store/main.ts @@ -1492,6 +1492,7 @@ export class MainStore { if (!uiStore.meInfo) return null; const info = uiStore.meInfo; + console.log('Refreshing token ===='); const r: any = await fetch(`${TribesURL}/refresh_jwt`, { method: 'GET', mode: 'cors',