import React, { useState, useEffect } from 'react'; import { Shield, AlertTriangle, CheckCircle, XCircle, RefreshCw, X, Ban, Globe, Lock, Activity, TrendingUp, AlertCircle, Info } from 'lucide-react'; import { securityService, SecurityEvent, SecurityStats, OAuthProvider, DataSubjectRequest } from '../../services/api/securityService'; import { toast } from 'react-toastify'; import Loading from '../../components/common/Loading'; import Pagination from '../../components/common/Pagination'; import { formatDate } from '../../utils/format'; type SecurityTab = 'events' | 'stats' | 'ip-whitelist' | 'ip-blacklist' | 'oauth' | 'gdpr' | 'scan'; const SecurityManagementPage: React.FC = () => { const [activeTab, setActiveTab] = useState('events'); const [loading, setLoading] = useState(false); const [events, setEvents] = useState([]); const [stats, setStats] = useState(null); const [currentPage, setCurrentPage] = useState(1); const [totalPages, setTotalPages] = useState(1); const [filters, setFilters] = useState({ event_type: '', severity: '', resolved: '', days: 7, search: '' }); useEffect(() => { if (activeTab === 'events') { fetchEvents(); } else if (activeTab === 'stats') { fetchStats(); } }, [activeTab, filters, currentPage]); const fetchEvents = async () => { setLoading(true); try { const data = await securityService.getSecurityEvents({ event_type: filters.event_type || undefined, severity: filters.severity || undefined, resolved: filters.resolved ? filters.resolved === 'true' : undefined, days: filters.days, limit: 20, offset: (currentPage - 1) * 20 }); setEvents(data); setTotalPages(Math.ceil(data.length / 20)); } catch (error: any) { toast.error(error.response?.data?.message || 'Failed to fetch security events'); } finally { setLoading(false); } }; const fetchStats = async () => { setLoading(true); try { const data = await securityService.getSecurityStats(filters.days); setStats(data); } catch (error: any) { toast.error(error.response?.data?.message || 'Failed to fetch security statistics'); } finally { setLoading(false); } }; const handleResolveEvent = async (eventId: number) => { try { await securityService.resolveSecurityEvent(eventId); toast.success('Event resolved successfully'); fetchEvents(); } catch (error: any) { toast.error(error.response?.data?.message || 'Failed to resolve event'); } }; const getSeverityColor = (severity: string) => { switch (severity) { case 'critical': return 'bg-red-100 text-red-800 border-red-200'; case 'high': return 'bg-orange-100 text-orange-800 border-orange-200'; case 'medium': return 'bg-yellow-100 text-yellow-800 border-yellow-200'; case 'low': return 'bg-blue-100 text-blue-800 border-blue-200'; default: return 'bg-gray-100 text-gray-800 border-gray-200'; } }; const getEventTypeIcon = (eventType: string) => { if (eventType.includes('login')) return ; if (eventType.includes('permission')) return ; if (eventType.includes('suspicious')) return ; return ; }; if (loading && !events.length && !stats) { return ; } return (
{/* Header */}

Security Management

Monitor and manage security events, IP access, and compliance

{/* Tabs */}
{[ { id: 'events', label: 'Security Events', icon: Activity }, { id: 'stats', label: 'Statistics', icon: TrendingUp }, { id: 'ip-whitelist', label: 'IP Whitelist', icon: CheckCircle }, { id: 'ip-blacklist', label: 'IP Blacklist', icon: Ban }, { id: 'oauth', label: 'OAuth Providers', icon: Globe }, { id: 'gdpr', label: 'GDPR Requests', icon: Shield }, { id: 'scan', label: 'Security Scan', icon: Activity } ].map(tab => { const Icon = tab.icon; return ( ); })}
{/* Content */}
{activeTab === 'events' && (
{/* Filters */}
{/* Events Table - Desktop */}
{events.map((event) => ( ))}
Type Severity IP Address Description Date Status Actions
{getEventTypeIcon(event.event_type)} {event.event_type.replace(/_/g, ' ')}
{event.severity} {event.ip_address || '-'} {event.description || '-'} {formatDate(event.created_at)} {event.resolved ? ( Resolved ) : ( Unresolved )} {!event.resolved && ( )}
{/* Events Cards - Mobile/Tablet */}
{events.map((event) => (
{getEventTypeIcon(event.event_type)} {event.event_type.replace(/_/g, ' ')}
{event.severity}
IP: {event.ip_address || '-'}
Date: {formatDate(event.created_at)}
{event.description && (
Description:

{event.description}

)}
{event.resolved ? ( Resolved ) : ( Unresolved )} {!event.resolved && ( )}
))}
)} {activeTab === 'stats' && stats && (

Total Events

{stats.total_events}

Critical Unresolved

{stats.unresolved_critical}

Events by Type

{Object.entries(stats.by_type).map(([type, count]) => (
{type.replace(/_/g, ' ')} {count}
))}

Events by Severity

{Object.entries(stats.by_severity).map(([severity, count]) => (
{severity} {count}
))}
)} {activeTab === 'ip-whitelist' && ( )} {activeTab === 'ip-blacklist' && ( )} {activeTab === 'oauth' && ( )} {activeTab === 'gdpr' && ( )} {activeTab === 'scan' && ( )}
); }; // IP Whitelist Tab Component const IPWhitelistTab: React.FC = () => { const [ips, setIPs] = useState([]); const [, setLoading] = useState(false); const [showAddModal, setShowAddModal] = useState(false); const [newIP, setNewIP] = useState({ ip_address: '', description: '' }); useEffect(() => { fetchIPs(); }, []); const fetchIPs = async () => { setLoading(true); try { const data = await securityService.getWhitelistedIPs(); setIPs(data); } catch (error: any) { toast.error(error.response?.data?.message || 'Failed to fetch whitelisted IPs'); } finally { setLoading(false); } }; const handleAdd = async () => { try { await securityService.addIPToWhitelist(newIP.ip_address, newIP.description); toast.success('IP added to whitelist'); setShowAddModal(false); setNewIP({ ip_address: '', description: '' }); fetchIPs(); } catch (error: any) { toast.error(error.response?.data?.message || 'Failed to add IP to whitelist'); } }; const handleRemove = async (ipAddress: string) => { if (!window.confirm('Are you sure you want to remove this IP from whitelist?')) return; try { await securityService.removeIPFromWhitelist(ipAddress); toast.success('IP removed from whitelist'); fetchIPs(); } catch (error: any) { toast.error(error.response?.data?.message || 'Failed to remove IP from whitelist'); } }; return (

IP Whitelist

{showAddModal && (

Add IP to Whitelist

setNewIP({ ...newIP, ip_address: e.target.value })} className="w-full px-3 sm:px-4 py-2 text-sm sm:text-base border border-gray-300 rounded-lg" />