secutorpro commited on
Commit
6dd64e7
·
verified ·
1 Parent(s): a1a9b32

tu es un ingenieur en sybersecurité active tout ça reel fais moi de bon travaille.Carte des Menaces

Browse files
Files changed (3) hide show
  1. index.html +94 -9
  2. script.js +178 -1
  3. style.css +52 -2
index.html CHANGED
@@ -47,27 +47,25 @@
47
  <i data-feather="shield" class="text-cyber-primary w-8 h-8 mr-2"></i>
48
  <span class="text-xl font-bold tracking-wider text-white">CYBER<span class="text-cyber-secondary">SHIELD</span></span>
49
  </div>
50
-
51
  <nav class="flex-1 px-4 py-6 space-y-2">
52
- <a href="#" class="flex items-center px-4 py-3 bg-gray-800/50 text-cyber-primary rounded-lg border border-gray-700">
53
  <i data-feather="activity" class="w-5 h-5 mr-3"></i>
54
  <span>Moniteur Temps Réel</span>
55
  </a>
56
- <a href="#" class="flex items-center px-4 py-3 text-gray-400 hover:text-white hover:bg-gray-800/30 rounded-lg transition-colors">
57
  <i data-feather="map" class="w-5 h-5 mr-3"></i>
58
  <span>Carte des Menaces</span>
59
  </a>
60
- <a href="#" class="flex items-center px-4 py-3 text-gray-400 hover:text-white hover:bg-gray-800/30 rounded-lg transition-colors">
61
  <i data-feather="lock" class="w-5 h-5 mr-3"></i>
62
  <span>Vulnérabilités</span>
63
  </a>
64
- <a href="#" class="flex items-center px-4 py-3 text-gray-400 hover:text-white hover:bg-gray-800/30 rounded-lg transition-colors">
65
  <i data-feather="server" class="w-5 h-5 mr-3"></i>
66
  <span>Infrastructure</span>
67
  </a>
68
  </nav>
69
-
70
- <div class="p-4 border-t border-gray-800">
71
  <div class="bg-gray-900 rounded-lg p-4 border border-gray-800">
72
  <p class="text-xs text-gray-500 uppercase mb-1">Système</p>
73
  <div class="flex items-center justify-between text-sm">
@@ -264,10 +262,97 @@
264
  </div>
265
 
266
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
  </main>
268
  </div>
269
-
270
- <script src="script.js"></script>
271
  <script>feather.replace();</script>
272
  <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
273
  </body>
 
47
  <i data-feather="shield" class="text-cyber-primary w-8 h-8 mr-2"></i>
48
  <span class="text-xl font-bold tracking-wider text-white">CYBER<span class="text-cyber-secondary">SHIELD</span></span>
49
  </div>
 
50
  <nav class="flex-1 px-4 py-6 space-y-2">
51
+ <a href="#" onclick="navigateTo('dashboard')" id="nav-dashboard" class="nav-link active flex items-center px-4 py-3 bg-gray-800/50 text-cyber-primary rounded-lg border border-gray-700 transition-colors">
52
  <i data-feather="activity" class="w-5 h-5 mr-3"></i>
53
  <span>Moniteur Temps Réel</span>
54
  </a>
55
+ <a href="#" onclick="navigateTo('map')" id="nav-map" class="nav-link flex items-center px-4 py-3 text-gray-400 hover:text-white hover:bg-gray-800/30 rounded-lg transition-colors">
56
  <i data-feather="map" class="w-5 h-5 mr-3"></i>
57
  <span>Carte des Menaces</span>
58
  </a>
59
+ <a href="#" onclick="navigateTo('vulns')" id="nav-vulns" class="nav-link flex items-center px-4 py-3 text-gray-400 hover:text-white hover:bg-gray-800/30 rounded-lg transition-colors">
60
  <i data-feather="lock" class="w-5 h-5 mr-3"></i>
61
  <span>Vulnérabilités</span>
62
  </a>
63
+ <a href="#" onclick="navigateTo('infra')" id="nav-infra" class="nav-link flex items-center px-4 py-3 text-gray-400 hover:text-white hover:bg-gray-800/30 rounded-lg transition-colors">
64
  <i data-feather="server" class="w-5 h-5 mr-3"></i>
65
  <span>Infrastructure</span>
66
  </a>
67
  </nav>
68
+ <div class="p-4 border-t border-gray-800">
 
69
  <div class="bg-gray-900 rounded-lg p-4 border border-gray-800">
70
  <p class="text-xs text-gray-500 uppercase mb-1">Système</p>
71
  <div class="flex items-center justify-between text-sm">
 
262
  </div>
263
 
264
  </div>
265
+
266
+ <!-- VIEW: THREAT MAP -->
267
+ <div id="view-map" class="hidden h-full flex flex-col p-8 animate-fade-in">
268
+ <h2 class="text-2xl font-bold text-white mb-6 flex items-center">
269
+ <i data-feather="globe" class="mr-3 text-red-500"></i> Analyse Géographique des Menaces
270
+ </h2>
271
+
272
+ <div class="grid grid-cols-1 lg:grid-cols-3 gap-8 h-full">
273
+ <!-- Map Visual -->
274
+ <div class="lg:col-span-2 bg-cyber-panel rounded-xl border border-gray-800 relative overflow-hidden p-6">
275
+ <div class="absolute inset-0 cyber-grid opacity-20"></div>
276
+ <h3 class="text-lg font-bold text-white mb-4 relative z-10">Flux d'Attaque en Direct (Live Feed)</h3>
277
+ <div id="attack-map-container" class="relative h-[500px] w-full bg-black/50 rounded border border-gray-800 flex items-center justify-center overflow-hidden">
278
+ <!-- Animated Nodes injected via JS -->
279
+ <div class="text-gray-500 font-mono text-xs">INITIALISATION DU RADAR GÉOGRAPHIQUE...</div>
280
+ </div>
281
+ </div>
282
+
283
+ <!-- Live Feed List -->
284
+ <div class="bg-black rounded-xl border border-gray-800 p-4 font-mono text-sm flex flex-col h-[550px]">
285
+ <div class="flex justify-between items-center mb-4 border-b border-gray-800 pb-2">
286
+ <span class="text-red-500 font-bold flex items-center">
287
+ <span class="w-2 h-2 bg-red-500 rounded-full mr-2 animate-ping"></span> DETECTIONS RÉCENTES
288
+ </span>
289
+ <span class="text-xs text-gray-500">GEO_IP</span>
290
+ </div>
291
+ <div id="geo-log-container" class="flex-1 overflow-y-auto space-y-2">
292
+ <!-- Logs -->
293
+ </div>
294
+ </div>
295
+ </div>
296
+ </div>
297
+
298
+ <!-- VIEW: VULNERABILITIES -->
299
+ <div id="view-vulns" class="hidden h-full flex flex-col p-8 animate-fade-in">
300
+ <div class="flex justify-between items-center mb-6">
301
+ <h2 class="text-2xl font-bold text-white flex items-center">
302
+ <i data-feather="alert-octagon" class="mr-3 text-orange-500"></i> Gestion des Vulnérabilités
303
+ </h2>
304
+ <button class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded text-sm font-mono border border-red-400 transition flex items-center">
305
+ <i data-feather="download" class="w-4 h-4 mr-2"></i> SCAN COMPLET
306
+ </button>
307
+ </div>
308
+
309
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
310
+ <div class="bg-cyber-panel p-4 rounded border border-gray-800 border-t-4 border-t-red-500">
311
+ <p class="text-gray-400 text-sm">Critique</p>
312
+ <p class="text-3xl font-bold text-white mt-1" id="vuln-critical-count">0</p>
313
+ </div>
314
+ <div class="bg-cyber-panel p-4 rounded border border-gray-800 border-t-4 border-t-yellow-500">
315
+ <p class="text-gray-400 text-sm">Haute</p>
316
+ <p class="text-3xl font-bold text-white mt-1" id="vuln-high-count">0</p>
317
+ </div>
318
+ <div class="bg-cyber-panel p-4 rounded border border-gray-800 border-t-4 border-t-blue-500">
319
+ <p class="text-gray-400 text-sm"> Moyenne</p>
320
+ <p class="text-3xl font-bold text-white mt-1" id="vuln-med-count">0</p>
321
+ </div>
322
+ </div>
323
+
324
+ <div class="bg-cyber-panel rounded-xl border border-gray-800 overflow-hidden flex-1">
325
+ <table class="w-full text-left text-sm text-gray-400">
326
+ <thead class="bg-gray-900 text-gray-200 uppercase font-medium">
327
+ <tr>
328
+ <th class="px-6 py-4">CVE ID</th>
329
+ <th class="px-6 py-4">Composant</th>
330
+ <th class="px-6 py-4">Score (CVSS)</th>
331
+ <th class="px-6 py-4">Statut</th>
332
+ <th class="px-6 py-4">Action</th>
333
+ </tr>
334
+ </thead>
335
+ <tbody id="vuln-table-body" class="divide-y divide-gray-800">
336
+ <!-- Rows injected via JS -->
337
+ </tbody>
338
+ </table>
339
+ </div>
340
+ </div>
341
+
342
+ <!-- VIEW: INFRASTRUCTURE -->
343
+ <div id="view-infra" class="hidden h-full flex flex-col p-8 animate-fade-in">
344
+ <h2 class="text-2xl font-bold text-white mb-6 flex items-center">
345
+ <i data-feather="cpu" class="mr-3 text-cyber-secondary"></i> Health Check Infrastructure
346
+ </h2>
347
+
348
+ <div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6 overflow-y-auto pb-20" id="server-rack-container">
349
+ <!-- Server Cards injected via JS -->
350
+ </div>
351
+ </div>
352
+
353
  </main>
354
  </div>
355
+ <script src="script.js"></script>
 
356
  <script>feather.replace();</script>
357
  <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
358
  </body>
script.js CHANGED
@@ -4,17 +4,46 @@ document.addEventListener('DOMContentLoaded', () => {
4
  // Initialize UI
5
  initLiveChart();
6
  startLogStream();
 
7
 
8
  // Start Real-time Data Fetching from Backend
9
  fetchStats();
10
  setInterval(fetchStats, 1000); // Poll every second
11
 
 
 
 
 
 
12
  // Feather Icons re-render
13
  if (typeof feather !== 'undefined') {
14
  feather.replace();
15
  }
16
  });
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  // 1. Real-time Chart Initialization
19
  function initLiveChart() {
20
  const chartContainer = document.getElementById('liveChart');
@@ -100,7 +129,6 @@ async function startLogStream() {
100
  // Poll every 2.5 seconds
101
  setInterval(fetchLog, 2500);
102
  }
103
-
104
  // Fallback to simulate data if user doesn't run the server
105
  function simulateFallbackData() {
106
  // Just ensures the chart keeps moving if no server is present
@@ -123,3 +151,152 @@ function simulateFallbackData() {
123
  lastBar.className = 'bg-cyber-primary w-2 rounded-t-sm opacity-50 transition-all duration-300';
124
  }
125
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  // Initialize UI
5
  initLiveChart();
6
  startLogStream();
7
+ initMap(); // Initialize Map
8
 
9
  // Start Real-time Data Fetching from Backend
10
  fetchStats();
11
  setInterval(fetchStats, 1000); // Poll every second
12
 
13
+ // Start secondary data streams
14
+ startVulnStream();
15
+ startInfraStream();
16
+ startMapStream();
17
+
18
  // Feather Icons re-render
19
  if (typeof feather !== 'undefined') {
20
  feather.replace();
21
  }
22
  });
23
 
24
+ // 0. Navigation Logic (SPA)
25
+ function navigateTo(viewId) {
26
+ // Hide all views
27
+ document.querySelectorAll('[id^="view-"]').forEach(el => el.classList.add('hidden'));
28
+ // Show selected
29
+ document.getElementById(`view-${viewId}`).classList.remove('hidden');
30
+
31
+ // Reset Nav Styles
32
+ document.querySelectorAll('.nav-link').forEach(el => {
33
+ el.classList.remove('active', 'bg-gray-800/50', 'text-cyber-primary', 'border-gray-700');
34
+ el.classList.add('text-gray-400');
35
+ });
36
+
37
+ // Set Active Nav
38
+ const activeNav = document.getElementById(`nav-${viewId}`);
39
+ if(activeNav) {
40
+ activeNav.classList.add('active', 'bg-gray-800/50', 'text-cyber-primary', 'border-gray-700');
41
+ activeNav.classList.remove('text-gray-400');
42
+ }
43
+
44
+ // Re-init icons
45
+ feather.replace();
46
+ }
47
  // 1. Real-time Chart Initialization
48
  function initLiveChart() {
49
  const chartContainer = document.getElementById('liveChart');
 
129
  // Poll every 2.5 seconds
130
  setInterval(fetchLog, 2500);
131
  }
 
132
  // Fallback to simulate data if user doesn't run the server
133
  function simulateFallbackData() {
134
  // Just ensures the chart keeps moving if no server is present
 
151
  lastBar.className = 'bg-cyber-primary w-2 rounded-t-sm opacity-50 transition-all duration-300';
152
  }
153
  }
154
+
155
+ // --- NEW FEATURES: MAP, VULNS, INFRA ---
156
+
157
+ // 4. Threat Map Logic
158
+ function initMap() {
159
+ const container = document.getElementById('attack-map-container');
160
+ // Create a central server node
161
+ const center = document.createElement('div');
162
+ center.className = 'w-4 h-4 bg-cyber-primary rounded-full z-20 shadow-[0_0_20px_#00f0ff]';
163
+ center.style.top = '50%';
164
+ center.style.left = '50%';
165
+ center.style.transform = 'translate(-50%, -50%)';
166
+ container.appendChild(center);
167
+ }
168
+
169
+ async function startMapStream() {
170
+ const container = document.getElementById('geo-log-container');
171
+ const mapArea = document.getElementById('attack-map-container');
172
+
173
+ const fetchMapData = async () => {
174
+ try {
175
+ const response = await fetch('http://localhost:3000/api/geo');
176
+ const data = await response.json();
177
+
178
+ // Add Log
179
+ const logLine = document.createElement('div');
180
+ logLine.className = 'border-b border-gray-900 pb-1 text-xs font-mono animate-fade-in';
181
+ logLine.innerHTML = `<span class="text-red-400">[${data.country}]</span> Attaque ${data.type} depuis <span class="text-white">${data.ip}</span>`;
182
+ container.prepend(logLine);
183
+ if(container.children.length > 15) container.lastChild.remove();
184
+
185
+ // Add Visual Node on Map
186
+ const node = document.createElement('div');
187
+ node.className = 'geo-node';
188
+ // Random pos within 90%
189
+ node.style.top = Math.random() * 90 + '%';
190
+ node.style.left = Math.random() * 90 + '%';
191
+ mapArea.appendChild(node);
192
+
193
+ // Remove node after animation
194
+ setTimeout(() => node.remove(), 2000);
195
+
196
+ } catch(e) { /* Silent fail if backend down */ }
197
+ };
198
+ setInterval(fetchMapData, 2000);
199
+ }
200
+
201
+ // 5. Vulnerabilities Logic
202
+ async function startVulnStream() {
203
+ const tableBody = document.getElementById('vuln-table-body');
204
+
205
+ const fetchVulns = async () => {
206
+ try {
207
+ const response = await fetch('http://localhost:3000/api/vulns');
208
+ const data = await response.json();
209
+
210
+ // Update Counts
211
+ document.getElementById('vuln-critical-count').innerText = data.stats.critical;
212
+ document.getElementById('vuln-high-count').innerText = data.stats.high;
213
+ document.getElementById('vuln-med-count').innerText = data.stats.medium;
214
+
215
+ // Render List (Simplified: Re-rendering top 5 for demo)
216
+ tableBody.innerHTML = '';
217
+ data.list.forEach(vuln => {
218
+ let color = 'text-blue-400';
219
+ if(vuln.score >= 9) color = 'text-red-400 font-bold';
220
+ else if(vuln.score >= 7) color = 'text-orange-400';
221
+
222
+ const row = `
223
+ <tr class="hover:bg-gray-800/30 transition border-b border-gray-800/50">
224
+ <td class="px-6 py-3 font-mono text-white">${vuln.id}</td>
225
+ <td class="px-6 py-3">${vuln.component}</td>
226
+ <td class="px-6 py-3 ${color}">${vuln.score}</td>
227
+ <td class="px-6 py-3"><span class="bg-gray-800 text-gray-300 px-2 py-1 rounded text-xs">Non corrigé</span></td>
228
+ <td class="px-6 py-3"><button class="text-cyber-primary hover:underline text-xs">APPLY PATCH</button></td>
229
+ </tr>
230
+ `;
231
+ tableBody.innerHTML += row;
232
+ });
233
+ feather.replace();
234
+ } catch(e) {}
235
+ };
236
+ fetchVulns();
237
+ setInterval(fetchVulns, 5000);
238
+ }
239
+
240
+ // 6. Infrastructure Logic
241
+ async function startInfraStream() {
242
+ const container = document.getElementById('server-rack-container');
243
+
244
+ const fetchInfra = async () => {
245
+ try {
246
+ const response = await fetch('http://localhost:3000/api/infra');
247
+ const data = await response.json;
248
+
249
+ // For visual stability, we only update existing or create if empty
250
+ // In a real app, we'd match IDs. Here we simulate a dynamic list.
251
+ if(container.children.length === 0) {
252
+ data.servers.forEach(srv => {
253
+ const card = document.createElement('div');
254
+ card.className = 'server-card p-4 rounded-xl shadow-lg relative';
255
+ card.id = `srv-${srv.id}`;
256
+ container.appendChild(card);
257
+ });
258
+ }
259
+
260
+ // Update values
261
+ data.servers.forEach(srv => {
262
+ const card = document.getElementById(`srv-${srv.id}`);
263
+ if(card) {
264
+ const loadColor = srv.load > 80 ? 'bg-red-500' : (srv.load > 50 ? 'bg-yellow-400' : 'bg-cyber-secondary');
265
+
266
+ card.innerHTML = `
267
+ <div class="flex justify-between items-center mb-4">
268
+ <h4 class="font-bold text-white text-sm">${srv.name}</h4>
269
+ <span class="text-xs ${srv.status === 'Online' ? 'text-green-400' : 'text-red-400'} flex items-center">
270
+ <div class="w-1.5 h-1.5 rounded-full bg-current mr-1 ${srv.status === 'Online' ? 'animate-pulse' : ''}"></div>
271
+ ${srv.status}
272
+ </span>
273
+ </div>
274
+ <div class="space-y-3">
275
+ <div>
276
+ <div class="flex justify-between text-xs text-gray-400 mb-1">
277
+ <span>CPU Load</span>
278
+ <span>${srv.load}%</span>
279
+ </div>
280
+ <div class="w-full bg-gray-800 rounded-full h-1.5">
281
+ <div class="${loadColor} h-1.5 rounded-full transition-all duration-500" style="width: ${srv.load}%"></div>
282
+ </div>
283
+ </div>
284
+ <div class="grid grid-cols-2 gap-2 mt-4">
285
+ <div class="bg-gray-900 p-2 rounded border border-gray-800">
286
+ <p class="text-[10px] text-gray-500">RAM</p>
287
+ <p class="text-xs font-mono text-white">${srv.ram} GB</p>
288
+ </div>
289
+ <div class="bg-gray-900 p-2 rounded border border-gray-800">
290
+ <p class="text-[10px] text-gray-500">TEMP</p>
291
+ <p class="text-xs font-mono ${srv.temp > 70 ? 'text-red-400' : 'text-white'}">${srv.temp}°C</p>
292
+ </div>
293
+ </div>
294
+ </div>
295
+ `;
296
+ }
297
+ });
298
+ } catch(e) {}
299
+ };
300
+ fetchInfra();
301
+ setInterval(fetchInfra, 2000);
302
+ }
style.css CHANGED
@@ -87,8 +87,58 @@ body {
87
  .log-entry {
88
  animation: fadeIn 0.3s ease-in;
89
  }
90
-
91
  @keyframes fadeIn {
92
  from { opacity: 0; transform: translateX(-10px); }
93
  to { opacity: 1; transform: translateX(0); }
94
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  .log-entry {
88
  animation: fadeIn 0.3s ease-in;
89
  }
 
90
  @keyframes fadeIn {
91
  from { opacity: 0; transform: translateX(-10px); }
92
  to { opacity: 1; transform: translateX(0); }
93
+ }
94
+
95
+ /* Navigation Active State */
96
+ .nav-link.active {
97
+ background: rgba(0, 240, 255, 0.1);
98
+ border-color: #00f0ff;
99
+ color: #00f0ff;
100
+ box-shadow: 0 0 15px rgba(0, 240, 255, 0.1);
101
+ }
102
+
103
+ /* Threat Map Nodes */
104
+ .geo-node {
105
+ position: absolute;
106
+ width: 10px;
107
+ height: 10px;
108
+ border-radius: 50%;
109
+ background: #00f0ff;
110
+ box-shadow: 0 0 10px #00f0ff;
111
+ z-index: 10;
112
+ }
113
+
114
+ .geo-node::after {
115
+ content: '';
116
+ position: absolute;
117
+ top: 50%;
118
+ left: 50%;
119
+ width: 20px;
120
+ height: 20px;
121
+ border: 1px solid #00f0ff;
122
+ border-radius: 50%;
123
+ transform: translate(-50%, -50%);
124
+ animation: ripple 2s infinite;
125
+ }
126
+
127
+ @keyframes ripple {
128
+ 0% { width: 0; height: 0; opacity: 1; }
129
+ 100% { width: 60px; height: 60px; opacity: 0; }
130
+ }
131
+
132
+ .server-card {
133
+ background: linear-gradient(145deg, #13131f, #0a0a12);
134
+ border: 1px solid #374151;
135
+ position: relative;
136
+ overflow: hidden;
137
+ }
138
+
139
+ .server-card::before {
140
+ content: '';
141
+ position: absolute;
142
+ top: 0; left: 0; right: 0; height: 2px;
143
+ background: linear-gradient(90deg, transparent, #00ff9d, transparent);
144
+ }