/* ============================================================ FLOWSHIELD — Active Directory dashboard Consolida todo lo lanzado desde las herramientas AD (scans/findings con prefijo `ad-`). Reutiliza componentes y estilos existentes. ============================================================ */ function AdCatCard({ cat, onClick }) { const sev = cat.severity || 'info'; const active = cat.count > 0; return (
active && onClick(cat)} className="panel" style={{ padding:16, display:'flex', flexDirection:'column', gap:8, cursor: active ? 'pointer' : 'default', opacity: active ? 1 : 0.55, borderLeft:`3px solid var(--sev-${sev})` }}>
{active && }
{cat.count}
{cat.label}
); } function AdDashboard({ onNav, onRelaunch, embedded, onNewScan, adSession, onClearSession }) { const [ov, setOv] = useStateL(null); // null = cargando const [drawer, setDrawer] = useStateL(null); const Drawer = window.RtFindingDrawer; const load = () => { window.fsApi('/api/results/ad-overview', { method:'GET' }) .then(d => setOv(d)).catch(() => setOv({ __error:true })); }; useEffectL(() => { load(); }, []); const openList = (filter, label) => setDrawer({ mode:'list', filter, label }); const fmtDate = (d) => window.rptDate ? window.rptDate(d) : d; const t = (ov && ov.totals) || { scans:0, domains:0, open:0, by_severity:{} }; const bySev = t.by_severity || {}; const cats = (ov && ov.categories) || []; const targets = (ov && ov.by_target) || []; const recent = (ov && ov.recent) || []; const bh = (ov && ov.bloodhound) || {}; const empty = ov && !ov.__error && t.scans === 0; return (
{embedded ? (
Active Directory · postura del dominio
{adSession && (adSession.domain || adSession.host || adSession.username) && ( {(adSession.domain || adSession.host || '—')}{adSession.username ? ' · ' + adSession.username : ''} {onClearSession && } )}
Actualizar onNewScan ? onNewScan() : (onNav && onNav('redteam'))}>Nuevo escaneo AD
) : ( Actualizar onNav && onNav('redteam')}>Nuevo escaneo AD} /> )} {ov === null &&
Cargando…
} {empty && (
Aún no hay datos de Active Directory

Lanza alguna herramienta de la pestaña Active Directory en Red Team (enum, NetExec, kerbrute, kerberoast, BloodHound, Certipy, secretsdump) y aquí verás la postura del dominio.

onNewScan ? onNewScan() : (onNav && onNav('redteam'))}>Ir a las herramientas AD
)} {ov && !ov.__error && !empty && ( <> {/* KPIs */}
openList({ status:'open', source_prefix:'ad-' }, 'Hallazgos AD abiertos')} style={{ cursor:'pointer', display:'grid' }}>
openList({ sev:'crit', source_prefix:'ad-' }, 'Críticos · Active Directory')} style={{ cursor:'pointer', display:'grid' }}>
{/* Postura del dominio (categorías) */}
Postura del dominio
{cats.map(c => openList({ ad_category:cc.key }, cc.label)} />)}
{/* BloodHound */} {bh.download_id && (
Grafo BloodHound disponible
Importa el .zip en la GUI de BloodHound para explorar rutas de ataque.
Descargar grafo (.zip) ↗
)} {/* Dominios / hosts */}
Dominios y hosts
{targets.length === 0 && } {targets.map((g,i) => ( ))}
ObjetivoEscaneosHallazgosSeveridad máx.
Sin objetivos AD todavía.
{g.target} {g.scans} {g.findings}
{/* Escaneos AD recientes */}
Escaneos AD recientes
{recent.length === 0 && } {recent.map(s => ( ))}
IDHerramientaObjetivoEstadoHallazgosFecha
Sin escaneos AD.
{s.code || s.id} {s.tool} {s.target} {s.findings} {fmtDate(s.date)} setDrawer({ mode:'scan', id:s.id, label:s.tool })} title="Ver el escaneo y sus hallazgos">Ver {onRelaunch && onRelaunch(s)} title="Re-escanear con los mismos parámetros">Re-escanear}
)} {ov && ov.__error &&
No se pudo cargar la vista de Active Directory.
} {drawer && Drawer && { setDrawer(null); load(); }} />}
); } Object.assign(window, { AdDashboard, AdCatCard });