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

continue tu as bien compris le systeme améliore le systeme

Browse files
Files changed (2) hide show
  1. index.html +43 -7
  2. script.js +192 -39
index.html CHANGED
@@ -94,20 +94,24 @@
94
  <i data-feather="chevron-right" class="w-4 h-4 mx-2"></i>
95
  <span class="text-white">Analyse en Cours</span>
96
  </div>
97
- <div class="flex items-center space-x-4">
98
- <button class="p-2 rounded-full hover:bg-gray-800 text-gray-400 hover:text-white transition">
99
- <i data-feather="bell" class="w-5 h-5"></i>
 
100
  </button>
101
- <button class="p-2 rounded-full hover:bg-gray-800 text-gray-400 hover:text-white transition">
102
- <i data-feather="settings" class="w-5 h-5"></i>
 
 
103
  </button>
 
104
  <div class="h-8 w-px bg-gray-700 mx-2"></div>
105
  <div class="flex items-center">
106
  <img src="https://ui-avatars.com/api/?name=Admin+S&background=00f0ff&color=000" alt="User" class="w-8 h-8 rounded-full border border-cyber-primary">
107
  <span class="ml-3 text-sm font-medium">Admin_Sys</span>
108
  </div>
109
  </div>
110
- </header>
111
 
112
  <!-- Dashboard Content -->
113
  <div class="flex-1 overflow-y-auto p-8 scrollbar-hide">
@@ -352,8 +356,40 @@
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>
359
- </html>
 
94
  <i data-feather="chevron-right" class="w-4 h-4 mx-2"></i>
95
  <span class="text-white">Analyse en Cours</span>
96
  </div>
97
+ <div class="flex items-center space-x-4">
98
+ <!-- Sound Toggle -->
99
+ <button id="btn-sound" class="p-2 rounded-full hover:bg-gray-800 text-gray-400 hover:text-cyber-primary transition" title="Activer/Désactiver les alertes sonores">
100
+ <i data-feather="volume-2" class="w-5 h-5"></i>
101
  </button>
102
+
103
+ <!-- Terminal Toggle -->
104
+ <button onclick="toggleTerminal()" class="p-2 rounded-full hover:bg-gray-800 text-gray-400 hover:text-cyber-secondary transition" title="Ouvrir le Terminal">
105
+ <i data-feather="terminal" class="w-5 h-5"></i>
106
  </button>
107
+
108
  <div class="h-8 w-px bg-gray-700 mx-2"></div>
109
  <div class="flex items-center">
110
  <img src="https://ui-avatars.com/api/?name=Admin+S&background=00f0ff&color=000" alt="User" class="w-8 h-8 rounded-full border border-cyber-primary">
111
  <span class="ml-3 text-sm font-medium">Admin_Sys</span>
112
  </div>
113
  </div>
114
+ </header>
115
 
116
  <!-- Dashboard Content -->
117
  <div class="flex-1 overflow-y-auto p-8 scrollbar-hide">
 
356
 
357
  </main>
358
  </div>
359
+
360
+ <!-- TERMINAL MODAL -->
361
+ <div id="terminal-modal" class="fixed inset-0 bg-black/90 z-50 hidden flex items-center justify-center backdrop-blur-sm">
362
+ <div class="bg-gray-900 border border-cyber-primary w-[800px] h-[500px] rounded-xl shadow-[0_0_50px_rgba(0,240,255,0.2)] flex flex-col overflow-hidden">
363
+ <!-- Terminal Header -->
364
+ <div class="bg-gray-800 px-4 py-2 flex justify-between items-center border-b border-gray-700">
365
+ <div class="flex items-center space-x-2">
366
+ <div class="w-3 h-3 rounded-full bg-red-500"></div>
367
+ <div class="w-3 h-3 rounded-full bg-yellow-500"></div>
368
+ <div class="w-3 h-3 rounded-full bg-green-500"></div>
369
+ </div>
370
+ <span class="text-cyber-primary font-mono text-sm">root@cybershield:~</span>
371
+ <button onclick="toggleTerminal()" class="text-gray-400 hover:text-white">
372
+ <i data-feather="x" class="w-5 h-5"></i>
373
+ </button>
374
+ </div>
375
+
376
+ <!-- Terminal Output -->
377
+ <div id="terminal-output" class="flex-1 p-4 overflow-y-auto font-mono text-sm text-green-400 space-y-1">
378
+ <p>CyberShield System v2.0 [Interactive Mode]</p>
379
+ <p>Type <span class="text-yellow-400">'help'</span> for available commands.</p>
380
+ <br>
381
+ </div>
382
+
383
+ <!-- Terminal Input -->
384
+ <div class="bg-gray-800 p-2 flex items-center border-t border-gray-700">
385
+ <span class="text-cyber-primary mr-2">root@sys:~$</span>
386
+ <input type="text" id="terminal-input" class="bg-transparent border-none outline-none text-white w-full font-mono text-sm focus:ring-0" autocomplete="off" autofocus>
387
+ </div>
388
+ </div>
389
+ </div>
390
+
391
  <script src="script.js"></script>
392
  <script>feather.replace();</script>
393
  <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
394
  </body>
395
+ </html>
script.js CHANGED
@@ -1,6 +1,14 @@
1
 
 
 
 
 
2
  document.addEventListener('DOMContentLoaded', () => {
3
 
 
 
 
 
4
  // Initialize UI
5
  initLiveChart();
6
  startLogStream();
@@ -15,12 +23,56 @@ document.addEventListener('DOMContentLoaded', () => {
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
@@ -47,42 +99,50 @@ function navigateTo(viewId) {
47
  // 1. Real-time Chart Initialization
48
  function initLiveChart() {
49
  const chartContainer = document.getElementById('liveChart');
50
- const barCount = 40;
51
 
52
  // Create initial bars
53
  for(let i = 0; i < barCount; i++) {
54
  const bar = document.createElement('div');
55
- bar.className = 'bg-cyber-primary w-2 rounded-t-sm opacity-50 transition-all duration-300';
56
- const height = Math.floor(Math.random() * 70) + 10;
57
  bar.style.height = `${height}%`;
58
  chartContainer.appendChild(bar);
59
  }
60
  }
61
-
62
  // 2. Fetch Statistics from Backend API
63
  async function fetchStats() {
64
  try {
65
- const response = await fetch('http://localhost:3000/api/stats');
66
- if (!response.ok) throw new Error('Network response was not ok');
67
- const data = await response.json();
68
-
69
- // Update Dashboard Data
70
- updateCounterValue('14205', data.threatsBlocked);
71
- document.querySelectorAll('.counter')[1].nextElementSibling.innerText = data.serverHealth + "%";
72
- document.querySelectorAll('.counter')[2].previousElementSibling.lastElementChild.innerText = data.networkTraffic;
73
- document.querySelectorAll('.counter')[3].innerText = data.criticalAlerts.toString().padStart(2, '0');
74
-
75
- // Update System Status Indicator
76
- const statusBadge = document.getElementById('system-status');
77
- statusBadge.className = "flex items-center justify-between text-sm";
78
- statusBadge.innerHTML = `<span class="text-green-400">Securité Active</span><i data-feather="check-circle" class="w-4 h-4 text-green-400"></i>`;
79
- feather.replace();
80
-
81
- } catch (error) {
82
- console.warn("Backend unreachable. Ensure server.js is running.");
83
- // Fallback simulation if backend is down
84
- simulateFallbackData();
85
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  }
87
 
88
  function updateCounterValue(idOrOldVal, newVal) {
@@ -153,23 +213,24 @@ function simulateFallbackData() {
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');
@@ -185,19 +246,111 @@ async function startMapStream() {
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');
 
1
 
2
+ // Audio Context for Sound Effects
3
+ let audioCtx = null;
4
+ let soundEnabled = false;
5
+
6
  document.addEventListener('DOMContentLoaded', () => {
7
 
8
+ // Initialize Audio on first interaction (browser policy)
9
+ document.body.addEventListener('click', initAudio, { once: true });
10
+ document.getElementById('btn-sound').addEventListener('click', toggleSound);
11
+
12
  // Initialize UI
13
  initLiveChart();
14
  startLogStream();
 
23
  startInfraStream();
24
  startMapStream();
25
 
26
+ // Terminal Setup
27
+ setupTerminal();
28
+
29
  // Feather Icons re-render
30
  if (typeof feather !== 'undefined') {
31
  feather.replace();
32
  }
33
  });
34
 
35
+ // --- Sound Manager ---
36
+ function initAudio() {
37
+ if (!audioCtx) {
38
+ audioCtx = new (window.AudioContext || window.webkitAudioContext)();
39
+ }
40
+ }
41
+
42
+ function toggleSound() {
43
+ soundEnabled = !soundEnabled;
44
+ const btn = document.getElementById('btn-sound');
45
+ const icon = btn.querySelector('i');
46
+
47
+ if (soundEnabled) {
48
+ icon.setAttribute('data-feather', 'volume-2');
49
+ icon.classList.replace('text-gray-400', 'text-cyber-primary');
50
+ playBeep(600, 'sine', 0.1); // Confirmation beep
51
+ } else {
52
+ icon.setAttribute('data-feather', 'volume-x');
53
+ icon.classList.replace('text-cyber-primary', 'text-gray-400');
54
+ }
55
+ feather.replace();
56
+ }
57
+
58
+ function playAlertSound() {
59
+ if (!soundEnabled || !audioCtx) return;
60
+
61
+ const osc = audioCtx.createOscillator();
62
+ const gain = audioCtx.createGain();
63
+
64
+ osc.type = 'sawtooth';
65
+ osc.frequency.setValueAtTime(440, audioCtx.currentTime);
66
+ osc.frequency.exponentialRampToValueAtTime(880, audioCtx.currentTime + 0.1);
67
+
68
+ gain.gain.setValueAtTime(0.1, audioCtx.currentTime);
69
+ gain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.3);
70
+
71
+ osc.connect(gain);
72
+ gain.connect(audioCtx.destination);
73
+ osc.start();
74
+ osc.stop(audioCtx.currentTime + 0.3);
75
+ }
76
  // 0. Navigation Logic (SPA)
77
  function navigateTo(viewId) {
78
  // Hide all views
 
99
  // 1. Real-time Chart Initialization
100
  function initLiveChart() {
101
  const chartContainer = document.getElementById('liveChart');
102
+ const barCount = 50;
103
 
104
  // Create initial bars
105
  for(let i = 0; i < barCount; i++) {
106
  const bar = document.createElement('div');
107
+ bar.className = 'bg-cyber-primary w-1.5 rounded-t-sm opacity-60 transition-all duration-300 ease-in-out hover:opacity-100 hover:bg-white';
108
+ const height = Math.floor(Math.random() * 60) + 10;
109
  bar.style.height = `${height}%`;
110
  chartContainer.appendChild(bar);
111
  }
112
  }
 
113
  // 2. Fetch Statistics from Backend API
114
  async function fetchStats() {
115
  try {
116
+ const response = await fetch('http://localhost:3000/api/stats');
117
+ if (!response.ok) throw new Error('Network response was not ok');
118
+ const data = await response.json();
119
+
120
+ // Check for new critical alert to trigger sound
121
+ const currentAlertEl = document.querySelectorAll('.counter')[3];
122
+ const prevAlert = parseInt(currentAlertEl.innerText);
123
+ const newAlert = data.criticalAlerts;
124
+
125
+ if (newAlert > prevAlert && newAlert > 0) {
126
+ playAlertSound(); // Play sound on new alert
 
 
 
 
 
 
 
 
 
127
  }
128
+
129
+ // Update Dashboard Data
130
+ updateCounterValue('14205', data.threatsBlocked);
131
+ document.querySelectorAll('.counter')[1].nextElementSibling.innerText = data.serverHealth + "%";
132
+ document.querySelectorAll('.counter')[2].previousElementSibling.lastElementChild.innerText = data.networkTraffic;
133
+ document.querySelectorAll('.counter')[3].innerText = data.criticalAlerts.toString().padStart(2, '0');
134
+
135
+ // Update System Status Indicator
136
+ const statusBadge = document.getElementById('system-status');
137
+ statusBadge.className = "flex items-center justify-between text-sm";
138
+ statusBadge.innerHTML = `<span class="text-green-400">Securité Active</span><i data-feather="check-circle" class="w-4 h-4 text-green-400"></i>`;
139
+ feather.replace();
140
+
141
+ } catch (error) {
142
+ console.warn("Backend unreachable. Ensure server.js is running.");
143
+ // Fallback simulation if backend is down
144
+ simulateFallbackData();
145
+ }
146
  }
147
 
148
  function updateCounterValue(idOrOldVal, newVal) {
 
213
  }
214
 
215
  // --- NEW FEATURES: MAP, VULNS, INFRA ---
 
216
  // 4. Threat Map Logic
217
  function initMap() {
218
+ // Clear existing svg lines if any
219
+ const svg = document.getElementById('map-svg-layer');
220
+ while (svg.lastChild) {
221
+ svg.removeChild(svg.lastChild);
222
+ }
 
 
 
223
  }
224
 
225
  async function startMapStream() {
226
  const container = document.getElementById('geo-log-container');
227
  const mapArea = document.getElementById('attack-map-container');
228
+ const svg = document.getElementById('map-svg-layer');
229
+ const centerNode = document.getElementById('map-center-node'); // Should be centered
230
 
231
+ // Get center coordinates relative to mapArea
232
+ // Note: In CSS, center is 50% 50%. We need pixel approx or just use 50% for SVG line coords.
233
+
234
  const fetchMapData = async () => {
235
  try {
236
  const response = await fetch('http://localhost:3000/api/geo');
 
246
  // Add Visual Node on Map
247
  const node = document.createElement('div');
248
  node.className = 'geo-node';
249
+ // Random pos
250
+ const top = Math.random() * 80 + 10; // Keep within 10-90%
251
+ const left = Math.random() * 80 + 10;
252
+
253
+ node.style.top = `${top}%`;
254
+ node.style.left = `${left}%`;
255
  mapArea.appendChild(node);
256
 
257
+ // Draw Line from Node to Center
258
+ const line = document.createElementNS("http://www.w3.org/2000/svg", "line");
259
+ line.setAttribute("x1", `${left}%`);
260
+ line.setAttribute("y1", `${top}%`);
261
+ line.setAttribute("x2", "50%");
262
+ line.setAttribute("y2", "50%");
263
+ line.setAttribute("stroke", "#00f0ff");
264
+ line.setAttribute("stroke-width", "2");
265
+ line.setAttribute("stroke-opacity", "0.5");
266
+ line.setAttribute("stroke-dasharray", "5,5");
267
+
268
+ // Animate the line
269
+ const animate = document.createElementNS("http://www.w3.org/2000/svg", "animate");
270
+ animate.setAttribute("attributeName", "stroke-dashoffset");
271
+ animate.setAttribute("from", "100");
272
+ animate.setAttribute("to", "0");
273
+ animate.setAttribute("dur", "1s");
274
+ animate.setAttribute("repeatCount", "1");
275
+
276
+ line.appendChild(animate);
277
+ svg.appendChild(line);
278
+
279
+ // Remove line and node after animation
280
+ setTimeout(() => {
281
+ node.remove();
282
+ line.remove();
283
+ }, 2000);
284
 
285
  } catch(e) { /* Silent fail if backend down */ }
286
  };
287
+ setInterval(fetchMapData, 1500);
288
  }
289
 
290
+ // --- 7. Terminal Logic ---
291
+ function toggleTerminal() {
292
+ const modal = document.getElementById('terminal-modal');
293
+ const input = document.getElementById('terminal-input');
294
+
295
+ if (modal.classList.contains('hidden')) {
296
+ modal.classList.remove('hidden');
297
+ input.focus();
298
+ } else {
299
+ modal.classList.add('hidden');
300
+ }
301
+ }
302
+
303
+ function setupTerminal() {
304
+ const input = document.getElementById('terminal-input');
305
+ const output = document.getElementById('terminal-output');
306
+
307
+ input.addEventListener('keypress', function (e) {
308
+ if (e.key === 'Enter') {
309
+ const command = input.value.trim();
310
+ if (command) {
311
+ printToTerminal(`root@sys:~$ ${command}`);
312
+ executeCommand(command);
313
+ }
314
+ input.value = '';
315
+ }
316
+ });
317
+ }
318
+
319
+ function printToTerminal(text, color = 'text-green-400') {
320
+ const output = document.getElementById('terminal-output');
321
+ const p = document.createElement('p');
322
+ p.className = color + " font-mono";
323
+ p.innerText = text;
324
+ output.appendChild(p);
325
+ output.scrollTop = output.scrollHeight;
326
+ }
327
+
328
+ async function executeCommand(cmd) {
329
+ const output = document.getElementById('terminal-output');
330
+
331
+ // Simulated commands logic
332
+ switch(cmd.toLowerCase()) {
333
+ case 'help':
334
+ printToTerminal("Available commands: status, scan, clear, uptime, hack (fun)");
335
+ break;
336
+ case 'clear':
337
+ output.innerHTML = '';
338
+ break;
339
+ case 'uptime':
340
+ printToTerminal(`System uptime: ${Math.floor(Math.random() * 100)} days, ${Math.floor(Math.random()*24)} hours`);
341
+ break;
342
+ case 'status':
343
+ printToTerminal("Checking systems...", "text-yellow-400");
344
+ setTimeout(() => {
345
+ printToTerminal(">> Firewall: ACTIVE");
346
+ printToTerminal(">> Encryption: 256-bit AES");
347
+ printToTerminal(">> All systems nominal.", "text-green-400");
348
+ }, 800);
349
+ break;
350
+ default:
351
+ printToTerminal(`Command not found: ${cmd}`, "text-red-400");
352
+ }
353
+ }
354
  // 5. Vulnerabilities Logic
355
  async function startVulnStream() {
356
  const tableBody = document.getElementById('vuln-table-body');