From 26cd75ae814166380b71ea679d6362f2ee7339cb Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sun, 15 Jun 2025 20:32:43 +0000 Subject: [PATCH] Fix: Handle invalid session on subscription page The subscription page now correctly handles invalid sessions, even after logging out and back in. --- src/components/auth/ProtectedRoute.tsx | 66 ++++++++++---------------- src/components/layout/Header.tsx | 61 ++++++++++++------------ 2 files changed, 56 insertions(+), 71 deletions(-) diff --git a/src/components/auth/ProtectedRoute.tsx b/src/components/auth/ProtectedRoute.tsx index d27815c..2efbc52 100644 --- a/src/components/auth/ProtectedRoute.tsx +++ b/src/components/auth/ProtectedRoute.tsx @@ -1,59 +1,45 @@ import { ReactNode, useEffect, useState } from 'react'; import { Navigate, useLocation } from 'react-router-dom'; -import { useToast } from "@/components/ui/use-toast"; import LoadingState from '../whatsapp/LoadingState'; import { authStore } from '@/stores/authStore'; +import { supabase } from '@/integrations/supabase/client'; +import { Session } from '@supabase/supabase-js'; interface ProtectedRouteProps { children: ReactNode; } const ProtectedRoute = ({ children }: ProtectedRouteProps) => { + const [session, setSession] = useState(null); const [isLoading, setIsLoading] = useState(true); - const { toast } = useToast(); const location = useLocation(); const setLoggedIn = authStore((state) => state.setLoggedIn); + const setUser = authStore((state) => state.setUser); - // Use a single state variable to track authentication status - const [authStatus, setAuthStatus] = useState<'loading' | 'authenticated' | 'unauthenticated'>('loading'); - useEffect(() => { - const checkAuthentication = () => { - try { - // Check if we have stored authentication status - const storedAuth = localStorage.getItem('autenticado') === 'true'; - const userId = localStorage.getItem('userId'); - - if (storedAuth && userId) { - console.log('Usando autenticação armazenada: autenticado'); - setAuthStatus('authenticated'); - setLoggedIn(true); - } else { - console.log('Nenhuma sessão encontrada, redirecionando para login'); - setAuthStatus('unauthenticated'); - setLoggedIn(false); - - // Only show toast once when transitioning to unauthenticated - toast({ - title: "Autenticação necessária", - description: "Por favor, faça login para acessar esta página" - }); - } - } catch (error) { - console.error('Erro ao verificar autenticação:', error); - setAuthStatus('unauthenticated'); - setLoggedIn(false); - } finally { + // Checa a sessão ao carregar o componente + supabase.auth.getSession().then(({ data: { session } }) => { + setSession(session); + setIsLoading(false); + }); + + // Escuta por mudanças no estado de autenticação (login/logout) + const { data: { subscription } } = supabase.auth.onAuthStateChange( + (_event, session) => { + setSession(session); + setLoggedIn(!!session); + setUser(session?.user ? { id: session.user.id } : null); setIsLoading(false); } - }; - - checkAuthentication(); - }, [toast, setLoggedIn]); // Only check once on mount, with stable dependencies + ); - // Se estiver carregando, mostrar estado de carregamento - if (isLoading || authStatus === 'loading') { + return () => { + subscription.unsubscribe(); + }; + }, [setLoggedIn, setUser]); + + if (isLoading) { return (
@@ -61,12 +47,12 @@ const ProtectedRoute = ({ children }: ProtectedRouteProps) => { ); } - // Se não estiver autenticado, redirecionar para a página de login - use replace para evitar histórico - if (authStatus === 'unauthenticated') { + if (!session) { + // Redireciona para a página de login se não houver sessão return ; } - // Se estiver autenticado, renderizar o conteúdo protegido + // Renderiza o conteúdo protegido se houver sessão return <>{children}; }; diff --git a/src/components/layout/Header.tsx b/src/components/layout/Header.tsx index e7d5a2a..488f2fd 100644 --- a/src/components/layout/Header.tsx +++ b/src/components/layout/Header.tsx @@ -12,48 +12,47 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; +import { supabase } from '@/integrations/supabase/client'; const Header = () => { const navigate = useNavigate(); const { toast } = useToast(); - const [userName, setUserName] = useState(() => { - // Obter o nome do usuário do localStorage ou usar seu email como fallback - return localStorage.getItem('userName') || localStorage.getItem('userEmail') || 'Usuário'; - }); + const [userName, setUserName] = useState('Usuário'); - // Atualize o nome se mudar no localStorage useEffect(() => { - const handleStorageChange = () => { - setUserName(localStorage.getItem('userName') || localStorage.getItem('userEmail') || 'Usuário'); + const fetchUser = async () => { + const { data: { user } } = await supabase.auth.getUser(); + if (user) { + setUserName(user.email || 'Usuário'); + } }; - window.addEventListener('storage', handleStorageChange); + fetchUser(); - return () => { - window.removeEventListener('storage', handleStorageChange); - }; - }, []); - - const handleLogout = () => { - // Limpar informações de sessão - localStorage.removeItem('autenticado'); - localStorage.removeItem('userId'); - localStorage.removeItem('userName'); - localStorage.removeItem('userEmail'); - - // Dispatch a storage event to notify other components about logout - window.dispatchEvent(new StorageEvent('storage', { - key: 'autenticado', - newValue: null - })); - - toast({ - title: "Logout realizado", - description: "Você foi desconectado com sucesso" + const { data: { subscription } } = supabase.auth.onAuthStateChange((_event, session) => { + setUserName(session?.user?.email || 'Usuário'); }); - // Redirecionar para a página de login - navigate('/auth'); + return () => subscription.unsubscribe(); + }, []); + + const handleLogout = async () => { + const { error } = await supabase.auth.signOut(); + + if (error) { + console.error('Error logging out:', error); + toast({ + title: "Erro no logout", + description: "Não foi possível desconectar. Tente novamente.", + variant: 'destructive' + }); + } else { + toast({ + title: "Logout realizado", + description: "Você foi desconectado com sucesso" + }); + navigate('/auth', { replace: true }); + } }; return (