(data)
| 12180 | |
| 12181 | function displayAttackLogs(data) { |
| 12182 | if (!data || !data.attack_logs) { |
| 12183 | document.getElementById('attack-logs-container').innerHTML = ` |
| 12184 | <div class="text-center text-gray-400 py-8"> |
| 12185 | <svg class="w-12 h-12 mx-auto mb-3 opacity-50" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| 12186 | <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path> |
| 12187 | </svg> |
| 12188 | <p>No attack logs found</p> |
| 12189 | </div> |
| 12190 | `; |
| 12191 | return; |
| 12192 | } |
| 12193 | |
| 12194 | // Update statistics |
| 12195 | document.getElementById('attack-stat-total').textContent = data.total_count || 0; |
| 12196 | document.getElementById('attack-stat-success').textContent = data.success_count || 0; |
| 12197 | document.getElementById('attack-stat-failed').textContent = data.failed_count || 0; |
| 12198 | const timeoutCount = data.attack_logs.filter(log => log.status === 'timeout').length; |
| 12199 | document.getElementById('attack-stat-timeout').textContent = timeoutCount; |
| 12200 | |
| 12201 | // Populate network dropdown from available_networks returned by the API |
| 12202 | _updateAttackNetworkDropdown(data.available_networks || []); |
| 12203 | |
| 12204 | // Apply status filter |
| 12205 | let logs = data.attack_logs; |
| 12206 | if (currentAttackFilter !== 'all') { |
| 12207 | logs = logs.filter(log => log.status === currentAttackFilter); |
| 12208 | } |
| 12209 | |
| 12210 | // Apply network filter |
| 12211 | if (currentAttackNetworkFilter !== 'all') { |
| 12212 | logs = logs.filter(log => (log.network_ssid || 'unknown') === currentAttackNetworkFilter); |
| 12213 | } |
| 12214 | |
| 12215 | // Apply IP search filter |
| 12216 | if (currentAttackIPSearch) { |
| 12217 | logs = logs.filter(log => (log.target_ip || '').toLowerCase().includes(currentAttackIPSearch)); |
| 12218 | } |
| 12219 | |
| 12220 | if (logs.length === 0) { |
| 12221 | document.getElementById('attack-logs-container').innerHTML = ` |
| 12222 | <div class="text-center text-gray-400 py-8"> |
| 12223 | <svg class="w-12 h-12 mx-auto mb-3 opacity-50" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| 12224 | <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"></path> |
| 12225 | </svg> |
| 12226 | <p>No attacks match the current filters</p> |
| 12227 | </div> |
| 12228 | `; |
| 12229 | return; |
| 12230 | } |
| 12231 | |
| 12232 | let html = '<div class="space-y-4">'; |
| 12233 | |
| 12234 | if (currentAttackGroupBy === 'network') { |
| 12235 | // --- Group by Network (SSID), then sub-group by IP --- |
| 12236 | const logsByNetwork = {}; |
| 12237 | logs.forEach(log => { |
nothing calls this directly
no test coverage detected