Add IPv6 fallback display for findings without IPv4
Findings with no IPv4 address now display Qualys IPv6 or Primary IPv6 as fallback in the IP column, with a badge indicator: - 'Q' (amber) = Qualys IPv6 from hostAdditionalDetails - 'v6' (indigo) = Primary IPv6 from assetCustomAttributes Priority: IPv4 > Qualys IPv6 > Primary IPv6 Backend changes: - extractFinding now captures qualysIpv6 and primaryIpv6 - New extractQualysIpv6 helper parses hostAdditionalDetails - upsertFindingsBatch stores both fields - API response includes qualysIpv6 and primaryIpv6 - Migration adds qualys_ipv6 and primary_ipv6 columns The Qualys IPv6 is preferred over Primary IPv6 because it resolves in CARD (confirmed via testing with PMADEV-1).
This commit is contained in:
@@ -1261,16 +1261,31 @@ function TableCell({ colKey, finding, canWrite, onCveMouseEnter, onCveMouseLeave
|
||||
}
|
||||
/>
|
||||
);
|
||||
case 'ipAddress':
|
||||
case 'ipAddress': {
|
||||
// Display priority: IPv4 > Qualys IPv6 > Primary IPv6
|
||||
const displayIp = finding.ipAddress || finding.qualysIpv6 || finding.primaryIpv6 || '';
|
||||
const ipSource = finding.ipAddress ? null : finding.qualysIpv6 ? 'Q' : finding.primaryIpv6 ? 'v6' : null;
|
||||
const hoverIp = displayIp || null;
|
||||
return (
|
||||
<td
|
||||
style={{ padding: '0.45rem 0.75rem', whiteSpace: 'nowrap', color: '#94A3B8', fontFamily: 'monospace', fontSize: '0.72rem', cursor: finding.ipAddress ? 'help' : 'default' }}
|
||||
onMouseEnter={onIpMouseEnter && finding.ipAddress ? (e) => onIpMouseEnter(finding.ipAddress, e, finding.hostId) : undefined}
|
||||
style={{ padding: '0.45rem 0.75rem', whiteSpace: 'nowrap', color: '#94A3B8', fontFamily: 'monospace', fontSize: '0.72rem', cursor: hoverIp ? 'help' : 'default' }}
|
||||
onMouseEnter={onIpMouseEnter && hoverIp ? (e) => onIpMouseEnter(hoverIp, e, finding.hostId) : undefined}
|
||||
onMouseLeave={onIpMouseLeave || undefined}
|
||||
title={ipSource === 'Q' ? 'Qualys IPv6 (no IPv4 available)' : ipSource === 'v6' ? 'Primary IPv6 (no IPv4 available)' : undefined}
|
||||
>
|
||||
{finding.ipAddress || '—'}
|
||||
{displayIp ? (
|
||||
<>
|
||||
<span style={{ maxWidth: '140px', overflow: 'hidden', textOverflow: 'ellipsis', display: 'inline-block', verticalAlign: 'middle' }}>{displayIp}</span>
|
||||
{ipSource && (
|
||||
<span style={{ marginLeft: '0.3rem', fontSize: '0.55rem', padding: '0.08rem 0.25rem', borderRadius: '0.2rem', background: ipSource === 'Q' ? 'rgba(245, 158, 11, 0.15)' : 'rgba(99, 102, 241, 0.15)', border: ipSource === 'Q' ? '1px solid rgba(245, 158, 11, 0.4)' : '1px solid rgba(99, 102, 241, 0.4)', color: ipSource === 'Q' ? '#FBBF24' : '#A5B4FC', fontWeight: '700', verticalAlign: 'middle' }}>
|
||||
{ipSource}
|
||||
</span>
|
||||
)}
|
||||
</>
|
||||
) : '—'}
|
||||
</td>
|
||||
);
|
||||
}
|
||||
case 'dns':
|
||||
return (
|
||||
<OverrideCell
|
||||
|
||||
Reference in New Issue
Block a user