@trustify-da/trustify-da-javascript-client 0.2.4-ea.13

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.
Files changed (57) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +482 -0
  3. package/config/config.properties +1 -0
  4. package/dist/package.json +106 -0
  5. package/dist/src/analysis.d.ts +43 -0
  6. package/dist/src/analysis.js +252 -0
  7. package/dist/src/cli.d.ts +2 -0
  8. package/dist/src/cli.js +102 -0
  9. package/dist/src/cyclone_dx_sbom.d.ts +77 -0
  10. package/dist/src/cyclone_dx_sbom.js +244 -0
  11. package/dist/src/index.d.ts +82 -0
  12. package/dist/src/index.js +194 -0
  13. package/dist/src/oci_image/images.d.ts +99 -0
  14. package/dist/src/oci_image/images.js +263 -0
  15. package/dist/src/oci_image/platform.d.ts +59 -0
  16. package/dist/src/oci_image/platform.js +138 -0
  17. package/dist/src/oci_image/utils.d.ts +42 -0
  18. package/dist/src/oci_image/utils.js +496 -0
  19. package/dist/src/provider.d.ts +29 -0
  20. package/dist/src/provider.js +47 -0
  21. package/dist/src/providers/base_java.d.ts +85 -0
  22. package/dist/src/providers/base_java.js +191 -0
  23. package/dist/src/providers/base_javascript.d.ts +127 -0
  24. package/dist/src/providers/base_javascript.js +350 -0
  25. package/dist/src/providers/golang_gomodules.d.ts +42 -0
  26. package/dist/src/providers/golang_gomodules.js +403 -0
  27. package/dist/src/providers/java_gradle.d.ts +35 -0
  28. package/dist/src/providers/java_gradle.js +399 -0
  29. package/dist/src/providers/java_gradle_groovy.d.ts +7 -0
  30. package/dist/src/providers/java_gradle_groovy.js +19 -0
  31. package/dist/src/providers/java_gradle_kotlin.d.ts +11 -0
  32. package/dist/src/providers/java_gradle_kotlin.js +23 -0
  33. package/dist/src/providers/java_maven.d.ts +52 -0
  34. package/dist/src/providers/java_maven.js +263 -0
  35. package/dist/src/providers/javascript_npm.d.ts +4 -0
  36. package/dist/src/providers/javascript_npm.js +15 -0
  37. package/dist/src/providers/javascript_pnpm.d.ts +5 -0
  38. package/dist/src/providers/javascript_pnpm.js +22 -0
  39. package/dist/src/providers/javascript_yarn.d.ts +11 -0
  40. package/dist/src/providers/javascript_yarn.js +39 -0
  41. package/dist/src/providers/manifest.d.ts +11 -0
  42. package/dist/src/providers/manifest.js +48 -0
  43. package/dist/src/providers/processors/yarn_berry_processor.d.ts +41 -0
  44. package/dist/src/providers/processors/yarn_berry_processor.js +130 -0
  45. package/dist/src/providers/processors/yarn_classic_processor.d.ts +37 -0
  46. package/dist/src/providers/processors/yarn_classic_processor.js +109 -0
  47. package/dist/src/providers/processors/yarn_processor.d.ts +9 -0
  48. package/dist/src/providers/processors/yarn_processor.js +20 -0
  49. package/dist/src/providers/python_controller.d.ts +31 -0
  50. package/dist/src/providers/python_controller.js +406 -0
  51. package/dist/src/providers/python_pip.d.ts +35 -0
  52. package/dist/src/providers/python_pip.js +227 -0
  53. package/dist/src/sbom.d.ts +59 -0
  54. package/dist/src/sbom.js +84 -0
  55. package/dist/src/tools.d.ts +74 -0
  56. package/dist/src/tools.js +159 -0
  57. package/package.json +106 -0
@@ -0,0 +1 @@
1
+ TRUSTIFY_DA_DEV_MODE=false
@@ -0,0 +1,106 @@
1
+ {
2
+ "name": "@trustify-da/trustify-da-javascript-client",
3
+ "version": "0.2.4-ea.13",
4
+ "description": "Code-Ready Dependency Analytics JavaScript API.",
5
+ "license": "Apache-2.0",
6
+ "homepage": "https://github.com/guacsec/trustify-da-javascript-client#README.md",
7
+ "bugs": "https://github.com/guacsec/trustify-da-javascript-client/issues",
8
+ "repository": "github:guacsec/trustify-da-javascript-client",
9
+ "keywords": [
10
+ "analysis",
11
+ "codeready",
12
+ "exhort",
13
+ "secure",
14
+ "supply-chain",
15
+ "vulnerability"
16
+ ],
17
+ "engines": {
18
+ "node": ">= 18.0.0",
19
+ "npm": ">= 9.0.0"
20
+ },
21
+ "type": "module",
22
+ "bin": "dist/src/cli.js",
23
+ "main": "dist/src/index.js",
24
+ "module": "dist/src/index.js",
25
+ "types": "dist/src/index.d.ts",
26
+ "files": [
27
+ "!*",
28
+ "dist/**/*",
29
+ "config/**/*"
30
+ ],
31
+ "scripts": {
32
+ "lint": "eslint src test --ext js",
33
+ "lint:fix": "eslint src test --ext js --fix",
34
+ "test": "c8 npm run tests",
35
+ "tests": "mocha --config .mocharc.json --grep \"Integration Tests|.*analysis module.*\" --invert",
36
+ "tests:rep": "mocha --reporter-option maxDiffSize=0 --reporter json > unit-tests-result.json",
37
+ "integration-tests": "mocha --grep \"Integration Tests\"",
38
+ "precompile": "rm -rf dist",
39
+ "compile": "tsc -p tsconfig.json"
40
+ },
41
+ "dependencies": {
42
+ "@babel/core": "^7.23.2",
43
+ "@cyclonedx/cyclonedx-library": "~1.13.3",
44
+ "fast-toml": "^0.5.4",
45
+ "fast-xml-parser": "^4.5.3",
46
+ "help": "^3.0.2",
47
+ "https-proxy-agent": "^7.0.6",
48
+ "node-fetch": "^2.7.0",
49
+ "packageurl-js": "^1.0.2",
50
+ "yargs": "^17.7.2"
51
+ },
52
+ "devDependencies": {
53
+ "@babel/core": "^7.23.2",
54
+ "@trustify-da/trustify-da-api-model": "^2.0.1",
55
+ "@types/node": "^20.17.30",
56
+ "@types/which": "^3.0.4",
57
+ "babel-plugin-rewire": "^1.2.0",
58
+ "c8": "^8.0.0",
59
+ "chai": "^4.3.7",
60
+ "eslint": "^8.42.0",
61
+ "eslint-plugin-editorconfig": "^4.0.3",
62
+ "eslint-plugin-import": "^2.29.1",
63
+ "esmock": "^2.6.2",
64
+ "mocha": "^10.2.0",
65
+ "msw": "^1.3.2",
66
+ "sinon": "^15.1.2",
67
+ "sinon-chai": "^3.7.0",
68
+ "typescript": "^5.1.3",
69
+ "which": "^5.0.0"
70
+ },
71
+ "mocha": {
72
+ "check-leaks": false,
73
+ "color": true,
74
+ "extension": "js",
75
+ "fail-zero": true,
76
+ "recursive": true,
77
+ "ui": "tdd"
78
+ },
79
+ "c8": {
80
+ "all": true,
81
+ "check-coverage": true,
82
+ "clean": true,
83
+ "include": [
84
+ "src/**"
85
+ ],
86
+ "exclude": [
87
+ "src/cli.js",
88
+ "src/index.js",
89
+ "src/analysis.js",
90
+ "src/providers/java_maven.js",
91
+ "src/providers/javascript_npm.js"
92
+ ],
93
+ "lines": 82,
94
+ "reporter": [
95
+ "html",
96
+ "json",
97
+ "text"
98
+ ]
99
+ },
100
+ "eslintIgnore": [
101
+ "index.js"
102
+ ],
103
+ "resolutions": {
104
+ "@hapi/joi": "17.1.1"
105
+ }
106
+ }
@@ -0,0 +1,43 @@
1
+ declare namespace _default {
2
+ export { requestComponent };
3
+ export { requestStack };
4
+ export { requestImages };
5
+ export { validateToken };
6
+ }
7
+ export default _default;
8
+ /**
9
+ * Send a component analysis request and get the report as 'application/json'.
10
+ * @param {import('./provider').Provider} provider - the provided data for constructing the request
11
+ * @param {string} manifest - path for the manifest
12
+ * @param {string} url - the backend url to send the request to
13
+ * @param {import("index.js").Options} [opts={}] - optional various options to pass along the application
14
+ * @returns {Promise<import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>}
15
+ */
16
+ declare function requestComponent(provider: import('./provider').Provider, manifest: string, url: string, opts?: import("index.js").Options | undefined): Promise<import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>;
17
+ /**
18
+ * Send a stack analysis request and get the report as 'text/html' or 'application/json'.
19
+ * @param {import('./provider').Provider} provider - the provided data for constructing the request
20
+ * @param {string} manifest - path for the manifest
21
+ * @param {string} url - the backend url to send the request to
22
+ * @param {boolean} [html=false] - true will return 'text/html', false will return 'application/json'
23
+ * @param {import("index.js").Options} [opts={}] - optional various options to pass along the application
24
+ * @returns {Promise<string|import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>}
25
+ */
26
+ declare function requestStack(provider: import('./provider').Provider, manifest: string, url: string, html?: boolean | undefined, opts?: import("index.js").Options | undefined): Promise<string | import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>;
27
+ /**
28
+ *
29
+ * @param {Array<string>} imageRefs
30
+ * @param {string} url
31
+ * @param {import("index.js").Options} [opts={}] - optional various options to pass along the application
32
+ * @returns {Promise<string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>>}
33
+ */
34
+ declare function requestImages(imageRefs: Array<string>, url: string, html?: boolean, opts?: import("index.js").Options | undefined): Promise<string | {
35
+ [x: string]: import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport;
36
+ }>;
37
+ /**
38
+ *
39
+ * @param url the backend url to send the request to
40
+ * @param {import("index.js").Options} [opts={}] - optional various options to pass headers for t he validateToken Request
41
+ * @return {Promise<number>} return the HTTP status Code of the response from the validate token request.
42
+ */
43
+ declare function validateToken(url: any, opts?: import("index.js").Options | undefined): Promise<number>;
@@ -0,0 +1,252 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { EOL } from "os";
4
+ import { HttpsProxyAgent } from "https-proxy-agent";
5
+ import { generateImageSBOM, parseImageRef } from "./oci_image/utils.js";
6
+ import { RegexNotToBeLogged, getCustom } from "./tools.js";
7
+ export default { requestComponent, requestStack, requestImages, validateToken };
8
+ const rhdaTokenHeader = "rhda-token";
9
+ const rhdaTelemetryId = "rhda-telemetry-id";
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 exhort 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
+ }
26
+ /**
27
+ * Send a stack analysis request and get the report as 'text/html' or 'application/json'.
28
+ * @param {import('./provider').Provider} provider - the provided data for constructing the request
29
+ * @param {string} manifest - path for the manifest
30
+ * @param {string} url - the backend url to send the request to
31
+ * @param {boolean} [html=false] - true will return 'text/html', false will return 'application/json'
32
+ * @param {import("index.js").Options} [opts={}] - optional various options to pass along the application
33
+ * @returns {Promise<string|import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>}
34
+ */
35
+ async function requestStack(provider, manifest, url, html = false, opts = {}) {
36
+ opts["source-manifest"] = Buffer.from(fs.readFileSync(manifest).toString()).toString('base64');
37
+ opts["manifest-type"] = path.parse(manifest).base;
38
+ let provided = provider.provideStack(manifest, opts); // throws error if content providing failed
39
+ opts["source-manifest"] = "";
40
+ opts[rhdaOperationTypeHeader.toUpperCase().replaceAll("-", "_")] = "stack-analysis";
41
+ let startTime = new Date();
42
+ let endTime;
43
+ if (process.env["TRUSTIFY_DA_DEBUG"] === "true") {
44
+ console.log("Starting time of sending stack analysis request to exhort server= " + startTime);
45
+ }
46
+ opts[rhdaPackageManagerHeader.toUpperCase().replaceAll("-", "_")] = provided.ecosystem;
47
+ const fetchOptions = addProxyAgent({
48
+ method: 'POST',
49
+ headers: {
50
+ 'Accept': html ? 'text/html' : 'application/json',
51
+ 'Content-Type': provided.contentType,
52
+ ...getTokenHeaders(opts),
53
+ },
54
+ body: provided.content
55
+ }, opts);
56
+ const finalUrl = new URL(`${url}/api/v4/analysis`);
57
+ if (opts['TRUSTIFY_DA_RECOMMENDATIONS_ENABLED'] === 'false') {
58
+ finalUrl.searchParams.append('recommend', 'false');
59
+ }
60
+ let resp = await fetch(finalUrl, fetchOptions);
61
+ let result;
62
+ if (resp.status === 200) {
63
+ if (!html) {
64
+ result = await resp.json();
65
+ }
66
+ else {
67
+ result = await resp.text();
68
+ }
69
+ if (process.env["TRUSTIFY_DA_DEBUG"] === "true") {
70
+ let exRequestId = resp.headers.get("ex-request-id");
71
+ if (exRequestId) {
72
+ console.log("Unique Identifier associated with this request - ex-request-id=" + exRequestId);
73
+ }
74
+ endTime = new Date();
75
+ console.log("Response body received from exhort server : " + EOL + EOL);
76
+ console.log(console.log(JSON.stringify(result, null, 4)));
77
+ console.log("Ending time of sending stack analysis request to exhort server= " + endTime);
78
+ let time = (endTime - startTime) / 1000;
79
+ console.log("Total Time in seconds: " + time);
80
+ }
81
+ }
82
+ else {
83
+ throw new Error(`Got error response from exhort backend - http return code : ${resp.status}, error message => ${await resp.text()}`);
84
+ }
85
+ return Promise.resolve(result);
86
+ }
87
+ /**
88
+ * Send a component analysis request and get the report as 'application/json'.
89
+ * @param {import('./provider').Provider} provider - the provided data for constructing the request
90
+ * @param {string} manifest - path for the manifest
91
+ * @param {string} url - the backend url to send the request to
92
+ * @param {import("index.js").Options} [opts={}] - optional various options to pass along the application
93
+ * @returns {Promise<import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>}
94
+ */
95
+ async function requestComponent(provider, manifest, url, opts = {}) {
96
+ opts["source-manifest"] = Buffer.from(fs.readFileSync(manifest).toString()).toString('base64');
97
+ let provided = provider.provideComponent(manifest, opts); // throws error if content providing failed
98
+ opts["source-manifest"] = "";
99
+ opts[rhdaOperationTypeHeader.toUpperCase().replaceAll("-", "_")] = "component-analysis";
100
+ if (process.env["TRUSTIFY_DA_DEBUG"] === "true") {
101
+ console.log("Starting time of sending component analysis request to exhort server= " + new Date());
102
+ }
103
+ opts[rhdaPackageManagerHeader.toUpperCase().replaceAll("-", "_")] = provided.ecosystem;
104
+ const fetchOptions = addProxyAgent({
105
+ method: 'POST',
106
+ headers: {
107
+ 'Accept': 'application/json',
108
+ 'Content-Type': provided.contentType,
109
+ ...getTokenHeaders(opts),
110
+ },
111
+ body: provided.content
112
+ }, opts);
113
+ const finalUrl = new URL(`${url}/api/v4/analysis`);
114
+ if (opts['TRUSTIFY_DA_RECOMMENDATIONS_ENABLED'] === 'false') {
115
+ finalUrl.searchParams.append('recommend', 'false');
116
+ }
117
+ let resp = await fetch(finalUrl, fetchOptions);
118
+ let result;
119
+ if (resp.status === 200) {
120
+ result = await resp.json();
121
+ if (process.env["TRUSTIFY_DA_DEBUG"] === "true") {
122
+ let exRequestId = resp.headers.get("ex-request-id");
123
+ if (exRequestId) {
124
+ console.log("Unique Identifier associated with this request - ex-request-id=" + exRequestId);
125
+ }
126
+ console.log("Response body received from exhort server : " + EOL + EOL);
127
+ console.log(JSON.stringify(result, null, 4));
128
+ console.log("Ending time of sending component analysis request to exhort server= " + new Date());
129
+ }
130
+ }
131
+ else {
132
+ throw new Error(`Got error response from exhort backend - http return code : ${resp.status}, ex-request-id: ${resp.headers.get("ex-request-id")} error message => ${await resp.text()}`);
133
+ }
134
+ return Promise.resolve(result);
135
+ }
136
+ /**
137
+ *
138
+ * @param {Array<string>} imageRefs
139
+ * @param {string} url
140
+ * @param {import("index.js").Options} [opts={}] - optional various options to pass along the application
141
+ * @returns {Promise<string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>>}
142
+ */
143
+ async function requestImages(imageRefs, url, html = false, opts = {}) {
144
+ const imageSboms = {};
145
+ for (const image of imageRefs) {
146
+ const parsedImageRef = parseImageRef(image, opts);
147
+ imageSboms[parsedImageRef.getPackageURL().toString()] = generateImageSBOM(parsedImageRef, opts);
148
+ }
149
+ const finalUrl = new URL(`${url}/api/v4/batch-analysis`);
150
+ if (opts['TRUSTIFY_DA_RECOMMENDATIONS_ENABLED'] === 'false') {
151
+ finalUrl.searchParams.append('recommend', 'false');
152
+ }
153
+ const resp = await fetch(finalUrl, {
154
+ method: 'POST',
155
+ headers: {
156
+ 'Accept': html ? 'text/html' : 'application/json',
157
+ 'Content-Type': 'application/vnd.cyclonedx+json',
158
+ ...getTokenHeaders(opts)
159
+ },
160
+ body: JSON.stringify(imageSboms),
161
+ });
162
+ if (resp.status === 200) {
163
+ let result;
164
+ if (!html) {
165
+ result = await resp.json();
166
+ }
167
+ else {
168
+ result = await resp.text();
169
+ }
170
+ if (process.env["TRUSTIFY_DA_DEBUG"] === "true") {
171
+ let exRequestId = resp.headers.get("ex-request-id");
172
+ if (exRequestId) {
173
+ console.log("Unique Identifier associated with this request - ex-request-id=" + exRequestId);
174
+ }
175
+ console.log("Response body received from exhort server : " + EOL + EOL);
176
+ console.log(JSON.stringify(result, null, 4));
177
+ console.log("Ending time of sending component analysis request to exhort server= " + new Date());
178
+ }
179
+ return result;
180
+ }
181
+ else {
182
+ throw new Error(`Got error response from exhort backend - http return code : ${resp.status}, ex-request-id: ${resp.headers.get("ex-request-id")} error message => ${await resp.text()}`);
183
+ }
184
+ }
185
+ /**
186
+ *
187
+ * @param url the backend url to send the request to
188
+ * @param {import("index.js").Options} [opts={}] - optional various options to pass headers for t he validateToken Request
189
+ * @return {Promise<number>} return the HTTP status Code of the response from the validate token request.
190
+ */
191
+ async function validateToken(url, opts = {}) {
192
+ const fetchOptions = addProxyAgent({
193
+ method: 'GET',
194
+ headers: {
195
+ ...getTokenHeaders(opts),
196
+ }
197
+ }, opts);
198
+ let resp = await fetch(`${url}/api/v4/token`, fetchOptions);
199
+ if (process.env["TRUSTIFY_DA_DEBUG"] === "true") {
200
+ let exRequestId = resp.headers.get("ex-request-id");
201
+ if (exRequestId) {
202
+ console.log("Unique Identifier associated with this request - ex-request-id=" + exRequestId);
203
+ }
204
+ }
205
+ return resp.status;
206
+ }
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 exhort:" + 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,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env node
2
+ import * as path from "path";
3
+ import yargs from 'yargs';
4
+ import { hideBin } from 'yargs/helpers';
5
+ import exhort from './index.js';
6
+ // command for component analysis take manifest type and content
7
+ const component = {
8
+ command: 'component </path/to/manifest>',
9
+ desc: 'produce component report for manifest path',
10
+ builder: yargs => yargs.positional('/path/to/manifest', {
11
+ desc: 'manifest path for analyzing',
12
+ type: 'string',
13
+ normalize: true,
14
+ }),
15
+ handler: async (args) => {
16
+ let manifestName = args['/path/to/manifest'];
17
+ let res = await exhort.componentAnalysis(manifestName);
18
+ console.log(JSON.stringify(res, null, 2));
19
+ }
20
+ };
21
+ const validateToken = {
22
+ command: 'validate-token <token-provider> [--token-value thevalue]',
23
+ desc: 'Validates input token if authentic and authorized',
24
+ builder: yargs => yargs.positional('token-provider', {
25
+ desc: 'the token provider',
26
+ type: 'string',
27
+ choices: ['snyk', 'oss-index'],
28
+ }).options({
29
+ tokenValue: {
30
+ alias: 'value',
31
+ desc: 'the actual token value to be checked',
32
+ type: 'string',
33
+ }
34
+ }),
35
+ handler: async (args) => {
36
+ let tokenProvider = args['token-provider'].toUpperCase();
37
+ let opts = {};
38
+ if (args['tokenValue'] !== undefined && args['tokenValue'].trim() !== "") {
39
+ let tokenValue = args['tokenValue'].trim();
40
+ opts[`TRUSTIFY_DA_${tokenProvider}_TOKEN`] = tokenValue;
41
+ }
42
+ let res = await exhort.validateToken(opts);
43
+ console.log(res);
44
+ }
45
+ };
46
+ // command for stack analysis takes a manifest path
47
+ const stack = {
48
+ command: 'stack </path/to/manifest> [--html|--summary]',
49
+ desc: 'produce stack report for manifest path',
50
+ builder: yargs => yargs.positional('/path/to/manifest', {
51
+ desc: 'manifest path for analyzing',
52
+ type: 'string',
53
+ normalize: true,
54
+ }).options({
55
+ html: {
56
+ alias: 'r',
57
+ desc: 'Get the report as HTML instead of JSON',
58
+ type: 'boolean',
59
+ conflicts: 'summary'
60
+ },
61
+ summary: {
62
+ alias: 's',
63
+ desc: 'For JSON report, get only the \'summary\'',
64
+ type: 'boolean',
65
+ conflicts: 'html'
66
+ }
67
+ }),
68
+ handler: async (args) => {
69
+ let manifest = args['/path/to/manifest'];
70
+ let html = args['html'];
71
+ let summary = args['summary'];
72
+ let theProvidersSummary = new Map();
73
+ let theProvidersObject = {};
74
+ let res = await exhort.stackAnalysis(manifest, html);
75
+ if (summary) {
76
+ for (let provider in res.providers) {
77
+ if (res.providers[provider].sources !== undefined) {
78
+ for (let source in res.providers[provider].sources) {
79
+ if (res.providers[provider].sources[source].summary) {
80
+ theProvidersSummary.set(source, res.providers[provider].sources[source].summary);
81
+ }
82
+ }
83
+ }
84
+ }
85
+ for (let [provider, providerSummary] of theProvidersSummary) {
86
+ theProvidersObject[provider] = providerSummary;
87
+ }
88
+ }
89
+ console.log(html ? res : JSON.stringify(!html && summary ? theProvidersObject : res, null, 2));
90
+ }
91
+ };
92
+ // parse and invoke the command
93
+ yargs(hideBin(process.argv))
94
+ .usage(`Usage: ${process.argv[0].includes("node") ? path.parse(process.argv[1]).base : path.parse(process.argv[0]).base} {component|stack|validate-token}`)
95
+ .command(stack)
96
+ .command(component)
97
+ .command(validateToken)
98
+ .scriptName('')
99
+ .version(false)
100
+ .demandCommand(1)
101
+ .wrap(null)
102
+ .parse();
@@ -0,0 +1,77 @@
1
+ /// <reference types="packageurl-js/src/package-url" />
2
+ export default class CycloneDxSbom {
3
+ sbomObject: any;
4
+ rootComponent: any;
5
+ components: any[];
6
+ dependencies: any[];
7
+ sourceManifestForAuditTrail: any;
8
+ /**
9
+ * @param {PackageURL} root - add main/root component for sbom
10
+ * @return {CycloneDxSbom} the CycloneDxSbom Sbom Object
11
+ */
12
+ addRoot(root: PackageURL): CycloneDxSbom;
13
+ /**
14
+ * @return {{{"bom-ref": string, name, purl: string, type, version}}} root component of sbom.
15
+ */
16
+ getRoot(): {};
17
+ /**
18
+ * Adds a dependency relationship between two components in the SBOM
19
+ * @param {PackageURL} sourceRef - The source component (parent)
20
+ * @param {PackageURL} targetRef - The target component (dependency)
21
+ * @return {CycloneDxSbom} The updated SBOM
22
+ */
23
+ addDependency(sourceRef: PackageURL, targetRef: PackageURL, scope: any): CycloneDxSbom;
24
+ /** @param {{}} opts - various options, settings and configuration of application.
25
+ * @return String CycloneDx Sbom json object in a string format
26
+ */
27
+ getAsJsonString(opts: {}): string;
28
+ /**
29
+ *
30
+ * @param {String} dependency - purl string of the component.
31
+ * @return {int} - the index of the dependency in dependencies Array, returns -1 if not found.
32
+ */
33
+ getDependencyIndex(dependency: string): int;
34
+ /**
35
+ *
36
+ * @param {component} theComponent - Component Object with purl field.
37
+ * @return {int} index of the found component entry, if not found returns -1.
38
+ * @private
39
+ */
40
+ private getComponentIndex;
41
+ /** This method gets a PackageUrl, and returns a Component of CycloneDx Sbom
42
+ * @param purl {PackageURL}
43
+ * @return component
44
+ */
45
+ purlToComponent(purl: PackageURL): {
46
+ "bom-ref": string;
47
+ name: any;
48
+ purl: string;
49
+ type: any;
50
+ version: any;
51
+ scope: any;
52
+ };
53
+ /**
54
+ * This method gets an array of dependencies to be ignored, and remove all of them from CycloneDx Sbom
55
+ * @param {Array[PackageURL]} dependencies to be removed from sbom
56
+ * @return {CycloneDxSbom} without ignored dependencies
57
+ */
58
+ filterIgnoredDeps(deps: any): CycloneDxSbom;
59
+ /**
60
+ * This method gets an array of dependencies with versions( purl string format) to be ignored, and remove all of them from CycloneDx Sbom
61
+ * @param {Array} dependencies to be removed from sbom
62
+ * @return {CycloneDxSbom} without ignored dependencies
63
+ */
64
+ filterIgnoredDepsIncludingVersion(deps: any): CycloneDxSbom;
65
+ /** This method gets a component object, and a string name, and checks if the name is a substring of the component' purl.
66
+ * @param {} component to search in its dependencies
67
+ * @param {String} name to be checked.
68
+ *
69
+ * @return {boolean}
70
+ */
71
+ checkIfPackageInsideDependsOnList(component: any, name: string): boolean;
72
+ /** Removes the root component from the sbom
73
+ */
74
+ removeRootComponent(): void;
75
+ setSourceManifest(manifestData: any): void;
76
+ }
77
+ import { PackageURL } from "packageurl-js";