vaspera 2.10.1 → 2.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/audit-trail.test.d.ts +7 -0
- package/dist/__tests__/audit-trail.test.d.ts.map +1 -0
- package/dist/__tests__/audit-trail.test.js +336 -0
- package/dist/__tests__/audit-trail.test.js.map +1 -0
- package/dist/__tests__/property-test-helpers.d.ts +1 -1
- package/dist/action/pr-comment.test.js +9 -0
- package/dist/action/pr-comment.test.js.map +1 -1
- package/dist/action/sarif-upload.test.js +9 -0
- package/dist/action/sarif-upload.test.js.map +1 -1
- package/dist/autofix/ast/__tests__/typescript.test.d.ts +5 -0
- package/dist/autofix/ast/__tests__/typescript.test.d.ts.map +1 -0
- package/dist/autofix/ast/__tests__/typescript.test.js +210 -0
- package/dist/autofix/ast/__tests__/typescript.test.js.map +1 -0
- package/dist/autofix/ast/index.d.ts +11 -0
- package/dist/autofix/ast/index.d.ts.map +1 -0
- package/dist/autofix/ast/index.js +11 -0
- package/dist/autofix/ast/index.js.map +1 -0
- package/dist/autofix/ast/types.d.ts +77 -0
- package/dist/autofix/ast/types.d.ts.map +1 -0
- package/dist/autofix/ast/types.js +9 -0
- package/dist/autofix/ast/types.js.map +1 -0
- package/dist/autofix/ast/typescript.d.ts +17 -0
- package/dist/autofix/ast/typescript.d.ts.map +1 -0
- package/dist/autofix/ast/typescript.js +427 -0
- package/dist/autofix/ast/typescript.js.map +1 -0
- package/dist/autofix/constitution.schema.d.ts +21 -21
- package/dist/autofix/index.d.ts +1 -0
- package/dist/autofix/index.d.ts.map +1 -1
- package/dist/autofix/index.js +2 -0
- package/dist/autofix/index.js.map +1 -1
- package/dist/config/flags.d.ts +6 -6
- package/dist/history/store.d.ts +55 -1
- package/dist/history/store.d.ts.map +1 -1
- package/dist/history/store.js +152 -4
- package/dist/history/store.js.map +1 -1
- package/dist/history/types.d.ts +9 -5
- package/dist/history/types.d.ts.map +1 -1
- package/dist/history/verify.d.ts.map +1 -1
- package/dist/history/verify.js +5 -3
- package/dist/history/verify.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +627 -0
- package/dist/index.js.map +1 -1
- package/dist/integrations/siem/datadog.d.ts +44 -0
- package/dist/integrations/siem/datadog.d.ts.map +1 -0
- package/dist/integrations/siem/datadog.js +211 -0
- package/dist/integrations/siem/datadog.js.map +1 -0
- package/dist/integrations/siem/format.d.ts +59 -0
- package/dist/integrations/siem/format.d.ts.map +1 -0
- package/dist/integrations/siem/format.js +360 -0
- package/dist/integrations/siem/format.js.map +1 -0
- package/dist/integrations/siem/index.d.ts +56 -0
- package/dist/integrations/siem/index.d.ts.map +1 -0
- package/dist/integrations/siem/index.js +117 -0
- package/dist/integrations/siem/index.js.map +1 -0
- package/dist/integrations/siem/sentinel.d.ts +53 -0
- package/dist/integrations/siem/sentinel.d.ts.map +1 -0
- package/dist/integrations/siem/sentinel.js +231 -0
- package/dist/integrations/siem/sentinel.js.map +1 -0
- package/dist/integrations/siem/splunk.d.ts +46 -0
- package/dist/integrations/siem/splunk.d.ts.map +1 -0
- package/dist/integrations/siem/splunk.js +210 -0
- package/dist/integrations/siem/splunk.js.map +1 -0
- package/dist/integrations/siem/types.d.ts +210 -0
- package/dist/integrations/siem/types.d.ts.map +1 -0
- package/dist/integrations/siem/types.js +9 -0
- package/dist/integrations/siem/types.js.map +1 -0
- package/dist/persistence/__tests__/persistence.test.d.ts +5 -0
- package/dist/persistence/__tests__/persistence.test.d.ts.map +1 -0
- package/dist/persistence/__tests__/persistence.test.js +369 -0
- package/dist/persistence/__tests__/persistence.test.js.map +1 -0
- package/dist/persistence/db.d.ts +15 -0
- package/dist/persistence/db.d.ts.map +1 -0
- package/dist/persistence/db.js +79 -0
- package/dist/persistence/db.js.map +1 -0
- package/dist/persistence/index.d.ts +66 -0
- package/dist/persistence/index.d.ts.map +1 -0
- package/dist/persistence/index.js +143 -0
- package/dist/persistence/index.js.map +1 -0
- package/dist/persistence/migrations/index.d.ts +10 -0
- package/dist/persistence/migrations/index.d.ts.map +1 -0
- package/dist/persistence/migrations/index.js +125 -0
- package/dist/persistence/migrations/index.js.map +1 -0
- package/dist/persistence/repositories/findings.d.ts +41 -0
- package/dist/persistence/repositories/findings.d.ts.map +1 -0
- package/dist/persistence/repositories/findings.js +238 -0
- package/dist/persistence/repositories/findings.js.map +1 -0
- package/dist/persistence/repositories/projects.d.ts +22 -0
- package/dist/persistence/repositories/projects.d.ts.map +1 -0
- package/dist/persistence/repositories/projects.js +71 -0
- package/dist/persistence/repositories/projects.js.map +1 -0
- package/dist/persistence/repositories/scans.d.ts +30 -0
- package/dist/persistence/repositories/scans.d.ts.map +1 -0
- package/dist/persistence/repositories/scans.js +107 -0
- package/dist/persistence/repositories/scans.js.map +1 -0
- package/dist/persistence/repositories/trends.d.ts +42 -0
- package/dist/persistence/repositories/trends.d.ts.map +1 -0
- package/dist/persistence/repositories/trends.js +178 -0
- package/dist/persistence/repositories/trends.js.map +1 -0
- package/dist/persistence/types.d.ts +105 -0
- package/dist/persistence/types.d.ts.map +1 -0
- package/dist/persistence/types.js +13 -0
- package/dist/persistence/types.js.map +1 -0
- package/dist/plugins/types.d.ts +2 -2
- package/dist/scanners/ai-code/types.d.ts +12 -12
- package/dist/scanners/cache.d.ts.map +1 -1
- package/dist/scanners/cache.js +9 -0
- package/dist/scanners/cache.js.map +1 -1
- package/dist/scanners/dast.d.ts +40 -0
- package/dist/scanners/dast.d.ts.map +1 -0
- package/dist/scanners/dast.js +228 -0
- package/dist/scanners/dast.js.map +1 -0
- package/dist/scanners/deploy/types.d.ts +19 -19
- package/dist/scanners/detection/__tests__/detection.test.d.ts +5 -0
- package/dist/scanners/detection/__tests__/detection.test.d.ts.map +1 -0
- package/dist/scanners/detection/__tests__/detection.test.js +265 -0
- package/dist/scanners/detection/__tests__/detection.test.js.map +1 -0
- package/dist/scanners/detection/engines/ast-query.d.ts +23 -0
- package/dist/scanners/detection/engines/ast-query.d.ts.map +1 -0
- package/dist/scanners/detection/engines/ast-query.js +232 -0
- package/dist/scanners/detection/engines/ast-query.js.map +1 -0
- package/dist/scanners/detection/engines/data-flow.d.ts +12 -0
- package/dist/scanners/detection/engines/data-flow.d.ts.map +1 -0
- package/dist/scanners/detection/engines/data-flow.js +269 -0
- package/dist/scanners/detection/engines/data-flow.js.map +1 -0
- package/dist/scanners/detection/index.d.ts +29 -0
- package/dist/scanners/detection/index.d.ts.map +1 -0
- package/dist/scanners/detection/index.js +140 -0
- package/dist/scanners/detection/index.js.map +1 -0
- package/dist/scanners/detection/rules/builtin.d.ts +14 -0
- package/dist/scanners/detection/rules/builtin.d.ts.map +1 -0
- package/dist/scanners/detection/rules/builtin.js +307 -0
- package/dist/scanners/detection/rules/builtin.js.map +1 -0
- package/dist/scanners/detection/rules/loader.d.ts +19 -0
- package/dist/scanners/detection/rules/loader.d.ts.map +1 -0
- package/dist/scanners/detection/rules/loader.js +111 -0
- package/dist/scanners/detection/rules/loader.js.map +1 -0
- package/dist/scanners/detection/types.d.ts +171 -0
- package/dist/scanners/detection/types.d.ts.map +1 -0
- package/dist/scanners/detection/types.js +36 -0
- package/dist/scanners/detection/types.js.map +1 -0
- package/dist/scanners/index.d.ts +13 -5
- package/dist/scanners/index.d.ts.map +1 -1
- package/dist/scanners/index.js +197 -15
- package/dist/scanners/index.js.map +1 -1
- package/dist/scanners/index.test.js +6 -6
- package/dist/scanners/index.test.js.map +1 -1
- package/dist/scanners/openapi.d.ts +20 -0
- package/dist/scanners/openapi.d.ts.map +1 -0
- package/dist/scanners/openapi.js +226 -0
- package/dist/scanners/openapi.js.map +1 -0
- package/dist/scanners/runtime/types.d.ts +4 -4
- package/dist/scanners/rust.d.ts +22 -0
- package/dist/scanners/rust.d.ts.map +1 -0
- package/dist/scanners/rust.js +239 -0
- package/dist/scanners/rust.js.map +1 -0
- package/dist/scanners/scale/types.d.ts +19 -19
- package/dist/scanners/terraform.d.ts +23 -0
- package/dist/scanners/terraform.d.ts.map +1 -0
- package/dist/scanners/terraform.js +207 -0
- package/dist/scanners/terraform.js.map +1 -0
- package/dist/scanners/types.d.ts +1 -1
- package/dist/scanners/types.d.ts.map +1 -1
- package/dist/scanners/types.js +9 -0
- package/dist/scanners/types.js.map +1 -1
- package/package.json +5 -1
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Datadog Logs Client
|
|
3
|
+
*
|
|
4
|
+
* Logs API client for Datadog integration.
|
|
5
|
+
*
|
|
6
|
+
* @module integrations/siem/datadog
|
|
7
|
+
*/
|
|
8
|
+
import type { SIEMClient, SIEMEvent, SIEMTestResult, SIEMSendResult, SIEMBatchResult, DatadogConfig } from "./types.js";
|
|
9
|
+
/**
|
|
10
|
+
* Datadog Logs API client
|
|
11
|
+
*/
|
|
12
|
+
export declare class DatadogClient implements SIEMClient {
|
|
13
|
+
readonly provider: "datadog";
|
|
14
|
+
private config;
|
|
15
|
+
private endpoint;
|
|
16
|
+
constructor(config: DatadogConfig);
|
|
17
|
+
/**
|
|
18
|
+
* Test connection to Datadog
|
|
19
|
+
*/
|
|
20
|
+
testConnection(): Promise<SIEMTestResult>;
|
|
21
|
+
/**
|
|
22
|
+
* Send a single event to Datadog
|
|
23
|
+
*/
|
|
24
|
+
sendEvent(event: SIEMEvent): Promise<SIEMSendResult>;
|
|
25
|
+
/**
|
|
26
|
+
* Send multiple events in batch
|
|
27
|
+
*/
|
|
28
|
+
sendEvents(events: SIEMEvent[]): Promise<SIEMBatchResult>;
|
|
29
|
+
/**
|
|
30
|
+
* Close connection
|
|
31
|
+
*/
|
|
32
|
+
close(): Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Create a Datadog client from configuration
|
|
36
|
+
*/
|
|
37
|
+
export declare function createDatadogClient(config: {
|
|
38
|
+
apiKey: string;
|
|
39
|
+
site?: string;
|
|
40
|
+
service?: string;
|
|
41
|
+
env?: string;
|
|
42
|
+
tags?: string[];
|
|
43
|
+
}): DatadogClient;
|
|
44
|
+
//# sourceMappingURL=datadog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datadog.d.ts","sourceRoot":"","sources":["../../../src/integrations/siem/datadog.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EACV,UAAU,EACV,SAAS,EACT,cAAc,EACd,cAAc,EACd,eAAe,EACf,aAAa,EACd,MAAM,YAAY,CAAC;AAcpB;;GAEG;AACH,qBAAa,aAAc,YAAW,UAAU;IAC9C,QAAQ,CAAC,QAAQ,EAAG,SAAS,CAAU;IACvC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,QAAQ,CAAS;gBAEb,MAAM,EAAE,aAAa;IAMjC;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,cAAc,CAAC;IAuC/C;;OAEG;IACG,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC;IAsD1D;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC;IAsE/D;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB,GAAG,aAAa,CAehB"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Datadog Logs Client
|
|
3
|
+
*
|
|
4
|
+
* Logs API client for Datadog integration.
|
|
5
|
+
*
|
|
6
|
+
* @module integrations/siem/datadog
|
|
7
|
+
*/
|
|
8
|
+
import { logger } from "../../logger.js";
|
|
9
|
+
import { formatForDatadog } from "./format.js";
|
|
10
|
+
/**
|
|
11
|
+
* Datadog site to API endpoint mapping
|
|
12
|
+
*/
|
|
13
|
+
const DATADOG_ENDPOINTS = {
|
|
14
|
+
"datadoghq.com": "https://http-intake.logs.datadoghq.com",
|
|
15
|
+
"us3.datadoghq.com": "https://http-intake.logs.us3.datadoghq.com",
|
|
16
|
+
"us5.datadoghq.com": "https://http-intake.logs.us5.datadoghq.com",
|
|
17
|
+
"datadoghq.eu": "https://http-intake.logs.datadoghq.eu",
|
|
18
|
+
"ap1.datadoghq.com": "https://http-intake.logs.ap1.datadoghq.com",
|
|
19
|
+
"ddog-gov.com": "https://http-intake.logs.ddog-gov.com",
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Datadog Logs API client
|
|
23
|
+
*/
|
|
24
|
+
export class DatadogClient {
|
|
25
|
+
provider = "datadog";
|
|
26
|
+
config;
|
|
27
|
+
endpoint;
|
|
28
|
+
constructor(config) {
|
|
29
|
+
this.config = config;
|
|
30
|
+
const site = config.options?.site || "datadoghq.com";
|
|
31
|
+
this.endpoint = DATADOG_ENDPOINTS[site] || DATADOG_ENDPOINTS["datadoghq.com"];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Test connection to Datadog
|
|
35
|
+
*/
|
|
36
|
+
async testConnection() {
|
|
37
|
+
const startTime = Date.now();
|
|
38
|
+
try {
|
|
39
|
+
// Datadog validates the API key on first request
|
|
40
|
+
const testEvent = {
|
|
41
|
+
timestamp: new Date().toISOString(),
|
|
42
|
+
eventType: "scan.started",
|
|
43
|
+
severity: "informational",
|
|
44
|
+
project: "test",
|
|
45
|
+
message: "Vaspera connection test",
|
|
46
|
+
source: "vaspera",
|
|
47
|
+
data: { test: true },
|
|
48
|
+
};
|
|
49
|
+
const result = await this.sendEvent(testEvent);
|
|
50
|
+
return {
|
|
51
|
+
success: result.success,
|
|
52
|
+
provider: "datadog",
|
|
53
|
+
endpoint: this.endpoint,
|
|
54
|
+
latencyMs: Date.now() - startTime,
|
|
55
|
+
error: result.error,
|
|
56
|
+
details: {
|
|
57
|
+
site: this.config.options?.site || "datadoghq.com",
|
|
58
|
+
service: this.config.options?.service,
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
return {
|
|
64
|
+
success: false,
|
|
65
|
+
provider: "datadog",
|
|
66
|
+
endpoint: this.endpoint,
|
|
67
|
+
latencyMs: Date.now() - startTime,
|
|
68
|
+
error: error instanceof Error ? error.message : String(error),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Send a single event to Datadog
|
|
74
|
+
*/
|
|
75
|
+
async sendEvent(event) {
|
|
76
|
+
const timestamp = new Date().toISOString();
|
|
77
|
+
try {
|
|
78
|
+
const payload = formatForDatadog(event, {
|
|
79
|
+
service: this.config.options?.service,
|
|
80
|
+
env: this.config.options?.env,
|
|
81
|
+
tags: this.config.options?.tags,
|
|
82
|
+
});
|
|
83
|
+
const response = await fetch(`${this.endpoint}/api/v2/logs`, {
|
|
84
|
+
method: "POST",
|
|
85
|
+
headers: {
|
|
86
|
+
"Content-Type": "application/json",
|
|
87
|
+
"DD-API-KEY": this.config.token,
|
|
88
|
+
},
|
|
89
|
+
body: JSON.stringify([payload]),
|
|
90
|
+
signal: AbortSignal.timeout(30000),
|
|
91
|
+
});
|
|
92
|
+
if (response.ok || response.status === 202) {
|
|
93
|
+
logger.debug("siem.datadog.event_sent", {
|
|
94
|
+
eventType: event.eventType,
|
|
95
|
+
});
|
|
96
|
+
return {
|
|
97
|
+
success: true,
|
|
98
|
+
timestamp,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
const errorText = await response.text();
|
|
102
|
+
logger.warn("siem.datadog.send_failed", {
|
|
103
|
+
status: response.status,
|
|
104
|
+
error: errorText,
|
|
105
|
+
});
|
|
106
|
+
return {
|
|
107
|
+
success: false,
|
|
108
|
+
timestamp,
|
|
109
|
+
error: `HTTP ${response.status}: ${errorText}`,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
114
|
+
logger.error("siem.datadog.send_error", { error: errorMessage });
|
|
115
|
+
return {
|
|
116
|
+
success: false,
|
|
117
|
+
timestamp,
|
|
118
|
+
error: errorMessage,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Send multiple events in batch
|
|
124
|
+
*/
|
|
125
|
+
async sendEvents(events) {
|
|
126
|
+
if (events.length === 0) {
|
|
127
|
+
return {
|
|
128
|
+
success: true,
|
|
129
|
+
totalEvents: 0,
|
|
130
|
+
successCount: 0,
|
|
131
|
+
failureCount: 0,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
const payloads = events.map((event) => formatForDatadog(event, {
|
|
136
|
+
service: this.config.options?.service,
|
|
137
|
+
env: this.config.options?.env,
|
|
138
|
+
tags: this.config.options?.tags,
|
|
139
|
+
}));
|
|
140
|
+
const response = await fetch(`${this.endpoint}/api/v2/logs`, {
|
|
141
|
+
method: "POST",
|
|
142
|
+
headers: {
|
|
143
|
+
"Content-Type": "application/json",
|
|
144
|
+
"DD-API-KEY": this.config.token,
|
|
145
|
+
},
|
|
146
|
+
body: JSON.stringify(payloads),
|
|
147
|
+
signal: AbortSignal.timeout(60000),
|
|
148
|
+
});
|
|
149
|
+
if (response.ok || response.status === 202) {
|
|
150
|
+
logger.info("siem.datadog.batch_sent", {
|
|
151
|
+
eventCount: events.length,
|
|
152
|
+
});
|
|
153
|
+
return {
|
|
154
|
+
success: true,
|
|
155
|
+
totalEvents: events.length,
|
|
156
|
+
successCount: events.length,
|
|
157
|
+
failureCount: 0,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
const errorText = await response.text();
|
|
161
|
+
logger.warn("siem.datadog.batch_failed", {
|
|
162
|
+
status: response.status,
|
|
163
|
+
error: errorText,
|
|
164
|
+
eventCount: events.length,
|
|
165
|
+
});
|
|
166
|
+
return {
|
|
167
|
+
success: false,
|
|
168
|
+
totalEvents: events.length,
|
|
169
|
+
successCount: 0,
|
|
170
|
+
failureCount: events.length,
|
|
171
|
+
errors: [{ index: 0, error: `HTTP ${response.status}: ${errorText}` }],
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
176
|
+
logger.error("siem.datadog.batch_error", { error: errorMessage });
|
|
177
|
+
return {
|
|
178
|
+
success: false,
|
|
179
|
+
totalEvents: events.length,
|
|
180
|
+
successCount: 0,
|
|
181
|
+
failureCount: events.length,
|
|
182
|
+
errors: [{ index: 0, error: errorMessage }],
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Close connection
|
|
188
|
+
*/
|
|
189
|
+
async close() {
|
|
190
|
+
// No persistent connection to close for Datadog API
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Create a Datadog client from configuration
|
|
195
|
+
*/
|
|
196
|
+
export function createDatadogClient(config) {
|
|
197
|
+
const site = config.site || "datadoghq.com";
|
|
198
|
+
return new DatadogClient({
|
|
199
|
+
provider: "datadog",
|
|
200
|
+
enabled: true,
|
|
201
|
+
endpoint: DATADOG_ENDPOINTS[site] || DATADOG_ENDPOINTS["datadoghq.com"],
|
|
202
|
+
token: config.apiKey,
|
|
203
|
+
options: {
|
|
204
|
+
site,
|
|
205
|
+
service: config.service || "vaspera-hardening",
|
|
206
|
+
env: config.env,
|
|
207
|
+
tags: config.tags,
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=datadog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datadog.js","sourceRoot":"","sources":["../../../src/integrations/siem/datadog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SIEM Event Formatting
|
|
3
|
+
*
|
|
4
|
+
* Converts Vaspera events to SIEM-compatible formats (CEF, JSON).
|
|
5
|
+
*
|
|
6
|
+
* @module integrations/siem/format
|
|
7
|
+
*/
|
|
8
|
+
import type { Severity } from "../../certification/types.js";
|
|
9
|
+
import type { SIEMEvent, SIEMSeverity, FindingEventData, ScanEventData, CertificationEventData } from "./types.js";
|
|
10
|
+
/**
|
|
11
|
+
* Map Vaspera severity to SIEM severity
|
|
12
|
+
*/
|
|
13
|
+
export declare function mapSeverity(severity: Severity): SIEMSeverity;
|
|
14
|
+
/**
|
|
15
|
+
* Map SIEM severity to CEF numeric severity (0-10)
|
|
16
|
+
*/
|
|
17
|
+
export declare function severityToCEF(severity: SIEMSeverity): number;
|
|
18
|
+
/**
|
|
19
|
+
* Format event as CEF string
|
|
20
|
+
*/
|
|
21
|
+
export declare function formatAsCEF(event: SIEMEvent): string;
|
|
22
|
+
/**
|
|
23
|
+
* Format event as JSON for generic SIEM ingestion
|
|
24
|
+
*/
|
|
25
|
+
export declare function formatAsJSON(event: SIEMEvent): object;
|
|
26
|
+
/**
|
|
27
|
+
* Format event for Splunk HEC
|
|
28
|
+
*/
|
|
29
|
+
export declare function formatForSplunk(event: SIEMEvent, options?: {
|
|
30
|
+
index?: string;
|
|
31
|
+
source?: string;
|
|
32
|
+
sourceType?: string;
|
|
33
|
+
host?: string;
|
|
34
|
+
}): object;
|
|
35
|
+
/**
|
|
36
|
+
* Format event for Microsoft Sentinel (Log Analytics)
|
|
37
|
+
*/
|
|
38
|
+
export declare function formatForSentinel(event: SIEMEvent): object;
|
|
39
|
+
/**
|
|
40
|
+
* Format event for Datadog
|
|
41
|
+
*/
|
|
42
|
+
export declare function formatForDatadog(event: SIEMEvent, options?: {
|
|
43
|
+
service?: string;
|
|
44
|
+
env?: string;
|
|
45
|
+
tags?: string[];
|
|
46
|
+
}): object;
|
|
47
|
+
/**
|
|
48
|
+
* Create a finding event
|
|
49
|
+
*/
|
|
50
|
+
export declare function createFindingEvent(project: string, eventType: "finding.new" | "finding.fixed" | "finding.false_positive", finding: FindingEventData, certificationId?: string): SIEMEvent;
|
|
51
|
+
/**
|
|
52
|
+
* Create a scan event
|
|
53
|
+
*/
|
|
54
|
+
export declare function createScanEvent(project: string, eventType: "scan.started" | "scan.completed" | "scan.failed", scan: ScanEventData, certificationId?: string): SIEMEvent;
|
|
55
|
+
/**
|
|
56
|
+
* Create a certification event
|
|
57
|
+
*/
|
|
58
|
+
export declare function createCertificationEvent(project: string, eventType: "certification.started" | "certification.completed", certification: CertificationEventData): SIEMEvent;
|
|
59
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/integrations/siem/format.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,KAAK,EACV,SAAS,EAET,YAAY,EAEZ,gBAAgB,EAChB,aAAa,EACb,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAMpB;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,QAAQ,GAAG,YAAY,CAe5D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAe5D;AAsDD;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAqEpD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAsBrD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,SAAS,EAChB,OAAO,GAAE;IACP,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACV,GACL,MAAM,CASR;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAa1D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,EAChB,OAAO,GAAE;IACP,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACZ,GACL,MAAM,CA0BR;AAmDD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,aAAa,GAAG,eAAe,GAAG,wBAAwB,EACrE,OAAO,EAAE,gBAAgB,EACzB,eAAe,CAAC,EAAE,MAAM,GACvB,SAAS,CAaX;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,cAAc,GAAG,gBAAgB,GAAG,aAAa,EAC5D,IAAI,EAAE,aAAa,EACnB,eAAe,CAAC,EAAE,MAAM,GACvB,SAAS,CA4BX;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,uBAAuB,GAAG,yBAAyB,EAC9D,aAAa,EAAE,sBAAsB,GACpC,SAAS,CAqBX"}
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SIEM Event Formatting
|
|
3
|
+
*
|
|
4
|
+
* Converts Vaspera events to SIEM-compatible formats (CEF, JSON).
|
|
5
|
+
*
|
|
6
|
+
* @module integrations/siem/format
|
|
7
|
+
*/
|
|
8
|
+
const DEVICE_VENDOR = "Vaspera";
|
|
9
|
+
const DEVICE_PRODUCT = "Hardening MCP";
|
|
10
|
+
const DEVICE_VERSION = "2.11.0";
|
|
11
|
+
/**
|
|
12
|
+
* Map Vaspera severity to SIEM severity
|
|
13
|
+
*/
|
|
14
|
+
export function mapSeverity(severity) {
|
|
15
|
+
switch (severity) {
|
|
16
|
+
case "critical":
|
|
17
|
+
return "critical";
|
|
18
|
+
case "high":
|
|
19
|
+
return "high";
|
|
20
|
+
case "medium":
|
|
21
|
+
return "medium";
|
|
22
|
+
case "low":
|
|
23
|
+
return "low";
|
|
24
|
+
case "info":
|
|
25
|
+
return "informational";
|
|
26
|
+
default:
|
|
27
|
+
return "informational";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Map SIEM severity to CEF numeric severity (0-10)
|
|
32
|
+
*/
|
|
33
|
+
export function severityToCEF(severity) {
|
|
34
|
+
switch (severity) {
|
|
35
|
+
case "critical":
|
|
36
|
+
return 10;
|
|
37
|
+
case "high":
|
|
38
|
+
return 8;
|
|
39
|
+
case "medium":
|
|
40
|
+
return 5;
|
|
41
|
+
case "low":
|
|
42
|
+
return 3;
|
|
43
|
+
case "informational":
|
|
44
|
+
return 1;
|
|
45
|
+
default:
|
|
46
|
+
return 0;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Map event type to signature ID
|
|
51
|
+
*/
|
|
52
|
+
function eventTypeToSignatureId(eventType) {
|
|
53
|
+
const mapping = {
|
|
54
|
+
"finding.new": "VASP-001",
|
|
55
|
+
"finding.fixed": "VASP-002",
|
|
56
|
+
"finding.false_positive": "VASP-003",
|
|
57
|
+
"scan.started": "VASP-010",
|
|
58
|
+
"scan.completed": "VASP-011",
|
|
59
|
+
"scan.failed": "VASP-012",
|
|
60
|
+
"certification.started": "VASP-020",
|
|
61
|
+
"certification.completed": "VASP-021",
|
|
62
|
+
"compliance.report": "VASP-030",
|
|
63
|
+
"autofix.applied": "VASP-040",
|
|
64
|
+
"autofix.pr_created": "VASP-041",
|
|
65
|
+
};
|
|
66
|
+
return mapping[eventType] || "VASP-999";
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Map event type to human-readable name
|
|
70
|
+
*/
|
|
71
|
+
function eventTypeToName(eventType) {
|
|
72
|
+
const mapping = {
|
|
73
|
+
"finding.new": "New Security Finding",
|
|
74
|
+
"finding.fixed": "Security Finding Fixed",
|
|
75
|
+
"finding.false_positive": "Finding Marked False Positive",
|
|
76
|
+
"scan.started": "Security Scan Started",
|
|
77
|
+
"scan.completed": "Security Scan Completed",
|
|
78
|
+
"scan.failed": "Security Scan Failed",
|
|
79
|
+
"certification.started": "Certification Started",
|
|
80
|
+
"certification.completed": "Certification Completed",
|
|
81
|
+
"compliance.report": "Compliance Report Generated",
|
|
82
|
+
"autofix.applied": "Autofix Applied",
|
|
83
|
+
"autofix.pr_created": "Autofix Pull Request Created",
|
|
84
|
+
};
|
|
85
|
+
return mapping[eventType] || "Unknown Event";
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Escape CEF special characters
|
|
89
|
+
*/
|
|
90
|
+
function escapeCEF(value) {
|
|
91
|
+
return value
|
|
92
|
+
.replace(/\\/g, "\\\\")
|
|
93
|
+
.replace(/=/g, "\\=")
|
|
94
|
+
.replace(/\|/g, "\\|")
|
|
95
|
+
.replace(/\n/g, "\\n")
|
|
96
|
+
.replace(/\r/g, "\\r");
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Format event as CEF string
|
|
100
|
+
*/
|
|
101
|
+
export function formatAsCEF(event) {
|
|
102
|
+
const fields = {
|
|
103
|
+
version: 0,
|
|
104
|
+
deviceVendor: DEVICE_VENDOR,
|
|
105
|
+
deviceProduct: DEVICE_PRODUCT,
|
|
106
|
+
deviceVersion: DEVICE_VERSION,
|
|
107
|
+
signatureId: eventTypeToSignatureId(event.eventType),
|
|
108
|
+
name: eventTypeToName(event.eventType),
|
|
109
|
+
severity: severityToCEF(event.severity),
|
|
110
|
+
extension: {},
|
|
111
|
+
};
|
|
112
|
+
// Build extension fields
|
|
113
|
+
const ext = fields.extension;
|
|
114
|
+
ext["rt"] = new Date(event.timestamp).getTime();
|
|
115
|
+
ext["msg"] = escapeCEF(event.message);
|
|
116
|
+
ext["src"] = event.source;
|
|
117
|
+
ext["cs1"] = event.project;
|
|
118
|
+
ext["cs1Label"] = "project";
|
|
119
|
+
if (event.certificationId) {
|
|
120
|
+
ext["cs2"] = event.certificationId;
|
|
121
|
+
ext["cs2Label"] = "certificationId";
|
|
122
|
+
}
|
|
123
|
+
// Add finding-specific fields
|
|
124
|
+
const data = event.data;
|
|
125
|
+
if (data.findingId) {
|
|
126
|
+
ext["externalId"] = data.findingId;
|
|
127
|
+
}
|
|
128
|
+
if (data.file) {
|
|
129
|
+
ext["filePath"] = escapeCEF(data.file);
|
|
130
|
+
}
|
|
131
|
+
if (data.line) {
|
|
132
|
+
ext["fileId"] = data.line;
|
|
133
|
+
}
|
|
134
|
+
if (data.category) {
|
|
135
|
+
ext["cat"] = escapeCEF(data.category);
|
|
136
|
+
}
|
|
137
|
+
if (data.scanner) {
|
|
138
|
+
ext["deviceCustomString3"] = escapeCEF(data.scanner);
|
|
139
|
+
ext["deviceCustomString3Label"] = "scanner";
|
|
140
|
+
}
|
|
141
|
+
if (data.ruleId) {
|
|
142
|
+
ext["cs4"] = escapeCEF(data.ruleId);
|
|
143
|
+
ext["cs4Label"] = "ruleId";
|
|
144
|
+
}
|
|
145
|
+
if (data.cweIds && data.cweIds.length > 0) {
|
|
146
|
+
ext["cs5"] = data.cweIds.join(",");
|
|
147
|
+
ext["cs5Label"] = "cweIds";
|
|
148
|
+
}
|
|
149
|
+
// Format CEF header
|
|
150
|
+
const header = [
|
|
151
|
+
`CEF:${fields.version}`,
|
|
152
|
+
escapeCEF(fields.deviceVendor),
|
|
153
|
+
escapeCEF(fields.deviceProduct),
|
|
154
|
+
escapeCEF(fields.deviceVersion),
|
|
155
|
+
escapeCEF(fields.signatureId),
|
|
156
|
+
escapeCEF(fields.name),
|
|
157
|
+
fields.severity.toString(),
|
|
158
|
+
].join("|");
|
|
159
|
+
// Format extension
|
|
160
|
+
const extension = Object.entries(ext)
|
|
161
|
+
.map(([key, value]) => `${key}=${value}`)
|
|
162
|
+
.join(" ");
|
|
163
|
+
return `${header}|${extension}`;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Format event as JSON for generic SIEM ingestion
|
|
167
|
+
*/
|
|
168
|
+
export function formatAsJSON(event) {
|
|
169
|
+
return {
|
|
170
|
+
"@timestamp": event.timestamp,
|
|
171
|
+
event: {
|
|
172
|
+
kind: "event",
|
|
173
|
+
category: ["security"],
|
|
174
|
+
type: [event.eventType.split(".")[0]],
|
|
175
|
+
action: event.eventType,
|
|
176
|
+
severity: severityToCEF(event.severity),
|
|
177
|
+
severity_name: event.severity,
|
|
178
|
+
},
|
|
179
|
+
message: event.message,
|
|
180
|
+
source: {
|
|
181
|
+
provider: event.source,
|
|
182
|
+
version: DEVICE_VERSION,
|
|
183
|
+
},
|
|
184
|
+
project: {
|
|
185
|
+
path: event.project,
|
|
186
|
+
certification_id: event.certificationId,
|
|
187
|
+
},
|
|
188
|
+
vaspera: event.data,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Format event for Splunk HEC
|
|
193
|
+
*/
|
|
194
|
+
export function formatForSplunk(event, options = {}) {
|
|
195
|
+
return {
|
|
196
|
+
time: Math.floor(new Date(event.timestamp).getTime() / 1000),
|
|
197
|
+
host: options.host || "vaspera",
|
|
198
|
+
source: options.source || "vaspera:hardening",
|
|
199
|
+
sourcetype: options.sourceType || "_json",
|
|
200
|
+
index: options.index,
|
|
201
|
+
event: formatAsJSON(event),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Format event for Microsoft Sentinel (Log Analytics)
|
|
206
|
+
*/
|
|
207
|
+
export function formatForSentinel(event) {
|
|
208
|
+
const json = formatAsJSON(event);
|
|
209
|
+
return {
|
|
210
|
+
TimeGenerated: event.timestamp,
|
|
211
|
+
EventType_s: event.eventType,
|
|
212
|
+
Severity_s: event.severity,
|
|
213
|
+
Project_s: event.project,
|
|
214
|
+
CertificationId_g: event.certificationId || "",
|
|
215
|
+
Message_s: event.message,
|
|
216
|
+
Source_s: event.source,
|
|
217
|
+
RawEvent_s: JSON.stringify(event.data),
|
|
218
|
+
...flattenData(event.data, "_"),
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Format event for Datadog
|
|
223
|
+
*/
|
|
224
|
+
export function formatForDatadog(event, options = {}) {
|
|
225
|
+
const tags = [
|
|
226
|
+
`project:${event.project}`,
|
|
227
|
+
`event_type:${event.eventType}`,
|
|
228
|
+
`severity:${event.severity}`,
|
|
229
|
+
...(event.certificationId ? [`certification_id:${event.certificationId}`] : []),
|
|
230
|
+
...(options.tags || []),
|
|
231
|
+
];
|
|
232
|
+
if (options.env) {
|
|
233
|
+
tags.push(`env:${options.env}`);
|
|
234
|
+
}
|
|
235
|
+
return {
|
|
236
|
+
ddsource: "vaspera",
|
|
237
|
+
ddtags: tags.join(","),
|
|
238
|
+
hostname: "vaspera-mcp",
|
|
239
|
+
service: options.service || "vaspera-hardening",
|
|
240
|
+
status: mapSeverityToDatadogStatus(event.severity),
|
|
241
|
+
message: event.message,
|
|
242
|
+
"@timestamp": event.timestamp,
|
|
243
|
+
event_type: event.eventType,
|
|
244
|
+
project: event.project,
|
|
245
|
+
certification_id: event.certificationId,
|
|
246
|
+
data: event.data,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Map SIEM severity to Datadog status
|
|
251
|
+
*/
|
|
252
|
+
function mapSeverityToDatadogStatus(severity) {
|
|
253
|
+
switch (severity) {
|
|
254
|
+
case "critical":
|
|
255
|
+
return "emergency";
|
|
256
|
+
case "high":
|
|
257
|
+
return "error";
|
|
258
|
+
case "medium":
|
|
259
|
+
return "warning";
|
|
260
|
+
case "low":
|
|
261
|
+
return "info";
|
|
262
|
+
case "informational":
|
|
263
|
+
return "debug";
|
|
264
|
+
default:
|
|
265
|
+
return "info";
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Flatten nested data object for Sentinel
|
|
270
|
+
*/
|
|
271
|
+
function flattenData(data, suffix, prefix = "") {
|
|
272
|
+
const result = {};
|
|
273
|
+
for (const [key, value] of Object.entries(data)) {
|
|
274
|
+
const newKey = prefix ? `${prefix}_${key}${suffix}` : `${key}${suffix}`;
|
|
275
|
+
if (value === null || value === undefined) {
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
if (typeof value === "object" && !Array.isArray(value)) {
|
|
279
|
+
Object.assign(result, flattenData(value, suffix, key));
|
|
280
|
+
}
|
|
281
|
+
else if (Array.isArray(value)) {
|
|
282
|
+
result[newKey] = value.join(",");
|
|
283
|
+
}
|
|
284
|
+
else if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
285
|
+
result[newKey] = value;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return result;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Create a finding event
|
|
292
|
+
*/
|
|
293
|
+
export function createFindingEvent(project, eventType, finding, certificationId) {
|
|
294
|
+
const actionVerb = eventType === "finding.new" ? "detected" : eventType === "finding.fixed" ? "fixed" : "marked as false positive";
|
|
295
|
+
return {
|
|
296
|
+
timestamp: new Date().toISOString(),
|
|
297
|
+
eventType,
|
|
298
|
+
severity: mapSeverity(finding.severity),
|
|
299
|
+
project,
|
|
300
|
+
certificationId,
|
|
301
|
+
message: `Security finding ${actionVerb}: ${finding.category} in ${finding.file || "unknown"}${finding.line ? `:${finding.line}` : ""}`,
|
|
302
|
+
source: "vaspera",
|
|
303
|
+
data: finding,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Create a scan event
|
|
308
|
+
*/
|
|
309
|
+
export function createScanEvent(project, eventType, scan, certificationId) {
|
|
310
|
+
let severity = "informational";
|
|
311
|
+
let message;
|
|
312
|
+
switch (eventType) {
|
|
313
|
+
case "scan.started":
|
|
314
|
+
message = `Security scan started with scanners: ${scan.scanners.join(", ")}`;
|
|
315
|
+
break;
|
|
316
|
+
case "scan.completed":
|
|
317
|
+
severity = scan.bySeverity.critical > 0 ? "critical" : scan.bySeverity.high > 0 ? "high" : "informational";
|
|
318
|
+
message = `Security scan completed: ${scan.findingsCount} findings (${scan.bySeverity.critical} critical, ${scan.bySeverity.high} high)`;
|
|
319
|
+
break;
|
|
320
|
+
case "scan.failed":
|
|
321
|
+
severity = "high";
|
|
322
|
+
message = `Security scan failed: ${scan.error || "Unknown error"}`;
|
|
323
|
+
break;
|
|
324
|
+
}
|
|
325
|
+
return {
|
|
326
|
+
timestamp: new Date().toISOString(),
|
|
327
|
+
eventType,
|
|
328
|
+
severity,
|
|
329
|
+
project,
|
|
330
|
+
certificationId,
|
|
331
|
+
message,
|
|
332
|
+
source: "vaspera",
|
|
333
|
+
data: scan,
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Create a certification event
|
|
338
|
+
*/
|
|
339
|
+
export function createCertificationEvent(project, eventType, certification) {
|
|
340
|
+
let severity = "informational";
|
|
341
|
+
let message;
|
|
342
|
+
if (eventType === "certification.started") {
|
|
343
|
+
message = `Certification started: ${certification.certificationId}`;
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
severity = certification.score && certification.score >= 80 ? "informational" : "medium";
|
|
347
|
+
message = `Certification completed: ${certification.level || "unknown"} (score: ${certification.score || 0})`;
|
|
348
|
+
}
|
|
349
|
+
return {
|
|
350
|
+
timestamp: new Date().toISOString(),
|
|
351
|
+
eventType,
|
|
352
|
+
severity,
|
|
353
|
+
project,
|
|
354
|
+
certificationId: certification.certificationId,
|
|
355
|
+
message,
|
|
356
|
+
source: "vaspera",
|
|
357
|
+
data: certification,
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
//# sourceMappingURL=format.js.map
|