feat(m4): frontend MitreTagPicker + /mitre showcase page
- lib/mitre.ts: shared types (MitreTactic, Technique, Subtechnique, MitreTag
kind/id/external_id/name) + TanStack query keys.
- components/MitreTagPicker.tsx: three-column controlled picker (tactic →
technique → subtechnique), multi-select with chip-removal, autocomplete on
each column, ARIA labels for screen readers. Returns MitreTag[] via
value/onChange — drop-in for M5 template forms.
- pages/MitrePage.tsx: status card (version, source URL, last_sync), admin-
gated Trigger Sync button with success/error alerts, picker showcase, JSON
preview of the current selection.
- Layout adds MITRE nav link for any logged-in user; App.tsx adds the
/mitre route under RequireAuth. HomePage roadmap bumped to next: M5
templates.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 13:54:15 +02:00
|
|
|
/** Shared types + query keys for MITRE ATT&CK browsing. */
|
|
|
|
|
|
|
|
|
|
export interface MitreTactic {
|
|
|
|
|
id: string;
|
|
|
|
|
external_id: string;
|
|
|
|
|
short_name: string;
|
|
|
|
|
name: string;
|
|
|
|
|
description: string | null;
|
|
|
|
|
url: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface MitreTechnique {
|
|
|
|
|
id: string;
|
|
|
|
|
external_id: string;
|
|
|
|
|
name: string;
|
|
|
|
|
description: string | null;
|
|
|
|
|
url: string | null;
|
|
|
|
|
tactics: Array<{ external_id: string; name: string }>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface MitreSubtechnique {
|
|
|
|
|
id: string;
|
|
|
|
|
external_id: string;
|
|
|
|
|
name: string;
|
|
|
|
|
description: string | null;
|
|
|
|
|
url: string | null;
|
|
|
|
|
technique_id: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface Paginated<T> {
|
|
|
|
|
items: T[];
|
|
|
|
|
total: number;
|
|
|
|
|
limit: number;
|
|
|
|
|
offset: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface MitreStatus {
|
|
|
|
|
last_sync: string | null;
|
|
|
|
|
version: string | null;
|
|
|
|
|
source_url: string | null;
|
|
|
|
|
default_url: string;
|
|
|
|
|
default_version: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export type MitreTagKind = 'tactic' | 'technique' | 'subtechnique';
|
|
|
|
|
|
|
|
|
|
export interface MitreTag {
|
|
|
|
|
kind: MitreTagKind;
|
|
|
|
|
id: string;
|
|
|
|
|
external_id: string;
|
|
|
|
|
name: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const mitreKeys = {
|
|
|
|
|
status: ['mitre', 'status'] as const,
|
2026-05-12 18:32:20 +02:00
|
|
|
matrix: ['mitre', 'matrix'] as const,
|
feat(m4): frontend MitreTagPicker + /mitre showcase page
- lib/mitre.ts: shared types (MitreTactic, Technique, Subtechnique, MitreTag
kind/id/external_id/name) + TanStack query keys.
- components/MitreTagPicker.tsx: three-column controlled picker (tactic →
technique → subtechnique), multi-select with chip-removal, autocomplete on
each column, ARIA labels for screen readers. Returns MitreTag[] via
value/onChange — drop-in for M5 template forms.
- pages/MitrePage.tsx: status card (version, source URL, last_sync), admin-
gated Trigger Sync button with success/error alerts, picker showcase, JSON
preview of the current selection.
- Layout adds MITRE nav link for any logged-in user; App.tsx adds the
/mitre route under RequireAuth. HomePage roadmap bumped to next: M5
templates.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 13:54:15 +02:00
|
|
|
tactics: (q?: string) => ['mitre', 'tactics', q ?? ''] as const,
|
|
|
|
|
techniques: (tactic?: string, q?: string) =>
|
|
|
|
|
['mitre', 'techniques', tactic ?? '', q ?? ''] as const,
|
|
|
|
|
subtechniques: (technique?: string, q?: string) =>
|
|
|
|
|
['mitre', 'subtechniques', technique ?? '', q ?? ''] as const,
|
|
|
|
|
};
|
2026-05-12 18:32:20 +02:00
|
|
|
|
|
|
|
|
export interface MatrixSubtechnique {
|
|
|
|
|
id: string;
|
|
|
|
|
external_id: string;
|
|
|
|
|
name: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface MatrixTechnique {
|
|
|
|
|
id: string;
|
|
|
|
|
external_id: string;
|
|
|
|
|
name: string;
|
|
|
|
|
subtechniques: MatrixSubtechnique[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface MatrixTactic {
|
|
|
|
|
id: string;
|
|
|
|
|
external_id: string;
|
|
|
|
|
short_name: string;
|
|
|
|
|
name: string;
|
|
|
|
|
techniques: MatrixTechnique[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface MitreMatrix {
|
|
|
|
|
tactics: MatrixTactic[];
|
|
|
|
|
}
|