@cyclonedx/cdxgen 12.4.0 → 12.4.2
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/README.md +6 -4
- package/bin/cdxgen.js +32 -11
- package/bin/convert.js +12 -8
- package/bin/evinse.js +15 -0
- package/bin/hbom.js +13 -8
- package/bin/repl.js +14 -10
- package/bin/validate.js +10 -13
- package/bin/verify.js +7 -29
- package/data/cyclonedx-2.0-bundled.schema.json +7182 -0
- package/lib/audit/index.js +2 -1
- package/lib/cli/index.js +77 -16
- package/lib/cli/index.poku.js +197 -0
- package/lib/evinser/evinser.js +118 -3
- package/lib/helpers/bomUtils.js +155 -1
- package/lib/helpers/bomUtils.poku.js +79 -1
- package/lib/helpers/cbomutils.js +162 -2
- package/lib/helpers/cbomutils.poku.js +100 -0
- package/lib/helpers/ciParsers/githubActions.js +15 -3
- package/lib/helpers/ciParsers/githubActions.poku.js +52 -0
- package/lib/helpers/dosai.js +433 -0
- package/lib/helpers/dosai.poku.js +302 -0
- package/lib/helpers/dosaiParsers.js +103 -0
- package/lib/helpers/plugins.js +17 -16
- package/lib/helpers/protobom.js +53 -0
- package/lib/helpers/protobom.poku.js +44 -1
- package/lib/helpers/protobomLoader.js +43 -0
- package/lib/helpers/protobomLoader.poku.js +31 -0
- package/lib/helpers/utils.js +130 -1
- package/lib/helpers/utils.poku.js +295 -0
- package/lib/server/server.js +2 -1
- package/lib/stages/postgen/annotator.js +2 -1
- package/lib/stages/postgen/annotator.poku.js +28 -0
- package/lib/stages/postgen/postgen.js +219 -12
- package/lib/stages/postgen/postgen.poku.js +163 -0
- package/lib/validator/bomValidator.js +90 -38
- package/lib/validator/bomValidator.poku.js +90 -0
- package/lib/validator/complianceRules.js +4 -2
- package/lib/validator/index.poku.js +14 -0
- package/package.json +12 -12
- package/types/bin/repl.d.ts +1 -1
- package/types/bin/repl.d.ts.map +1 -1
- package/types/lib/audit/index.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/evinser/evinser.d.ts +15 -0
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/helpers/bomUtils.d.ts +8 -0
- package/types/lib/helpers/bomUtils.d.ts.map +1 -1
- package/types/lib/helpers/cbomutils.d.ts +1 -0
- package/types/lib/helpers/cbomutils.d.ts.map +1 -1
- package/types/lib/helpers/ciParsers/githubActions.d.ts.map +1 -1
- package/types/lib/helpers/dosai.d.ts +24 -0
- package/types/lib/helpers/dosai.d.ts.map +1 -0
- package/types/lib/helpers/dosaiParsers.d.ts +8 -0
- package/types/lib/helpers/dosaiParsers.d.ts.map +1 -0
- package/types/lib/helpers/hbomAnalysis.d.ts +14 -0
- package/types/lib/helpers/hbomAnalysis.d.ts.map +1 -1
- package/types/lib/helpers/hostTopology.d.ts.map +1 -1
- package/types/lib/helpers/plugins.d.ts.map +1 -1
- package/types/lib/helpers/protobom.d.ts +2 -0
- package/types/lib/helpers/protobom.d.ts.map +1 -1
- package/types/lib/helpers/protobomLoader.d.ts +17 -0
- package/types/lib/helpers/protobomLoader.d.ts.map +1 -0
- package/types/lib/helpers/utils.d.ts.map +1 -1
- package/types/lib/server/server.d.ts.map +1 -1
- package/types/lib/stages/postgen/annotator.d.ts.map +1 -1
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
- package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
- package/types/lib/third-party/arborist/lib/node.d.ts +23 -0
- package/types/lib/third-party/arborist/lib/node.d.ts.map +1 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
- package/types/lib/validator/complianceRules.d.ts.map +1 -1
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { basename, delimiter, join, resolve } from "node:path";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
addDosaiSetValue,
|
|
6
|
+
buildDosaiPurlAliasMap,
|
|
7
|
+
dosaiSourceLocation,
|
|
8
|
+
dosaiSourceLocationFromNode,
|
|
9
|
+
resolveDosaiComponentPurl,
|
|
10
|
+
} from "./dosaiParsers.js";
|
|
11
|
+
import { resolvePluginBinary } from "./plugins.js";
|
|
12
|
+
import {
|
|
13
|
+
DEBUG_MODE,
|
|
14
|
+
getTmpDir,
|
|
15
|
+
safeExistsSync,
|
|
16
|
+
safeMkdtempSync,
|
|
17
|
+
safeRmSync,
|
|
18
|
+
safeSpawnSync,
|
|
19
|
+
} from "./utils.js";
|
|
20
|
+
|
|
21
|
+
const DOTNET_LANGUAGES = new Set([
|
|
22
|
+
"c#",
|
|
23
|
+
"csharp",
|
|
24
|
+
"cs",
|
|
25
|
+
"dotnet",
|
|
26
|
+
"dotnet-framework",
|
|
27
|
+
"f#",
|
|
28
|
+
"fsharp",
|
|
29
|
+
"fs",
|
|
30
|
+
"nuget",
|
|
31
|
+
"vb",
|
|
32
|
+
"vbnet",
|
|
33
|
+
"visualbasic",
|
|
34
|
+
]);
|
|
35
|
+
|
|
36
|
+
const DOSAI_COMMANDS = new Set(["crypto", "dataflows", "methods"]);
|
|
37
|
+
|
|
38
|
+
function dosaiBin() {
|
|
39
|
+
return resolvePluginBinary("dosai");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function frameFromDosaiNode(node) {
|
|
43
|
+
if (!node) {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
const fullFilename =
|
|
47
|
+
node.Path || node.FileName || node.CallLocation?.FileName;
|
|
48
|
+
if (!fullFilename || fullFilename === "<unknown>") {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
package: node.Namespace || "",
|
|
53
|
+
module: node.ClassName || node.Module || "",
|
|
54
|
+
function: node.MethodName || node.Name || node.CalledMethodName || "",
|
|
55
|
+
line: node.LineNumber || node.CallLocation?.LineNumber || undefined,
|
|
56
|
+
column: node.ColumnNumber || node.CallLocation?.ColumnNumber || undefined,
|
|
57
|
+
fullFilename,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function appendUniqueProperty(properties, name, value) {
|
|
62
|
+
if (value === undefined || value === null || value === "") {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (
|
|
66
|
+
!properties.some(
|
|
67
|
+
(property) => property.name === name && property.value === String(value),
|
|
68
|
+
)
|
|
69
|
+
) {
|
|
70
|
+
properties.push({ name, value: String(value) });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function sanitizeEndpoint(endpoint) {
|
|
75
|
+
const value = String(endpoint || "").trim();
|
|
76
|
+
if (!value) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
if (/^https?:\/\//i.test(value)) {
|
|
80
|
+
try {
|
|
81
|
+
const parsedUrl = new URL(value);
|
|
82
|
+
parsedUrl.username = "";
|
|
83
|
+
parsedUrl.password = "";
|
|
84
|
+
parsedUrl.search = "";
|
|
85
|
+
parsedUrl.hash = "";
|
|
86
|
+
return parsedUrl.toString();
|
|
87
|
+
} catch (_err) {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return value.split("?")[0].split("#")[0].slice(0, 512);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function serviceNameFromEndpoint(endpoint) {
|
|
95
|
+
const className = endpoint.ClassName || endpoint.FileName || "dotnet";
|
|
96
|
+
const methodName = endpoint.MethodName || endpoint.HttpMethod || "endpoint";
|
|
97
|
+
return `dosai-${className}-${methodName}-service`
|
|
98
|
+
.replace(/[^A-Za-z0-9_.-]+/g, "-")
|
|
99
|
+
.replace(/-+/g, "-");
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function dosaiSdkMessage(result) {
|
|
103
|
+
return (
|
|
104
|
+
result?.stdout?.includes(
|
|
105
|
+
"You must install or update .NET to run this application",
|
|
106
|
+
) ||
|
|
107
|
+
result?.stderr?.includes(
|
|
108
|
+
"You must install or update .NET to run this application",
|
|
109
|
+
)
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function safeDosaiPath(value) {
|
|
114
|
+
if (!value || typeof value !== "string" || /[\0\r\n]/.test(value)) {
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
return resolve(value);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function safeDosaiPatternPacks(value) {
|
|
121
|
+
if (!value || typeof value !== "string" || /[\0\r\n]/.test(value)) {
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
return value
|
|
125
|
+
.split(delimiter)
|
|
126
|
+
.map((patternPack) => safeDosaiPath(patternPack.trim()))
|
|
127
|
+
.filter(Boolean)
|
|
128
|
+
.join(delimiter);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function safeDosaiExecutable(value) {
|
|
132
|
+
if (!value || typeof value !== "string" || /[\0\r\n]/.test(value)) {
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
return value.trim();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export function isDosaiDotnetLanguage(language) {
|
|
139
|
+
return DOTNET_LANGUAGES.has(String(language || "").toLowerCase());
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function readDosaiJsonFile(jsonFile) {
|
|
143
|
+
if (!jsonFile || !safeExistsSync(jsonFile)) {
|
|
144
|
+
return undefined;
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
return JSON.parse(readFileSync(jsonFile, "utf-8"));
|
|
148
|
+
} catch (_err) {
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function runDosaiCommand(command, src, outputFile, options = {}) {
|
|
154
|
+
if (!DOSAI_COMMANDS.has(command)) {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
const executable = safeDosaiExecutable(options.dosaiCommand || dosaiBin());
|
|
158
|
+
const srcPath = safeDosaiPath(src);
|
|
159
|
+
const outputPath = safeDosaiPath(outputFile);
|
|
160
|
+
if (!executable || !srcPath || !outputPath) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
const args = [command, "--path", srcPath, "--o", outputPath];
|
|
164
|
+
if (command === "dataflows") {
|
|
165
|
+
if (options.dataFlowPatterns) {
|
|
166
|
+
const patternsPath = safeDosaiPath(options.dataFlowPatterns);
|
|
167
|
+
if (patternsPath) {
|
|
168
|
+
args.push("--patterns", patternsPath);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (options.dataFlowPatternPacks || options.patternPacks) {
|
|
172
|
+
const patternPacks = safeDosaiPatternPacks(
|
|
173
|
+
options.dataFlowPatternPacks || options.patternPacks,
|
|
174
|
+
);
|
|
175
|
+
if (patternPacks) {
|
|
176
|
+
args.push("--pattern-packs", patternPacks);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
} else if (command === "crypto") {
|
|
180
|
+
args.push("--format", "dosai");
|
|
181
|
+
}
|
|
182
|
+
if (DEBUG_MODE) {
|
|
183
|
+
console.log("Executing", executable, args.join(" "));
|
|
184
|
+
}
|
|
185
|
+
const result = safeSpawnSync(executable, args, {
|
|
186
|
+
cwd: srcPath,
|
|
187
|
+
shell: false,
|
|
188
|
+
});
|
|
189
|
+
if (dosaiSdkMessage(result)) {
|
|
190
|
+
console.log(
|
|
191
|
+
"Dotnet SDK is not installed. Please use the cdxgen dotnet container images to analyze this project with dosai.",
|
|
192
|
+
);
|
|
193
|
+
console.log(
|
|
194
|
+
"Alternatively, download the dosai self-contained binary (-full suffix) from https://github.com/owasp-dep-scan/dosai/releases and set DOSAI_CMD to its location.",
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
if (result?.status !== 0 || result?.error || !safeExistsSync(outputPath)) {
|
|
198
|
+
if (DEBUG_MODE) {
|
|
199
|
+
if (result?.stderr || result?.stdout) {
|
|
200
|
+
console.error(result.stdout, result.stderr);
|
|
201
|
+
} else {
|
|
202
|
+
console.log("Check if the dosai plugin was installed successfully.");
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export function createDosaiMethodsSlice(src, outputFile, options = {}) {
|
|
211
|
+
return runDosaiCommand("methods", src, outputFile, options);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export function createDosaiDataFlowSlice(src, outputFile, options = {}) {
|
|
215
|
+
return runDosaiCommand("dataflows", src, outputFile, options);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export function createDosaiCryptoAnalysis(src, outputFile, options = {}) {
|
|
219
|
+
return runDosaiCommand("crypto", src, outputFile, options);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export function analyzeDosaiCrypto(src, options = {}) {
|
|
223
|
+
const tempDir = safeMkdtempSync(join(getTmpDir(), "dosai-crypto-"));
|
|
224
|
+
const outputFile = join(tempDir, "dosai-crypto.json");
|
|
225
|
+
try {
|
|
226
|
+
if (!createDosaiCryptoAnalysis(src, outputFile, options)) {
|
|
227
|
+
return undefined;
|
|
228
|
+
}
|
|
229
|
+
return readDosaiJsonFile(outputFile);
|
|
230
|
+
} finally {
|
|
231
|
+
if (tempDir?.startsWith(getTmpDir())) {
|
|
232
|
+
safeRmSync(tempDir, { recursive: true, force: true });
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export function buildPurlAliasMap(components = []) {
|
|
238
|
+
return buildDosaiPurlAliasMap(components);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export function resolveComponentPurl(purl, purlAliasMap) {
|
|
242
|
+
return resolveDosaiComponentPurl(purl, purlAliasMap);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export function collectDosaiPurlEvidence(methodsSlice, components = []) {
|
|
246
|
+
const purlAliasMap = buildPurlAliasMap(components);
|
|
247
|
+
const purlLocationMap = {};
|
|
248
|
+
const purlModulesMap = {};
|
|
249
|
+
const purlMethodsMap = {};
|
|
250
|
+
const edgesById = new Map(
|
|
251
|
+
(methodsSlice?.CallGraph?.Edges || []).map((edge) => [edge.Id, edge]),
|
|
252
|
+
);
|
|
253
|
+
const nodesById = new Map(
|
|
254
|
+
(methodsSlice?.CallGraph?.Nodes || []).map((node) => [node.Id, node]),
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
for (const dependency of methodsSlice?.Dependencies || []) {
|
|
258
|
+
const purl = resolveComponentPurl(dependency.Purl, purlAliasMap);
|
|
259
|
+
if (!purl) {
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
addDosaiSetValue(purlLocationMap, purl, dosaiSourceLocation(dependency));
|
|
263
|
+
addDosaiSetValue(
|
|
264
|
+
purlModulesMap,
|
|
265
|
+
purl,
|
|
266
|
+
dependency.Name || dependency.Namespace,
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
for (const reachability of methodsSlice?.PackageReachability || []) {
|
|
271
|
+
const purl = resolveComponentPurl(reachability.Purl, purlAliasMap);
|
|
272
|
+
if (!purl) {
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
let hasExplicitSourceLocations = false;
|
|
276
|
+
for (const sourceLocation of reachability.SourceLocations || []) {
|
|
277
|
+
const location = dosaiSourceLocation(sourceLocation);
|
|
278
|
+
addDosaiSetValue(purlLocationMap, purl, location);
|
|
279
|
+
hasExplicitSourceLocations ||= Boolean(location);
|
|
280
|
+
}
|
|
281
|
+
for (const edgeId of reachability.EdgeIds || []) {
|
|
282
|
+
const edge = edgesById.get(edgeId);
|
|
283
|
+
if (!hasExplicitSourceLocations) {
|
|
284
|
+
addDosaiSetValue(purlLocationMap, purl, dosaiSourceLocation(edge));
|
|
285
|
+
}
|
|
286
|
+
addDosaiSetValue(
|
|
287
|
+
purlMethodsMap,
|
|
288
|
+
purl,
|
|
289
|
+
edge?.CalledMethodName || edge?.TargetName,
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
for (const nodeId of reachability.NodeIds || []) {
|
|
293
|
+
const node = nodesById.get(nodeId);
|
|
294
|
+
if (!hasExplicitSourceLocations) {
|
|
295
|
+
addDosaiSetValue(
|
|
296
|
+
purlLocationMap,
|
|
297
|
+
purl,
|
|
298
|
+
dosaiSourceLocationFromNode(node),
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
addDosaiSetValue(purlModulesMap, purl, node?.ClassName || node?.Module);
|
|
302
|
+
addDosaiSetValue(
|
|
303
|
+
purlMethodsMap,
|
|
304
|
+
purl,
|
|
305
|
+
node?.Name || node?.Identity?.MethodName,
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
return { purlLocationMap, purlModulesMap, purlMethodsMap };
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export function collectDosaiDataFlowFrames(dataFlowResult, components = []) {
|
|
313
|
+
const purlAliasMap = buildPurlAliasMap(components);
|
|
314
|
+
const nodesById = new Map(
|
|
315
|
+
(dataFlowResult?.Nodes || []).map((node) => [node.Id, node]),
|
|
316
|
+
);
|
|
317
|
+
const dataFlowFrames = {};
|
|
318
|
+
const addFramesForPurl = (purl, frames) => {
|
|
319
|
+
const componentPurl = resolveComponentPurl(purl, purlAliasMap);
|
|
320
|
+
if (!componentPurl || !frames.length) {
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
dataFlowFrames[componentPurl] ??= [];
|
|
324
|
+
dataFlowFrames[componentPurl].push(frames);
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
for (const slice of dataFlowResult?.Slices || []) {
|
|
328
|
+
const frames = (slice.NodeIds || [])
|
|
329
|
+
.map((nodeId) => frameFromDosaiNode(nodesById.get(nodeId)))
|
|
330
|
+
.filter(Boolean);
|
|
331
|
+
const purls = new Set(
|
|
332
|
+
[...(slice.Purls || []), slice.SourcePurl, slice.SinkPurl].filter(
|
|
333
|
+
Boolean,
|
|
334
|
+
),
|
|
335
|
+
);
|
|
336
|
+
for (const purl of purls) {
|
|
337
|
+
addFramesForPurl(purl, frames);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
for (const reachability of dataFlowResult?.PackageReachability || []) {
|
|
342
|
+
const frames = (reachability.NodeIds || [])
|
|
343
|
+
.map((nodeId) => frameFromDosaiNode(nodesById.get(nodeId)))
|
|
344
|
+
.filter(Boolean);
|
|
345
|
+
addFramesForPurl(reachability.Purl, frames);
|
|
346
|
+
}
|
|
347
|
+
return dataFlowFrames;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export function collectDosaiServicesFromMethods(
|
|
351
|
+
methodsSlice,
|
|
352
|
+
servicesMap = {},
|
|
353
|
+
) {
|
|
354
|
+
for (const endpoint of methodsSlice?.ApiEndpoints || []) {
|
|
355
|
+
const route = sanitizeEndpoint(endpoint.Route || endpoint.Path);
|
|
356
|
+
if (!route) {
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
const serviceName = serviceNameFromEndpoint(endpoint);
|
|
360
|
+
servicesMap[serviceName] ??= {
|
|
361
|
+
endpoints: new Set(),
|
|
362
|
+
authenticated: endpoint.AuthorizationRequired,
|
|
363
|
+
xTrustBoundary:
|
|
364
|
+
endpoint.AuthorizationRequired === true ? true : undefined,
|
|
365
|
+
properties: [],
|
|
366
|
+
};
|
|
367
|
+
servicesMap[serviceName].endpoints.add(route);
|
|
368
|
+
const properties = servicesMap[serviceName].properties;
|
|
369
|
+
appendUniqueProperty(
|
|
370
|
+
properties,
|
|
371
|
+
"cdx:service:httpMethod",
|
|
372
|
+
endpoint.HttpMethod || "ANY",
|
|
373
|
+
);
|
|
374
|
+
appendUniqueProperty(
|
|
375
|
+
properties,
|
|
376
|
+
"cdx:dosai:endpointKind",
|
|
377
|
+
endpoint.EndpointKind,
|
|
378
|
+
);
|
|
379
|
+
appendUniqueProperty(
|
|
380
|
+
properties,
|
|
381
|
+
"cdx:dosai:authorizationRequired",
|
|
382
|
+
endpoint.AuthorizationRequired,
|
|
383
|
+
);
|
|
384
|
+
appendUniqueProperty(
|
|
385
|
+
properties,
|
|
386
|
+
"cdx:dosai:allowAnonymous",
|
|
387
|
+
endpoint.AllowAnonymous,
|
|
388
|
+
);
|
|
389
|
+
appendUniqueProperty(
|
|
390
|
+
properties,
|
|
391
|
+
"cdx:dosai:authorizationPolicyCount",
|
|
392
|
+
endpoint.AuthorizationPolicies?.length,
|
|
393
|
+
);
|
|
394
|
+
appendUniqueProperty(
|
|
395
|
+
properties,
|
|
396
|
+
"cdx:dosai:roleCount",
|
|
397
|
+
endpoint.Roles?.length,
|
|
398
|
+
);
|
|
399
|
+
appendUniqueProperty(
|
|
400
|
+
properties,
|
|
401
|
+
"cdx:dosai:requiredClaimCount",
|
|
402
|
+
endpoint.RequiredClaims?.length,
|
|
403
|
+
);
|
|
404
|
+
appendUniqueProperty(
|
|
405
|
+
properties,
|
|
406
|
+
"cdx:dosai:requiredScopeCount",
|
|
407
|
+
endpoint.RequiredScopes?.length,
|
|
408
|
+
);
|
|
409
|
+
appendUniqueProperty(
|
|
410
|
+
properties,
|
|
411
|
+
"SrcFile",
|
|
412
|
+
endpoint.Path || endpoint.FileName,
|
|
413
|
+
);
|
|
414
|
+
if (endpoint.LineNumber) {
|
|
415
|
+
appendUniqueProperty(
|
|
416
|
+
properties,
|
|
417
|
+
"cdx:dosai:location",
|
|
418
|
+
`${endpoint.Path || endpoint.FileName}:${endpoint.LineNumber}:${endpoint.ColumnNumber || 0}`,
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
return servicesMap;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
export function normalizeDosaiServiceMap(servicesMap = {}) {
|
|
426
|
+
return Object.keys(servicesMap).map((serviceName) => ({
|
|
427
|
+
name: serviceName || `dosai-${basename(serviceName)}-service`,
|
|
428
|
+
endpoints: Array.from(servicesMap[serviceName].endpoints || []).sort(),
|
|
429
|
+
authenticated: servicesMap[serviceName].authenticated,
|
|
430
|
+
"x-trust-boundary": servicesMap[serviceName].xTrustBoundary,
|
|
431
|
+
properties: servicesMap[serviceName].properties,
|
|
432
|
+
}));
|
|
433
|
+
}
|