import React, { useState, useEffect, useContext } from 'react'; import { AuthContext } from '../contexts/AuthContext'; import { formatDistanceToNow } from 'date-fns'; const SecurityLogs = () => { const { user, tenant } = useContext(AuthContext); const [logs, setLogs] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [filters, setFilters] = useState({ level: 'all', eventType: 'all', timeRange: '24h', search: '' }); const [pagination, setPagination] = useState({ page: 1, limit: 50, total: 0 }); useEffect(() => { if (user && tenant) { loadSecurityLogs(); } }, [user, tenant, filters, pagination.page]); const loadSecurityLogs = async () => { setLoading(true); try { const params = new URLSearchParams({ page: pagination.page, limit: pagination.limit, ...filters }); const response = await fetch(`/api/${tenant.slug}/security-logs?${params}`, { headers: { 'Authorization': `Bearer ${user.token}`, 'Content-Type': 'application/json' } }); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } const data = await response.json(); setLogs(data.logs || []); setPagination(prev => ({ ...prev, total: data.total || 0 })); } catch (err) { console.error('Failed to load security logs:', err); setError(err.message); } finally { setLoading(false); } }; const getLogLevelBadge = (level) => { const styles = { 'critical': 'bg-red-500 text-white px-2 py-1 rounded text-xs font-semibold', 'high': 'bg-orange-500 text-white px-2 py-1 rounded text-xs font-semibold', 'medium': 'bg-yellow-500 text-black px-2 py-1 rounded text-xs font-semibold', 'low': 'bg-blue-500 text-white px-2 py-1 rounded text-xs font-semibold', 'info': 'bg-gray-500 text-white px-2 py-1 rounded text-xs font-semibold' }; return styles[level] || styles.info; }; const getEventTypeIcon = (eventType) => { const icons = { 'failed_login': '🚫', 'successful_login': '✅', 'suspicious_activity': '⚠️', 'country_alert': '🌍', 'brute_force': '🔨', 'account_lockout': '🔒', 'password_reset': '🔄', 'admin_action': '👤' }; return icons[eventType] || '📋'; }; const formatMetadata = (metadata) => { if (!metadata) return ''; const items = []; if (metadata.ip_address) items.push(`IP: ${metadata.ip_address}`); if (metadata.country) items.push(`Country: ${metadata.country}`); if (metadata.user_agent) items.push(`Agent: ${metadata.user_agent.substring(0, 50)}...`); return items.join(' | '); }; const totalPages = Math.ceil(pagination.total / pagination.limit); // Don't render if user is not authenticated if (!user || !tenant) { return (
Monitor security events for your tenant: {tenant.name}
| Time | Level | Event | Message | Details |
|---|---|---|---|---|
|
{new Date(log.timestamp).toLocaleString()}
{formatDistanceToNow(new Date(log.timestamp), { addSuffix: true })}
|
{log.level.toUpperCase()} |
{getEventTypeIcon(log.event_type)}
{log.event_type.replace('_', ' ').toUpperCase()}
|
{log.message}
|
{formatMetadata(log.metadata)}
|