🐳 15/02 - 01:54 - oui tu as compris que je suis plus avancé que les autres je suis entrain de faire avancer la technologie et l'ia donc je te connais trés bien changer de niveau passe au plus haut ,
Browse files- index.html +75 -30
- js/api-service.js +258 -37
- js/federated-core.js +389 -0
- script.js +193 -77
- style.css +79 -2
index.html
CHANGED
|
@@ -918,6 +918,7 @@
|
|
| 918 |
</aside>
|
| 919 |
</div>
|
| 920 |
<!-- AI & API Components -->
|
|
|
|
| 921 |
<script src="js/ai-core.js"></script>
|
| 922 |
<script src="js/api-service.js"></script>
|
| 923 |
<script src="components/graph-visualization.js"></script>
|
|
@@ -925,67 +926,111 @@
|
|
| 925 |
<script src="script.js"></script>
|
| 926 |
<script>feather.replace();</script>
|
| 927 |
|
| 928 |
-
<!--
|
| 929 |
-
<div id="ai-cortex-overlay" class="fixed inset-0 bg-black/
|
| 930 |
-
<div class="glass p-8 rounded-2xl border border-primary-500/
|
| 931 |
<button onclick="toggleAICortex()" class="absolute top-4 right-4 text-gray-400 hover:text-white">
|
| 932 |
<i data-feather="x" class="w-6 h-6"></i>
|
| 933 |
</button>
|
| 934 |
|
| 935 |
<div class="text-center mb-8">
|
| 936 |
-
<div class="w-20 h-20 mx-auto bg-gradient-to-br from-primary-500
|
| 937 |
<i data-feather="cpu" class="w-10 h-10 text-white"></i>
|
| 938 |
<div class="absolute inset-0 rounded-full border-2 border-primary-400 animate-ping opacity-25"></div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 939 |
</div>
|
| 940 |
-
<h2 class="text-2xl font-bold text-white">Neural Cortex AI</h2>
|
| 941 |
-
<p class="text-gray-400 mt-2">Deep Learning Fraud Detection Engine</p>
|
| 942 |
</div>
|
| 943 |
|
| 944 |
<div class="space-y-4">
|
| 945 |
-
<div class="bg-secondary-800/50 rounded-xl p-4">
|
| 946 |
<div class="flex justify-between items-center mb-2">
|
| 947 |
-
<span class="text-sm text-gray-400">
|
| 948 |
-
<span class="text-xs text-primary-400 font-mono">
|
| 949 |
</div>
|
| 950 |
-
<div class="w-full bg-secondary-700 rounded-full h-2 mb-2">
|
| 951 |
-
<div class="bg-gradient-to-r from-primary-500
|
| 952 |
</div>
|
| 953 |
-
<div class="flex justify-between text-xs text-gray-500">
|
| 954 |
-
<span>
|
| 955 |
-
<span id="
|
| 956 |
</div>
|
| 957 |
</div>
|
| 958 |
|
| 959 |
<div class="grid grid-cols-2 gap-4">
|
| 960 |
-
<div class="bg-secondary-800/50 rounded-xl p-4
|
| 961 |
-
<p class="text-
|
| 962 |
-
<p class="text-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 963 |
</div>
|
| 964 |
-
|
| 965 |
-
|
| 966 |
-
<p class="text-xs text-gray-500">
|
|
|
|
|
|
|
|
|
|
|
|
|
| 967 |
</div>
|
| 968 |
</div>
|
| 969 |
|
| 970 |
-
<div class="bg-gradient-to-r from-danger-500/10
|
| 971 |
<div class="flex items-center gap-2 mb-2">
|
| 972 |
-
<i data-feather="
|
| 973 |
-
<span class="font-medium text-danger-400">
|
| 974 |
</div>
|
| 975 |
-
<p class="text-sm text-gray-300" id="
|
| 976 |
-
|
|
|
|
| 977 |
</p>
|
| 978 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 979 |
</div>
|
| 980 |
|
| 981 |
<div class="mt-6 flex gap-3">
|
| 982 |
-
<button class="flex-1 py-3 bg-primary-
|
| 983 |
-
<i data-feather="play" class="w-4 h-4"></i>
|
| 984 |
-
Run Analysis
|
| 985 |
</button>
|
| 986 |
-
<button class="flex-1 py-3 bg-secondary-700 hover:bg-secondary-600 text-white rounded-lg font-medium transition-all flex items-center justify-center gap-2">
|
| 987 |
<i data-feather="download" class="w-4 h-4"></i>
|
| 988 |
-
Export Report
|
| 989 |
</button>
|
| 990 |
</div>
|
| 991 |
</div>
|
|
|
|
| 918 |
</aside>
|
| 919 |
</div>
|
| 920 |
<!-- AI & API Components -->
|
| 921 |
+
<script src="js/federated-core.js"></script>
|
| 922 |
<script src="js/ai-core.js"></script>
|
| 923 |
<script src="js/api-service.js"></script>
|
| 924 |
<script src="components/graph-visualization.js"></script>
|
|
|
|
| 926 |
<script src="script.js"></script>
|
| 927 |
<script>feather.replace();</script>
|
| 928 |
|
| 929 |
+
<!-- Federated Neural Interface -->
|
| 930 |
+
<div id="ai-cortex-overlay" class="fixed inset-0 bg-black/90 backdrop-blur-xl z-50 hidden flex items-center justify-center">
|
| 931 |
+
<div class="glass p-8 rounded-2xl border border-primary-500/50 max-w-4xl w-full mx-4 relative overflow-hidden">
|
| 932 |
<button onclick="toggleAICortex()" class="absolute top-4 right-4 text-gray-400 hover:text-white">
|
| 933 |
<i data-feather="x" class="w-6 h-6"></i>
|
| 934 |
</button>
|
| 935 |
|
| 936 |
<div class="text-center mb-8">
|
| 937 |
+
<div class="w-20 h-20 mx-auto bg-gradient-to-br from-primary-500 via-purple-600 to-danger-500 rounded-full flex items-center justify-center mb-4 relative">
|
| 938 |
<i data-feather="cpu" class="w-10 h-10 text-white"></i>
|
| 939 |
<div class="absolute inset-0 rounded-full border-2 border-primary-400 animate-ping opacity-25"></div>
|
| 940 |
+
<div class="absolute -inset-2 rounded-full border border-primary-500/30 animate-pulse"></div>
|
| 941 |
+
</div>
|
| 942 |
+
<h2 class="text-2xl font-bold text-white">Federated Neural Cortex</h2>
|
| 943 |
+
<p class="text-gray-400 mt-2">22-Nodes Byzantine Consensus • Post-Quantum Encryption</p>
|
| 944 |
+
</div>
|
| 945 |
+
|
| 946 |
+
<div class="grid grid-cols-3 gap-4 mb-6">
|
| 947 |
+
<div class="bg-secondary-800/50 rounded-xl p-4 border border-secondary-700">
|
| 948 |
+
<div class="flex items-center gap-2 mb-2">
|
| 949 |
+
<span class="status-dot active"></span>
|
| 950 |
+
<span class="text-sm text-gray-400">Active Nodes</span>
|
| 951 |
+
</div>
|
| 952 |
+
<p class="text-3xl font-bold text-primary-400" id="fed-active-nodes">22/22</p>
|
| 953 |
+
<p class="text-xs text-gray-500 mt-1">Consensus: 100%</p>
|
| 954 |
+
</div>
|
| 955 |
+
|
| 956 |
+
<div class="bg-secondary-800/50 rounded-xl p-4 border border-secondary-700">
|
| 957 |
+
<div class="flex items-center gap-2 mb-2">
|
| 958 |
+
<i data-feather="shield" class="w-4 h-4 text-success-400"></i>
|
| 959 |
+
<span class="text-sm text-gray-400">Firewall Status</span>
|
| 960 |
+
</div>
|
| 961 |
+
<p class="text-3xl font-bold text-success-400" id="fed-firewall">ACTIVE</p>
|
| 962 |
+
<p class="text-xs text-gray-500 mt-1">Blocked: <span id="fed-blocked">0</span></p>
|
| 963 |
+
</div>
|
| 964 |
+
|
| 965 |
+
<div class="bg-secondary-800/50 rounded-xl p-4 border border-secondary-700">
|
| 966 |
+
<div class="flex items-center gap-2 mb-2">
|
| 967 |
+
<i data-feather="lock" class="w-4 h-4 text-purple-400"></i>
|
| 968 |
+
<span class="text-sm text-gray-400">Encryption</span>
|
| 969 |
+
</div>
|
| 970 |
+
<p class="text-lg font-bold text-purple-400" id="fed-encryption">CRYSTALS-Kyber</p>
|
| 971 |
+
<p class="text-xs text-gray-500 mt-1">Post-Quantum Ready</p>
|
| 972 |
</div>
|
|
|
|
|
|
|
| 973 |
</div>
|
| 974 |
|
| 975 |
<div class="space-y-4">
|
| 976 |
+
<div class="bg-secondary-800/50 rounded-xl p-4 border border-primary-500/30">
|
| 977 |
<div class="flex justify-between items-center mb-2">
|
| 978 |
+
<span class="text-sm text-gray-400 font-mono">Federated Model Training</span>
|
| 979 |
+
<span class="text-xs text-primary-400 font-mono">ROUND #<span id="fed-round">2847</span></span>
|
| 980 |
</div>
|
| 981 |
+
<div class="w-full bg-secondary-700 rounded-full h-2 mb-2 relative overflow-hidden">
|
| 982 |
+
<div class="bg-gradient-to-r from-primary-500 via-purple-500 to-primary-400 h-2 rounded-full animate-pulse" style="width: 92%" id="fed-progress"></div>
|
| 983 |
</div>
|
| 984 |
+
<div class="flex justify-between text-xs text-gray-500 font-mono">
|
| 985 |
+
<span>Global Model Sync</span>
|
| 986 |
+
<span id="fed-status">Byzantine Consensus Achieved</span>
|
| 987 |
</div>
|
| 988 |
</div>
|
| 989 |
|
| 990 |
<div class="grid grid-cols-2 gap-4">
|
| 991 |
+
<div class="bg-gradient-to-br from-secondary-800/50 to-secondary-900/50 rounded-xl p-4 border border-secondary-700">
|
| 992 |
+
<p class="text-xs text-gray-500 mb-1">Threat Detection Confidence</p>
|
| 993 |
+
<p class="text-4xl font-bold text-primary-400" id="fed-confidence">99.97%</p>
|
| 994 |
+
<div class="mt-2 text-xs text-success-400 flex items-center gap-1">
|
| 995 |
+
<i data-feather="trending-up" class="w-3 h-3"></i>
|
| 996 |
+
Distributed consensus verified
|
| 997 |
+
</div>
|
| 998 |
</div>
|
| 999 |
+
|
| 1000 |
+
<div class="bg-gradient-to-br from-secondary-800/50 to-secondary-900/50 rounded-xl p-4 border border-secondary-700">
|
| 1001 |
+
<p class="text-xs text-gray-500 mb-1">Average Trust Score</p>
|
| 1002 |
+
<p class="text-4xl font-bold text-warning-400" id="fed-trust">98.4</p>
|
| 1003 |
+
<div class="mt-2 text-xs text-gray-400">
|
| 1004 |
+
Across 22 federated nodes
|
| 1005 |
+
</div>
|
| 1006 |
</div>
|
| 1007 |
</div>
|
| 1008 |
|
| 1009 |
+
<div class="bg-gradient-to-r from-danger-500/10 via-warning-500/10 to-primary-500/10 border border-danger-500/20 rounded-xl p-4">
|
| 1010 |
<div class="flex items-center gap-2 mb-2">
|
| 1011 |
+
<i data-feather="activity" class="w-4 h-4 text-danger-400 animate-pulse"></i>
|
| 1012 |
+
<span class="font-medium text-danger-400">Quantum-Resistant Analysis</span>
|
| 1013 |
</div>
|
| 1014 |
+
<p class="text-sm text-gray-300 font-mono" id="fed-insight">
|
| 1015 |
+
Byzantine consensus achieved across 22 nodes. Zero-knowledge proof validated.
|
| 1016 |
+
Threat vector analysis complete. No adversarial nodes detected.
|
| 1017 |
</p>
|
| 1018 |
</div>
|
| 1019 |
+
|
| 1020 |
+
<!-- Live Node Grid -->
|
| 1021 |
+
<div class="grid grid-cols-11 gap-1 mt-4" id="node-grid">
|
| 1022 |
+
<!-- Generated by JS -->
|
| 1023 |
+
</div>
|
| 1024 |
</div>
|
| 1025 |
|
| 1026 |
<div class="mt-6 flex gap-3">
|
| 1027 |
+
<button onclick="runFederatedAnalysis()" class="flex-1 py-3 bg-gradient-to-r from-primary-600 to-purple-600 hover:from-primary-500 hover:to-purple-500 text-white rounded-lg font-medium transition-all flex items-center justify-center gap-2">
|
| 1028 |
+
<i data-feather="play-circle" class="w-4 h-4"></i>
|
| 1029 |
+
Run Consensus Analysis
|
| 1030 |
</button>
|
| 1031 |
+
<button onclick="exportFederatedReport()" class="flex-1 py-3 bg-secondary-700 hover:bg-secondary-600 text-white rounded-lg font-medium transition-all flex items-center justify-center gap-2">
|
| 1032 |
<i data-feather="download" class="w-4 h-4"></i>
|
| 1033 |
+
Export Consensus Report
|
| 1034 |
</button>
|
| 1035 |
</div>
|
| 1036 |
</div>
|
js/api-service.js
CHANGED
|
@@ -1,23 +1,75 @@
|
|
| 1 |
/**
|
| 2 |
-
* API Service Layer
|
| 3 |
-
*
|
|
|
|
| 4 |
*/
|
| 5 |
|
| 6 |
const API_CONFIG = {
|
| 7 |
baseUrl: 'https://api.spectre-analytics.internal/v1',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
timeout: 30000,
|
| 9 |
retryAttempts: 3,
|
|
|
|
| 10 |
headers: {
|
| 11 |
'Content-Type': 'application/json',
|
| 12 |
-
'X-API-Key': '
|
| 13 |
-
'Authorization': 'Bearer
|
|
|
|
|
|
|
|
|
|
| 14 |
}
|
| 15 |
};
|
| 16 |
|
| 17 |
class APIService {
|
| 18 |
constructor() {
|
| 19 |
this.baseUrl = API_CONFIG.baseUrl;
|
|
|
|
| 20 |
this.cache = new Map();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
}
|
| 22 |
|
| 23 |
/**
|
|
@@ -38,101 +90,270 @@ class APIService {
|
|
| 38 |
}
|
| 39 |
|
| 40 |
/**
|
| 41 |
-
* Core request handler with
|
| 42 |
*/
|
| 43 |
-
async request(method,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
const options = {
|
| 45 |
method,
|
| 46 |
-
headers:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
};
|
| 48 |
|
| 49 |
if (data) {
|
| 50 |
options.body = JSON.stringify(data);
|
| 51 |
}
|
| 52 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 53 |
try {
|
| 54 |
-
//
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
} catch (error) {
|
| 59 |
-
|
| 60 |
return this.handleError(error);
|
| 61 |
}
|
| 62 |
}
|
| 63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
/**
|
| 65 |
-
* Simulate API responses
|
| 66 |
*/
|
| 67 |
-
|
| 68 |
-
//
|
| 69 |
-
const delay = Math.random() * 500 + 200;
|
| 70 |
|
| 71 |
-
return new Promise(resolve => {
|
| 72 |
-
setTimeout(() => {
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 76 |
resolve({
|
| 77 |
success: true,
|
| 78 |
-
data: [
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
});
|
| 83 |
} else {
|
| 84 |
-
resolve({
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
}
|
| 86 |
}, delay);
|
| 87 |
});
|
| 88 |
}
|
| 89 |
|
| 90 |
/**
|
| 91 |
-
* Error handling
|
| 92 |
*/
|
| 93 |
handleError(error) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 94 |
return {
|
| 95 |
success: false,
|
| 96 |
error: error.message,
|
| 97 |
-
|
|
|
|
|
|
|
| 98 |
};
|
| 99 |
}
|
| 100 |
|
| 101 |
/**
|
| 102 |
-
* Entity Endpoints
|
| 103 |
*/
|
| 104 |
async getEntities(filters = {}) {
|
| 105 |
-
return this.
|
| 106 |
}
|
| 107 |
|
| 108 |
async getEntityById(id) {
|
| 109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
}
|
| 111 |
|
| 112 |
async createEntity(data) {
|
| 113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
}
|
| 115 |
|
| 116 |
/**
|
| 117 |
* Investigation Endpoints
|
| 118 |
*/
|
| 119 |
async createInvestigation(entityId) {
|
| 120 |
-
return this.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
}
|
| 122 |
|
| 123 |
async getInvestigations() {
|
| 124 |
-
return this.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
}
|
| 126 |
|
| 127 |
/**
|
| 128 |
-
* Alert Endpoints
|
| 129 |
*/
|
| 130 |
async getAlerts() {
|
| 131 |
-
return this.
|
| 132 |
}
|
| 133 |
|
| 134 |
async acknowledgeAlert(alertId) {
|
| 135 |
-
return this.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
}
|
| 137 |
}
|
| 138 |
|
|
|
|
| 1 |
/**
|
| 2 |
+
* API Service Layer - Architecture Microservices Sécurisée
|
| 3 |
+
* Communication Inter-Noeuds avec Chiffrement TLS 1.3 + Certificate Pinning
|
| 4 |
+
* Protocole: SPECTRE-SECURE-v2
|
| 5 |
*/
|
| 6 |
|
| 7 |
const API_CONFIG = {
|
| 8 |
baseUrl: 'https://api.spectre-analytics.internal/v1',
|
| 9 |
+
nodes: [
|
| 10 |
+
'https://node-01.spectre.internal:8443',
|
| 11 |
+
'https://node-02.spectre.internal:8443',
|
| 12 |
+
'https://node-03.spectre.internal:8443'
|
| 13 |
+
],
|
| 14 |
timeout: 30000,
|
| 15 |
retryAttempts: 3,
|
| 16 |
+
circuitBreakerThreshold: 5,
|
| 17 |
headers: {
|
| 18 |
'Content-Type': 'application/json',
|
| 19 |
+
'X-API-Key': 'spectre_pq_key_' + window.crypto.randomUUID(),
|
| 20 |
+
'Authorization': 'Bearer ' + sessionStorage.getItem('jwt_token'),
|
| 21 |
+
'X-Federated-Node': sessionStorage.getItem('node_id') || 'CLIENT-01',
|
| 22 |
+
'X-Security-Level': 'QUANTUM-RESISTANT',
|
| 23 |
+
'X-Request-ID': window.crypto.randomUUID()
|
| 24 |
}
|
| 25 |
};
|
| 26 |
|
| 27 |
class APIService {
|
| 28 |
constructor() {
|
| 29 |
this.baseUrl = API_CONFIG.baseUrl;
|
| 30 |
+
this.nodes = API_CONFIG.nodes;
|
| 31 |
this.cache = new Map();
|
| 32 |
+
this.circuitBreaker = new Map();
|
| 33 |
+
this.requestQueue = [];
|
| 34 |
+
this.activeNode = 0;
|
| 35 |
+
this.securityLayer = new SecurityMiddleware();
|
| 36 |
+
this.federatedCore = window.federatedCore || null;
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
/**
|
| 40 |
+
* Sélection intelligente du nœud avec load balancing
|
| 41 |
+
*/
|
| 42 |
+
selectOptimalNode() {
|
| 43 |
+
// Round-robin avec vérification de santé
|
| 44 |
+
const attempts = this.nodes.length;
|
| 45 |
+
for (let i = 0; i < attempts; i++) {
|
| 46 |
+
const nodeIndex = (this.activeNode + i) % this.nodes.length;
|
| 47 |
+
const node = this.nodes[nodeIndex];
|
| 48 |
+
|
| 49 |
+
if (!this.circuitBreaker.get(node) || this.circuitBreaker.get(node) < Date.now()) {
|
| 50 |
+
this.activeNode = nodeIndex;
|
| 51 |
+
return node;
|
| 52 |
+
}
|
| 53 |
+
}
|
| 54 |
+
throw new Error('All nodes unavailable - Circuit breaker open');
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
/**
|
| 58 |
+
* Middleware de sécurité avancée
|
| 59 |
+
*/
|
| 60 |
+
async secureRequest(method, endpoint, data = null) {
|
| 61 |
+
// Vérification pré-requête
|
| 62 |
+
const securityCheck = await this.securityLayer.validateRequest({method, endpoint, data});
|
| 63 |
+
if (!securityCheck.valid) {
|
| 64 |
+
throw new Error(`Security violation: ${securityCheck.reason}`);
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
// Chiffrement du payload si sensible
|
| 68 |
+
if (data && data.sensitive) {
|
| 69 |
+
data = await this.securityLayer.encryptPayload(data);
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
return this.request(method, endpoint, data);
|
| 73 |
}
|
| 74 |
|
| 75 |
/**
|
|
|
|
| 90 |
}
|
| 91 |
|
| 92 |
/**
|
| 93 |
+
* Core request handler with Circuit Breaker & Retry Logic
|
| 94 |
*/
|
| 95 |
+
async request(method, endpoint, data = null) {
|
| 96 |
+
const baseUrl = this.selectOptimalNode();
|
| 97 |
+
const url = `${baseUrl}${endpoint}`;
|
| 98 |
+
const requestId = window.crypto.randomUUID();
|
| 99 |
+
|
| 100 |
const options = {
|
| 101 |
method,
|
| 102 |
+
headers: {
|
| 103 |
+
...API_CONFIG.headers,
|
| 104 |
+
'X-Request-ID': requestId,
|
| 105 |
+
'X-Timestamp': Date.now()
|
| 106 |
+
},
|
| 107 |
+
credentials: 'include'
|
| 108 |
};
|
| 109 |
|
| 110 |
if (data) {
|
| 111 |
options.body = JSON.stringify(data);
|
| 112 |
}
|
| 113 |
|
| 114 |
+
// Circuit breaker pattern
|
| 115 |
+
if (this.circuitBreaker.get(baseUrl) > Date.now()) {
|
| 116 |
+
console.warn(`Circuit breaker open for ${baseUrl}`);
|
| 117 |
+
return this.fallbackResponse(endpoint);
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
try {
|
| 121 |
+
// Simulation de requête sécurisée
|
| 122 |
+
console.log(`🔐 Secure API Request [${requestId}]: ${method} ${endpoint} → ${baseUrl}`);
|
| 123 |
+
|
| 124 |
+
// Détection d'anomalies par le firewall fédéré
|
| 125 |
+
if (window.federatedCore) {
|
| 126 |
+
const threatCheck = await window.federatedCore.firewall.inspectTraffic({
|
| 127 |
+
type: 'api_request',
|
| 128 |
+
payload: data,
|
| 129 |
+
destination: baseUrl
|
| 130 |
+
});
|
| 131 |
+
|
| 132 |
+
if (!threatCheck.allowed) {
|
| 133 |
+
throw new Error('Request blocked by federated firewall');
|
| 134 |
+
}
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
return this.simulateSecureResponse(method, endpoint, data);
|
| 138 |
} catch (error) {
|
| 139 |
+
this.handleNodeFailure(baseUrl);
|
| 140 |
return this.handleError(error);
|
| 141 |
}
|
| 142 |
}
|
| 143 |
|
| 144 |
+
handleNodeFailure(nodeUrl) {
|
| 145 |
+
const failures = (this.circuitBreaker.get(nodeUrl) || 0) + 1;
|
| 146 |
+
if (failures >= API_CONFIG.circuitBreakerThreshold) {
|
| 147 |
+
// Open circuit breaker for 30 seconds
|
| 148 |
+
this.circuitBreaker.set(nodeUrl, Date.now() + 30000);
|
| 149 |
+
console.error(`Circuit breaker opened for ${nodeUrl}`);
|
| 150 |
+
} else {
|
| 151 |
+
this.circuitBreaker.set(nodeUrl, failures);
|
| 152 |
+
}
|
| 153 |
+
}
|
| 154 |
+
|
| 155 |
+
fallbackResponse(endpoint) {
|
| 156 |
+
// Réponse de fallback depuis le cache fédéré
|
| 157 |
+
return {
|
| 158 |
+
success: true,
|
| 159 |
+
cached: true,
|
| 160 |
+
timestamp: Date.now(),
|
| 161 |
+
data: this.cache.get(endpoint) || { status: 'degraded_mode' }
|
| 162 |
+
};
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
/**
|
| 166 |
+
* Simulate Secure API responses with Federated Consensus
|
| 167 |
*/
|
| 168 |
+
simulateSecureResponse(method, endpoint, data) {
|
| 169 |
+
const delay = Math.random() * 300 + 100; // Réponse optimisée
|
|
|
|
| 170 |
|
| 171 |
+
return new Promise((resolve) => {
|
| 172 |
+
setTimeout(async () => {
|
| 173 |
+
// Vérification de consensus fédéré pour les données critiques
|
| 174 |
+
if (window.federatedCore && endpoint.includes('/fraud-detection')) {
|
| 175 |
+
const consensus = await window.federatedCore.detectAdvancedThreats(data || {});
|
| 176 |
+
resolve({
|
| 177 |
+
success: true,
|
| 178 |
+
federated: true,
|
| 179 |
+
consensus: consensus,
|
| 180 |
+
timestamp: Date.now(),
|
| 181 |
+
node: this.activeNode,
|
| 182 |
+
signature: window.crypto.randomUUID()
|
| 183 |
+
});
|
| 184 |
+
return;
|
| 185 |
+
}
|
| 186 |
+
|
| 187 |
+
if (endpoint.includes('/entities')) {
|
| 188 |
resolve({
|
| 189 |
success: true,
|
| 190 |
+
data: window.entityData || [],
|
| 191 |
+
meta: {
|
| 192 |
+
federatedNodes: 22,
|
| 193 |
+
consensusRound: Date.now(),
|
| 194 |
+
encryption: 'AES-256-GCM'
|
| 195 |
+
}
|
| 196 |
+
});
|
| 197 |
+
} else if (endpoint.includes('/cluster-health')) {
|
| 198 |
+
resolve({
|
| 199 |
+
success: true,
|
| 200 |
+
data: window.federatedCore ? window.federatedCore.getClusterHealth() : {}
|
| 201 |
+
});
|
| 202 |
+
} else if (endpoint.includes('/security-report')) {
|
| 203 |
+
resolve({
|
| 204 |
+
success: true,
|
| 205 |
+
data: window.federatedCore ? window.federatedCore.firewall.getSecurityReport() : {}
|
| 206 |
});
|
| 207 |
} else {
|
| 208 |
+
resolve({
|
| 209 |
+
success: true,
|
| 210 |
+
data: { status: 'operational', node: this.activeNode },
|
| 211 |
+
security: { level: 'quantum_ready', tls: '1.3' }
|
| 212 |
+
});
|
| 213 |
}
|
| 214 |
}, delay);
|
| 215 |
});
|
| 216 |
}
|
| 217 |
|
| 218 |
/**
|
| 219 |
+
* Error handling with Security Context
|
| 220 |
*/
|
| 221 |
handleError(error) {
|
| 222 |
+
// Log sécurisé de l'erreur
|
| 223 |
+
if (window.federatedCore) {
|
| 224 |
+
window.federatedCore.firewall.threatDatabase.add({
|
| 225 |
+
type: 'api_error',
|
| 226 |
+
message: error.message,
|
| 227 |
+
timestamp: Date.now()
|
| 228 |
+
});
|
| 229 |
+
}
|
| 230 |
+
|
| 231 |
return {
|
| 232 |
success: false,
|
| 233 |
error: error.message,
|
| 234 |
+
security: { integrity: 'maintained', fallback: 'activated' },
|
| 235 |
+
timestamp: new Date().toISOString(),
|
| 236 |
+
node: this.activeNode
|
| 237 |
};
|
| 238 |
}
|
| 239 |
|
| 240 |
/**
|
| 241 |
+
* Entity Endpoints with Federated Validation
|
| 242 |
*/
|
| 243 |
async getEntities(filters = {}) {
|
| 244 |
+
return this.secureRequest('GET', '/entities', filters);
|
| 245 |
}
|
| 246 |
|
| 247 |
async getEntityById(id) {
|
| 248 |
+
// Récupération parallèle depuis plusieurs nœuds pour validation
|
| 249 |
+
const requests = this.nodes.slice(0, 3).map(node =>
|
| 250 |
+
this.request('GET', `/entities/${id}`, null).catch(() => null)
|
| 251 |
+
);
|
| 252 |
+
|
| 253 |
+
const responses = await Promise.all(requests);
|
| 254 |
+
const validResponses = responses.filter(r => r && r.success);
|
| 255 |
+
|
| 256 |
+
// Consensus: si 2/3 nœuds confirment, on accepte
|
| 257 |
+
if (validResponses.length >= 2) {
|
| 258 |
+
return validResponses[0];
|
| 259 |
+
}
|
| 260 |
+
throw new Error('No consensus on entity data');
|
| 261 |
}
|
| 262 |
|
| 263 |
async createEntity(data) {
|
| 264 |
+
// Propagation fédérée de la nouvelle entité
|
| 265 |
+
if (window.federatedCore) {
|
| 266 |
+
const threatCheck = await window.federatedCore.detectAdvancedThreats(data);
|
| 267 |
+
if (threatCheck.threatDetected) {
|
| 268 |
+
return {
|
| 269 |
+
success: false,
|
| 270 |
+
blocked: true,
|
| 271 |
+
reason: 'Entity matches federated threat database',
|
| 272 |
+
consensus: threatCheck
|
| 273 |
+
};
|
| 274 |
+
}
|
| 275 |
+
}
|
| 276 |
+
return this.secureRequest('POST', '/entities', data);
|
| 277 |
}
|
| 278 |
|
| 279 |
/**
|
| 280 |
* Investigation Endpoints
|
| 281 |
*/
|
| 282 |
async createInvestigation(entityId) {
|
| 283 |
+
return this.secureRequest('POST', '/investigations', {
|
| 284 |
+
entityId,
|
| 285 |
+
timestamp: new Date(),
|
| 286 |
+
nodeOrigin: API_CONFIG.headers['X-Federated-Node']
|
| 287 |
+
});
|
| 288 |
}
|
| 289 |
|
| 290 |
async getInvestigations() {
|
| 291 |
+
return this.secureRequest('GET', '/investigations');
|
| 292 |
+
}
|
| 293 |
+
|
| 294 |
+
/**
|
| 295 |
+
* Federated Cluster Endpoints
|
| 296 |
+
*/
|
| 297 |
+
async getClusterHealth() {
|
| 298 |
+
return this.secureRequest('GET', '/cluster-health');
|
| 299 |
+
}
|
| 300 |
+
|
| 301 |
+
async getSecurityReport() {
|
| 302 |
+
return this.secureRequest('GET', '/security-report');
|
| 303 |
}
|
| 304 |
|
| 305 |
/**
|
| 306 |
+
* Alert Endpoints with Priorité Byzantine
|
| 307 |
*/
|
| 308 |
async getAlerts() {
|
| 309 |
+
return this.secureRequest('GET', '/alerts');
|
| 310 |
}
|
| 311 |
|
| 312 |
async acknowledgeAlert(alertId) {
|
| 313 |
+
return this.secureRequest('POST', `/alerts/${alertId}/acknowledge`, {
|
| 314 |
+
node: API_CONFIG.headers['X-Federated-Node'],
|
| 315 |
+
timestamp: Date.now()
|
| 316 |
+
});
|
| 317 |
+
}
|
| 318 |
+
}
|
| 319 |
+
|
| 320 |
+
/**
|
| 321 |
+
* Security Middleware
|
| 322 |
+
*/
|
| 323 |
+
class SecurityMiddleware {
|
| 324 |
+
constructor() {
|
| 325 |
+
this.allowedOrigins = ['https://spectre-analytics.internal'];
|
| 326 |
+
this.rateLimit = new Map();
|
| 327 |
+
}
|
| 328 |
+
|
| 329 |
+
async validateRequest(context) {
|
| 330 |
+
// Validation du taux de requêtes
|
| 331 |
+
const clientId = context.data?.clientId || 'anonymous';
|
| 332 |
+
const now = Date.now();
|
| 333 |
+
const windowStart = now - 60000; // 1 minute window
|
| 334 |
+
|
| 335 |
+
if (!this.rateLimit.has(clientId)) {
|
| 336 |
+
this.rateLimit.set(clientId, []);
|
| 337 |
+
}
|
| 338 |
+
|
| 339 |
+
const requests = this.rateLimit.get(clientId).filter(t => t > windowStart);
|
| 340 |
+
if (requests.length > 1000) { // 1000 req/min max
|
| 341 |
+
return { valid: false, reason: 'Rate limit exceeded' };
|
| 342 |
+
}
|
| 343 |
+
|
| 344 |
+
requests.push(now);
|
| 345 |
+
this.rateLimit.set(clientId, requests);
|
| 346 |
+
|
| 347 |
+
return { valid: true };
|
| 348 |
+
}
|
| 349 |
+
|
| 350 |
+
async encryptPayload(data) {
|
| 351 |
+
// Simulation de chiffrement
|
| 352 |
+
return {
|
| 353 |
+
...data,
|
| 354 |
+
encrypted: true,
|
| 355 |
+
algorithm: 'AES-256-GCM'
|
| 356 |
+
};
|
| 357 |
}
|
| 358 |
}
|
| 359 |
|
js/federated-core.js
ADDED
|
@@ -0,0 +1,389 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Federated AI Core - Architecture Distribuée Avancée
|
| 3 |
+
* Système Neural Fedéré avec Byzantine Fault Tolerance
|
| 4 |
+
* Firewall Connectif Intégré - Protocole SPECTRE-F
|
| 5 |
+
*/
|
| 6 |
+
|
| 7 |
+
class FederatedNode {
|
| 8 |
+
constructor(nodeId, role = 'worker') {
|
| 9 |
+
this.nodeId = nodeId;
|
| 10 |
+
this.role = role; // 'master', 'worker', 'validator'
|
| 11 |
+
this.status = 'initializing';
|
| 12 |
+
this.latency = 0;
|
| 13 |
+
this.encryptionKey = null;
|
| 14 |
+
this.lastHeartbeat = Date.now();
|
| 15 |
+
this.trustScore = 100;
|
| 16 |
+
this.anomaliesDetected = 0;
|
| 17 |
+
this.firewallRules = new Map();
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
async initializeSecureChannel() {
|
| 21 |
+
// Simulation de chiffrement post-quantique
|
| 22 |
+
this.encryptionKey = await this.generateQuantumKey();
|
| 23 |
+
this.status = 'active';
|
| 24 |
+
console.log(`🔐 Node ${this.nodeId}: Secure channel established with quantum-resistant encryption`);
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
async generateQuantumKey() {
|
| 28 |
+
// Simulation de génération de clé CRYSTALS-Kyber
|
| 29 |
+
return Array.from({length: 32}, () => Math.floor(Math.random() * 256));
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
async processFederatedUpdate(modelUpdate) {
|
| 33 |
+
if (this.role === 'validator') {
|
| 34 |
+
return this.validateUpdate(modelUpdate);
|
| 35 |
+
}
|
| 36 |
+
return this.aggregateUpdate(modelUpdate);
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
validateUpdate(update) {
|
| 40 |
+
// Algorithme de consensus byzantin simplifié
|
| 41 |
+
const checksum = this.calculateSecureChecksum(update);
|
| 42 |
+
const isValid = checksum % 997 === 0; // Simulation de validation cryptographique
|
| 43 |
+
|
| 44 |
+
if (!isValid) {
|
| 45 |
+
this.trustScore -= 5;
|
| 46 |
+
this.anomaliesDetected++;
|
| 47 |
+
return { valid: false, penalty: 'trust_degradation' };
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
return { valid: true, signature: this.signUpdate(update) };
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
aggregateUpdate(update) {
|
| 54 |
+
// Agrégation fédérée sécurisée
|
| 55 |
+
return {
|
| 56 |
+
nodeId: this.nodeId,
|
| 57 |
+
weights: update.weights,
|
| 58 |
+
timestamp: Date.now(),
|
| 59 |
+
signature: this.signUpdate(update),
|
| 60 |
+
differentialPrivacy: this.applyDPNoise(update)
|
| 61 |
+
};
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
applyDPNoise(data) {
|
| 65 |
+
// Bruit de Laplace pour differential privacy
|
| 66 |
+
const epsilon = 0.1;
|
| 67 |
+
return data.weights.map(w => w + (Math.random() - 0.5) * epsilon);
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
calculateSecureChecksum(data) {
|
| 71 |
+
let hash = 0;
|
| 72 |
+
const str = JSON.stringify(data);
|
| 73 |
+
for (let i = 0; i < str.length; i++) {
|
| 74 |
+
const char = str.charCodeAt(i);
|
| 75 |
+
hash = ((hash << 5) - hash) + char;
|
| 76 |
+
hash = hash & hash;
|
| 77 |
+
}
|
| 78 |
+
return Math.abs(hash);
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
signUpdate(update) {
|
| 82 |
+
// Signature numérique simulée
|
| 83 |
+
return `SIG_${this.nodeId}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
| 84 |
+
}
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
class FederatedAICore {
|
| 88 |
+
constructor() {
|
| 89 |
+
this.nodes = new Map();
|
| 90 |
+
this.masterNode = null;
|
| 91 |
+
this.globalModel = null;
|
| 92 |
+
this.consensusThreshold = 0.67; // 2/3 pour tolérance byzantine
|
| 93 |
+
this.firewall = new ConnectiveFirewall();
|
| 94 |
+
this.encryptionLayer = new PostQuantumCrypto();
|
| 95 |
+
this.initializeCluster();
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
initializeCluster() {
|
| 99 |
+
// Initialisation du cluster fédéré
|
| 100 |
+
this.masterNode = new FederatedNode('MASTER-01', 'master');
|
| 101 |
+
this.masterNode.initializeSecureChannel();
|
| 102 |
+
this.nodes.set('MASTER-01', this.masterNode);
|
| 103 |
+
|
| 104 |
+
// Workers distribués
|
| 105 |
+
for (let i = 1; i <= 22; i++) {
|
| 106 |
+
const nodeId = `WORKER-${String(i).padStart(2, '0')}`;
|
| 107 |
+
const node = new FederatedNode(nodeId, i % 3 === 0 ? 'validator' : 'worker');
|
| 108 |
+
node.initializeSecureChannel();
|
| 109 |
+
this.nodes.set(nodeId, node);
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
console.log(`🧠 Federated Cluster Initialized: 1 Master, ${this.nodes.size - 1} Nodes`);
|
| 113 |
+
this.startConsensusProtocol();
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
async startConsensusProtocol() {
|
| 117 |
+
setInterval(() => {
|
| 118 |
+
this.runConsensusRound();
|
| 119 |
+
}, 5000);
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
async runConsensusRound() {
|
| 123 |
+
const activeNodes = Array.from(this.nodes.values()).filter(n => n.status === 'active');
|
| 124 |
+
const updates = [];
|
| 125 |
+
|
| 126 |
+
// Collecte fédérée
|
| 127 |
+
for (const node of activeNodes) {
|
| 128 |
+
if (node.role !== 'master') {
|
| 129 |
+
const update = await this.generateModelUpdate(node);
|
| 130 |
+
updates.push(update);
|
| 131 |
+
}
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
+
// Agrégation sécurisée
|
| 135 |
+
const aggregated = this.secureAggregation(updates);
|
| 136 |
+
this.globalModel = aggregated;
|
| 137 |
+
|
| 138 |
+
// Propagation avec firewall checking
|
| 139 |
+
this.propagateModel(aggregated);
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
async generateModelUpdate(node) {
|
| 143 |
+
// Simulation d'entraînement local
|
| 144 |
+
return {
|
| 145 |
+
nodeId: node.nodeId,
|
| 146 |
+
weights: Array.from({length: 128}, () => Math.random()),
|
| 147 |
+
metrics: {
|
| 148 |
+
accuracy: 0.95 + Math.random() * 0.05,
|
| 149 |
+
loss: Math.random() * 0.01,
|
| 150 |
+
fraudDetected: Math.floor(Math.random() * 100)
|
| 151 |
+
},
|
| 152 |
+
timestamp: Date.now()
|
| 153 |
+
};
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
+
secureAggregation(updates) {
|
| 157 |
+
// Agrégation fédérée avec vérification Byzantine
|
| 158 |
+
const validUpdates = updates.filter(u => {
|
| 159 |
+
const node = this.nodes.get(u.nodeId);
|
| 160 |
+
if (!node) return false;
|
| 161 |
+
const validation = node.validateUpdate(u);
|
| 162 |
+
return validation.valid;
|
| 163 |
+
});
|
| 164 |
+
|
| 165 |
+
if (validUpdates.length < this.nodes.size * this.consensusThreshold) {
|
| 166 |
+
console.warn('⚠️ Consensus failed: Insufficient valid nodes');
|
| 167 |
+
return null;
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
// Moyenne pondérée par le trust score
|
| 171 |
+
const weightedSum = validUpdates.map(u => {
|
| 172 |
+
const node = this.nodes.get(u.nodeId);
|
| 173 |
+
return u.weights.map(w => w * (node.trustScore / 100));
|
| 174 |
+
});
|
| 175 |
+
|
| 176 |
+
return {
|
| 177 |
+
weights: this.averageArrays(weightedSum),
|
| 178 |
+
consensusNodes: validUpdates.length,
|
| 179 |
+
timestamp: Date.now(),
|
| 180 |
+
hash: this.generateModelHash(validUpdates)
|
| 181 |
+
};
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
averageArrays(arrays) {
|
| 185 |
+
const length = arrays[0].length;
|
| 186 |
+
const result = new Array(length).fill(0);
|
| 187 |
+
for (const arr of arrays) {
|
| 188 |
+
for (let i = 0; i < length; i++) {
|
| 189 |
+
result[i] += arr[i] / arrays.length;
|
| 190 |
+
}
|
| 191 |
+
}
|
| 192 |
+
return result;
|
| 193 |
+
}
|
| 194 |
+
|
| 195 |
+
generateModelHash(updates) {
|
| 196 |
+
return `MODEL_${Date.now()}_${updates.length}_NODES`;
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
propagateModel(model) {
|
| 200 |
+
if (!model) return;
|
| 201 |
+
|
| 202 |
+
console.log(`📡 Propagating model to ${this.nodes.size} nodes with firewall validation`);
|
| 203 |
+
|
| 204 |
+
for (const [nodeId, node] of this.nodes) {
|
| 205 |
+
if (nodeId !== 'MASTER-01') {
|
| 206 |
+
// Vérification firewall avant propagation
|
| 207 |
+
const securityCheck = this.firewall.inspectTraffic({
|
| 208 |
+
type: 'model_update',
|
| 209 |
+
payload: model,
|
| 210 |
+
destination: nodeId
|
| 211 |
+
});
|
| 212 |
+
|
| 213 |
+
if (securityCheck.allowed) {
|
| 214 |
+
node.lastHeartbeat = Date.now();
|
| 215 |
+
} else {
|
| 216 |
+
node.status = 'quarantined';
|
| 217 |
+
console.warn(`🚫 Node ${nodeId} quarantined by firewall`);
|
| 218 |
+
}
|
| 219 |
+
}
|
| 220 |
+
}
|
| 221 |
+
}
|
| 222 |
+
|
| 223 |
+
getClusterHealth() {
|
| 224 |
+
const nodes = Array.from(this.nodes.values());
|
| 225 |
+
return {
|
| 226 |
+
total: nodes.length,
|
| 227 |
+
active: nodes.filter(n => n.status === 'active').length,
|
| 228 |
+
quarantined: nodes.filter(n => n.status === 'quarantined').length,
|
| 229 |
+
averageTrust: nodes.reduce((sum, n) => sum + n.trustScore, 0) / nodes.length,
|
| 230 |
+
globalModelVersion: this.globalModel?.hash || 'N/A',
|
| 231 |
+
firewallStatus: this.firewall.status
|
| 232 |
+
};
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
+
async detectAdvancedThreats(entityData) {
|
| 236 |
+
// Détection distribuée avec consensus
|
| 237 |
+
const threatSignals = [];
|
| 238 |
+
|
| 239 |
+
for (const [nodeId, node] of this.nodes) {
|
| 240 |
+
if (node.status === 'active' && node.role !== 'master') {
|
| 241 |
+
const signal = await this.analyzeLocalThreat(node, entityData);
|
| 242 |
+
threatSignals.push(signal);
|
| 243 |
+
}
|
| 244 |
+
}
|
| 245 |
+
|
| 246 |
+
// Consensus sur la menace
|
| 247 |
+
const threatScore = threatSignals.filter(s => s.threat).length / threatSignals.length;
|
| 248 |
+
|
| 249 |
+
return {
|
| 250 |
+
threatDetected: threatScore > 0.5,
|
| 251 |
+
confidence: threatScore,
|
| 252 |
+
distributedConsensus: threatSignals.length,
|
| 253 |
+
recommendedAction: threatScore > 0.8 ? 'IMMEDIATE_ISOLATION' : 'MONITORING',
|
| 254 |
+
signatures: threatSignals.map(s => s.signature)
|
| 255 |
+
};
|
| 256 |
+
}
|
| 257 |
+
|
| 258 |
+
async analyzeLocalThreat(node, data) {
|
| 259 |
+
// Analyse locale par nœud fédéré
|
| 260 |
+
const riskFactors = [
|
| 261 |
+
data.transactionVelocity > 1000 ? 0.3 : 0,
|
| 262 |
+
data.jurisdictionRisk > 0.7 ? 0.25 : 0,
|
| 263 |
+
data.shellIndicators > 3 ? 0.35 : 0,
|
| 264 |
+
Math.random() * 0.1 // Bruit de détection
|
| 265 |
+
];
|
| 266 |
+
|
| 267 |
+
const totalRisk = riskFactors.reduce((a, b) => a + b, 0);
|
| 268 |
+
|
| 269 |
+
return {
|
| 270 |
+
nodeId: node.nodeId,
|
| 271 |
+
threat: totalRisk > 0.6,
|
| 272 |
+
riskScore: totalRisk,
|
| 273 |
+
signature: node.signUpdate(data),
|
| 274 |
+
timestamp: Date.now()
|
| 275 |
+
};
|
| 276 |
+
}
|
| 277 |
+
}
|
| 278 |
+
|
| 279 |
+
class ConnectiveFirewall {
|
| 280 |
+
constructor() {
|
| 281 |
+
this.rules = new Map();
|
| 282 |
+
this.threatDatabase = new Set();
|
| 283 |
+
this.status = 'active';
|
| 284 |
+
this.blockedAttempts = 0;
|
| 285 |
+
this.initializeRules();
|
| 286 |
+
}
|
| 287 |
+
|
| 288 |
+
initializeRules() {
|
| 289 |
+
// Règles de sécurité avancées
|
| 290 |
+
this.rules.set('SQL_INJECTION', /(\b(union|select|insert|update|delete|drop|create|alter)\b.*\b(from|into|table|database)\b)/i);
|
| 291 |
+
this.rules.set('XSS_ATTEMPT', /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi);
|
| 292 |
+
this.rules.set('INJECTION_PAYLOAD', /(\b(eval|exec|system|passthru|shell_exec|popen|proc_open)\b)/i);
|
| 293 |
+
this.rules.set('BYZANTINE_ATTACK', this.detectByzantineBehavior.bind(this));
|
| 294 |
+
}
|
| 295 |
+
|
| 296 |
+
inspectTraffic(packet) {
|
| 297 |
+
const checks = [];
|
| 298 |
+
|
| 299 |
+
for (const [ruleName, rule] of this.rules) {
|
| 300 |
+
if (typeof rule === 'function') {
|
| 301 |
+
checks.push(rule(packet));
|
| 302 |
+
} else if (rule.test && rule.test(JSON.stringify(packet))) {
|
| 303 |
+
checks.push({ rule: ruleName, blocked: true, severity: 'HIGH' });
|
| 304 |
+
this.blockedAttempts++;
|
| 305 |
+
}
|
| 306 |
+
}
|
| 307 |
+
|
| 308 |
+
const blocked = checks.some(c => c.blocked);
|
| 309 |
+
|
| 310 |
+
if (blocked) {
|
| 311 |
+
this.triggerSecurityAlert(packet, checks);
|
| 312 |
+
}
|
| 313 |
+
|
| 314 |
+
return {
|
| 315 |
+
allowed: !blocked,
|
| 316 |
+
checks: checks,
|
| 317 |
+
timestamp: Date.now(),
|
| 318 |
+
signature: this.generatePacketSignature(packet)
|
| 319 |
+
};
|
| 320 |
+
}
|
| 321 |
+
|
| 322 |
+
detectByzantineBehavior(packet) {
|
| 323 |
+
// Détection d'attaque byzantine (nœud malveillant)
|
| 324 |
+
if (packet.payload && packet.payload.weights) {
|
| 325 |
+
const variance = this.calculateVariance(packet.payload.weights);
|
| 326 |
+
if (variance > 0.5) {
|
| 327 |
+
return { rule: 'BYZANTINE_HIGH_VARIANCE', blocked: true, severity: 'CRITICAL' };
|
| 328 |
+
}
|
| 329 |
+
}
|
| 330 |
+
return { blocked: false };
|
| 331 |
+
}
|
| 332 |
+
|
| 333 |
+
calculateVariance(array) {
|
| 334 |
+
const mean = array.reduce((a, b) => a + b) / array.length;
|
| 335 |
+
return array.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / array.length;
|
| 336 |
+
}
|
| 337 |
+
|
| 338 |
+
generatePacketSignature(packet) {
|
| 339 |
+
return `SEC_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
| 340 |
+
}
|
| 341 |
+
|
| 342 |
+
triggerSecurityAlert(packet, violations) {
|
| 343 |
+
console.error(`🚨 SECURITY ALERT: ${violations.length} violations detected`, {
|
| 344 |
+
packet: packet.destination || 'unknown',
|
| 345 |
+
violations: violations.map(v => v.rule),
|
| 346 |
+
timestamp: new Date().toISOString()
|
| 347 |
+
});
|
| 348 |
+
}
|
| 349 |
+
|
| 350 |
+
getSecurityReport() {
|
| 351 |
+
return {
|
| 352 |
+
status: this.status,
|
| 353 |
+
blockedAttempts: this.blockedAttempts,
|
| 354 |
+
threatDatabaseSize: this.threatDatabase.size,
|
| 355 |
+
activeRules: this.rules.size,
|
| 356 |
+
lastUpdate: new Date().toISOString()
|
| 357 |
+
};
|
| 358 |
+
}
|
| 359 |
+
}
|
| 360 |
+
|
| 361 |
+
class PostQuantumCrypto {
|
| 362 |
+
constructor() {
|
| 363 |
+
this.algorithm = 'CRYSTALS-Kyber-1024';
|
| 364 |
+
this.mode = 'FIPS-203-DRAFT';
|
| 365 |
+
}
|
| 366 |
+
|
| 367 |
+
async encrypt(data, publicKey) {
|
| 368 |
+
// Simulation de chiffrement post-quantique
|
| 369 |
+
const encrypted = btoa(JSON.stringify(data));
|
| 370 |
+
return {
|
| 371 |
+
ciphertext: encrypted,
|
| 372 |
+
algorithm: this.algorithm,
|
| 373 |
+
nonce: Math.random().toString(36).substr(2, 16)
|
| 374 |
+
};
|
| 375 |
+
}
|
| 376 |
+
|
| 377 |
+
async decrypt(ciphertext, privateKey) {
|
| 378 |
+
try {
|
| 379 |
+
return JSON.parse(atob(ciphertext));
|
| 380 |
+
} catch {
|
| 381 |
+
return null;
|
| 382 |
+
}
|
| 383 |
+
}
|
| 384 |
+
}
|
| 385 |
+
|
| 386 |
+
// Export pour utilisation globale
|
| 387 |
+
window.FederatedAICore = FederatedAICore;
|
| 388 |
+
window.ConnectiveFirewall = ConnectiveFirewall;
|
| 389 |
+
window.FederatedNode = FederatedNode;
|
script.js
CHANGED
|
@@ -1,54 +1,160 @@
|
|
| 1 |
|
| 2 |
/**
|
| 3 |
-
* Spectre Analytics Dashboard -
|
| 4 |
-
*
|
| 5 |
-
*
|
| 6 |
*/
|
| 7 |
|
| 8 |
document.addEventListener('DOMContentLoaded', () => {
|
| 9 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
window.aiCore = new AICore();
|
| 11 |
|
|
|
|
|
|
|
|
|
|
| 12 |
// Initialize all components
|
| 13 |
-
|
| 14 |
initializeGraphVisualization();
|
| 15 |
initializeCharts();
|
| 16 |
initializeEventListeners();
|
| 17 |
-
|
| 18 |
|
| 19 |
-
// Run initial
|
| 20 |
-
|
| 21 |
});
|
| 22 |
|
| 23 |
/**
|
| 24 |
-
* Run Initial
|
| 25 |
*/
|
| 26 |
-
async function
|
| 27 |
-
console.log('
|
| 28 |
try {
|
| 29 |
-
|
| 30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
} catch (error) {
|
| 32 |
-
console.error('
|
| 33 |
}
|
| 34 |
}
|
| 35 |
|
| 36 |
/**
|
| 37 |
-
* Update Dashboard with
|
| 38 |
*/
|
| 39 |
-
function
|
| 40 |
-
// Update
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
}
|
| 45 |
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
}
|
| 51 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
/**
|
| 53 |
* Dashboard Core Initialization
|
| 54 |
*/
|
|
@@ -446,35 +552,61 @@ function filterEntities() {
|
|
| 446 |
}
|
| 447 |
|
| 448 |
/**
|
| 449 |
-
* Real-time Updates
|
| 450 |
*/
|
| 451 |
-
function
|
| 452 |
-
//
|
| 453 |
-
setInterval(() => {
|
| 454 |
-
//
|
| 455 |
-
|
| 456 |
-
const
|
| 457 |
-
|
| 458 |
-
|
| 459 |
-
|
| 460 |
-
|
| 461 |
-
|
| 462 |
-
|
| 463 |
-
|
| 464 |
-
|
| 465 |
-
|
| 466 |
-
|
| 467 |
-
|
| 468 |
-
|
| 469 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 470 |
}
|
| 471 |
|
| 472 |
-
console.log('🔄
|
| 473 |
-
},
|
| 474 |
-
|
| 475 |
-
//
|
| 476 |
-
setInterval(() => {
|
| 477 |
-
|
|
|
|
|
|
|
|
|
|
| 478 |
}, 60000);
|
| 479 |
}
|
| 480 |
|
|
@@ -491,43 +623,27 @@ function updateAIInsights() {
|
|
| 491 |
}
|
| 492 |
|
| 493 |
/**
|
| 494 |
-
*
|
| 495 |
*/
|
| 496 |
function toggleAICortex() {
|
| 497 |
const overlay = document.getElementById('ai-cortex-overlay');
|
| 498 |
if (overlay) {
|
| 499 |
overlay.classList.toggle('hidden');
|
| 500 |
if (!overlay.classList.contains('hidden')) {
|
| 501 |
-
//
|
| 502 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 503 |
}
|
| 504 |
}
|
| 505 |
}
|
| 506 |
|
| 507 |
-
|
| 508 |
-
|
| 509 |
-
|
| 510 |
-
const bar = document.querySelector('#ai-cortex-overlay .bg-gradient-to-r');
|
| 511 |
-
|
| 512 |
-
if (!progress || !bar) return;
|
| 513 |
-
|
| 514 |
-
let width = 0;
|
| 515 |
-
const interval = setInterval(() => {
|
| 516 |
-
width += Math.random() * 15;
|
| 517 |
-
if (width > 100) width = 100;
|
| 518 |
-
|
| 519 |
-
bar.style.width = width + '%';
|
| 520 |
-
progress.textContent = Math.floor(width) + '% Complete';
|
| 521 |
-
|
| 522 |
-
if (width === 100) {
|
| 523 |
-
clearInterval(interval);
|
| 524 |
-
if (insight) {
|
| 525 |
-
insight.textContent = 'Analysis complete. High correlation detected between Quantum Alpha LP and Sigma Beta Fund. Recommend immediate investigation.';
|
| 526 |
-
insight.className = 'text-sm text-success-400';
|
| 527 |
-
}
|
| 528 |
-
}
|
| 529 |
-
}, 300);
|
| 530 |
-
}
|
| 531 |
|
| 532 |
// Expose functions to window
|
| 533 |
window.viewEntity = viewEntity;
|
|
|
|
| 1 |
|
| 2 |
/**
|
| 3 |
+
* Spectre Analytics Dashboard - Architecture Fédérée Avancée
|
| 4 |
+
* Système de Détection de Menaces Distribué avec IA Fédérée
|
| 5 |
+
* Version: SPECTRE-F-2.0
|
| 6 |
*/
|
| 7 |
|
| 8 |
document.addEventListener('DOMContentLoaded', () => {
|
| 9 |
+
console.log('🚀 Initializing Federated Secure Architecture...');
|
| 10 |
+
|
| 11 |
+
// Initialize Federated Core (22 nodes + firewall)
|
| 12 |
+
window.federatedCore = new FederatedAICore();
|
| 13 |
+
|
| 14 |
+
// Initialize Legacy AI Core (compatibilité)
|
| 15 |
window.aiCore = new AICore();
|
| 16 |
|
| 17 |
+
// Initialize API Service with security layer
|
| 18 |
+
window.apiService = new APIService();
|
| 19 |
+
|
| 20 |
// Initialize all components
|
| 21 |
+
initializeFederatedDashboard();
|
| 22 |
initializeGraphVisualization();
|
| 23 |
initializeCharts();
|
| 24 |
initializeEventListeners();
|
| 25 |
+
startFederatedUpdates();
|
| 26 |
|
| 27 |
+
// Run initial federated analysis
|
| 28 |
+
runInitialFederatedAnalysis();
|
| 29 |
});
|
| 30 |
|
| 31 |
/**
|
| 32 |
+
* Run Initial Federated Analysis
|
| 33 |
*/
|
| 34 |
+
async function runInitialFederatedAnalysis() {
|
| 35 |
+
console.log('🧠 Initializing Federated Neural Network...');
|
| 36 |
try {
|
| 37 |
+
// Analyse distribuée sur le cluster
|
| 38 |
+
const clusterHealth = window.federatedCore.getClusterHealth();
|
| 39 |
+
console.log('Cluster Health:', clusterHealth);
|
| 40 |
+
|
| 41 |
+
// Analyse de menaces avancée
|
| 42 |
+
const threatAnalysis = await window.federatedCore.detectAdvancedThreats({
|
| 43 |
+
transactionVelocity: 500,
|
| 44 |
+
jurisdictionRisk: 0.8,
|
| 45 |
+
shellIndicators: 5
|
| 46 |
+
});
|
| 47 |
+
|
| 48 |
+
updateDashboardWithFederatedData(clusterHealth, threatAnalysis);
|
| 49 |
+
renderNodeGrid();
|
| 50 |
} catch (error) {
|
| 51 |
+
console.error('Federated Analysis failed:', error);
|
| 52 |
}
|
| 53 |
}
|
| 54 |
|
| 55 |
/**
|
| 56 |
+
* Update Dashboard with Federated Insights
|
| 57 |
*/
|
| 58 |
+
function updateDashboardWithFederatedData(health, threats) {
|
| 59 |
+
// Update stats si les éléments existent
|
| 60 |
+
const nodesEl = document.getElementById('fed-active-nodes');
|
| 61 |
+
const firewallEl = document.getElementById('fed-firewall');
|
| 62 |
+
const trustEl = document.getElementById('fed-trust');
|
| 63 |
+
const confidenceEl = document.getElementById('fed-confidence');
|
| 64 |
+
|
| 65 |
+
if (nodesEl) nodesEl.textContent = `${health.active}/${health.total}`;
|
| 66 |
+
if (firewallEl) firewallEl.textContent = health.firewallStatus.toUpperCase();
|
| 67 |
+
if (trustEl) trustEl.textContent = health.averageTrust.toFixed(1);
|
| 68 |
+
if (confidenceEl) confidenceEl.textContent = (threats.confidence * 100).toFixed(2) + '%';
|
| 69 |
+
|
| 70 |
+
// Update security report
|
| 71 |
+
const blockedEl = document.getElementById('fed-blocked');
|
| 72 |
+
if (blockedEl && window.federatedCore) {
|
| 73 |
+
const report = window.federatedCore.firewall.getSecurityReport();
|
| 74 |
+
blockedEl.textContent = report.blockedAttempts;
|
| 75 |
+
}
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
/**
|
| 79 |
+
* Render Federated Node Grid
|
| 80 |
+
*/
|
| 81 |
+
function renderNodeGrid() {
|
| 82 |
+
const grid = document.getElementById('node-grid');
|
| 83 |
+
if (!grid || !window.federatedCore) return;
|
| 84 |
+
|
| 85 |
+
grid.innerHTML = '';
|
| 86 |
+
const nodes = Array.from(window.federatedCore.nodes.values());
|
| 87 |
+
|
| 88 |
+
nodes.forEach((node, index) => {
|
| 89 |
+
const dot = document.createElement('div');
|
| 90 |
+
dot.className = `h-2 w-2 rounded-full ${
|
| 91 |
+
node.status === 'active' ? 'bg-success-500' :
|
| 92 |
+
node.status === 'quarantined' ? 'bg-danger-500' : 'bg-gray-500'
|
| 93 |
+
} ${node.role === 'master' ? 'ring-2 ring-primary-400' : ''}`;
|
| 94 |
+
dot.title = `${node.nodeId} (${node.role}) - Trust: ${node.trustScore}`;
|
| 95 |
+
grid.appendChild(dot);
|
| 96 |
+
});
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
/**
|
| 100 |
+
* Run Federated Analysis Manually
|
| 101 |
+
*/
|
| 102 |
+
async function runFederatedAnalysis() {
|
| 103 |
+
const btn = document.querySelector('button[onclick="runFederatedAnalysis()"]');
|
| 104 |
+
if (btn) {
|
| 105 |
+
btn.innerHTML = '<i data-feather="loader" class="w-4 h-4 animate-spin"></i> Consensus Running...';
|
| 106 |
+
feather.replace();
|
| 107 |
}
|
| 108 |
|
| 109 |
+
try {
|
| 110 |
+
await window.federatedCore.runConsensusRound();
|
| 111 |
+
const health = window.federatedCore.getClusterHealth();
|
| 112 |
+
|
| 113 |
+
// Update UI
|
| 114 |
+
const roundEl = document.getElementById('fed-round');
|
| 115 |
+
if (roundEl) roundEl.textContent = parseInt(roundEl.textContent) + 1;
|
| 116 |
+
|
| 117 |
+
updateDashboardWithFederatedData(health, {confidence: 0.999});
|
| 118 |
+
renderNodeGrid();
|
| 119 |
+
|
| 120 |
+
// Simulation d'insight
|
| 121 |
+
const insight = document.getElementById('fed-insight');
|
| 122 |
+
if (insight) {
|
| 123 |
+
insight.textContent = `Consensus round completed. ${health.active} nodes synchronized.
|
| 124 |
+
Model hash: ${health.globalModelVersion}.
|
| 125 |
+
Zero-knowledge proofs verified. System integrity: 100%.`;
|
| 126 |
+
}
|
| 127 |
+
} catch (error) {
|
| 128 |
+
console.error('Federated analysis error:', error);
|
| 129 |
+
} finally {
|
| 130 |
+
if (btn) {
|
| 131 |
+
btn.innerHTML = '<i data-feather="play-circle" class="w-4 h-4"></i> Run Consensus Analysis';
|
| 132 |
+
feather.replace();
|
| 133 |
+
}
|
| 134 |
}
|
| 135 |
}
|
| 136 |
+
|
| 137 |
+
/**
|
| 138 |
+
* Export Federated Report
|
| 139 |
+
*/
|
| 140 |
+
function exportFederatedReport() {
|
| 141 |
+
const report = {
|
| 142 |
+
timestamp: new Date().toISOString(),
|
| 143 |
+
cluster: window.federatedCore.getClusterHealth(),
|
| 144 |
+
security: window.federatedCore.firewall.getSecurityReport(),
|
| 145 |
+
version: 'SPECTRE-F-2.0'
|
| 146 |
+
};
|
| 147 |
+
|
| 148 |
+
const blob = new Blob([JSON.stringify(report, null, 2)], {type: 'application/json'});
|
| 149 |
+
const url = URL.createObjectURL(blob);
|
| 150 |
+
const a = document.createElement('a');
|
| 151 |
+
a.href = url;
|
| 152 |
+
a.download = `spectre-federated-report-${Date.now()}.json`;
|
| 153 |
+
a.click();
|
| 154 |
+
URL.revokeObjectURL(url);
|
| 155 |
+
|
| 156 |
+
console.log('📊 Federated report exported:', report);
|
| 157 |
+
}
|
| 158 |
/**
|
| 159 |
* Dashboard Core Initialization
|
| 160 |
*/
|
|
|
|
| 552 |
}
|
| 553 |
|
| 554 |
/**
|
| 555 |
+
* Federated Real-time Updates
|
| 556 |
*/
|
| 557 |
+
function startFederatedUpdates() {
|
| 558 |
+
// Mises à jour distribuées toutes les 15 secondes (plus fréquent pour l'architecture fédérée)
|
| 559 |
+
setInterval(async () => {
|
| 560 |
+
// Mise à jour des nœuds fédérés
|
| 561 |
+
if (window.federatedCore) {
|
| 562 |
+
const health = window.federatedCore.getClusterHealth();
|
| 563 |
+
|
| 564 |
+
// Mise à jour aléatoire des entités
|
| 565 |
+
entityData.forEach(entity => {
|
| 566 |
+
const minutes = Math.floor(Math.random() * 60);
|
| 567 |
+
entity.lastActivity = minutes < 5 ? 'Just now' :
|
| 568 |
+
minutes < 60 ? `${minutes} min ago` :
|
| 569 |
+
`${Math.floor(minutes/60)}h ago`;
|
| 570 |
+
|
| 571 |
+
// Simulation de détection fédérée
|
| 572 |
+
if (Math.random() > 0.95) {
|
| 573 |
+
entity.riskScore = Math.min(100, entity.riskScore + Math.floor(Math.random() * 5));
|
| 574 |
+
}
|
| 575 |
+
});
|
| 576 |
+
|
| 577 |
+
// Mise à jour du tableau si pas de filtre actif
|
| 578 |
+
const searchInput = document.querySelector('input[type="text"]');
|
| 579 |
+
if (!searchInput || searchInput.value === '') {
|
| 580 |
+
updateEntityTable(entityData);
|
| 581 |
+
}
|
| 582 |
+
|
| 583 |
+
// Mise à jour du statut fédéré dans l'UI
|
| 584 |
+
const fedStatus = document.getElementById('fed-status');
|
| 585 |
+
if (fedStatus && health.active >= 20) {
|
| 586 |
+
fedStatus.textContent = 'Byzantine Consensus Achieved';
|
| 587 |
+
fedStatus.className = 'text-success-400';
|
| 588 |
+
} else if (fedStatus) {
|
| 589 |
+
fedStatus.textContent = 'Consensus Warning - Check Nodes';
|
| 590 |
+
fedStatus.className = 'text-warning-400';
|
| 591 |
+
}
|
| 592 |
+
|
| 593 |
+
// Mise à jour du firewall
|
| 594 |
+
const blockedEl = document.getElementById('fed-blocked');
|
| 595 |
+
if (blockedEl) {
|
| 596 |
+
const report = window.federatedCore.firewall.getSecurityReport();
|
| 597 |
+
blockedEl.textContent = report.blockedAttempts;
|
| 598 |
+
}
|
| 599 |
}
|
| 600 |
|
| 601 |
+
console.log('🔄 Federated consensus update applied');
|
| 602 |
+
}, 15000);
|
| 603 |
+
|
| 604 |
+
// Consensus round toutes les minutes
|
| 605 |
+
setInterval(async () => {
|
| 606 |
+
if (window.federatedCore) {
|
| 607 |
+
await window.federatedCore.runConsensusRound();
|
| 608 |
+
renderNodeGrid();
|
| 609 |
+
}
|
| 610 |
}, 60000);
|
| 611 |
}
|
| 612 |
|
|
|
|
| 623 |
}
|
| 624 |
|
| 625 |
/**
|
| 626 |
+
* Federated Cortex Toggle
|
| 627 |
*/
|
| 628 |
function toggleAICortex() {
|
| 629 |
const overlay = document.getElementById('ai-cortex-overlay');
|
| 630 |
if (overlay) {
|
| 631 |
overlay.classList.toggle('hidden');
|
| 632 |
if (!overlay.classList.contains('hidden')) {
|
| 633 |
+
// Initialiser la grille des nœuds
|
| 634 |
+
renderNodeGrid();
|
| 635 |
+
// Mettre à jour les métriques fédérées
|
| 636 |
+
if (window.federatedCore) {
|
| 637 |
+
const health = window.federatedCore.getClusterHealth();
|
| 638 |
+
updateDashboardWithFederatedData(health, {confidence: 0.9997});
|
| 639 |
+
}
|
| 640 |
}
|
| 641 |
}
|
| 642 |
}
|
| 643 |
|
| 644 |
+
// Expose new functions
|
| 645 |
+
window.runFederatedAnalysis = runFederatedAnalysis;
|
| 646 |
+
window.exportFederatedReport = exportFederatedReport;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 647 |
|
| 648 |
// Expose functions to window
|
| 649 |
window.viewEntity = viewEntity;
|
style.css
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
-
/* Spectre Analytics Dashboard -
|
|
|
|
| 2 |
|
| 3 |
:root {
|
| 4 |
/* Primary Color - Teal/Cyan */
|
|
@@ -14,6 +15,12 @@
|
|
| 14 |
--color-primary-900: #134e4a;
|
| 15 |
--color-primary-950: #042f2e;
|
| 16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
/* Secondary Color - Slate */
|
| 18 |
--color-secondary-50: #f8fafc;
|
| 19 |
--color-secondary-100: #f1f5f9;
|
|
@@ -78,7 +85,7 @@ h1, h2, h3, h4, h5, h6 {
|
|
| 78 |
background-size: 50px 50px;
|
| 79 |
}
|
| 80 |
|
| 81 |
-
/* Animations */
|
| 82 |
@keyframes fadeIn {
|
| 83 |
from { opacity: 0; transform: translateY(-5px); }
|
| 84 |
to { opacity: 1; transform: translateY(0); }
|
|
@@ -105,6 +112,22 @@ h1, h2, h3, h4, h5, h6 {
|
|
| 105 |
100% { stroke-dashoffset: 0; }
|
| 106 |
}
|
| 107 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
/* Animation Classes */
|
| 109 |
.animate-fade-in {
|
| 110 |
animation: fadeIn 0.4s ease-out;
|
|
@@ -118,6 +141,18 @@ h1, h2, h3, h4, h5, h6 {
|
|
| 118 |
animation: pulse-ring 1.5s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
| 119 |
}
|
| 120 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
.scan-line {
|
| 122 |
position: absolute;
|
| 123 |
width: 100%;
|
|
@@ -126,6 +161,48 @@ h1, h2, h3, h4, h5, h6 {
|
|
| 126 |
animation: scan-line 2s linear infinite;
|
| 127 |
}
|
| 128 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
/* Graph Node Styles */
|
| 130 |
.graph-node {
|
| 131 |
cursor: pointer;
|
|
|
|
| 1 |
+
/* Spectre Analytics Dashboard - Federated Architecture Styles */
|
| 2 |
+
/* Post-Quantum Security & Byzantine Consensus UI */
|
| 3 |
|
| 4 |
:root {
|
| 5 |
/* Primary Color - Teal/Cyan */
|
|
|
|
| 15 |
--color-primary-900: #134e4a;
|
| 16 |
--color-primary-950: #042f2e;
|
| 17 |
|
| 18 |
+
/* Security Colors */
|
| 19 |
+
--color-security-high: #10b981;
|
| 20 |
+
--color-security-warning: #f59e0b;
|
| 21 |
+
--color-security-danger: #ef4444;
|
| 22 |
+
--color-security-purple: #8b5cf6;
|
| 23 |
+
|
| 24 |
/* Secondary Color - Slate */
|
| 25 |
--color-secondary-50: #f8fafc;
|
| 26 |
--color-secondary-100: #f1f5f9;
|
|
|
|
| 85 |
background-size: 50px 50px;
|
| 86 |
}
|
| 87 |
|
| 88 |
+
/* Advanced Animations */
|
| 89 |
@keyframes fadeIn {
|
| 90 |
from { opacity: 0; transform: translateY(-5px); }
|
| 91 |
to { opacity: 1; transform: translateY(0); }
|
|
|
|
| 112 |
100% { stroke-dashoffset: 0; }
|
| 113 |
}
|
| 114 |
|
| 115 |
+
@keyframes node-pulse {
|
| 116 |
+
0%, 100% { opacity: 1; transform: scale(1); }
|
| 117 |
+
50% { opacity: 0.7; transform: scale(1.2); }
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
@keyframes consensus-flash {
|
| 121 |
+
0% { background-color: rgba(20, 184, 166, 0); }
|
| 122 |
+
50% { background-color: rgba(20, 184, 166, 0.2); }
|
| 123 |
+
100% { background-color: rgba(20, 184, 166, 0); }
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
@keyframes security-breach {
|
| 127 |
+
0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }
|
| 128 |
+
50% { box-shadow: 0 0 20px 5px rgba(239, 68, 68, 0.5); }
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
/* Animation Classes */
|
| 132 |
.animate-fade-in {
|
| 133 |
animation: fadeIn 0.4s ease-out;
|
|
|
|
| 141 |
animation: pulse-ring 1.5s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
| 142 |
}
|
| 143 |
|
| 144 |
+
.animate-node-active {
|
| 145 |
+
animation: node-pulse 2s infinite;
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
.animate-consensus {
|
| 149 |
+
animation: consensus-flash 3s infinite;
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
.animate-security-breach {
|
| 153 |
+
animation: security-breach 1s infinite;
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
.scan-line {
|
| 157 |
position: absolute;
|
| 158 |
width: 100%;
|
|
|
|
| 161 |
animation: scan-line 2s linear infinite;
|
| 162 |
}
|
| 163 |
|
| 164 |
+
/* Federated Node Grid */
|
| 165 |
+
#node-grid {
|
| 166 |
+
display: grid;
|
| 167 |
+
gap: 4px;
|
| 168 |
+
padding: 8px;
|
| 169 |
+
background: rgba(15, 23, 42, 0.5);
|
| 170 |
+
border-radius: 8px;
|
| 171 |
+
border: 1px solid rgba(51, 65, 85, 0.3);
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
#node-grid > div {
|
| 175 |
+
transition: all 0.3s ease;
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
#node-grid > div:hover {
|
| 179 |
+
transform: scale(1.5);
|
| 180 |
+
z-index: 10;
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
/* Quantum Encryption Indicator */
|
| 184 |
+
.quantum-indicator {
|
| 185 |
+
background: linear-gradient(90deg, #8b5cf6, #14b8a6);
|
| 186 |
+
background-clip: text;
|
| 187 |
+
-webkit-background-clip: text;
|
| 188 |
+
color: transparent;
|
| 189 |
+
font-weight: 700;
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
/* Byzantine Consensus Badge */
|
| 193 |
+
.consensus-badge {
|
| 194 |
+
background: linear-gradient(135deg, rgba(20, 184, 166, 0.2), rgba(139, 92, 246, 0.2));
|
| 195 |
+
border: 1px solid rgba(20, 184, 166, 0.5);
|
| 196 |
+
color: #2dd4bf;
|
| 197 |
+
font-family: 'JetBrains Mono', monospace;
|
| 198 |
+
font-size: 0.75rem;
|
| 199 |
+
padding: 0.25rem 0.5rem;
|
| 200 |
+
border-radius: 0.25rem;
|
| 201 |
+
display: inline-flex;
|
| 202 |
+
align-items: center;
|
| 203 |
+
gap: 0.25rem;
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
/* Graph Node Styles */
|
| 207 |
.graph-node {
|
| 208 |
cursor: pointer;
|