diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index f6b4fa1..f2cb9cd 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -4,7 +4,7 @@ import './globals.css' import { ThemeProvider } from '@/components/providers/theme-provider' import { Toaster } from '@/components/ui/toaster' import { Toaster as HotToaster } from 'react-hot-toast' -import { AuthProvider } from '@/contexts/AuthContext' +import { AuthProvider } from '@/components/providers/auth-provider' import { ModulesProvider } from '@/contexts/ModulesContext' import { PluginProvider } from '@/contexts/PluginContext' import { ToastProvider } from '@/contexts/ToastContext' diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index 7d8e1ee..770e950 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -1,6 +1,6 @@ "use client" -import { useAuth } from "@/contexts/AuthContext" +import { useAuth } from "@/components/providers/auth-provider" import { useRouter } from "next/navigation" import { useEffect } from "react" diff --git a/frontend/src/components/auth/ProtectedRoute.tsx b/frontend/src/components/auth/ProtectedRoute.tsx index b30b51b..bdfb4f5 100644 --- a/frontend/src/components/auth/ProtectedRoute.tsx +++ b/frontend/src/components/auth/ProtectedRoute.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from "react" import { useRouter } from "next/navigation" -import { useAuth } from "@/contexts/AuthContext" +import { useAuth } from "@/components/providers/auth-provider" interface ProtectedRouteProps { children: React.ReactNode diff --git a/frontend/src/components/ui/navigation.tsx b/frontend/src/components/ui/navigation.tsx index 3743a69..bfeea94 100644 --- a/frontend/src/components/ui/navigation.tsx +++ b/frontend/src/components/ui/navigation.tsx @@ -8,7 +8,7 @@ import { Button } from "@/components/ui/button" import { Badge } from "@/components/ui/badge" import { ThemeToggle } from "@/components/ui/theme-toggle" import { UserMenu } from "@/components/ui/user-menu" -import { useAuth } from "@/contexts/AuthContext" +import { useAuth } from "@/components/providers/auth-provider" import { useModules } from "@/contexts/ModulesContext" import { usePlugin } from "@/contexts/PluginContext" import { diff --git a/frontend/src/components/ui/user-menu.tsx b/frontend/src/components/ui/user-menu.tsx index 78e070d..2a198f1 100644 --- a/frontend/src/components/ui/user-menu.tsx +++ b/frontend/src/components/ui/user-menu.tsx @@ -6,7 +6,7 @@ import { Badge } from "@/components/ui/badge" import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog" import { Label } from "@/components/ui/label" import { Input } from "@/components/ui/input" -import { useAuth } from "@/contexts/AuthContext" +import { useAuth } from "@/components/providers/auth-provider" import { useToast } from "@/hooks/use-toast" import { DropdownMenu, diff --git a/frontend/src/contexts/AuthContext.tsx b/frontend/src/contexts/AuthContext.tsx index 33030d8..20f5c48 100644 --- a/frontend/src/contexts/AuthContext.tsx +++ b/frontend/src/contexts/AuthContext.tsx @@ -114,9 +114,17 @@ export function AuthProvider({ children }: { children: ReactNode }) { if (typeof window !== 'undefined') { localStorage.setItem('user', JSON.stringify(user)) } + } else if (response.status === 401) { + // Token is invalid or expired, clear it + console.log('Token invalid, clearing tokens') + tokenManager.clearTokens() + setUser(null) } } catch (error) { console.error('Failed to fetch user info:', error) + // If there's an error, clear tokens to be safe + tokenManager.clearTokens() + setUser(null) } } @@ -140,11 +148,7 @@ export function AuthProvider({ children }: { children: ReactNode }) { const data = await response.json() // Store tokens in TokenManager - tokenManager.setTokens( - data.access_token, - data.refresh_token, - data.expires_in - ) + tokenManager.setTokens(data.access_token, data.refresh_token) // Fetch user info await fetchUserInfo() @@ -161,8 +165,9 @@ export function AuthProvider({ children }: { children: ReactNode }) { } const logout = () => { - tokenManager.logout() - // Token manager will emit 'logout' event which we handle above + tokenManager.clearTokens() + setUser(null) + router.push('/login') } return ( diff --git a/frontend/src/contexts/ModulesContext.tsx b/frontend/src/contexts/ModulesContext.tsx index 1069e96..216a57b 100644 --- a/frontend/src/contexts/ModulesContext.tsx +++ b/frontend/src/contexts/ModulesContext.tsx @@ -69,8 +69,15 @@ export function ModulesProvider({ children }: { children: ReactNode }) { setLastUpdated(new Date()) } catch (err) { - // Only set error if we're authenticated (to avoid noise on auth pages) - if (tokenManager.isAuthenticated()) { + // If we get a 401 error, clear the tokens + if (err && typeof err === 'object' && 'response' in err && (err.response as any)?.status === 401) { + tokenManager.clearTokens() + setModules([]) + setEnabledModules(new Set()) + setError(null) + setLastUpdated(null) + } else if (tokenManager.isAuthenticated()) { + // Only set error if we're authenticated (to avoid noise on auth pages) setError(err instanceof Error ? err.message : "Failed to load modules") } } finally {