diff --git a/client/src/pages/SecurityLogs.jsx b/client/src/pages/SecurityLogs.jsx index 152872e..7e1f9ed 100644 --- a/client/src/pages/SecurityLogs.jsx +++ b/client/src/pages/SecurityLogs.jsx @@ -1,8 +1,5 @@ import React, { useState, useEffect, useContext } from 'react'; import { AuthContext } from '../contexts/AuthContext'; -import { Card, CardHeader, CardTitle, CardContent } from '../components/ui/card'; -import { Alert, AlertDescription } from '../components/ui/alert'; -import { Badge } from '../components/ui/badge'; import { formatDistanceToNow } from 'date-fns'; const SecurityLogs = () => { @@ -23,19 +20,12 @@ const SecurityLogs = () => { }); useEffect(() => { - // Only allow admins to view security logs - if (!user || user.role !== 'admin') { - setError('Access denied. Only tenant administrators can view security logs.'); - setLoading(false); - return; + if (user && tenant) { + loadSecurityLogs(); } - - loadSecurityLogs(); - }, [filters, pagination.page, user]); + }, [user, tenant, filters, pagination.page]); const loadSecurityLogs = async () => { - if (!user || user.role !== 'admin') return; - setLoading(true); try { const params = new URLSearchParams({ @@ -44,10 +34,10 @@ const SecurityLogs = () => { ...filters }); - const response = await fetch(`/api/security-logs?${params}`, { + const response = await fetch(`/api/${tenant.slug}/security-logs?${params}`, { headers: { - 'Authorization': `Bearer ${localStorage.getItem('token')}`, - 'X-Tenant-ID': tenant?.id || '' + 'Authorization': `Bearer ${user.token}`, + 'Content-Type': 'application/json' } }); @@ -71,11 +61,11 @@ const SecurityLogs = () => { const getLogLevelBadge = (level) => { const styles = { - 'critical': 'bg-red-500 text-white', - 'high': 'bg-orange-500 text-white', - 'medium': 'bg-yellow-500 text-black', - 'low': 'bg-blue-500 text-white', - 'info': 'bg-gray-500 text-white' + '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; }; @@ -100,55 +90,48 @@ const SecurityLogs = () => { 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)}...`); - if (metadata.username) items.push(`User: ${metadata.username}`); return items.join(' | '); }; - // Access control check - if (!user || user.role !== 'admin') { + const totalPages = Math.ceil(pagination.total / pagination.limit); + + // Don't render if user is not authenticated + if (!user || !tenant) { return (
- Security events for {tenant?.name || 'your organization'} -
+Monitor security events for your tenant: {tenant.name}
| Time | -Level | -Event | -Message | -Details | +||||
|---|---|---|---|---|---|---|---|---|
| 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)}
@@ -280,22 +263,22 @@ const SecurityLogs = () => {
)}
-
-
+
+
);
};
|