auth consolidation

This commit is contained in:
2025-09-18 08:10:20 +02:00
parent 8ef0f234e4
commit 901e60c21b
7 changed files with 26 additions and 14 deletions

View File

@@ -4,7 +4,7 @@ import './globals.css'
import { ThemeProvider } from '@/components/providers/theme-provider' import { ThemeProvider } from '@/components/providers/theme-provider'
import { Toaster } from '@/components/ui/toaster' import { Toaster } from '@/components/ui/toaster'
import { Toaster as HotToaster } from 'react-hot-toast' 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 { ModulesProvider } from '@/contexts/ModulesContext'
import { PluginProvider } from '@/contexts/PluginContext' import { PluginProvider } from '@/contexts/PluginContext'
import { ToastProvider } from '@/contexts/ToastContext' import { ToastProvider } from '@/contexts/ToastContext'

View File

@@ -1,6 +1,6 @@
"use client" "use client"
import { useAuth } from "@/contexts/AuthContext" import { useAuth } from "@/components/providers/auth-provider"
import { useRouter } from "next/navigation" import { useRouter } from "next/navigation"
import { useEffect } from "react" import { useEffect } from "react"

View File

@@ -2,7 +2,7 @@
import { useEffect, useState } from "react" import { useEffect, useState } from "react"
import { useRouter } from "next/navigation" import { useRouter } from "next/navigation"
import { useAuth } from "@/contexts/AuthContext" import { useAuth } from "@/components/providers/auth-provider"
interface ProtectedRouteProps { interface ProtectedRouteProps {
children: React.ReactNode children: React.ReactNode

View File

@@ -8,7 +8,7 @@ import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge" import { Badge } from "@/components/ui/badge"
import { ThemeToggle } from "@/components/ui/theme-toggle" import { ThemeToggle } from "@/components/ui/theme-toggle"
import { UserMenu } from "@/components/ui/user-menu" 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 { useModules } from "@/contexts/ModulesContext"
import { usePlugin } from "@/contexts/PluginContext" import { usePlugin } from "@/contexts/PluginContext"
import { import {

View File

@@ -6,7 +6,7 @@ import { Badge } from "@/components/ui/badge"
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog" import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
import { Label } from "@/components/ui/label" import { Label } from "@/components/ui/label"
import { Input } from "@/components/ui/input" 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 { useToast } from "@/hooks/use-toast"
import { import {
DropdownMenu, DropdownMenu,

View File

@@ -114,9 +114,17 @@ export function AuthProvider({ children }: { children: ReactNode }) {
if (typeof window !== 'undefined') { if (typeof window !== 'undefined') {
localStorage.setItem('user', JSON.stringify(user)) 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) { } catch (error) {
console.error('Failed to fetch user info:', 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() const data = await response.json()
// Store tokens in TokenManager // Store tokens in TokenManager
tokenManager.setTokens( tokenManager.setTokens(data.access_token, data.refresh_token)
data.access_token,
data.refresh_token,
data.expires_in
)
// Fetch user info // Fetch user info
await fetchUserInfo() await fetchUserInfo()
@@ -161,8 +165,9 @@ export function AuthProvider({ children }: { children: ReactNode }) {
} }
const logout = () => { const logout = () => {
tokenManager.logout() tokenManager.clearTokens()
// Token manager will emit 'logout' event which we handle above setUser(null)
router.push('/login')
} }
return ( return (

View File

@@ -69,8 +69,15 @@ export function ModulesProvider({ children }: { children: ReactNode }) {
setLastUpdated(new Date()) setLastUpdated(new Date())
} catch (err) { } catch (err) {
// 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) // Only set error if we're authenticated (to avoid noise on auth pages)
if (tokenManager.isAuthenticated()) {
setError(err instanceof Error ? err.message : "Failed to load modules") setError(err instanceof Error ? err.message : "Failed to load modules")
} }
} finally { } finally {