@trustify-da/trustify-da-javascript-client 0.3.0-ea.e12bc82 → 0.3.0-ea.e258fba
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 +367 -13
- package/dist/package.json +48 -28
- package/dist/src/analysis.d.ts +28 -5
- package/dist/src/analysis.js +99 -89
- package/dist/src/batch_opts.d.ts +24 -0
- package/dist/src/batch_opts.js +35 -0
- package/dist/src/cli.js +346 -9
- package/dist/src/cyclone_dx_sbom.d.ts +30 -3
- package/dist/src/cyclone_dx_sbom.js +95 -9
- package/dist/src/index.d.ts +202 -12
- package/dist/src/index.js +365 -30
- package/dist/src/license/index.d.ts +28 -0
- package/dist/src/license/index.js +103 -0
- package/dist/src/license/license_utils.d.ts +40 -0
- package/dist/src/license/license_utils.js +137 -0
- package/dist/src/license/licenses_api.d.ts +34 -0
- package/dist/src/license/licenses_api.js +98 -0
- package/dist/src/license/project_license.d.ts +20 -0
- package/dist/src/license/project_license.js +62 -0
- package/dist/src/oci_image/images.d.ts +4 -5
- package/dist/src/oci_image/images.js +15 -1
- package/dist/src/oci_image/utils.d.ts +7 -7
- package/dist/src/oci_image/utils.js +11 -2
- package/dist/src/package_version.d.ts +8 -0
- package/dist/src/package_version.js +31 -0
- package/dist/src/provider.d.ts +18 -5
- package/dist/src/provider.js +33 -5
- package/dist/src/providers/base_java.d.ts +68 -15
- package/dist/src/providers/base_java.js +82 -61
- package/dist/src/providers/base_javascript.d.ts +99 -12
- package/dist/src/providers/base_javascript.js +243 -27
- package/dist/src/providers/base_pyproject.d.ts +158 -0
- package/dist/src/providers/base_pyproject.js +322 -0
- package/dist/src/providers/containerfile_parser.d.ts +5 -0
- package/dist/src/providers/containerfile_parser.js +20 -0
- package/dist/src/providers/golang_gomodules.d.ts +30 -13
- package/dist/src/providers/golang_gomodules.js +219 -122
- package/dist/src/providers/gomod_parser.d.ts +4 -0
- package/dist/src/providers/gomod_parser.js +16 -0
- package/dist/src/providers/java_gradle.d.ts +76 -3
- package/dist/src/providers/java_gradle.js +323 -21
- package/dist/src/providers/java_gradle_groovy.d.ts +1 -1
- package/dist/src/providers/java_gradle_kotlin.d.ts +1 -1
- package/dist/src/providers/java_maven.d.ts +45 -10
- package/dist/src/providers/java_maven.js +300 -14
- package/dist/src/providers/javascript_bun.d.ts +22 -0
- package/dist/src/providers/javascript_bun.js +141 -0
- package/dist/src/providers/javascript_npm.d.ts +19 -0
- package/dist/src/providers/javascript_npm.js +61 -1
- package/dist/src/providers/javascript_pnpm.d.ts +14 -1
- package/dist/src/providers/javascript_pnpm.js +55 -5
- package/dist/src/providers/javascript_yarn.d.ts +12 -0
- package/dist/src/providers/javascript_yarn.js +75 -2
- package/dist/src/providers/manifest.d.ts +2 -0
- package/dist/src/providers/manifest.js +28 -7
- package/dist/src/providers/marker_evaluator.d.ts +14 -0
- package/dist/src/providers/marker_evaluator.js +191 -0
- package/dist/src/providers/oci_dockerfile.d.ts +51 -0
- package/dist/src/providers/oci_dockerfile.js +177 -0
- package/dist/src/providers/processors/yarn_berry_processor.d.ts +6 -2
- package/dist/src/providers/processors/yarn_berry_processor.js +91 -7
- package/dist/src/providers/processors/yarn_classic_processor.d.ts +6 -2
- package/dist/src/providers/processors/yarn_classic_processor.js +8 -6
- package/dist/src/providers/python_controller.d.ts +10 -3
- package/dist/src/providers/python_controller.js +122 -63
- package/dist/src/providers/python_pip.d.ts +16 -4
- package/dist/src/providers/python_pip.js +51 -58
- package/dist/src/providers/python_pip_pyproject.d.ts +61 -0
- package/dist/src/providers/python_pip_pyproject.js +146 -0
- package/dist/src/providers/python_poetry.d.ts +98 -0
- package/dist/src/providers/python_poetry.js +286 -0
- package/dist/src/providers/python_uv.d.ts +46 -0
- package/dist/src/providers/python_uv.js +269 -0
- package/dist/src/providers/requirements_parser.d.ts +6 -0
- package/dist/src/providers/requirements_parser.js +24 -0
- package/dist/src/providers/rust_cargo.d.ts +56 -0
- package/dist/src/providers/rust_cargo.js +682 -0
- package/dist/src/providers/tree-sitter-containerfile.wasm +0 -0
- package/dist/src/providers/tree-sitter-gomod.wasm +0 -0
- package/dist/src/providers/tree-sitter-requirements.wasm +0 -0
- package/dist/src/remediate.d.ts +21 -0
- package/dist/src/remediate.js +149 -0
- package/dist/src/remediation.d.ts +57 -0
- package/dist/src/remediation.js +436 -0
- package/dist/src/remediation_report.d.ts +40 -0
- package/dist/src/remediation_report.js +159 -0
- package/dist/src/sbom.d.ts +28 -2
- package/dist/src/sbom.js +26 -4
- package/dist/src/tools.d.ts +48 -6
- package/dist/src/tools.js +138 -2
- package/dist/src/updaters/maven_updater.d.ts +26 -0
- package/dist/src/updaters/maven_updater.js +322 -0
- package/dist/src/updaters/toml_updater.d.ts +33 -0
- package/dist/src/updaters/toml_updater.js +244 -0
- package/dist/src/workspace.d.ts +70 -0
- package/dist/src/workspace.js +256 -0
- package/package.json +49 -29
package/dist/package.json
CHANGED
|
@@ -25,7 +25,9 @@
|
|
|
25
25
|
"provenance": true
|
|
26
26
|
},
|
|
27
27
|
"type": "module",
|
|
28
|
-
"bin":
|
|
28
|
+
"bin": {
|
|
29
|
+
"trustify-da": "dist/src/cli.js"
|
|
30
|
+
},
|
|
29
31
|
"main": "dist/src/index.js",
|
|
30
32
|
"module": "dist/src/index.js",
|
|
31
33
|
"types": "dist/src/index.d.ts",
|
|
@@ -35,43 +37,60 @@
|
|
|
35
37
|
"config/**/*"
|
|
36
38
|
],
|
|
37
39
|
"scripts": {
|
|
38
|
-
"lint": "eslint src test
|
|
39
|
-
"lint:fix": "eslint src test --
|
|
40
|
+
"lint": "eslint src test",
|
|
41
|
+
"lint:fix": "eslint src test --fix",
|
|
40
42
|
"test": "c8 npm run tests",
|
|
41
|
-
"tests": "mocha --config .mocharc.json
|
|
43
|
+
"tests": "mocha --config .mocharc.json",
|
|
42
44
|
"tests:rep": "mocha --reporter-option maxDiffSize=0 --reporter json > unit-tests-result.json",
|
|
45
|
+
"pretest": "cp node_modules/tree-sitter-requirements/tree-sitter-requirements.wasm src/providers/tree-sitter-requirements.wasm && cp node_modules/tree-sitter-gomod/tree-sitter-gomod.wasm src/providers/tree-sitter-gomod.wasm && cp node_modules/tree-sitter-containerfile/tree-sitter-containerfile.wasm src/providers/tree-sitter-containerfile.wasm",
|
|
43
46
|
"precompile": "rm -rf dist",
|
|
44
|
-
"compile": "tsc -p tsconfig.json"
|
|
47
|
+
"compile": "tsc -p tsconfig.json",
|
|
48
|
+
"compile:dev": "tsc -p tsconfig.dev.json",
|
|
49
|
+
"postcompile": "cp node_modules/tree-sitter-requirements/tree-sitter-requirements.wasm dist/src/providers/tree-sitter-requirements.wasm && cp node_modules/tree-sitter-gomod/tree-sitter-gomod.wasm dist/src/providers/tree-sitter-gomod.wasm && cp node_modules/tree-sitter-containerfile/tree-sitter-containerfile.wasm dist/src/providers/tree-sitter-containerfile.wasm"
|
|
45
50
|
},
|
|
46
51
|
"dependencies": {
|
|
47
52
|
"@babel/core": "^7.23.2",
|
|
48
|
-
"@
|
|
49
|
-
"
|
|
50
|
-
"fast-
|
|
53
|
+
"@yarnpkg/parsers": "^3.1.0",
|
|
54
|
+
"eslint-import-resolver-typescript": "^4.4.4",
|
|
55
|
+
"fast-glob": "^3.3.3",
|
|
56
|
+
"fast-xml-parser": "^5.3.4",
|
|
51
57
|
"help": "^3.0.2",
|
|
52
|
-
"https-proxy-agent": "^
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
58
|
+
"https-proxy-agent": "^9.0.0",
|
|
59
|
+
"js-yaml": "^4.1.1",
|
|
60
|
+
"jsonc-parser": "^3.3.1",
|
|
61
|
+
"micromatch": "^4.0.8",
|
|
62
|
+
"node-fetch": "^3.3.2",
|
|
63
|
+
"p-limit": "^7.3.0",
|
|
64
|
+
"packageurl-js": "~1.0.2",
|
|
65
|
+
"smol-toml": "^1.6.0",
|
|
66
|
+
"tree-sitter-containerfile": "^0.8.1",
|
|
67
|
+
"tree-sitter-gomod": "github:strum355/tree-sitter-go-mod#56326f2ad478892ace58ff247a97d492a3cbcdda",
|
|
68
|
+
"tree-sitter-requirements": "github:Strum355/tree-sitter-requirements#d0261ee76b84253997fe70d7d397e78c006c3801",
|
|
69
|
+
"web-tree-sitter": "^0.26.7",
|
|
70
|
+
"yargs": "^18.0.0"
|
|
56
71
|
},
|
|
57
72
|
"devDependencies": {
|
|
58
73
|
"@babel/core": "^7.23.2",
|
|
59
|
-
"@
|
|
60
|
-
"@
|
|
74
|
+
"@cyclonedx/cyclonedx-library": "^10.2.0",
|
|
75
|
+
"@eslint/js": "^10.0.0",
|
|
76
|
+
"@trustify-da/trustify-da-api-model": "^2.0.12",
|
|
77
|
+
"@types/node": "^25.9.1",
|
|
61
78
|
"@types/which": "^3.0.4",
|
|
79
|
+
"ajv": "^8.20.0",
|
|
62
80
|
"babel-plugin-rewire": "^1.2.0",
|
|
63
|
-
"c8": "^
|
|
64
|
-
"chai": "^
|
|
65
|
-
"eslint": "^
|
|
66
|
-
"eslint-
|
|
67
|
-
"eslint-plugin-import": "^
|
|
81
|
+
"c8": "^11.0.0",
|
|
82
|
+
"chai": "^6.2.2",
|
|
83
|
+
"eslint": "^10.4.1",
|
|
84
|
+
"eslint-import-resolver-typescript": "^4.4.4",
|
|
85
|
+
"eslint-plugin-import-x": "^4.16.2",
|
|
68
86
|
"esmock": "^2.6.2",
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"sinon
|
|
73
|
-
"
|
|
74
|
-
"
|
|
87
|
+
"globals": "^17.6.0",
|
|
88
|
+
"mocha": "^11.7.6",
|
|
89
|
+
"msw": "^2.12.7",
|
|
90
|
+
"sinon": "^22.0.0",
|
|
91
|
+
"sinon-chai": "^4.0.1",
|
|
92
|
+
"typescript": "^6.0.3",
|
|
93
|
+
"which": "^7.0.0"
|
|
75
94
|
},
|
|
76
95
|
"mocha": {
|
|
77
96
|
"check-leaks": false,
|
|
@@ -99,12 +118,13 @@
|
|
|
99
118
|
"reporter": [
|
|
100
119
|
"html",
|
|
101
120
|
"json",
|
|
121
|
+
"lcov",
|
|
102
122
|
"text"
|
|
103
123
|
]
|
|
104
124
|
},
|
|
105
|
-
"
|
|
106
|
-
"
|
|
107
|
-
|
|
125
|
+
"overrides": {
|
|
126
|
+
"tree-sitter": "0.22.4"
|
|
127
|
+
},
|
|
108
128
|
"resolutions": {
|
|
109
129
|
"@hapi/joi": "17.1.1"
|
|
110
130
|
}
|
package/dist/src/analysis.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
/** Media type for CycloneDX JSON batch payloads (batch-analysis API). */
|
|
2
|
+
export const CYCLONEDX_JSON_MEDIA_TYPE: "application/vnd.cyclonedx+json";
|
|
1
3
|
declare namespace _default {
|
|
2
4
|
export { requestComponent };
|
|
3
5
|
export { requestStack };
|
|
6
|
+
export { requestStackBatch };
|
|
4
7
|
export { requestImages };
|
|
5
8
|
export { validateToken };
|
|
9
|
+
export { appendAnalysisQueryParams };
|
|
6
10
|
}
|
|
7
11
|
export default _default;
|
|
8
12
|
/**
|
|
@@ -13,7 +17,7 @@ export default _default;
|
|
|
13
17
|
* @param {import("index.js").Options} [opts={}] - optional various options to pass along the application
|
|
14
18
|
* @returns {Promise<import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>}
|
|
15
19
|
*/
|
|
16
|
-
declare function requestComponent(provider:
|
|
20
|
+
declare function requestComponent(provider: any, manifest: string, url: string, opts?: any): Promise<any>;
|
|
17
21
|
/**
|
|
18
22
|
* Send a stack analysis request and get the report as 'text/html' or 'application/json'.
|
|
19
23
|
* @param {import('./provider').Provider} provider - the provided data for constructing the request
|
|
@@ -23,7 +27,20 @@ declare function requestComponent(provider: import('./provider').Provider, manif
|
|
|
23
27
|
* @param {import("index.js").Options} [opts={}] - optional various options to pass along the application
|
|
24
28
|
* @returns {Promise<string|import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>}
|
|
25
29
|
*/
|
|
26
|
-
declare function requestStack(provider:
|
|
30
|
+
declare function requestStack(provider: any, manifest: string, url: string, html?: boolean, opts?: any): Promise<string | any>;
|
|
31
|
+
/**
|
|
32
|
+
* Send a batch stack analysis request for multiple manifests (SBOMs keyed by purl).
|
|
33
|
+
* @param {Object.<string, object>} sbomByPurl - Map of root purl to CycloneDX SBOM object
|
|
34
|
+
* @param {string} url - the backend url
|
|
35
|
+
* @param {boolean} [html=false] - true returns HTML, false returns JSON
|
|
36
|
+
* @param {import("index.js").Options} [opts={}]
|
|
37
|
+
* @returns {Promise<string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>>}
|
|
38
|
+
*/
|
|
39
|
+
declare function requestStackBatch(sbomByPurl: {
|
|
40
|
+
[x: string]: object;
|
|
41
|
+
}, url: string, html?: boolean, opts?: any): Promise<string | {
|
|
42
|
+
[x: string]: any;
|
|
43
|
+
}>;
|
|
27
44
|
/**
|
|
28
45
|
*
|
|
29
46
|
* @param {Array<string>} imageRefs
|
|
@@ -31,8 +48,8 @@ declare function requestStack(provider: import('./provider').Provider, manifest:
|
|
|
31
48
|
* @param {import("index.js").Options} [opts={}] - optional various options to pass along the application
|
|
32
49
|
* @returns {Promise<string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>>}
|
|
33
50
|
*/
|
|
34
|
-
declare function requestImages(imageRefs: Array<string>, url: string, html?: boolean, opts?:
|
|
35
|
-
[x: string]:
|
|
51
|
+
declare function requestImages(imageRefs: Array<string>, url: string, html?: boolean, opts?: any): Promise<string | {
|
|
52
|
+
[x: string]: any;
|
|
36
53
|
}>;
|
|
37
54
|
/**
|
|
38
55
|
*
|
|
@@ -40,4 +57,10 @@ declare function requestImages(imageRefs: Array<string>, url: string, html?: boo
|
|
|
40
57
|
* @param {import("index.js").Options} [opts={}] - optional various options to pass headers for t he validateToken Request
|
|
41
58
|
* @return {Promise<number>} return the HTTP status Code of the response from the validate token request.
|
|
42
59
|
*/
|
|
43
|
-
declare function validateToken(url: any, opts?:
|
|
60
|
+
declare function validateToken(url: any, opts?: any): Promise<number>;
|
|
61
|
+
/**
|
|
62
|
+
* Append common analysis query parameters (recommend, providers, sources) to a URL.
|
|
63
|
+
* @param {URL} url - the URL object to append query parameters to
|
|
64
|
+
* @param {import("index.js").Options} [opts={}] - options containing parameter overrides
|
|
65
|
+
*/
|
|
66
|
+
declare function appendAnalysisQueryParams(url: URL, opts?: any): void;
|
package/dist/src/analysis.js
CHANGED
|
@@ -1,28 +1,12 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { EOL } from "os";
|
|
4
|
-
import {
|
|
4
|
+
import { runLicenseCheck } from "./license/index.js";
|
|
5
5
|
import { generateImageSBOM, parseImageRef } from "./oci_image/utils.js";
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
const rhdaSourceHeader = "rhda-source";
|
|
11
|
-
const rhdaOperationTypeHeader = "rhda-operation-type";
|
|
12
|
-
const rhdaPackageManagerHeader = "rhda-pkg-manager";
|
|
13
|
-
/**
|
|
14
|
-
* Adds proxy agent configuration to fetch options if a proxy URL is specified
|
|
15
|
-
* @param {RequestInit} options - The base fetch options
|
|
16
|
-
* @param {import("index.js").Options} opts - The trustify DA options that may contain proxy configuration
|
|
17
|
-
* @returns {RequestInit} The fetch options with proxy agent if applicable
|
|
18
|
-
*/
|
|
19
|
-
function addProxyAgent(options, opts) {
|
|
20
|
-
const proxyUrl = getCustom('TRUSTIFY_DA_PROXY_URL', null, opts);
|
|
21
|
-
if (proxyUrl) {
|
|
22
|
-
options.agent = new HttpsProxyAgent(proxyUrl);
|
|
23
|
-
}
|
|
24
|
-
return options;
|
|
25
|
-
}
|
|
6
|
+
import { addProxyAgent, getCustom, getTokenHeaders, TRUSTIFY_DA_OPERATION_TYPE_HEADER, TRUSTIFY_DA_PACKAGE_MANAGER_HEADER } from "./tools.js";
|
|
7
|
+
/** Media type for CycloneDX JSON batch payloads (batch-analysis API). */
|
|
8
|
+
export const CYCLONEDX_JSON_MEDIA_TYPE = 'application/vnd.cyclonedx+json';
|
|
9
|
+
export default { requestComponent, requestStack, requestStackBatch, requestImages, validateToken, appendAnalysisQueryParams };
|
|
26
10
|
/**
|
|
27
11
|
* Send a stack analysis request and get the report as 'text/html' or 'application/json'.
|
|
28
12
|
* @param {import('./provider').Provider} provider - the provided data for constructing the request
|
|
@@ -35,15 +19,18 @@ function addProxyAgent(options, opts) {
|
|
|
35
19
|
async function requestStack(provider, manifest, url, html = false, opts = {}) {
|
|
36
20
|
opts["source-manifest"] = Buffer.from(fs.readFileSync(manifest).toString()).toString('base64');
|
|
37
21
|
opts["manifest-type"] = path.parse(manifest).base;
|
|
38
|
-
let provided = provider.provideStack(manifest, opts); // throws error if content providing failed
|
|
22
|
+
let provided = await provider.provideStack(manifest, opts); // throws error if content providing failed
|
|
23
|
+
if (provided.batch) {
|
|
24
|
+
return requestStackBatch(JSON.parse(provided.content), url, html, opts);
|
|
25
|
+
}
|
|
39
26
|
opts["source-manifest"] = "";
|
|
40
|
-
opts[
|
|
27
|
+
opts[TRUSTIFY_DA_OPERATION_TYPE_HEADER.toUpperCase().replaceAll("-", "_")] = "stack-analysis";
|
|
41
28
|
let startTime = new Date();
|
|
42
29
|
let endTime;
|
|
43
30
|
if (process.env["TRUSTIFY_DA_DEBUG"] === "true") {
|
|
44
31
|
console.log("Starting time of sending stack analysis request to the dependency analytics server= " + startTime);
|
|
45
32
|
}
|
|
46
|
-
opts[
|
|
33
|
+
opts[TRUSTIFY_DA_PACKAGE_MANAGER_HEADER.toUpperCase().replaceAll("-", "_")] = provided.ecosystem;
|
|
47
34
|
const fetchOptions = addProxyAgent({
|
|
48
35
|
method: 'POST',
|
|
49
36
|
headers: {
|
|
@@ -53,10 +40,8 @@ async function requestStack(provider, manifest, url, html = false, opts = {}) {
|
|
|
53
40
|
},
|
|
54
41
|
body: provided.content
|
|
55
42
|
}, opts);
|
|
56
|
-
const finalUrl = new URL(`${url}/api/
|
|
57
|
-
|
|
58
|
-
finalUrl.searchParams.append('recommend', 'false');
|
|
59
|
-
}
|
|
43
|
+
const finalUrl = new URL(`${url}/api/v5/analysis`);
|
|
44
|
+
appendAnalysisQueryParams(finalUrl, opts);
|
|
60
45
|
let resp = await fetch(finalUrl, fetchOptions);
|
|
61
46
|
let result;
|
|
62
47
|
if (resp.status === 200) {
|
|
@@ -94,13 +79,16 @@ async function requestStack(provider, manifest, url, html = false, opts = {}) {
|
|
|
94
79
|
*/
|
|
95
80
|
async function requestComponent(provider, manifest, url, opts = {}) {
|
|
96
81
|
opts["source-manifest"] = Buffer.from(fs.readFileSync(manifest).toString()).toString('base64');
|
|
97
|
-
let provided = provider.provideComponent(manifest, opts); // throws error if content providing failed
|
|
82
|
+
let provided = await provider.provideComponent(manifest, opts); // throws error if content providing failed
|
|
83
|
+
if (provided.batch) {
|
|
84
|
+
return requestStackBatch(JSON.parse(provided.content), url, false, opts);
|
|
85
|
+
}
|
|
98
86
|
opts["source-manifest"] = "";
|
|
99
|
-
opts[
|
|
87
|
+
opts[TRUSTIFY_DA_OPERATION_TYPE_HEADER.toUpperCase().replaceAll("-", "_")] = "component-analysis";
|
|
100
88
|
if (process.env["TRUSTIFY_DA_DEBUG"] === "true") {
|
|
101
89
|
console.log("Starting time of sending component analysis request to Trustify DA backend server= " + new Date());
|
|
102
90
|
}
|
|
103
|
-
opts[
|
|
91
|
+
opts[TRUSTIFY_DA_PACKAGE_MANAGER_HEADER.toUpperCase().replaceAll("-", "_")] = provided.ecosystem;
|
|
104
92
|
const fetchOptions = addProxyAgent({
|
|
105
93
|
method: 'POST',
|
|
106
94
|
headers: {
|
|
@@ -110,10 +98,8 @@ async function requestComponent(provider, manifest, url, opts = {}) {
|
|
|
110
98
|
},
|
|
111
99
|
body: provided.content
|
|
112
100
|
}, opts);
|
|
113
|
-
const finalUrl = new URL(`${url}/api/
|
|
114
|
-
|
|
115
|
-
finalUrl.searchParams.append('recommend', 'false');
|
|
116
|
-
}
|
|
101
|
+
const finalUrl = new URL(`${url}/api/v5/analysis`);
|
|
102
|
+
appendAnalysisQueryParams(finalUrl, opts);
|
|
117
103
|
let resp = await fetch(finalUrl, fetchOptions);
|
|
118
104
|
let result;
|
|
119
105
|
if (resp.status === 200) {
|
|
@@ -127,12 +113,65 @@ async function requestComponent(provider, manifest, url, opts = {}) {
|
|
|
127
113
|
console.log(JSON.stringify(result, null, 4));
|
|
128
114
|
console.log("Ending time of sending component analysis request to Trustify DA backend server= " + new Date());
|
|
129
115
|
}
|
|
116
|
+
const licenseCheckEnabled = getCustom('TRUSTIFY_DA_LICENSE_CHECK', 'true', opts) !== 'false' && opts.licenseCheck !== false;
|
|
117
|
+
if (licenseCheckEnabled) {
|
|
118
|
+
try {
|
|
119
|
+
result.licenseSummary = await runLicenseCheck(provided.content, manifest, url, opts, result);
|
|
120
|
+
}
|
|
121
|
+
catch (licenseErr) {
|
|
122
|
+
result.licenseSummary = { error: licenseErr.message };
|
|
123
|
+
}
|
|
124
|
+
}
|
|
130
125
|
}
|
|
131
126
|
else {
|
|
132
127
|
throw new Error(`Got error response from Trustify DA backend - http return code : ${resp.status}, ex-request-id: ${resp.headers.get("ex-request-id")} error message => ${await resp.text()}`);
|
|
133
128
|
}
|
|
134
129
|
return Promise.resolve(result);
|
|
135
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Send a batch stack analysis request for multiple manifests (SBOMs keyed by purl).
|
|
133
|
+
* @param {Object.<string, object>} sbomByPurl - Map of root purl to CycloneDX SBOM object
|
|
134
|
+
* @param {string} url - the backend url
|
|
135
|
+
* @param {boolean} [html=false] - true returns HTML, false returns JSON
|
|
136
|
+
* @param {import("index.js").Options} [opts={}]
|
|
137
|
+
* @returns {Promise<string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>>}
|
|
138
|
+
*/
|
|
139
|
+
async function requestStackBatch(sbomByPurl, url, html = false, opts = {}) {
|
|
140
|
+
const finalUrl = new URL(`${url}/api/v5/batch-analysis`);
|
|
141
|
+
appendAnalysisQueryParams(finalUrl, opts);
|
|
142
|
+
const fetchOptions = addProxyAgent({
|
|
143
|
+
method: 'POST',
|
|
144
|
+
headers: {
|
|
145
|
+
'Accept': html ? 'text/html' : 'application/json',
|
|
146
|
+
'Content-Type': CYCLONEDX_JSON_MEDIA_TYPE,
|
|
147
|
+
...getTokenHeaders(opts)
|
|
148
|
+
},
|
|
149
|
+
body: JSON.stringify(sbomByPurl)
|
|
150
|
+
}, opts);
|
|
151
|
+
const resp = await fetch(finalUrl, fetchOptions);
|
|
152
|
+
if (resp.status === 200) {
|
|
153
|
+
let result;
|
|
154
|
+
if (!html) {
|
|
155
|
+
result = await resp.json();
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
result = await resp.text();
|
|
159
|
+
}
|
|
160
|
+
if (process.env["TRUSTIFY_DA_DEBUG"] === "true") {
|
|
161
|
+
const exRequestId = resp.headers.get("ex-request-id");
|
|
162
|
+
if (exRequestId) {
|
|
163
|
+
console.log("Unique Identifier associated with this request - ex-request-id=" + exRequestId);
|
|
164
|
+
}
|
|
165
|
+
console.log("Response body received from Trustify DA backend server : " + EOL + EOL);
|
|
166
|
+
console.log(JSON.stringify(result, null, 4));
|
|
167
|
+
console.log("Ending time of sending batch stack analysis request to Trustify DA backend server= " + new Date());
|
|
168
|
+
}
|
|
169
|
+
return result;
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
throw new Error(`Got error response from Trustify DA backend - http return code : ${resp.status}, ex-request-id: ${resp.headers.get("ex-request-id")} error message => ${await resp.text()}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
136
175
|
/**
|
|
137
176
|
*
|
|
138
177
|
* @param {Array<string>} imageRefs
|
|
@@ -146,19 +185,18 @@ async function requestImages(imageRefs, url, html = false, opts = {}) {
|
|
|
146
185
|
const parsedImageRef = parseImageRef(image, opts);
|
|
147
186
|
imageSboms[parsedImageRef.getPackageURL().toString()] = generateImageSBOM(parsedImageRef, opts);
|
|
148
187
|
}
|
|
149
|
-
const finalUrl = new URL(`${url}/api/
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
const resp = await fetch(finalUrl, {
|
|
188
|
+
const finalUrl = new URL(`${url}/api/v5/batch-analysis`);
|
|
189
|
+
appendAnalysisQueryParams(finalUrl, opts);
|
|
190
|
+
const fetchOptions = addProxyAgent({
|
|
154
191
|
method: 'POST',
|
|
155
192
|
headers: {
|
|
156
193
|
'Accept': html ? 'text/html' : 'application/json',
|
|
157
|
-
'Content-Type':
|
|
194
|
+
'Content-Type': CYCLONEDX_JSON_MEDIA_TYPE,
|
|
158
195
|
...getTokenHeaders(opts)
|
|
159
196
|
},
|
|
160
197
|
body: JSON.stringify(imageSboms),
|
|
161
|
-
});
|
|
198
|
+
}, opts);
|
|
199
|
+
const resp = await fetch(finalUrl, fetchOptions);
|
|
162
200
|
if (resp.status === 200) {
|
|
163
201
|
let result;
|
|
164
202
|
if (!html) {
|
|
@@ -182,6 +220,24 @@ async function requestImages(imageRefs, url, html = false, opts = {}) {
|
|
|
182
220
|
throw new Error(`Got error response from Trustify DA backend - http return code : ${resp.status}, ex-request-id: ${resp.headers.get("ex-request-id")} error message => ${await resp.text()}`);
|
|
183
221
|
}
|
|
184
222
|
}
|
|
223
|
+
/**
|
|
224
|
+
* Append common analysis query parameters (recommend, providers, sources) to a URL.
|
|
225
|
+
* @param {URL} url - the URL object to append query parameters to
|
|
226
|
+
* @param {import("index.js").Options} [opts={}] - options containing parameter overrides
|
|
227
|
+
*/
|
|
228
|
+
function appendAnalysisQueryParams(url, opts = {}) {
|
|
229
|
+
if (getCustom('TRUSTIFY_DA_RECOMMEND', 'true', opts) === 'false') {
|
|
230
|
+
url.searchParams.append('recommend', 'false');
|
|
231
|
+
}
|
|
232
|
+
const providers = getCustom('TRUSTIFY_DA_PROVIDERS', null, opts);
|
|
233
|
+
if (providers) {
|
|
234
|
+
url.searchParams.append('providers', providers);
|
|
235
|
+
}
|
|
236
|
+
const sources = getCustom('TRUSTIFY_DA_SOURCES', null, opts);
|
|
237
|
+
if (sources) {
|
|
238
|
+
url.searchParams.append('sources', sources);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
185
241
|
/**
|
|
186
242
|
*
|
|
187
243
|
* @param url the backend url to send the request to
|
|
@@ -195,7 +251,7 @@ async function validateToken(url, opts = {}) {
|
|
|
195
251
|
...getTokenHeaders(opts),
|
|
196
252
|
}
|
|
197
253
|
}, opts);
|
|
198
|
-
let resp = await fetch(`${url}/api/
|
|
254
|
+
let resp = await fetch(`${url}/api/v5/token`, fetchOptions);
|
|
199
255
|
if (process.env["TRUSTIFY_DA_DEBUG"] === "true") {
|
|
200
256
|
let exRequestId = resp.headers.get("ex-request-id");
|
|
201
257
|
if (exRequestId) {
|
|
@@ -204,49 +260,3 @@ async function validateToken(url, opts = {}) {
|
|
|
204
260
|
}
|
|
205
261
|
return resp.status;
|
|
206
262
|
}
|
|
207
|
-
/**
|
|
208
|
-
*
|
|
209
|
-
* @param {string} headerName - the header name to populate in request
|
|
210
|
-
* @param headers
|
|
211
|
-
* @param {import("index.js").Options} [opts={}] - optional various options to pass along the application
|
|
212
|
-
* @private
|
|
213
|
-
*/
|
|
214
|
-
function setRhdaHeader(headerName, headers, opts) {
|
|
215
|
-
let rhdaHeaderValue = getCustom(headerName.toUpperCase().replaceAll("-", "_"), null, opts);
|
|
216
|
-
if (rhdaHeaderValue) {
|
|
217
|
-
headers[headerName] = rhdaHeaderValue;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* Utility function for fetching vendor tokens
|
|
222
|
-
* @param {import("index.js").Options} [opts={}] - optional various options to pass along the application
|
|
223
|
-
* @returns {{}}
|
|
224
|
-
*/
|
|
225
|
-
function getTokenHeaders(opts = {}) {
|
|
226
|
-
let supportedTokens = ['snyk', 'oss-index'];
|
|
227
|
-
let headers = {};
|
|
228
|
-
supportedTokens.forEach(vendor => {
|
|
229
|
-
let token = getCustom(`TRUSTIFY_DA_${vendor.replace("-", "_").toUpperCase()}_TOKEN`, null, opts);
|
|
230
|
-
if (token) {
|
|
231
|
-
headers[`ex-${vendor}-token`] = token;
|
|
232
|
-
}
|
|
233
|
-
let user = getCustom(`TRUSTIFY_DA_${vendor.replace("-", "_").toUpperCase()}_USER`, null, opts);
|
|
234
|
-
if (user) {
|
|
235
|
-
headers[`ex-${vendor}-user`] = user;
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
setRhdaHeader(rhdaTokenHeader, headers, opts);
|
|
239
|
-
setRhdaHeader(rhdaSourceHeader, headers, opts);
|
|
240
|
-
setRhdaHeader(rhdaOperationTypeHeader, headers, opts);
|
|
241
|
-
setRhdaHeader(rhdaPackageManagerHeader, headers, opts);
|
|
242
|
-
setRhdaHeader(rhdaTelemetryId, headers, opts);
|
|
243
|
-
if (process.env["TRUSTIFY_DA_DEBUG"] === "true") {
|
|
244
|
-
console.log("Headers Values to be sent to Trustify DA backend:" + EOL);
|
|
245
|
-
for (const headerKey in headers) {
|
|
246
|
-
if (!headerKey.match(RegexNotToBeLogged)) {
|
|
247
|
-
console.log(`${headerKey}: ${headers[headerKey]}`);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
return headers;
|
|
252
|
-
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether to skip failed manifests and continue (default), or fail on first SBOM/validation error.
|
|
3
|
+
* `opts.continueOnError` overrides; env `TRUSTIFY_DA_CONTINUE_ON_ERROR=false` disables continuation.
|
|
4
|
+
*
|
|
5
|
+
* @param {{ continueOnError?: boolean, TRUSTIFY_DA_CONTINUE_ON_ERROR?: string, [key: string]: unknown }} [opts={}]
|
|
6
|
+
* @returns {boolean} true = collect errors (default), false = fail-fast
|
|
7
|
+
*/
|
|
8
|
+
export function resolveContinueOnError(opts?: {
|
|
9
|
+
continueOnError?: boolean;
|
|
10
|
+
TRUSTIFY_DA_CONTINUE_ON_ERROR?: string;
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* When true, `stackAnalysisBatch` returns `{ analysis, metadata }` instead of the backend response only.
|
|
15
|
+
* `opts.batchMetadata` overrides; env `TRUSTIFY_DA_BATCH_METADATA=true` enables.
|
|
16
|
+
*
|
|
17
|
+
* @param {{ batchMetadata?: boolean, TRUSTIFY_DA_BATCH_METADATA?: string, [key: string]: unknown }} [opts={}]
|
|
18
|
+
* @returns {boolean}
|
|
19
|
+
*/
|
|
20
|
+
export function resolveBatchMetadata(opts?: {
|
|
21
|
+
batchMetadata?: boolean;
|
|
22
|
+
TRUSTIFY_DA_BATCH_METADATA?: string;
|
|
23
|
+
[key: string]: unknown;
|
|
24
|
+
}): boolean;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { getCustom } from './tools.js';
|
|
2
|
+
/**
|
|
3
|
+
* Whether to skip failed manifests and continue (default), or fail on first SBOM/validation error.
|
|
4
|
+
* `opts.continueOnError` overrides; env `TRUSTIFY_DA_CONTINUE_ON_ERROR=false` disables continuation.
|
|
5
|
+
*
|
|
6
|
+
* @param {{ continueOnError?: boolean, TRUSTIFY_DA_CONTINUE_ON_ERROR?: string, [key: string]: unknown }} [opts={}]
|
|
7
|
+
* @returns {boolean} true = collect errors (default), false = fail-fast
|
|
8
|
+
*/
|
|
9
|
+
export function resolveContinueOnError(opts = {}) {
|
|
10
|
+
if (typeof opts.continueOnError === 'boolean') {
|
|
11
|
+
return opts.continueOnError;
|
|
12
|
+
}
|
|
13
|
+
const v = getCustom('TRUSTIFY_DA_CONTINUE_ON_ERROR', null, opts);
|
|
14
|
+
if (v != null && String(v).trim() !== '') {
|
|
15
|
+
return String(v).toLowerCase() !== 'false';
|
|
16
|
+
}
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* When true, `stackAnalysisBatch` returns `{ analysis, metadata }` instead of the backend response only.
|
|
21
|
+
* `opts.batchMetadata` overrides; env `TRUSTIFY_DA_BATCH_METADATA=true` enables.
|
|
22
|
+
*
|
|
23
|
+
* @param {{ batchMetadata?: boolean, TRUSTIFY_DA_BATCH_METADATA?: string, [key: string]: unknown }} [opts={}]
|
|
24
|
+
* @returns {boolean}
|
|
25
|
+
*/
|
|
26
|
+
export function resolveBatchMetadata(opts = {}) {
|
|
27
|
+
if (typeof opts.batchMetadata === 'boolean') {
|
|
28
|
+
return opts.batchMetadata;
|
|
29
|
+
}
|
|
30
|
+
const v = getCustom('TRUSTIFY_DA_BATCH_METADATA', null, opts);
|
|
31
|
+
if (v != null && String(v).trim() !== '') {
|
|
32
|
+
return String(v).toLowerCase() === 'true';
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
}
|