الملفات
ghaymah-exam-ahmedmohamed-S…/q4-siem-system/dashboard/app.js

344 أسطر
13 KiB
JavaScript
خام اللوم التاريخ

هذا الملف يحتوي على أحرف Unicode غير مرئية

هذا الملف يحتوي على أحرف Unicode غير مرئية لا يمكن التمييز بينها بعين الإنسان ولكن قد تتم معالجتها بشكل مختلف بواسطة الحاسوب. إذا كنت تعتقد أن هذا مقصود، يمكنك تجاهل هذا التحذير بأمان. استخدم زر الهروب للكشف عنها.

هذا الملف يحتوي على أحرف Unicode قد تُخلط مع أحرف أخرى. إذا كنت تعتقد أن هذا مقصود، يمكنك تجاهل هذا التحذير بأمان. استخدم زر الهروب للكشف عنها.

/**
* SIEM Dashboard - JavaScript
* نظام مراقبة وتحليل السجلات الأمنية
*/
// ═══════════════════════════════════════════════════════════════
// بيانات تجريبية (في الإنتاج تأتي من API)
// ═══════════════════════════════════════════════════════════════
const sampleData = {
statistics: {
total_lines: 1250,
threats_detected: 15,
sources_analyzed: 3
},
summary: {
total_alerts: 15,
critical: 5,
high: 6,
medium: 4,
suspicious_ips_count: 4
},
alerts: [
{
id: "a1b2c3d4",
timestamp: "2026-07-26T14:05:01",
threat_type: "brute_force",
description: "محاولات تسجيل دخول فاشلة متكررة",
severity: "critical",
source_ip: "192.168.1.100",
details: { path: "/api/login", attempts: 15 }
},
{
id: "e5f6g7h8",
timestamp: "2026-07-26T14:10:02",
threat_type: "sql_injection",
description: "محاولة SQL Injection",
severity: "critical",
source_ip: "10.0.0.50",
details: { path: "/api/users?id=1' OR '1'='1" }
},
{
id: "i9j0k1l2",
timestamp: "2026-07-26T14:15:01",
threat_type: "xss_attempt",
description: "محاولة XSS",
severity: "high",
source_ip: "172.16.0.25",
details: { path: "/page?q=<script>alert('xss')</script>" }
},
{
id: "m3n4o5p6",
timestamp: "2026-07-26T14:15:02",
threat_type: "path_traversal",
description: "محاولة Path Traversal",
severity: "high",
source_ip: "172.16.0.25",
details: { path: "/../../etc/passwd" }
},
{
id: "q7r8s9t0",
timestamp: "2026-07-26T14:00:05",
threat_type: "ssh_brute_force",
description: "محاولات SSH فاشلة",
severity: "critical",
source_ip: "192.168.1.200",
details: { attempts: 5, usernames: ["admin", "root", "test"] }
},
{
id: "u1v2w3x4",
timestamp: "2026-07-26T14:10:01",
threat_type: "suspicious_user_agent",
description: "User-Agent مشبوه",
severity: "medium",
source_ip: "10.0.0.50",
details: { user_agent: "sqlmap/1.5" }
}
],
suspicious_ips: [
{
ip: "192.168.1.100",
threat_count: 15,
request_count: 120,
threats: ["brute_force", "auth_failure"],
last_seen: "2026-07-26T14:05:06"
},
{
ip: "10.0.0.50",
threat_count: 8,
request_count: 45,
threats: ["sql_injection", "suspicious_user_agent"],
last_seen: "2026-07-26T14:10:02"
},
{
ip: "172.16.0.25",
threat_count: 5,
request_count: 30,
threats: ["xss_attempt", "path_traversal"],
last_seen: "2026-07-26T14:15:02"
},
{
ip: "192.168.1.200",
threat_count: 5,
request_count: 25,
threats: ["ssh_brute_force"],
last_seen: "2026-07-26T14:00:05"
}
],
threat_counts: {
"SQL Injection": 3,
"Brute Force": 5,
"XSS": 2,
"Path Traversal": 2,
"SSH Attacks": 3
},
source_lines: {
nginx: 850,
auth: 200,
app: 200
}
};
// ═══════════════════════════════════════════════════════════════
// تحديث الإحصائيات
// ═══════════════════════════════════════════════════════════════
function updateStats(data) {
document.getElementById('criticalCount').textContent = data.summary.critical;
document.getElementById('highCount').textContent = data.summary.high;
document.getElementById('mediumCount').textContent = data.summary.medium;
document.getElementById('suspiciousIPs').textContent = data.summary.suspicious_ips_count;
// تحديث عدد الأسطر لكل مصدر
document.getElementById('nginxLines').textContent = data.source_lines.nginx.toLocaleString();
document.getElementById('authLines').textContent = data.source_lines.auth.toLocaleString();
document.getElementById('appLines').textContent = data.source_lines.app.toLocaleString();
}
// ═══════════════════════════════════════════════════════════════
// عرض التنبيهات
// ═══════════════════════════════════════════════════════════════
function renderAlerts(alerts, filter = 'all') {
const container = document.getElementById('alertsList');
container.innerHTML = '';
const filteredAlerts = filter === 'all'
? alerts
: alerts.filter(a => a.severity === filter);
if (filteredAlerts.length === 0) {
container.innerHTML = '<p style="text-align: center; color: var(--text-secondary); padding: 40px;">لا توجد تنبيهات</p>';
return;
}
filteredAlerts.forEach(alert => {
const icon = getAlertIcon(alert.severity);
const time = formatTime(alert.timestamp);
const alertHtml = `
<div class="alert-item ${alert.severity}">
<div class="alert-icon">${icon}</div>
<div class="alert-content">
<div class="alert-title">${alert.description}</div>
<div class="alert-details">
<strong>IP:</strong> ${alert.source_ip} |
<strong>النوع:</strong> ${alert.threat_type}
</div>
<div class="alert-time">${time}</div>
</div>
<span class="severity-badge ${alert.severity}">${getSeverityLabel(alert.severity)}</span>
</div>
`;
container.innerHTML += alertHtml;
});
}
function getAlertIcon(severity) {
const icons = {
critical: '🚨',
high: '⚠️',
medium: '📊',
low: ''
};
return icons[severity] || '📋';
}
function getSeverityLabel(severity) {
const labels = {
critical: 'حرج',
high: 'عالي',
medium: 'متوسط',
low: 'منخفض'
};
return labels[severity] || severity;
}
function formatTime(timestamp) {
const date = new Date(timestamp);
return date.toLocaleString('ar-SA', {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
}
// ═══════════════════════════════════════════════════════════════
// عرض عناوين IP المشبوهة
// ═══════════════════════════════════════════════════════════════
function renderSuspiciousIPs(ips) {
const tbody = document.getElementById('ipsTableBody');
tbody.innerHTML = '';
ips.forEach(ip => {
const row = `
<tr>
<td><span class="ip-address">${ip.ip}</span></td>
<td><span class="threat-count">${ip.threat_count}</span></td>
<td>${ip.request_count}</td>
<td>${formatTime(ip.last_seen)}</td>
<td><button class="btn-block" onclick="blockIP('${ip.ip}')">حظر</button></td>
</tr>
`;
tbody.innerHTML += row;
});
}
function blockIP(ip) {
if (confirm(`هل تريد حظر عنوان IP: ${ip}؟`)) {
alert(`تم إرسال طلب حظر ${ip} إلى الخادم`);
// في الإنتاج: إرسال طلب API لحظر IP
}
}
// ═══════════════════════════════════════════════════════════════
// عرض الرسم البياني
// ═══════════════════════════════════════════════════════════════
function renderChart(threatCounts) {
const container = document.getElementById('threatChart');
container.innerHTML = '';
const maxCount = Math.max(...Object.values(threatCounts));
const colors = ['sql', 'brute', 'xss', 'traversal', 'sql'];
let colorIndex = 0;
for (const [threat, count] of Object.entries(threatCounts)) {
const percentage = (count / maxCount) * 100;
const color = colors[colorIndex % colors.length];
const barHtml = `
<div class="chart-bar">
<span class="chart-label">${threat}</span>
<div class="chart-bar-container">
<div class="chart-bar-fill ${color}" style="width: ${percentage}%">
${count}
</div>
</div>
</div>
`;
container.innerHTML += barHtml;
colorIndex++;
}
}
// ═══════════════════════════════════════════════════════════════
// تصفية التنبيهات
// ═══════════════════════════════════════════════════════════════
function setupFilters() {
const filterButtons = document.querySelectorAll('.filter-btn');
filterButtons.forEach(btn => {
btn.addEventListener('click', () => {
// إزالة active من جميع الأزرار
filterButtons.forEach(b => b.classList.remove('active'));
// إضافة active للزر المضغوط
btn.classList.add('active');
// تصفية التنبيهات
const filter = btn.dataset.filter;
renderAlerts(sampleData.alerts, filter);
});
});
}
// ═══════════════════════════════════════════════════════════════
// تحديث الوقت
// ═══════════════════════════════════════════════════════════════
function updateTime() {
const now = new Date();
const timeStr = now.toLocaleTimeString('ar-SA');
document.getElementById('lastUpdate').textContent = timeStr;
}
// ═══════════════════════════════════════════════════════════════
// جلب البيانات من API (للإنتاج)
// ═══════════════════════════════════════════════════════════════
async function fetchData() {
try {
// في الإنتاج: استبدل بـ API حقيقي
// const response = await fetch('/api/siem/report');
// const data = await response.json();
// استخدام البيانات التجريبية
return sampleData;
} catch (error) {
console.error('خطأ في جلب البيانات:', error);
return sampleData;
}
}
// ═══════════════════════════════════════════════════════════════
// التهيئة
// ═══════════════════════════════════════════════════════════════
async function init() {
const data = await fetchData();
updateStats(data);
renderAlerts(data.alerts);
renderSuspiciousIPs(data.suspicious_ips);
renderChart(data.threat_counts);
setupFilters();
updateTime();
// تحديث الوقت كل ثانية
setInterval(updateTime, 1000);
// تحديث البيانات كل 30 ثانية
setInterval(async () => {
const newData = await fetchData();
updateStats(newData);
// يمكن إضافة تحديث للتنبيهات أيضاً
}, 30000);
}
// بدء التطبيق
document.addEventListener('DOMContentLoaded', init);