feat(web): mitre_url deeplinks + lazy groups subpanel in TTPInspector
Every technique_id in TechniqueBar and TTPInspector now links to its
canonical attack.mitre.org page. The inspector drawer gains a GROUPS
subpanel that lazy-fetches the new /ttp/techniques/{id}/groups endpoint
and renders each MITRE-tracked intrusion-set with deeplink and aliases.
Centralizes TTP row interfaces into src/types/ttp.ts and API wrappers
into src/utils/ttpApi.ts to give the new GroupRef type a clean home and
avoid a third inline fetch declaration.
This commit is contained in:
26
decnet_web/src/utils/ttpApi.ts
Normal file
26
decnet_web/src/utils/ttpApi.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import api from './api';
|
||||
import type { GroupRef, TechniqueRow, TTPTagDetailRow } from '../types/ttp';
|
||||
|
||||
export type TTPScope = 'identity' | 'attacker' | 'session';
|
||||
|
||||
export async function fetchTechniques(scope: TTPScope, uuid: string): Promise<TechniqueRow[]> {
|
||||
const res = await api.get(`/ttp/by-${scope}/${uuid}`);
|
||||
return Array.isArray(res.data) ? res.data : [];
|
||||
}
|
||||
|
||||
export async function fetchTagsForTechnique(
|
||||
scope: TTPScope,
|
||||
uuid: string,
|
||||
techniqueId: string,
|
||||
subTechniqueId?: string | null,
|
||||
): Promise<TTPTagDetailRow[]> {
|
||||
const params: Record<string, string> = {};
|
||||
if (subTechniqueId) params.sub_technique_id = subTechniqueId;
|
||||
const res = await api.get(`/ttp/tags/by-${scope}/${uuid}/${techniqueId}`, { params });
|
||||
return Array.isArray(res.data) ? res.data : [];
|
||||
}
|
||||
|
||||
export async function fetchGroupsForTechnique(techniqueId: string): Promise<GroupRef[]> {
|
||||
const res = await api.get(`/ttp/techniques/${techniqueId}/groups`);
|
||||
return Array.isArray(res.data) ? res.data : [];
|
||||
}
|
||||
Reference in New Issue
Block a user