feat(web): surface bgp_prefix and rpki_status in AttackerDetail and export
AttackerData type gets bgp_prefix / rpki_status / rpki_source. TimelineSection renders prefix inline next to AS number; RPKI status shows as a green RPKI VALID / red RPKI INVALID badge, or dim NO ROA for not-found. rpki-status-badge CSS added to Dashboard.css. Export network block extended with the three new fields.
This commit is contained in:
@@ -164,6 +164,11 @@ export const TimelineSection: React.FC<Props> = ({ attacker, open, onToggle }) =
|
||||
{attacker.asn != null ? (
|
||||
<span className="matrix-text">
|
||||
AS{attacker.asn}
|
||||
{attacker.bgp_prefix && (
|
||||
<span className="dim" style={{ marginLeft: 6, fontSize: '0.75rem', fontFamily: 'monospace' }}>
|
||||
{attacker.bgp_prefix}
|
||||
</span>
|
||||
)}
|
||||
{attacker.as_name && (
|
||||
<span className="dim" style={{ marginLeft: 6, fontSize: '0.75rem' }}>
|
||||
{attacker.as_name}
|
||||
@@ -174,6 +179,15 @@ export const TimelineSection: React.FC<Props> = ({ attacker, open, onToggle }) =
|
||||
({attacker.asn_source})
|
||||
</span>
|
||||
)}
|
||||
{attacker.rpki_status === 'valid' && (
|
||||
<span className="rpki-status-badge valid" style={{ marginLeft: 8 }}>RPKI VALID</span>
|
||||
)}
|
||||
{attacker.rpki_status === 'invalid' && (
|
||||
<span className="rpki-status-badge invalid" style={{ marginLeft: 8 }}>RPKI INVALID</span>
|
||||
)}
|
||||
{attacker.rpki_status === 'not-found' && (
|
||||
<span className="dim" style={{ marginLeft: 8, fontSize: '0.7rem' }}>RPKI NO ROA</span>
|
||||
)}
|
||||
</span>
|
||||
) : (
|
||||
<span className="dim">unknown</span>
|
||||
|
||||
@@ -73,7 +73,10 @@ export interface AttackerData {
|
||||
country_source: string | null;
|
||||
asn: number | null;
|
||||
as_name: string | null;
|
||||
bgp_prefix: string | null;
|
||||
asn_source: string | null;
|
||||
rpki_status: string | null;
|
||||
rpki_source: string | null;
|
||||
ptr_record: string | null;
|
||||
updated_at: string;
|
||||
behavior: AttackerBehavior | null;
|
||||
|
||||
@@ -514,6 +514,22 @@
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.rpki-status-badge {
|
||||
font-size: 0.65rem;
|
||||
padding: 2px 8px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.rpki-status-badge.valid {
|
||||
border: 1px solid var(--matrix);
|
||||
background: var(--matrix-tint-5);
|
||||
color: var(--matrix);
|
||||
}
|
||||
.rpki-status-badge.invalid {
|
||||
border: 1px solid var(--alert);
|
||||
background: var(--alert-tint-10);
|
||||
color: var(--alert);
|
||||
}
|
||||
|
||||
.back-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
6
decnet_web/src/test/fixtures/attacker.ts
vendored
6
decnet_web/src/test/fixtures/attacker.ts
vendored
@@ -19,7 +19,10 @@ export interface AttackerFixture {
|
||||
country_source: string | null;
|
||||
asn: number | null;
|
||||
as_name: string | null;
|
||||
bgp_prefix: string | null;
|
||||
asn_source: string | null;
|
||||
rpki_status: string | null;
|
||||
rpki_source: string | null;
|
||||
ptr_record: string | null;
|
||||
updated_at: string;
|
||||
behavior: null;
|
||||
@@ -61,7 +64,10 @@ export const makeAttacker = (overrides: Partial<AttackerFixture> = {}): Attacker
|
||||
country_source: 'maxmind',
|
||||
asn: 64500,
|
||||
as_name: 'EXAMPLE-AS',
|
||||
bgp_prefix: null,
|
||||
asn_source: 'maxmind',
|
||||
rpki_status: null,
|
||||
rpki_source: null,
|
||||
ptr_record: null,
|
||||
updated_at: '2026-05-09T11:00:00Z',
|
||||
behavior: null,
|
||||
|
||||
Reference in New Issue
Block a user