@contrast/contrast 2.3.2 → 2.5.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/audit/auditRequests.js +8 -2
- package/dist/audit/processAudit.js +2 -0
- package/dist/auth/auth.js +2 -1
- package/dist/cliConstants.js +8 -1
- package/dist/constants/constants.js +1 -1
- package/dist/constants/locales.js +6 -1
- package/dist/github/projectGroup.js +3 -0
- package/dist/index.js +7 -2
- package/dist/scaAnalysis/common/scaServicesUpload.js +3 -0
- package/dist/scaAnalysis/processServicesFlow.js +6 -0
- package/dist/scan/processScan.js +2 -0
- package/dist/utils/getConfig.js +1 -1
- package/dist/utils/validationCheck.js +5 -0
- package/package.json +5 -5
|
@@ -50,13 +50,19 @@ const retrieveProjectByOrganizationIdUrl = (config) => {
|
|
|
50
50
|
: baseUrl.concat(`&type=CLI`);
|
|
51
51
|
return baseUrl;
|
|
52
52
|
};
|
|
53
|
-
export function registerProjectGroup(config, requestBody) {
|
|
53
|
+
export async function registerProjectGroup(config, requestBody) {
|
|
54
54
|
const options = buildBaseRequestOptions(config, ErrorType.GENERIC);
|
|
55
55
|
options.url = registerProjectGroupUrl(config);
|
|
56
56
|
options.json = requestBody;
|
|
57
57
|
logDebug(config, 'registerProjectGroup');
|
|
58
58
|
logDebug(config, `url ${options.url}`);
|
|
59
|
-
|
|
59
|
+
try {
|
|
60
|
+
return await got.post(options);
|
|
61
|
+
}
|
|
62
|
+
catch (e) {
|
|
63
|
+
console.log(`\nResource group ${config.resourceGroup} does not exist`);
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
60
66
|
}
|
|
61
67
|
const registerProjectGroupUrl = (config) => {
|
|
62
68
|
return `${config.host}/api/v4/organizations/${config.organizationId}/project-groups`;
|
|
@@ -4,12 +4,14 @@ import { processSca } from '../scaAnalysis/scaAnalysis.js';
|
|
|
4
4
|
import { sendTelemetryConfigAsObject } from '../telemetry/telemetry.js';
|
|
5
5
|
import { postRunMessage } from '../common/commonHelp.js';
|
|
6
6
|
import { logInfo } from '../common/logging.js';
|
|
7
|
+
import { validateHost } from '../utils/validationCheck.js';
|
|
7
8
|
export const processAudit = async (contrastConf, argvMain) => {
|
|
8
9
|
if (argvMain.indexOf('--help') !== -1) {
|
|
9
10
|
printHelpMessage();
|
|
10
11
|
process.exit(0);
|
|
11
12
|
}
|
|
12
13
|
let config = await getAuditConfig(contrastConf, 'audit', argvMain);
|
|
14
|
+
validateHost(config);
|
|
13
15
|
await processSca(config);
|
|
14
16
|
if (!config.fingerprint) {
|
|
15
17
|
postRunMessage('audit');
|
package/dist/auth/auth.js
CHANGED
|
@@ -23,7 +23,8 @@ export const processAuth = async (argv, config) => {
|
|
|
23
23
|
processCustomCredentials(authParams, config);
|
|
24
24
|
}
|
|
25
25
|
else {
|
|
26
|
-
|
|
26
|
+
logInfo(i18n.__('noParams'));
|
|
27
|
+
process.exit(0);
|
|
27
28
|
}
|
|
28
29
|
};
|
|
29
30
|
const startAuthProcess = async (config) => {
|
package/dist/cliConstants.js
CHANGED
|
@@ -474,6 +474,14 @@ const auditOptionDefinitions = [
|
|
|
474
474
|
'}:' +
|
|
475
475
|
i18n.__('auditOptionsTrackSummary')
|
|
476
476
|
},
|
|
477
|
+
{
|
|
478
|
+
name: 'resource-group',
|
|
479
|
+
type: String,
|
|
480
|
+
description: '{bold ' +
|
|
481
|
+
i18n.__('constantsOptional') +
|
|
482
|
+
'}:' +
|
|
483
|
+
i18n.__('auditOptionsResourceGroupSummary')
|
|
484
|
+
},
|
|
477
485
|
{
|
|
478
486
|
name: 'branch',
|
|
479
487
|
description: '{bold ' +
|
|
@@ -561,7 +569,6 @@ const mainUsageGuide = commandLineUsage([
|
|
|
561
569
|
{ name: i18n.__('lambdaName'), summary: i18n.__('helpLambdaSummary') },
|
|
562
570
|
{ name: i18n.__('helpName'), summary: i18n.__('helpSummary') },
|
|
563
571
|
{ name: i18n.__('learnName'), summary: i18n.__('helpLearnSummary') },
|
|
564
|
-
{ name: i18n.__('sarifName'), summary: i18n.__('sarifSummary') },
|
|
565
572
|
{
|
|
566
573
|
name: i18n.__('configGenerate'),
|
|
567
574
|
summary: i18n.__('configGenerateSummary')
|
|
@@ -17,7 +17,7 @@ export const HIGH = 'HIGH';
|
|
|
17
17
|
export const CRITICAL = 'CRITICAL';
|
|
18
18
|
// App
|
|
19
19
|
export const APP_NAME = 'contrast';
|
|
20
|
-
const APP_VERSION = '2.
|
|
20
|
+
const APP_VERSION = '2.5.0';
|
|
21
21
|
export const TIMEOUT = 120000;
|
|
22
22
|
export const CRITICAL_PRIORITY = 1;
|
|
23
23
|
export const HIGH_PRIORITY = 2;
|
|
@@ -148,6 +148,7 @@ export const en_locales = () => {
|
|
|
148
148
|
scanOptionsFileNameSummary: 'Path of the file you want to scan. If no file is specified, Contrast searches for a .jar, .war, .exe or .zip file in the working directory.',
|
|
149
149
|
scanOptionsVerboseSummary: ' Returns extended information to the terminal.',
|
|
150
150
|
auditOptionsTrackSummary: ' Send your dependency audit to Contrast to see results in the UI and start automating security checks. For instance when running local SCA checks you may not need or want to track the results.',
|
|
151
|
+
auditOptionsResourceGroupSummary: ' Add permissions for a new project to selected resource group.',
|
|
151
152
|
auditOptionsBranchSummary: ' Set the branch name to associate the library results to.',
|
|
152
153
|
auditOptionsLegacySummary: ' Creates an application in Contrast (a legacy workflow) - displays a dependency tree for your piece of code, utilizes metadata.' +
|
|
153
154
|
'\n' +
|
|
@@ -205,7 +206,11 @@ export const en_locales = () => {
|
|
|
205
206
|
lambdaJsonSummery: 'Return response in JSON (versus default human readable format).',
|
|
206
207
|
lambdaVerbosSummery: 'Returns extended information to the terminal.',
|
|
207
208
|
configNotFound: 'Configuration details not found. Try authenticating by using ‘contrast auth’.',
|
|
208
|
-
|
|
209
|
+
noParams: 'No parameters provided. \n' +
|
|
210
|
+
'Please run `contrast auth --api-key <KEY> --authorization <TOKEN> --host <HOST> --organization-id <ORGID>`',
|
|
211
|
+
noHost: 'No host provided. \n' +
|
|
212
|
+
'Please run `contrast auth --api-key <KEY> --authorization <TOKEN> --host <HOST> --organization-id <ORGID>`',
|
|
213
|
+
codeSecEoL: chalk.hex('#ef1414')('❗ WARNING: CodeSec / Community Edition is deprecated. Please configure the CLI with a valid Contrast host URL'),
|
|
209
214
|
fileNotExist: 'File specified does not exist, please check and try again.',
|
|
210
215
|
scanFileIsEmpty: 'File specified is empty. Please choose another.',
|
|
211
216
|
fileHasWhiteSpacesError: 'File cannot have spaces, please rename or choose another file to Scan.',
|
|
@@ -27,6 +27,9 @@ export const buildNewProjectGroupBody = async (config) => {
|
|
|
27
27
|
body.type = 'CLI';
|
|
28
28
|
body.name = getProjectGroupNameCLI(config);
|
|
29
29
|
}
|
|
30
|
+
if (config.resourceGroup) {
|
|
31
|
+
body.resourceGroups = [config.resourceGroup];
|
|
32
|
+
}
|
|
30
33
|
return body;
|
|
31
34
|
};
|
|
32
35
|
const getProjectGroupNameRepo = config => {
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { localConfig } from './utils/getConfig.js';
|
|
3
|
-
import { APP_NAME, getAppVersion } from './constants/constants.js';
|
|
3
|
+
import { APP_NAME, CE_URL, getAppVersion } from './constants/constants.js';
|
|
4
4
|
import commandLineArgs from 'command-line-args';
|
|
5
5
|
import { commandLineDefinitions } from './cliConstants.js';
|
|
6
6
|
import { findLatestCLIVersion, isCorrectNodeVersion } from './common/versionChecker.js';
|
|
@@ -17,6 +17,7 @@ import { processAssess } from './assess/index.js';
|
|
|
17
17
|
import { processSarif } from './sarif/generateSarif.js';
|
|
18
18
|
import { logInfo } from './common/logging.js';
|
|
19
19
|
import { generateYamlConfiguration } from './generateYaml/index.js';
|
|
20
|
+
import i18n from 'i18n';
|
|
20
21
|
const config = localConfig(APP_NAME, getAppVersion());
|
|
21
22
|
const getMainOption = () => {
|
|
22
23
|
const mainOptions = commandLineArgs(commandLineDefinitions.mainDefinition, {
|
|
@@ -54,11 +55,15 @@ const start = async () => {
|
|
|
54
55
|
config.set('numOfRuns', 0);
|
|
55
56
|
}
|
|
56
57
|
if (command === 'config') {
|
|
58
|
+
console.log('config command');
|
|
57
59
|
return processConfig(argvMain, config);
|
|
58
60
|
}
|
|
59
61
|
if (command === 'auth') {
|
|
60
62
|
return await processAuth(argvMain, config);
|
|
61
63
|
}
|
|
64
|
+
if (config.get('host') === CE_URL) {
|
|
65
|
+
logInfo(i18n.__('codeSecEoL'));
|
|
66
|
+
}
|
|
62
67
|
if (command === 'lambda') {
|
|
63
68
|
return await processLambda(argvMain);
|
|
64
69
|
}
|
|
@@ -104,7 +109,7 @@ const start = async () => {
|
|
|
104
109
|
process.exit(9);
|
|
105
110
|
}
|
|
106
111
|
else {
|
|
107
|
-
logInfo('Contrast supports Node versions >=
|
|
112
|
+
logInfo('Contrast supports Node versions >=22.3.0 Node LTS. Please use one of those versions.');
|
|
108
113
|
process.exit(9);
|
|
109
114
|
}
|
|
110
115
|
}
|
|
@@ -42,6 +42,9 @@ export const scaTreeUpload = async (analysis, config, reportSpinner) => {
|
|
|
42
42
|
doPoll = false;
|
|
43
43
|
const reportRes = await scaServiceReport(config, reportId);
|
|
44
44
|
const reportBody = reportRes.body;
|
|
45
|
+
if (config.saveResults !== undefined) {
|
|
46
|
+
fs.writeFileSync('audit-results.json', JSON.stringify(reportBody));
|
|
47
|
+
}
|
|
45
48
|
return { reportArray: reportBody, reportId: reportId };
|
|
46
49
|
}
|
|
47
50
|
handleTimeout(startTime, timeout, reportSpinner);
|
|
@@ -88,6 +88,12 @@ const trackProcess = async (analysis, config, reportSpinner) => {
|
|
|
88
88
|
if (projectId === '') {
|
|
89
89
|
return dealWithNoProjectId(analysis, config, reportSpinner);
|
|
90
90
|
}
|
|
91
|
+
else if (config.resourceGroup) {
|
|
92
|
+
console.log('\nProject ' +
|
|
93
|
+
projectId +
|
|
94
|
+
' already exists and will not be added to resource group ' +
|
|
95
|
+
config.resourceGroup);
|
|
96
|
+
}
|
|
91
97
|
config.projectId = projectId;
|
|
92
98
|
// we can always register just in case but normally we exit when
|
|
93
99
|
await registerProjectIdOnCliServices(config, projectId);
|
package/dist/scan/processScan.js
CHANGED
|
@@ -7,8 +7,10 @@ import { sendTelemetryConfigAsObject } from '../telemetry/telemetry.js';
|
|
|
7
7
|
import { processFail } from '../common/fail.js';
|
|
8
8
|
import { postRunMessage } from '../common/commonHelp.js';
|
|
9
9
|
import { logInfo } from '../common/logging.js';
|
|
10
|
+
import { validateHost } from '../utils/validationCheck.js';
|
|
10
11
|
export const processScan = async (contrastConf, argv) => {
|
|
11
12
|
let config = await scanConfig.getScanConfig(contrastConf, 'scan', argv);
|
|
13
|
+
validateHost(config);
|
|
12
14
|
let output = undefined;
|
|
13
15
|
const scanResults = new ScanResultsModel(await startScan(config));
|
|
14
16
|
await sendTelemetryConfigAsObject(config, 'scan', argv, 'SUCCESS', scanResults.scanDetail.language);
|
package/dist/utils/getConfig.js
CHANGED
|
@@ -15,6 +15,6 @@ const setConfigValues = (config, values) => {
|
|
|
15
15
|
config.set('apiKey', values.apiKey);
|
|
16
16
|
config.set('organizationId', values.orgId);
|
|
17
17
|
config.set('authorization', values.authHeader);
|
|
18
|
-
|
|
18
|
+
config.set('host', values.host);
|
|
19
19
|
};
|
|
20
20
|
export { localConfig, setConfigValues };
|
|
@@ -18,6 +18,11 @@ export const validateAuthParams = params => {
|
|
|
18
18
|
params.host &&
|
|
19
19
|
params.authorization);
|
|
20
20
|
};
|
|
21
|
+
export const validateHost = config => {
|
|
22
|
+
if (config.host.endsWith('/')) {
|
|
23
|
+
config.host = config.host.slice(0, -1);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
21
26
|
export const validateFingerprintParams = params => {
|
|
22
27
|
return !!(params.repositoryUrl && params.repositoryName);
|
|
23
28
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contrast/contrast",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "Contrast Security's command line tool",
|
|
5
5
|
"exports": "./dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"scripts": {
|
|
27
27
|
"build": "tsc",
|
|
28
28
|
"build-binary": "esbuild src/index.ts --bundle --outdir=dist-binary --platform=node",
|
|
29
|
-
"package-binary": "pkg dist-binary/index.js --out-path binaries --targets
|
|
29
|
+
"package-binary": "pkg dist-binary/index.js --out-path binaries --targets node22-macos,node22-linux,node22-win",
|
|
30
30
|
"build-package": "yarn build && yarn build-binary && yarn package-binary",
|
|
31
31
|
"test": "export VITEST_MAX_THREADS=4 && export VITEST_MIN_THREADS=1 && vitest --dir ./tests/unit-tests/",
|
|
32
32
|
"test-debug": "export VITEST_MAX_THREADS=4 && export VITEST_MIN_THREADS=1 && vitest --dir ./tests/unit-tests/ --inspect-brk",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"proxy-tests": "vitest ./tests/integration-tests/proxy/proxy-coverage.spec.js --pool=forks"
|
|
51
51
|
},
|
|
52
52
|
"engines": {
|
|
53
|
-
"node": ">=
|
|
53
|
+
"node": ">=22.3.0"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@aws-sdk/client-iam": "3.370.0",
|
|
@@ -84,6 +84,7 @@
|
|
|
84
84
|
"semver": "7.5.4",
|
|
85
85
|
"string-builder": "0.1.8",
|
|
86
86
|
"string-multiple-replace": "1.0.5",
|
|
87
|
+
"tsx": "^4.19.2",
|
|
87
88
|
"xml2js": "0.6.1",
|
|
88
89
|
"yarn-lockfile": "1.1.1"
|
|
89
90
|
},
|
|
@@ -100,6 +101,7 @@
|
|
|
100
101
|
"@typescript-eslint/eslint-plugin": "5.62.0",
|
|
101
102
|
"@typescript-eslint/parser": "5.62.0",
|
|
102
103
|
"@vitest/coverage-v8": "0.34.3",
|
|
104
|
+
"@yao-pkg/pkg": "^6.1.0",
|
|
103
105
|
"csv-writer": "1.6.0",
|
|
104
106
|
"dotenv": "16.3.1",
|
|
105
107
|
"esbuild": "0.18.16",
|
|
@@ -110,10 +112,8 @@
|
|
|
110
112
|
"mocha": "10.2.0",
|
|
111
113
|
"nock": "13.3.2",
|
|
112
114
|
"npm-license-crawler": "0.2.1",
|
|
113
|
-
"pkg": "5.8.1",
|
|
114
115
|
"prettier": "2.8.8",
|
|
115
116
|
"tmp": "0.2.1",
|
|
116
|
-
"ts-node": "^10.9.2",
|
|
117
117
|
"typescript": "5.1.6",
|
|
118
118
|
"uuid": "9.0.0",
|
|
119
119
|
"vitest": "1.4.0"
|