import React, { createContext, useContext, useState, useEffect } from 'react'; import Cookies from 'js-cookie'; import { checkSession } from '@/functions/auth/checkSession'; import { saveSession } from '@/functions/auth/saveSession'; import UserProps from '@/interfaces/User'; import { decrypt } from '@/functions/system/decrypt'; interface AuthContextProps { user: UserProps | null; status: 'loading' | 'authenticated' | 'unauthenticated'; refreshSession: () => Promise; } const AuthContext = createContext(null!); let lastExecutionTime = 0; export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { const [user, setUser] = useState(null); const [status, setStatus] = useState<'loading' | 'authenticated' | 'unauthenticated'>('loading'); const refreshSession = async () => { await checkSession({ user: { set: setUser, value: user }, status: { set: setStatus, value: status } }); } const handleFocus = async () => { const currentTime = Date.now(); const timeSinceLastExecution = currentTime - lastExecutionTime; // If less than 1 minute has passed since the last execution, skip the function if (timeSinceLastExecution < 60000) { return; } else { lastExecutionTime = currentTime; await refreshSession(); } }; async function checkUser() { try { const cookieSession = Cookies.get('ultima-auth-session'); const storageSessionUser = localStorage.getItem('ultima-auth-jwt-session'); if (storageSessionUser && cookieSession) { try { const parsedSession = JSON.parse(cookieSession); const jsonSessionUser: any = await decrypt(parsedSession.userId, storageSessionUser); if (jsonSessionUser) { setUser({ ...jsonSessionUser }); setStatus('authenticated'); } } catch (error) { console.error(error); // localStorage.removeItem('ultima-auth-jwt-session'); } } return; } catch (error) { console.error(error); setTimeout(checkUser, 500); }; }; useEffect(() => { // Handle token from redirect (mobile) const handleRedirectCallback = () => { const urlParams = new URLSearchParams(window.location.search); const tokens = urlParams.get('tokens'); const authError = urlParams.get('authError'); if (authError) { new Notification('Authentication Error', { body: 'There was an error authenticating your account. Please try again later.' }); } else if (tokens) { const parsedTokens = JSON.parse(decodeURIComponent(tokens)); saveSession(parsedTokens); setStatus('authenticated'); } }; handleRedirectCallback(); checkUser(); handleFocus(); window.addEventListener('visibilitychange', handleFocus); window.addEventListener('ultimaCheckSession', refreshSession); return () => { window.removeEventListener('visibilitychange', handleFocus); window.removeEventListener('ultimaCheckSession', refreshSession); }; }, []); return ( {children} ); }; export const useSession = () => { const context: AuthContextProps = useContext(AuthContext); if (context === null) { throw new Error('useSession must be used within an AuthProvider'); } return context; };