"use client" import React, { createContext, useContext, useEffect, useState, ReactNode } from 'react' import { authApi } from './api' interface User { id: string username: string email?: string role: 'admin' | 'user' createdAt: string lastLogin?: string } interface AuthState { user: User | null token: string | null isAuthenticated: boolean isLoading: boolean error: string | null } interface AuthContextType extends AuthState { login: (username: string, password?: string) => Promise logout: () => void refreshToken: () => Promise clearError: () => void authMethod: 'none' | 'unix' | 'jwt' authEnabled: boolean } const AuthContext = createContext(undefined) export function AuthProvider({ children }: { children: ReactNode }) { const [state, setState] = useState({ user: null, token: null, isAuthenticated: false, isLoading: true, error: null }) // Get authentication method from server config const authMethod = typeof window !== 'undefined' && window.__SERVER_CONFIG__ ? window.__SERVER_CONFIG__.authMethod : 'jwt'; const authEnabled = typeof window !== 'undefined' && window.__SERVER_CONFIG__ ? window.__SERVER_CONFIG__.authEnabled : false; useEffect(() => { // Check for existing authentication on mount if (authMethod === 'unix') { // For Unix auth, check for unix_user in localStorage const unixUser = localStorage.getItem('unix_user') if (unixUser) { validateUnixUser(unixUser) } else { setState(prev => ({ ...prev, isLoading: false })) } } else { // For JWT auth, check for token in localStorage const token = localStorage.getItem('auth_token') if (token) { validateToken(token) } else { setState(prev => ({ ...prev, isLoading: false })) } } }, [authMethod]) const validateToken = async (token: string) => { try { const data = await authApi.validateToken(token) setState({ user: data.user, token, isAuthenticated: true, isLoading: false, error: null }) localStorage.setItem('auth_token', token) } catch (error) { console.error('Token validation error:', error) localStorage.removeItem('auth_token') setState({ user: null, token: null, isAuthenticated: false, isLoading: false, error: 'Session expired. Please log in again.' }) } } const validateUnixUser = async (unixUser: string) => { try { // For Unix auth, we need to validate by attempting to get current user const data = await authApi.getCurrentUser() setState({ user: data.user, token: `unix_${unixUser}`, // Store a pseudo-token for consistency isAuthenticated: true, isLoading: false, error: null }) localStorage.setItem('unix_user', unixUser) localStorage.setItem('auth_token', `unix_${unixUser}`) // Store pseudo-token for API calls } catch (error) { console.error('Unix user validation error:', error) localStorage.removeItem('unix_user') localStorage.removeItem('auth_token') setState({ user: null, token: null, isAuthenticated: false, isLoading: false, error: 'Session expired. Please log in again.' }) } } const login = async (username: string, password?: string) => { setState(prev => ({ ...prev, isLoading: true, error: null })) try { const data = await authApi.login(username, password) const { token, user } = data setState({ user, token, isAuthenticated: true, isLoading: false, error: null }) if (authMethod === 'unix') { localStorage.setItem('unix_user', username) localStorage.setItem('auth_token', token) // Store token for API calls } else { localStorage.setItem('auth_token', token) } } catch (error) { setState(prev => ({ ...prev, isLoading: false, error: error instanceof Error ? error.message : 'Login failed' })) } } const logout = () => { if (authMethod === 'unix') { localStorage.removeItem('unix_user') } localStorage.removeItem('auth_token') setState({ user: null, token: null, isAuthenticated: false, isLoading: false, error: null }) } const refreshToken = async () => { const { token } = state if (!token) return try { const data = await authApi.refreshToken() const newToken = data.token setState(prev => ({ ...prev, token: newToken })) localStorage.setItem('auth_token', newToken) } catch (error) { console.error('Token refresh error:', error) logout() } } const clearError = () => { setState(prev => ({ ...prev, error: null })) } const value: AuthContextType = { ...state, login, logout, refreshToken, clearError, authMethod, authEnabled } return ( {children} ) } export function useAuth(): AuthContextType { const context = useContext(AuthContext) if (context === undefined) { throw new Error('useAuth must be used within an AuthProvider') } return context }