import React, { useState, useEffect } from 'react'; import { Routes, Route, Navigate, useLocation, useNavigate } from 'react-router-dom'; import Login from './pages/Login'; import Register from './pages/Register'; import Chat from './pages/Chat'; import { usePlatform } from './platform'; import { useSearch } from './contexts/SearchContext'; const THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1000; function AuthGuard({ children }) { const [authState, setAuthState] = useState('loading'); // 'loading' | 'authenticated' | 'unauthenticated' const location = useLocation(); const navigate = useNavigate(); const { session, settings } = usePlatform(); const searchCtx = useSearch(); useEffect(() => { let cancelled = false; async function restoreSession() { // Already have keys in sessionStorage — current session is active if (sessionStorage.getItem('privateKey') && sessionStorage.getItem('signingKey')) { searchCtx?.initialize(); if (!cancelled) setAuthState('authenticated'); return; } // Try restoring from safeStorage if (session) { try { const savedSession = await session.load(); if (savedSession && savedSession.savedAt && (Date.now() - savedSession.savedAt) < THIRTY_DAYS_MS) { // Restore to localStorage + sessionStorage localStorage.setItem('userId', savedSession.userId); localStorage.setItem('username', savedSession.username); if (savedSession.publicKey) localStorage.setItem('publicKey', savedSession.publicKey); sessionStorage.setItem('signingKey', savedSession.signingKey); sessionStorage.setItem('privateKey', savedSession.privateKey); if (savedSession.searchDbKey) sessionStorage.setItem('searchDbKey', savedSession.searchDbKey); searchCtx?.initialize(); // Restore user preferences from file-based backup into localStorage if (settings) { try { const savedPrefs = await settings.get(`userPrefs_${savedSession.userId}`); if (savedPrefs && typeof savedPrefs === 'object') { localStorage.setItem(`userPrefs_${savedSession.userId}`, JSON.stringify(savedPrefs)); } } catch {} } if (!cancelled) setAuthState('authenticated'); return; } // Expired — clear stale session if (savedSession && savedSession.savedAt) { await session.clear(); } } catch (err) { console.error('Session restore failed:', err); } } if (!cancelled) setAuthState('unauthenticated'); } restoreSession(); return () => { cancelled = true; }; }, []); useEffect(() => { if (authState === 'loading') return; const isAuthPage = location.pathname === '/' || location.pathname === '/register'; const hasSession = sessionStorage.getItem('privateKey') && sessionStorage.getItem('signingKey'); if (hasSession && isAuthPage) { navigate('/chat', { replace: true }); } else if (!hasSession && !isAuthPage) { navigate('/', { replace: true }); } }, [authState, location.pathname]); if (authState === 'loading') { return (
Loading...
); } return children; } function App() { return ( } /> } /> } /> ); } export default App;