elmeg-demo/frontend/contexts/auth-context.tsx
fullsizemalt cddd3e2389
Some checks are pending
Deploy Elmeg / deploy (push) Waiting to run
fix: Silent handling of expired auth tokens (no console error)
2025-12-23 15:40:03 -08:00

90 lines
2.4 KiB
TypeScript

"use client"
import React, { createContext, useContext, useState, useEffect, useCallback } from "react"
import { getApiUrl } from "@/lib/api-config"
interface User {
id: number
email: string
is_active: boolean
is_superuser: boolean
role: string
}
interface AuthContextType {
user: User | null
token: string | null
loading: boolean
login: (token: string) => Promise<void>
logout: () => void
}
const AuthContext = createContext<AuthContextType>({
user: null,
token: null,
loading: true,
login: async () => { },
logout: () => { },
})
export function AuthProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = useState<User | null>(null)
const [token, setToken] = useState<string | null>(null)
const [loading, setLoading] = useState(true)
const fetchUser = useCallback(async (authToken: string): Promise<boolean> => {
const res = await fetch(`${getApiUrl()}/auth/users/me`, {
headers: {
Authorization: `Bearer ${authToken}`
}
})
if (res.ok) {
const userData = await res.json()
setUser(userData)
return true
} else if (res.status === 401 || res.status === 403) {
// Token expired or invalid - handle silently
return false
} else {
// Unexpected error
console.warn("Auth check failed with status:", res.status)
return false
}
}, [])
useEffect(() => {
const initAuth = async () => {
const storedToken = localStorage.getItem("token")
if (storedToken) {
setToken(storedToken)
const success = await fetchUser(storedToken)
if (!success) {
localStorage.removeItem("token")
setToken(null)
}
}
setLoading(false)
}
initAuth()
}, [fetchUser])
const login = async (newToken: string) => {
localStorage.setItem("token", newToken)
setToken(newToken)
await fetchUser(newToken)
}
const logout = () => {
localStorage.removeItem("token")
setToken(null)
setUser(null)
}
return (
<AuthContext.Provider value={{ user, token, loading, login, logout }}>
{children}
</AuthContext.Provider>
)
}
export const useAuth = () => useContext(AuthContext)