From 915bc6d7ef46f0272a2ee66ec3bc9219384176b4 Mon Sep 17 00:00:00 2001 From: anti Date: Sat, 9 May 2026 07:24:59 -0400 Subject: [PATCH] feat(web): add Download STIX button to AttackerHeader --- .../sections/AttackerHeader.tsx | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/decnet_web/src/components/AttackerDetail/sections/AttackerHeader.tsx b/decnet_web/src/components/AttackerDetail/sections/AttackerHeader.tsx index feb67769..7d53a67f 100644 --- a/decnet_web/src/components/AttackerDetail/sections/AttackerHeader.tsx +++ b/decnet_web/src/components/AttackerDetail/sections/AttackerHeader.tsx @@ -1,7 +1,8 @@ import React from 'react'; import { useNavigate } from 'react-router-dom'; -import { Crosshair } from '../../../icons'; +import { Crosshair, Download } from '../../../icons'; import { Tag } from '../ui'; +import api from '../../../utils/api'; import type { AttackerData } from '../types'; interface Props { @@ -12,6 +13,20 @@ interface Props { * The identity badge is click-through to the resolved-actor page. */ export const AttackerHeader: React.FC = ({ attacker }) => { const navigate = useNavigate(); + + const handleStixDownload = async () => { + try { + const res = await api.get(`/attackers/${attacker.uuid}/export/stix`, { responseType: 'blob' }); + const href = URL.createObjectURL(res.data); + const a = document.createElement('a'); + a.href = href; + a.download = `decnet-attacker-${attacker.uuid.slice(0, 8)}.stix.json`; + a.click(); + URL.revokeObjectURL(href); + } catch { + // best-effort + } + }; return (
@@ -45,6 +60,16 @@ export const AttackerHeader: React.FC = ({ attacker }) => { IDENTITY ยท {attacker.identity_id.slice(0, 8)} )} +
); };