chore(ops): restore all source files in newwhats.clube67.com
continuous-integration/webhook Falha no deploy de clube67_newwhats.local (VPS 4)
continuous-integration/webhook Falha no deploy de clube67_newwhats.local (VPS 4)
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
import React, { createContext, useContext, useState, useEffect, useCallback } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { authApi, api } from '../services/chatApiService'
|
||||
import { socketService } from '../services/socketService'
|
||||
|
||||
interface User {
|
||||
id: string
|
||||
email: string
|
||||
name?: string
|
||||
role: 'user' | 'admin'
|
||||
daysRemaining?: number | null
|
||||
planId?: string | null
|
||||
}
|
||||
|
||||
interface AuthContextType {
|
||||
user: User | null
|
||||
token: string | null
|
||||
loading: boolean
|
||||
login: (token: string, userData: User, refreshToken?: string) => void
|
||||
logout: () => void
|
||||
}
|
||||
|
||||
const AuthContext = createContext<AuthContextType>({
|
||||
user: null,
|
||||
token: null,
|
||||
loading: true,
|
||||
login: () => {},
|
||||
logout: () => {},
|
||||
})
|
||||
|
||||
const PUBLIC_ROUTES = ['/login']
|
||||
|
||||
export const 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 router = useRouter()
|
||||
|
||||
// ── Valida sessão ao montar ──────────────────────────────────────────────
|
||||
|
||||
useEffect(() => {
|
||||
const init = async () => {
|
||||
try {
|
||||
const storedToken = localStorage.getItem('token')
|
||||
if (!storedToken) return
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
document.cookie = `accessToken=${storedToken}; path=/; SameSite=Lax; Secure`
|
||||
}
|
||||
|
||||
setToken(storedToken)
|
||||
socketService.connect(storedToken)
|
||||
const me = await authApi.me()
|
||||
|
||||
if (me?.id) {
|
||||
setUser({
|
||||
id: me.id,
|
||||
email: me.email,
|
||||
name: me.name,
|
||||
role: (me.role ?? 'USER').toLowerCase() as 'user' | 'admin',
|
||||
daysRemaining: me.daysRemaining ?? null,
|
||||
planId: me.planId ?? null,
|
||||
})
|
||||
} else {
|
||||
await tryRefresh()
|
||||
}
|
||||
} catch {
|
||||
await tryRefresh()
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
init()
|
||||
}, [])
|
||||
|
||||
// ── Redirect guard ───────────────────────────────────────────────────────
|
||||
|
||||
useEffect(() => {
|
||||
if (loading) return
|
||||
const isPublic = PUBLIC_ROUTES.some((r) => router.pathname.startsWith(r))
|
||||
if (!user && !isPublic) router.replace('/login')
|
||||
}, [loading, user, router.pathname])
|
||||
|
||||
// ── Helpers ──────────────────────────────────────────────────────────────
|
||||
|
||||
const tryRefresh = async () => {
|
||||
try {
|
||||
const refreshToken = localStorage.getItem('refreshToken')
|
||||
if (!refreshToken) { clearSession(); return }
|
||||
|
||||
const { data } = await api.post('/api/auth/refresh', { refreshToken })
|
||||
localStorage.setItem('token', data.accessToken)
|
||||
if (typeof window !== 'undefined') {
|
||||
document.cookie = `accessToken=${data.accessToken}; path=/; SameSite=Lax; Secure`
|
||||
}
|
||||
localStorage.setItem('refreshToken', data.refreshToken)
|
||||
setToken(data.accessToken)
|
||||
setUser({
|
||||
id: data.user.id,
|
||||
email: data.user.email,
|
||||
name: data.user.name,
|
||||
role: (data.user.role ?? 'USER').toLowerCase() as 'user' | 'admin',
|
||||
})
|
||||
} catch {
|
||||
clearSession()
|
||||
}
|
||||
}
|
||||
|
||||
const clearSession = () => {
|
||||
localStorage.removeItem('token')
|
||||
localStorage.removeItem('refreshToken')
|
||||
if (typeof window !== 'undefined') {
|
||||
document.cookie = 'accessToken=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/'
|
||||
}
|
||||
setToken(null)
|
||||
setUser(null)
|
||||
}
|
||||
|
||||
const login = useCallback((newToken: string, userData: User, refreshToken?: string) => {
|
||||
localStorage.setItem('token', newToken)
|
||||
if (typeof window !== 'undefined') {
|
||||
document.cookie = `accessToken=${newToken}; path=/; SameSite=Lax; Secure`
|
||||
}
|
||||
if (refreshToken) localStorage.setItem('refreshToken', refreshToken)
|
||||
setToken(newToken)
|
||||
setUser(userData)
|
||||
socketService.connect(newToken)
|
||||
router.push(userData.role === 'admin' ? '/admin/dashboard' : '/inbox')
|
||||
}, [router])
|
||||
|
||||
const logout = useCallback(async () => {
|
||||
try {
|
||||
await authApi.logout().catch(() => {})
|
||||
} finally {
|
||||
socketService.disconnect()
|
||||
clearSession()
|
||||
router.replace('/login')
|
||||
}
|
||||
}, [router])
|
||||
|
||||
return (
|
||||
<AuthContext.Provider value={{ user, token, loading, login, logout }}>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export const useAuth = () => useContext(AuthContext)
|
||||
Reference in New Issue
Block a user