94 lines
2.8 KiB
JavaScript
94 lines
2.8 KiB
JavaScript
import { createContext, useContext, useMemo, useState, useEffect } from 'react'
|
|
import { login as apiLogin } from '../api/client'
|
|
|
|
const AuthContext = createContext(null)
|
|
|
|
export function AuthProvider({ children }) {
|
|
const [token, setToken] = useState(() => localStorage.getItem('speedbb_token'))
|
|
const [email, setEmail] = useState(() => localStorage.getItem('speedbb_email'))
|
|
const [userId, setUserId] = useState(() => {
|
|
const stored = localStorage.getItem('speedbb_user_id')
|
|
if (stored) return stored
|
|
return null
|
|
})
|
|
const [roles, setRoles] = useState(() => {
|
|
const stored = localStorage.getItem('speedbb_roles')
|
|
if (stored) return JSON.parse(stored)
|
|
return []
|
|
})
|
|
|
|
const effectiveRoles = token ? roles : []
|
|
const effectiveUserId = token ? userId : null
|
|
|
|
const value = useMemo(
|
|
() => ({
|
|
token,
|
|
email,
|
|
userId: effectiveUserId,
|
|
roles: effectiveRoles,
|
|
isAdmin: effectiveRoles.includes('ROLE_ADMIN'),
|
|
async login(emailInput, password) {
|
|
const data = await apiLogin(emailInput, password)
|
|
localStorage.setItem('speedbb_token', data.token)
|
|
localStorage.setItem('speedbb_email', data.email || emailInput)
|
|
if (data.user_id) {
|
|
localStorage.setItem('speedbb_user_id', String(data.user_id))
|
|
setUserId(String(data.user_id))
|
|
}
|
|
if (Array.isArray(data.roles)) {
|
|
localStorage.setItem('speedbb_roles', JSON.stringify(data.roles))
|
|
setRoles(data.roles)
|
|
} else {
|
|
localStorage.removeItem('speedbb_roles')
|
|
setRoles([])
|
|
}
|
|
setToken(data.token)
|
|
setEmail(data.email || emailInput)
|
|
},
|
|
logout() {
|
|
localStorage.removeItem('speedbb_token')
|
|
localStorage.removeItem('speedbb_email')
|
|
localStorage.removeItem('speedbb_user_id')
|
|
localStorage.removeItem('speedbb_roles')
|
|
setToken(null)
|
|
setEmail(null)
|
|
setUserId(null)
|
|
setRoles([])
|
|
},
|
|
}),
|
|
[token, email, effectiveUserId, effectiveRoles]
|
|
)
|
|
|
|
useEffect(() => {
|
|
const handleUnauthorized = () => {
|
|
setToken(null)
|
|
setEmail(null)
|
|
setUserId(null)
|
|
setRoles([])
|
|
}
|
|
|
|
window.addEventListener('speedbb-unauthorized', handleUnauthorized)
|
|
return () => window.removeEventListener('speedbb-unauthorized', handleUnauthorized)
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
console.log('speedBB auth', {
|
|
email,
|
|
userId: effectiveUserId,
|
|
roles: effectiveRoles,
|
|
isAdmin: effectiveRoles.includes('ROLE_ADMIN'),
|
|
hasToken: Boolean(token),
|
|
})
|
|
}, [email, effectiveUserId, effectiveRoles, token])
|
|
|
|
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>
|
|
}
|
|
|
|
export function useAuth() {
|
|
const ctx = useContext(AuthContext)
|
|
if (!ctx) {
|
|
throw new Error('useAuth must be used within AuthProvider')
|
|
}
|
|
return ctx
|
|
}
|