Skip to content

Commit 7f822f0

Browse files
committed
AF-280 enable type checking on build
1 parent 37a8faa commit 7f822f0

File tree

8 files changed

+37
-25
lines changed

8 files changed

+37
-25
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,7 @@ jobs:
6868
run: npm ci
6969
- name: Build
7070
working-directory: ./src/attack_flow_builder/
71-
# Temporarily disable type checking
72-
# run: npm run build
73-
run: npm run build-only
71+
run: npm run build
7472
- name: Upload artifact
7573
uses: actions/upload-artifact@v4
7674
with:

src/attack_flow_builder/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
"preview": "vite preview",
1111
"test:unit": "vitest run",
1212
"test:watch": "vitest",
13-
"build-only": "vite build",
1413
"type-check": "vue-tsc --build",
1514
"lint": "eslint .",
1615
"lint:fix": "eslint . --fix",

src/attack_flow_builder/src/assets/configuration/AttackFlowPublisher/AttackFlowPublisher.ts

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ import {
66
EnumProperty, ListProperty, Property, SemanticAnalyzer,
77
SemanticGraphNode, StringProperty
88
} from "@OpenChart/DiagramModel";
9-
import type { GraphExport } from "@OpenChart/DiagramModel";
9+
import type { GraphExport, JsonValue } from "@OpenChart/DiagramModel";
1010
import type { FilePublisher } from "@/assets/scripts/Application";
1111
import Enums from "../AttackFlowTemplates/MitreAttack";
12+
import type { Prop } from "vue";
1213

1314

1415
///////////////////////////////////////////////////////////////////////////////
@@ -192,17 +193,19 @@ class AttackFlowPublisher implements FilePublisher {
192193
for (let [key, prop] of property.value) {
193194
switch (key) {
194195
case "ttp":
195-
const json = prop.toJson();
196-
if (json.tactic) {
197-
node["tactic_id"] = json.tactic;
198-
if (json.tactic in Enums.stixIds) {
199-
node["tactic_ref"] = Enums.stixIds[json.tactic];
196+
const json = prop.toJson() as { [x: string]: JsonValue };
197+
const tactic = json?.tactic as null | string;
198+
if (tactic) {
199+
node["tactic_id"] = tactic;
200+
if (tactic in Enums.stixIds) {
201+
node["tactic_ref"] = Enums.stixIds[tactic as keyof typeof Enums.stixIds];
200202
}
201203
}
202-
if (json.technique) {
203-
node["technique_id"] = json.technique;
204-
if (json.technique in Enums.stixIds) {
205-
node["technique_ref"] = Enums.stixIds[json.technique];
204+
const technique = json?.technique as null | string;
205+
if (technique) {
206+
node["technique_id"] = technique;
207+
if (technique in Enums.stixIds) {
208+
node["technique_ref"] = Enums.stixIds[technique as keyof typeof Enums.stixIds];
206209
}
207210
}
208211
break;
@@ -324,7 +327,14 @@ class AttackFlowPublisher implements FilePublisher {
324327
}
325328
}
326329
if (hashList.length > 0) {
327-
const hashes = hashList.map(hash => [hash.hash_type, hash.hash_value]); // Drop the property labels
330+
const hashes = hashList.map(hash => {
331+
const hashJson = hash as { [x: string]: JsonValue };
332+
if (hashJson) {
333+
return [hashJson.hash_type, hashJson.hash_value];
334+
} else {
335+
return [];
336+
}
337+
}); // Drop the property labels
328338
node[key] = Object.fromEntries(hashes);
329339
}
330340
}
@@ -728,10 +738,13 @@ class AttackFlowPublisher implements FilePublisher {
728738
if (!(ref instanceof DictionaryProperty)) {
729739
throw new Error(`'${key}' is improperly defined.`);
730740
}
731-
const entries = Object
732-
.entries(this.toStixValue(ref))
733-
.filter(o => o[1] !== null);
734-
extRefs.push(Object.fromEntries(entries));
741+
const stixVal = this.toStixValue(ref);
742+
if (stixVal) {
743+
const entries = Object
744+
.entries(stixVal)
745+
.filter(o => o[1] !== null);
746+
extRefs.push(Object.fromEntries(entries));
747+
}
735748
}
736749
if (extRefs.length > 0) {
737750
flow[key] = extRefs;
@@ -993,7 +1006,7 @@ class AttackFlowPublisher implements FilePublisher {
9931006
* @returns
9941007
* A STIX-formatted JSON property
9951008
*/
996-
public toStixValue(prop: Property) {
1009+
public toStixValue(prop: Property): JsonValue {
9971010
if (prop instanceof DateProperty) {
9981011
return prop.toUtcIso();
9991012
} else {

src/attack_flow_builder/src/assets/scripts/OpenChart/DiagramView/DiagramLayoutEngine/AutomaticLayoutEngine/AutomaticLayoutEngine.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@ export class AutomaticLayoutEngine implements DiagramLayoutEngine {
2222
const nodes = new Set<DiagramObjectView>();
2323
const lines = new Set<LineView>();
2424

25+
// @ts-expect-error: this is a work in progress
2526
for (const block of objects[0]._blocks) {
2627
if (block instanceof BlockView) {
2728
nodes.add(block);
2829
}
2930
}
3031

32+
// @ts-expect-error: this is a work in progress
3133
for (const line of objects[0]._lines) {
3234
if (line instanceof LineView) {
3335
lines.add(line);

src/attack_flow_builder/src/assets/scripts/OpenChart/OpenChart.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,8 @@ describe("OpenChart", () => {
281281
it("exports valid import", async () => {
282282
const file = await createTestingFile();
283283
const expected = file.toExport();
284-
expected.layout["1dd3ff00-4931-4005-9e7b-b6511e9cd246"] = [5, 5];
285-
expected.layout["9aee95bb-6c28-48ad-9ad1-1042ff3e0aaf"] = [7.5, 7.5];
284+
expected.layout!["1dd3ff00-4931-4005-9e7b-b6511e9cd246"] = [5, 5];
285+
expected.layout!["9aee95bb-6c28-48ad-9ad1-1042ff3e0aaf"] = [7.5, 7.5];
286286
for (const obj of expected.objects) {
287287
if (typeof obj.properties === "undefined") {
288288
delete obj.properties;

src/attack_flow_builder/src/assets/scripts/StixToAttackFlow/StixToAttackFlow.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ export class StixToAttackFlowConverter {
143143
*/
144144
private translateStix<T extends DiagramObject>(stix: StixObject, type?: Constructor<T>): T | null {
145145
// Resolve template
146-
const template = StixToTemplate[stix.type];
146+
const template = StixToTemplate[stix.type as keyof typeof StixToTemplate];
147147
if (template === null) {
148148
return null;
149149
}

src/attack_flow_builder/src/assets/scripts/StixToAttackFlow/StixTypes/StixObservableObject/StixObservableObject.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import type { Mutex } from "./Mutex";
1212
import type { NetworkTraffic } from "./NetworkTraffic";
1313
import type { Process } from "./Process";
1414
import type { Software } from "./Software";
15-
import type { Url } from "./URL";
15+
import type { Url } from "./Url";
1616
import type { UserAccount } from "./UserAccount";
1717
import type { WindowsRegistryKey } from "./WindowsRegistryKey";
1818
import type { X509Certificate } from "./X509Certificate";

src/attack_flow_builder/src/stores/ContextMenuStore.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,7 @@ export const useContextMenuStore = defineStore("contextMenuStore", {
795795
*/
796796
function prepareCreateMenu(
797797
templates: ReadonlyMap<string, DiagramObjectTemplate>,
798-
spawn: (id: string) => SpawnObject
798+
spawn: (id: string) => EditorCommands.GroupCommand
799799
): ContextMenuSubmenu<CommandEmitter> {
800800
type MenuMap<T> = {
801801
menu: T;

0 commit comments

Comments
 (0)