@aarpaardev/stix-visualizer
Version:
STIX Visualizer is a React-based, enhanced version of the OASIS CTI STIX Visualization project. It offers interactive canvas-based rendering of STIX 2.0 bundles with support for custom nodes, links, labels, and complete styling and behavior control.
256 lines (251 loc) • 8.05 kB
TypeScript
import React from 'react';
import ForceGraphInstance from 'force-graph';
declare enum Stix2ObjectTypes {
Artifact = "artifact",
AttackPattern = "attack-pattern",
Autonomous_system = "autonomous-system",
Bundle = "bundle",
Campaign = "campaign",
Coa = "coa",
CourseOfAction = "course-of-action",
CustomObject = "custom-object",
Directory = "directory",
DomainName = "domain-name",
EmailAddr = "email-addr",
EmailMessage = "email-message",
Event = "event",
File = "file",
Grouping = "grouping",
Http = "http",
Identity = "identity",
Impact = "impact",
Incident = "incident",
Indicator = "indicator",
Infrastructure = "infrastructure",
IntrusionSet = "intrusion-set",
Ipv4Addr = "ipv4-addr",
Ipv6Addr = "ipv6-addr",
Language = "language",
Location = "location",
MacAddr = "mac-addr",
MalwareAnalysis = "malware-analysis",
Malware = "malware",
MarkingDefinition = "marking-definition",
Mutex = "mutex",
NetworkTraffic = "network-traffic",
Note = "note",
Observed_data = "observed-data",
Opinion = "opinion",
Process = "process",
Relationship = "relationship",
Report = "report",
Sighting = "sighting",
Software = "software",
Source = "source",
Task = "task",
Threat_actor = "threat-actor",
Tlp = "tlp",
Tool = "tool",
Url = "url",
UserAccount = "user-account",
Victim = "victim",
VictimTarget = "victim-target",
Vulnerability = "vulnerability",
WindowsRegistryKey = "windows-registry-key",
X509Certificate = "x509-certificate"
}
interface KillChainPhase {
kill_chain_name: string;
phase_name: string;
}
interface ExternalReference {
source_name: string;
url?: string;
hashes?: Record<string, string>;
}
interface StixObject {
type: Stix2ObjectTypes;
id: string;
created: string;
modified?: string;
definition_type?: string;
definition?: {
statement?: string;
};
name?: string;
labels?: string[];
description?: string;
published?: string;
object_refs?: string[];
object_marking_refs?: string[];
external_references?: ExternalReference[];
kill_chain_phases?: KillChainPhase[];
valid_from?: string;
pattern?: string;
first_seen?: string;
resource_level?: string;
primary_motivation?: string;
aliases?: Array<string>;
threat_actor_types?: Array<string>;
roles?: Array<string>;
spec_version?: string;
relationship_type?: string;
source_ref?: string;
target_ref?: string;
}
type StixBundle = {
type: Stix2ObjectTypes.Bundle;
id: string;
spec_version: string;
objects: StixObject[];
};
type Coordinates = {
x: number;
y: number;
};
type ZoomTransformation = {
k: number;
x: number;
y: number;
};
interface ILegend {
type: Stix2ObjectTypes | string;
icon?: HTMLImageElement;
}
type NodeObject<NodeType = object> = NodeType & {
id: string | number;
img?: HTMLImageElement;
size?: number;
name?: string;
val?: number;
x?: number;
y?: number;
z?: number;
vx?: number;
vy?: number;
vz?: number;
fx?: number;
fy?: number;
fz?: number;
draw?: (ctx: CanvasRenderingContext2D, x: number, y: number) => void;
drawHighlight?: (ctx: CanvasRenderingContext2D, x: number, y: number) => void;
neighbors?: Array<NodeObject>;
links?: Array<LinkObject>;
[others: string]: unknown;
};
type LinkObject<NodeType = object, LinkType = object> = LinkType & {
source?: string | number | NodeObject<NodeType>;
target?: string | number | NodeObject<NodeType>;
drawHighlight?: (ctx: CanvasRenderingContext2D) => void;
particleWidth?: number;
color?: string;
[others: string]: unknown;
};
interface ForceFn<NodeType = object> {
(alpha: number): void;
initialize?: (nodes: NodeObject<NodeType>[], ...args: unknown[]) => void;
[key: string]: any;
}
interface ForceGraphMethods<NodeType = object, LinkType = object> {
emitParticle(link: LinkObject<NodeType, LinkType>): ForceGraphInstance;
d3Force(forceName: 'link' | 'charge' | 'center' | string): ForceFn<NodeObject<NodeType>> | undefined;
d3Force(forceName: 'link' | 'charge' | 'center' | string, forceFn: ForceFn<NodeObject<NodeType>> | null): ForceGraphInstance;
d3ReheatSimulation(): ForceGraphInstance;
pauseAnimation(): ForceGraphInstance;
resumeAnimation(): ForceGraphInstance;
centerAt(): {
x: number;
y: number;
};
centerAt(x?: number, y?: number, durationMs?: number): ForceGraphInstance;
zoom(): number;
zoom(scale: number, durationMs?: number): ForceGraphInstance;
zoomToFit(durationMs?: number, padding?: number, nodeFilter?: (node: NodeObject<NodeType>) => boolean): ForceGraphInstance;
getGraphBbox(nodeFilter?: (node: NodeObject<NodeType>) => boolean): {
x: [number, number];
y: [number, number];
};
screen2GraphCoords(x: number, y: number): {
x: number;
y: number;
};
graph2ScreenCoords(x: number, y: number): {
x: number;
y: number;
};
cameraPosition: (position: {
x: number;
y: number;
z: number;
}, lookAt?: NodeObject, durationMs?: number) => {
x: number;
y: number;
z: number;
};
}
type ReactForceRef = ForceGraphMethods<NodeObject<object>, LinkObject<object, object> | undefined>;
interface GraphData<NodeType = object, LinkType = object> {
nodes: NodeObject<NodeType>[];
links: LinkObject<NodeType, LinkType>[];
}
interface FormattedData {
data: GraphData;
legends: Array<ILegend>;
}
interface ILabelOptions {
font?: string;
fontSize?: number;
backgroundColor?: string;
color?: string;
display?: boolean;
onZoomOutDisplay?: boolean;
}
interface ILinkDirectionOptions {
directionSize?: ((link: LinkObject) => number) | number;
arrowRelativePositions?: ((link: LinkObject) => number) | number;
directionalParticles?: ((link: LinkObject) => number) | number;
directionalParticleSpeed?: ((link: LinkObject) => number) | number;
directionalParticleSize?: ((link: LinkObject) => number) | number;
directionalParticlesAndArrowColor?: ((link: LinkObject) => string) | string;
onHoverParticlesSize?: number;
onHoverArrowSize?: number;
displayDirections?: boolean;
displayParticles?: boolean;
}
interface ILinkOptions {
width?: ((link: LinkObject) => number) | number;
curvature?: number;
distance?: number;
color?: string;
disableZoomOnClick?: boolean;
onHover?: (link: LinkObject, ctx: CanvasRenderingContext2D) => void;
onClick?: (link: LinkObject, ref?: ReactForceRef) => void;
}
interface INodeOptions {
size?: number;
disableZoomOnClick?: boolean;
onHover?: (node: NodeObject, ctx: CanvasRenderingContext2D, highlightedNeighbors: Set<NodeObject>) => void;
onClick?: (node: NodeObject, ref?: ReactForceRef) => void;
}
type LegendPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'top-center' | 'bottom-center';
interface ILegendOptions {
display?: boolean;
position?: LegendPosition;
containerStyle?: React.CSSProperties;
}
interface Stix2VisualizerProps {
data: StixBundle | object;
nodeOptions?: INodeOptions;
linkOptions?: ILinkOptions;
legendOptions?: ILegendOptions;
directionOptions?: ILinkDirectionOptions;
linkLabelOptions?: ILabelOptions;
nodeLabelOptions?: ILabelOptions;
}
/**
* @param {Stix2VisualizerProps} props properties
* @returns {React.FC} Stix Visualizer Component
*/
declare const Stix2Visualizer: React.FC<Stix2VisualizerProps>;
export { Stix2ObjectTypes, Stix2Visualizer };
export type { Coordinates, ForceGraphMethods, FormattedData, GraphData, ILabelOptions, ILegend, ILinkOptions, LegendPosition, LinkObject, NodeObject, ReactForceRef, Stix2VisualizerProps, StixBundle, StixObject, ZoomTransformation };