()
| 10985 | } |
| 10986 | info.tooltip = tooltipParts.join('\n'); |
| 10987 | |
| 10988 | return info; |
| 10989 | } |
| 10990 | |
| 10991 | function normalizeHostRecord(hostData) { |
| 10992 | if (!hostData) { |
| 10993 | return null; |
| 10994 | } |
| 10995 | |
| 10996 | const ip = hostData.IPs || hostData.ip || hostData.address || hostData.target || ''; |
| 10997 | if (!ip) { |
| 10998 | return null; |
| 10999 | } |
| 11000 | |
| 11001 | const hostname = hostData.Hostnames || hostData.Hostname || hostData.hostname || hostData.name || ''; |
| 11002 | const mac = hostData['MAC Address'] || hostData.MAC || hostData.mac || ''; |
| 11003 | |
| 11004 | const aliveValue = hostData.Alive ?? hostData.alive ?? hostData.Status ?? hostData.status ?? ''; |
| 11005 | const aliveString = aliveValue === undefined || aliveValue === null ? '' : String(aliveValue).trim(); |
| 11006 | const aliveLower = aliveString.toLowerCase(); |
| 11007 | const isActive = ['1', 'true', 'online', 'up', 'active', 'success'].includes(aliveLower); |
| 11008 | const isInactive = ['0', 'false', 'offline', 'down', 'inactive', 'failed'].includes(aliveLower); |
| 11009 | |
| 11010 | let statusText = 'Unknown'; |
| 11011 | if (isActive) { |
| 11012 | statusText = 'Active'; |
| 11013 | } else if (isInactive) { |
| 11014 | statusText = 'Inactive'; |
| 11015 | } else if (aliveString) { |
| 11016 | statusText = aliveString.charAt(0).toUpperCase() + aliveString.slice(1); |
| 11017 | } |
| 11018 | |
| 11019 | const statusClass = isActive ? 'text-green-400' : (isInactive ? 'text-red-400' : 'text-yellow-400'); |
| 11020 | |
| 11021 | const rawPorts = hostData.Ports ?? hostData.ports ?? hostData.port_list ?? hostData.open_ports; |
| 11022 | let ports = []; |
| 11023 | if (Array.isArray(rawPorts)) { |
| 11024 | ports = rawPorts.map(port => String(port).trim()).filter(Boolean); |
| 11025 | } else if (typeof rawPorts === 'string') { |
| 11026 | ports = rawPorts.split(/[,;\s]+/).map(port => port.trim()).filter(Boolean); |
| 11027 | } else if (rawPorts) { |
| 11028 | ports = [String(rawPorts).trim()]; |
| 11029 | } |
| 11030 | |
| 11031 | const vulnObjects = Array.isArray(hostData.vulnerabilities) ? hostData.vulnerabilities : []; |
| 11032 | const normalizedVulnObjects = vulnObjects.map(vuln => { |
| 11033 | if (typeof vuln === 'string') { |
| 11034 | return vuln; |
| 11035 | } |
| 11036 | if (vuln && typeof vuln === 'object') { |
| 11037 | return vuln.vulnerability || vuln.raw_output || vuln.description || vuln.id || ''; |
| 11038 | } |
| 11039 | return ''; |
| 11040 | }).filter(Boolean); |
| 11041 | |
| 11042 | let vulnSummary = hostData['Nmap Vulnerabilities'] || hostData['nmap_vulnerabilities'] || hostData.vulnerability_summary || ''; |
| 11043 | if (!vulnSummary && typeof hostData.NmapVulnerabilities === 'string') { |
| 11044 | vulnSummary = hostData.NmapVulnerabilities; |
no test coverage detected