diff --git a/App.tsx b/App.tsx index 5d75010..5f74772 100644 --- a/App.tsx +++ b/App.tsx @@ -35,15 +35,27 @@ const AuthGuard: React.FC<{ children: React.ReactNode, roles?: string[] }> = ({ try { const fetchedUser = await getUserById(storedUserId); - if (fetchedUser && fetchedUser.status === 'active') { - setUser(fetchedUser); + if (fetchedUser) { + if (fetchedUser.status === 'active') { + setUser(fetchedUser); + } else { + // User explicitly marked inactive or deleted + logout(); + setUser(null); + } } else { + // If fetchedUser is undefined but didn't throw, it usually means a 401/403/404 (invalid token or user missing). + // However, to be safe against random failures, we should only clear if we are sure it's invalid. + // For now, if the token is completely rejected, we log out. logout(); setUser(null); } } catch (err) { - console.error("Auth check failed", err); - logout(); + console.error("Auth check failed (network/server error):", err); + // DO NOT logout() here. If the server is offline or restarting, + // we shouldn't wipe the user's local storage tokens. + // We just leave the user as null, which will redirect them to login, + // but their tokens remain so they can auto-login when the server is back. setUser(null); } finally { setLoading(false); @@ -53,7 +65,7 @@ const AuthGuard: React.FC<{ children: React.ReactNode, roles?: string[] }> = ({ }, [location.pathname]); if (loading) { - return
Carregando...
; + return
Carregando...
; } if (!user) { diff --git a/pages/Login.tsx b/pages/Login.tsx index c9ea423..0aa9059 100644 --- a/pages/Login.tsx +++ b/pages/Login.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { useNavigate, Link } from 'react-router-dom'; import { Hexagon, Lock, Mail, ArrowRight, Loader2, Eye, EyeOff, AlertCircle } from 'lucide-react'; import { login, logout } from '../services/dataService'; @@ -12,6 +12,16 @@ export const Login: React.FC = () => { const [error, setError] = useState(''); const [emailError, setEmailError] = useState(''); + // Auto-redirect if already logged in + useEffect(() => { + const token = localStorage.getItem('ctms_token'); + const userId = localStorage.getItem('ctms_user_id'); + if (token && userId && token !== 'undefined' && token !== 'null') { + // Opt to send them to root, AuthGuard will handle role-based routing + navigate('/'); + } + }, [navigate]); + const validateEmail = (val: string) => { setEmail(val); if (!val) { diff --git a/services/dataService.ts b/services/dataService.ts index 74983e5..793ae7f 100644 --- a/services/dataService.ts +++ b/services/dataService.ts @@ -280,16 +280,20 @@ export const getUserById = async (id: string): Promise => { const response = await fetch(`${API_URL}/users/${id}`, { headers: getHeaders() }); - if (!response.ok) return undefined; - + if (!response.ok) { + if (response.status === 401 || response.status === 403 || response.status === 404) { + return undefined; // Invalid user or token + } + throw new Error(`Server error: ${response.status}`); + } + const contentType = response.headers.get("content-type"); if (contentType && contentType.indexOf("application/json") !== -1) { return await response.json(); } - return undefined; } catch (error) { console.error("API Error (getUserById):", error); - return undefined; + throw error; // Rethrow so AuthGuard catches it and doesn't wipe tokens } };