Spaces:
Running
Running
File size: 3,065 Bytes
df1fcb2 61aec16 92dff23 ffcd038 d212ba6 f6d96e2 61aec16 2471e68 df1fcb2 92dff23 df1fcb2 5e07ced df1fcb2 d97497a 5e07ced d97497a 5e07ced d97497a df1fcb2 ffcd038 df1fcb2 5e07ced ffcd038 df1fcb2 9a238c2 df1fcb2 5e07ced df1fcb2 d212ba6 df1fcb2 5e07ced 92dff23 2471e68 92dff23 f6d96e2 92dff23 2471e68 61aec16 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
import { useEffect, useState } from 'react';
import { BrowserRouter, Routes, Route, Navigate, useNavigate, useLocation } from 'react-router-dom';
import { MainApp } from './pages/MainApp';
import { Login } from './pages/Login';
import { Settings } from './pages/Settings';
import { isAuthenticated, getCurrentUser, setAuthTokenFromHash, ensureDemoToken, isDemoSession } from './services/auth';
import { AuthLoadingSkeleton } from './components/AuthLoadingSkeleton';
import { Toaster } from './components/ui/toaster';
import './App.css';
// Protected route wrapper with auth check
function ProtectedRoute({ children }: { children: React.ReactNode }) {
const navigate = useNavigate();
const location = useLocation();
const [isChecking, setIsChecking] = useState(true);
const [hasToken, setHasToken] = useState<boolean>(isAuthenticated());
// T110: Check if user is authenticated on mount
useEffect(() => {
const checkAuth = async () => {
// Check for OAuth callback token in URL hash
const tokenExtracted = setAuthTokenFromHash();
if (tokenExtracted) {
console.log('OAuth token extracted from URL hash');
setHasToken(true);
setIsChecking(false);
return;
}
if (!isAuthenticated()) {
const demoReady = await ensureDemoToken();
if (!demoReady) {
setHasToken(false);
setIsChecking(false);
return;
}
}
setHasToken(true);
if (isDemoSession()) {
setIsChecking(false);
return;
}
const token = localStorage.getItem('auth_token');
// Skip validation for local dev token
if (token === 'local-dev-token') {
setIsChecking(false);
return;
}
try {
// Verify the token is valid by calling getCurrentUser
await getCurrentUser();
setIsChecking(false);
} catch {
// Token is invalid (401), redirect to login
console.warn('Authentication failed, redirecting to login');
localStorage.removeItem('auth_token');
setHasToken(false);
setIsChecking(false);
if (location.pathname !== '/login') {
navigate('/login', { replace: true, state: { from: location } });
}
}
};
checkAuth();
}, [navigate, location]);
if (isChecking) {
return <AuthLoadingSkeleton />;
}
if (!hasToken) {
return <Navigate to="/login" replace />;
}
return <>{children}</>;
}
function App() {
return (
<>
<BrowserRouter>
<Routes>
<Route path="/login" element={<Login />} />
<Route
path="/"
element={
<ProtectedRoute>
<MainApp />
</ProtectedRoute>
}
/>
<Route
path="/settings"
element={
<ProtectedRoute>
<Settings />
</ProtectedRoute>
}
/>
</Routes>
</BrowserRouter>
<Toaster />
</>
);
}
export default App;
|