"use client"; import { useState, useEffect, useCallback } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Lock, Eye, EyeOff, Shield, AlertTriangle, XCircle, Loader2 } from 'lucide-react'; import ModernAdminDashboard from '@/components/ModernAdminDashboard'; // Security constants const MAX_ATTEMPTS = 3; const LOCKOUT_DURATION = 15 * 60 * 1000; // 15 minutes const RATE_LIMIT_DELAY = 1000; // 1 second base delay // Rate limiting with exponential backoff const getRateLimitDelay = (attempts: number): number => { return RATE_LIMIT_DELAY * Math.pow(2, attempts); }; interface AuthState { isAuthenticated: boolean; isLoading: boolean; showLogin: boolean; password: string; showPassword: boolean; error: string; attempts: number; isLocked: boolean; lastAttempt: number; csrfToken: string; } const AdminPage = () => { const [authState, setAuthState] = useState({ isAuthenticated: false, isLoading: true, showLogin: false, password: '', showPassword: false, error: '', attempts: 0, isLocked: false, lastAttempt: 0, csrfToken: '' }); // Fetch CSRF token const fetchCSRFToken = useCallback(async () => { try { const response = await fetch('/api/auth/csrf'); const data = await response.json(); if (response.ok && data.csrfToken) { setAuthState(prev => ({ ...prev, csrfToken: data.csrfToken })); return data.csrfToken; } } catch { console.error('Failed to fetch CSRF token'); } return ''; }, []); // Check if user is locked out const checkLockout = useCallback(() => { const lockoutData = localStorage.getItem('admin_lockout'); if (lockoutData) { try { const { timestamp, attempts } = JSON.parse(lockoutData); const now = Date.now(); if (now - timestamp < LOCKOUT_DURATION) { setAuthState(prev => ({ ...prev, isLocked: true, attempts, isLoading: false })); return true; } else { localStorage.removeItem('admin_lockout'); } } catch { localStorage.removeItem('admin_lockout'); } } return false; }, []); // Check session validity via API const checkSession = useCallback(async () => { const authStatus = sessionStorage.getItem('admin_authenticated'); const sessionToken = sessionStorage.getItem('admin_session_token'); const csrfToken = authState.csrfToken; // If no session data, show login immediately if (!authStatus || !sessionToken || !csrfToken) { setAuthState(prev => ({ ...prev, isAuthenticated: false, isLoading: false, showLogin: true })); return; } try { const response = await fetch('/api/auth/validate', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': csrfToken }, body: JSON.stringify({ sessionToken, csrfToken }) }); if (response.ok) { setAuthState(prev => ({ ...prev, isAuthenticated: true, isLoading: false, showLogin: false })); return; } else { // Clear invalid session sessionStorage.removeItem('admin_authenticated'); sessionStorage.removeItem('admin_session_token'); setAuthState(prev => ({ ...prev, isAuthenticated: false, isLoading: false, showLogin: true })); } } catch (error) { console.error('Session validation error:', error); // Clear session on error sessionStorage.removeItem('admin_authenticated'); sessionStorage.removeItem('admin_session_token'); setAuthState(prev => ({ ...prev, isAuthenticated: false, isLoading: false, showLogin: true })); } }, [authState.csrfToken]); // Initialize useEffect(() => { const init = async () => { if (checkLockout()) return; const token = await fetchCSRFToken(); if (token) { setAuthState(prev => ({ ...prev, csrfToken: token })); } }; init(); }, [checkLockout, fetchCSRFToken]); useEffect(() => { if (authState.csrfToken && !authState.isLocked) { checkSession(); } }, [authState.csrfToken, authState.isLocked]); // Handle logout const handleLogout = useCallback(() => { sessionStorage.removeItem('admin_authenticated'); sessionStorage.removeItem('admin_session_token'); setAuthState(prev => ({ ...prev, isAuthenticated: false, showLogin: true, password: '', error: '' })); }, []); // Handle login form submission const handleLogin = async (e: React.FormEvent) => { e.preventDefault(); if (!authState.password.trim() || authState.isLoading) return; setAuthState(prev => ({ ...prev, isLoading: true, error: '' })); // Rate limiting delay const delay = getRateLimitDelay(authState.attempts); await new Promise(resolve => setTimeout(resolve, delay)); try { const response = await fetch('/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': authState.csrfToken }, body: JSON.stringify({ password: authState.password, csrfToken: authState.csrfToken }) }); const data = await response.json(); if (response.ok && data.success) { // Store session sessionStorage.setItem('admin_authenticated', 'true'); sessionStorage.setItem('admin_session_token', data.sessionToken); // Clear lockout data localStorage.removeItem('admin_lockout'); // Update state setAuthState(prev => ({ ...prev, isAuthenticated: true, showLogin: false, isLoading: false, password: '', attempts: 0, error: '' })); } else { // Failed login const newAttempts = authState.attempts + 1; const newLastAttempt = Date.now(); if (newAttempts >= MAX_ATTEMPTS) { // Lock user out localStorage.setItem('admin_lockout', JSON.stringify({ timestamp: newLastAttempt, attempts: newAttempts })); setAuthState(prev => ({ ...prev, isLocked: true, attempts: newAttempts, lastAttempt: newLastAttempt, isLoading: false, error: `Too many failed attempts. Access locked for ${Math.ceil(LOCKOUT_DURATION / 60000)} minutes.` })); } else { setAuthState(prev => ({ ...prev, attempts: newAttempts, lastAttempt: newLastAttempt, isLoading: false, error: data.error || `Wrong password. ${MAX_ATTEMPTS - newAttempts} attempts remaining.`, password: '' })); } } } catch { setAuthState(prev => ({ ...prev, isLoading: false, error: 'An error occurred. Please try again.' })); } }; // Get remaining lockout time const getRemainingTime = () => { const lockoutData = localStorage.getItem('admin_lockout'); if (lockoutData) { try { const { timestamp } = JSON.parse(lockoutData); const remaining = Math.ceil((LOCKOUT_DURATION - (Date.now() - timestamp)) / 1000 / 60); return Math.max(0, remaining); } catch { return 0; } } return 0; }; // Loading state if (authState.isLoading && !authState.showLogin) { return (

Verifying Access...

Please wait while we authenticate your session

); } // Lockout state if (authState.isLocked) { return (

Access Locked

Too many failed authentication attempts

Attempts

{authState.attempts}/{MAX_ATTEMPTS}

Time Left

{getRemainingTime()}m

Access will be automatically restored in {Math.ceil(LOCKOUT_DURATION / 60000)} minutes

); } // Login form if (authState.showLogin || !authState.isAuthenticated) { return (
{/* Animated Background - same as admin dashboard */}

Admin Panel

Secure access to dashboard

System Online
setAuthState(prev => ({ ...prev, password: e.target.value }))} className="w-full px-4 py-4 admin-glass-light border border-white/30 rounded-xl text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500/50 transition-all text-lg pr-12" placeholder="Enter admin password" required disabled={authState.isLoading} autoComplete="current-password" />
{authState.error && (

{authState.error}

)}
{/* Security info */}

Security Information

Max Attempts: {MAX_ATTEMPTS}
Lockout: {Math.ceil(LOCKOUT_DURATION / 60000)}m
Session: 2h
Attempts: 0 ? 'text-orange-400' : 'text-green-400'}`}> {authState.attempts}/{MAX_ATTEMPTS}
{/* Debug: Clear Session Button */}
); } // Authenticated state - show admin dashboard return (
); }; export default AdminPage;