Files
ecommerce-platform/app/src/context/UserContext.tsx
T
davide fcfa0707a1 fix(security): replace localStorage user state with server-side session
- Add GET /api/auth/me endpoint returning current user from httpOnly cookie
- Add UserContext + useUser() hook that fetches from /api/auth/me on mount
- Wrap root layout with UserProvider
- Remove all localStorage.setItem/getItem('user') calls from login, register,
  navbar, account pages, change-password, and checkout
- mustChangePassword redirect now reads from refreshed server session
2026-05-19 10:10:24 +02:00

61 lines
1.4 KiB
TypeScript

'use client'
import { createContext, useContext, useState, useEffect, useCallback } from 'react'
interface User {
id: string
email: string
name: string
role: string
mustChangePassword: boolean
}
interface UserContextValue {
user: User | null
isLoading: boolean
setUser: (user: User | null) => void
refreshUser: () => Promise<User | null>
}
const UserContext = createContext<UserContextValue | null>(null)
export function UserProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = useState<User | null>(null)
const [isLoading, setIsLoading] = useState(true)
const refreshUser = useCallback(async (): Promise<User | null> => {
try {
const res = await fetch('/api/auth/me')
if (res.ok) {
const data = await res.json()
setUser(data.user)
return data.user
} else {
setUser(null)
return null
}
} catch {
setUser(null)
return null
} finally {
setIsLoading(false)
}
}, [])
useEffect(() => {
refreshUser()
}, [refreshUser])
return (
<UserContext.Provider value={{ user, isLoading, setUser, refreshUser }}>
{children}
</UserContext.Provider>
)
}
export function useUser(): UserContextValue {
const ctx = useContext(UserContext)
if (!ctx) throw new Error('useUser must be used within a UserProvider')
return ctx
}