@contrast/contrast 1.0.15 → 1.0.17
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/catalogueApplication/catalogueApplication.js +1 -1
- package/dist/audit/languageAnalysisEngine/sendSnapshot.js +2 -2
- package/dist/audit/report/commonReportingFunctions.js +1 -19
- package/dist/{constants.js → cliConstants.js} +47 -32
- package/dist/commands/audit/auditConfig.js +10 -12
- package/dist/commands/audit/auditController.js +12 -16
- package/dist/commands/audit/help.js +24 -26
- package/dist/commands/audit/processAudit.js +16 -22
- package/dist/commands/audit/saveFile.js +3 -9
- package/dist/commands/auth/auth.js +1 -1
- package/dist/commands/config/config.js +1 -1
- package/dist/commands/scan/processScan.js +5 -7
- package/dist/commands/scan/sca/scaAnalysis.js +118 -89
- package/dist/common/HTTPClient.js +4 -2
- package/dist/common/commonHelp.js +35 -17
- package/dist/common/errorHandling.js +28 -57
- package/dist/common/versionChecker.js +24 -27
- package/dist/constants/constants.js +1 -1
- package/dist/constants/locales.js +11 -33
- package/dist/index.js +5 -5
- package/dist/lambda/help.js +2 -1
- package/dist/lambda/lambda.js +2 -7
- package/dist/scaAnalysis/common/auditReport.js +3 -2
- package/dist/scaAnalysis/common/scaParserForGoAndJava.js +1 -1
- package/dist/scaAnalysis/java/analysis.js +40 -5
- package/dist/scaAnalysis/java/index.js +15 -2
- package/dist/scaAnalysis/javascript/scaServiceParser.js +2 -2
- package/dist/scaAnalysis/php/phpNewServicesMapper.js +3 -3
- package/dist/scaAnalysis/python/analysis.js +1 -1
- package/dist/scaAnalysis/repoMode/gradleParser.js +75 -0
- package/dist/scaAnalysis/repoMode/index.js +21 -0
- package/dist/scaAnalysis/repoMode/mavenParser.js +76 -0
- package/dist/scaAnalysis/ruby/analysis.js +4 -4
- package/dist/scan/autoDetection.js +12 -3
- package/dist/scan/fileUtils.js +24 -1
- package/dist/scan/help.js +3 -2
- package/dist/scan/saveResults.js +1 -1
- package/dist/scan/scanConfig.js +1 -1
- package/dist/utils/commonApi.js +10 -1
- package/dist/utils/generalAPI.js +1 -2
- package/dist/utils/paramsUtil/configStoreParams.js +12 -1
- package/dist/utils/paramsUtil/paramHandler.js +7 -1
- package/dist/utils/saveFile.js +2 -1
- package/package.json +3 -1
- package/src/audit/catalogueApplication/catalogueApplication.js +1 -1
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +2 -6
- package/src/audit/report/commonReportingFunctions.js +1 -23
- package/src/{constants.js → cliConstants.js} +53 -36
- package/src/commands/audit/auditConfig.js +19 -0
- package/src/commands/audit/{auditController.ts → auditController.js} +17 -12
- package/src/commands/audit/{help.ts → help.js} +10 -7
- package/src/commands/audit/processAudit.js +37 -0
- package/src/commands/audit/{saveFile.ts → saveFile.js} +2 -2
- package/src/commands/auth/auth.js +1 -1
- package/src/commands/config/config.js +1 -1
- package/src/commands/scan/processScan.js +4 -10
- package/src/commands/scan/sca/scaAnalysis.js +146 -118
- package/src/common/HTTPClient.js +4 -2
- package/src/common/commonHelp.js +43 -0
- package/src/common/{errorHandling.ts → errorHandling.js} +6 -31
- package/src/common/{versionChecker.ts → versionChecker.js} +15 -10
- package/src/constants/constants.js +1 -1
- package/src/constants/locales.js +13 -47
- package/src/index.ts +1 -1
- package/src/lambda/help.ts +2 -1
- package/src/lambda/lambda.ts +2 -10
- package/src/scaAnalysis/common/auditReport.js +3 -4
- package/src/scaAnalysis/common/scaParserForGoAndJava.js +1 -1
- package/src/scaAnalysis/java/analysis.js +43 -10
- package/src/scaAnalysis/java/index.js +19 -2
- package/src/scaAnalysis/javascript/scaServiceParser.js +8 -2
- package/src/scaAnalysis/php/phpNewServicesMapper.js +3 -3
- package/src/scaAnalysis/python/analysis.js +1 -1
- package/src/scaAnalysis/repoMode/gradleParser.js +88 -0
- package/src/scaAnalysis/repoMode/index.js +21 -0
- package/src/scaAnalysis/repoMode/mavenParser.js +89 -0
- package/src/scaAnalysis/ruby/analysis.js +4 -4
- package/src/scan/autoDetection.js +14 -3
- package/src/scan/fileUtils.js +29 -1
- package/src/scan/help.js +3 -2
- package/src/scan/saveResults.js +1 -1
- package/src/scan/scanConfig.js +1 -1
- package/src/utils/commonApi.js +13 -1
- package/src/utils/generalAPI.js +1 -2
- package/src/utils/getConfig.ts +1 -0
- package/src/utils/paramsUtil/configStoreParams.js +14 -1
- package/src/utils/paramsUtil/paramHandler.js +9 -1
- package/src/utils/saveFile.js +2 -1
- package/src/commands/audit/auditConfig.ts +0 -21
- package/src/commands/audit/processAudit.ts +0 -40
- package/src/common/commonHelp.ts +0 -13
|
@@ -1,26 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
const { supportedLanguages: { JAVA, GO, PYTHON, RUBY, JAVASCRIPT, NODE, PHP, DOTNET } } = require('../../../constants/constants');
|
|
3
|
+
const { pollForSnapshotCompletion } = require('../../../audit/languageAnalysisEngine/sendSnapshot');
|
|
4
|
+
const { returnOra, startSpinner, succeedSpinner } = require('../../../utils/oraWrapper');
|
|
5
|
+
const { vulnerabilityReportV2 } = require('../../../audit/report/reportingFeature');
|
|
2
6
|
const autoDetection = require('../../../scan/autoDetection');
|
|
3
|
-
const javaAnalysis = require('../../../scaAnalysis/java');
|
|
4
7
|
const treeUpload = require('../../../scaAnalysis/common/treeUpload');
|
|
5
8
|
const auditController = require('../../audit/auditController');
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const phpAnalysis = require('../../../scaAnalysis/php/index');
|
|
9
|
-
const { rubyAnalysis } = require('../../../scaAnalysis/ruby');
|
|
10
|
-
const { pythonAnalysis } = require('../../../scaAnalysis/python');
|
|
11
|
-
const javascriptAnalysis = require('../../../scaAnalysis/javascript');
|
|
12
|
-
const { pollForSnapshotCompletition } = require('../../../audit/languageAnalysisEngine/sendSnapshot');
|
|
13
|
-
const { returnOra, startSpinner, succeedSpinner } = require('../../../utils/oraWrapper');
|
|
9
|
+
const rootFile = require('../../../audit/languageAnalysisEngine/getProjectRootFilenames');
|
|
10
|
+
const path = require('path');
|
|
14
11
|
const i18n = require('i18n');
|
|
15
|
-
const { vulnerabilityReportV2 } = require('../../../audit/report/reportingFeature');
|
|
16
12
|
const auditSave = require('../../../audit/save');
|
|
17
|
-
const { dotNetAnalysis } = require('../../../scaAnalysis/dotnet');
|
|
18
13
|
const { auditUsageGuide } = require('../../audit/help');
|
|
19
|
-
const
|
|
20
|
-
const
|
|
14
|
+
const repoMode = require('../../../scaAnalysis/repoMode/index');
|
|
15
|
+
const { dotNetAnalysis } = require('../../../scaAnalysis/dotnet');
|
|
16
|
+
const { goAnalysis } = require('../../../scaAnalysis/go/goAnalysis');
|
|
17
|
+
const { phpAnalysis } = require('../../../scaAnalysis/php/index');
|
|
18
|
+
const { rubyAnalysis } = require('../../../scaAnalysis/ruby');
|
|
19
|
+
const { pythonAnalysis } = require('../../../scaAnalysis/python');
|
|
20
|
+
const javaAnalysis = require('../../../scaAnalysis/java');
|
|
21
|
+
const jsAnalysis = require('../../../scaAnalysis/javascript');
|
|
21
22
|
const auditReport = require('../../../scaAnalysis/common/auditReport');
|
|
22
23
|
const scaUpload = require('../../../scaAnalysis/common/scaServicesUpload');
|
|
23
24
|
const settingsHelper = require('../../../utils/settingsHelper');
|
|
25
|
+
const chalk = require('chalk');
|
|
26
|
+
const saveResults = require('../../../scan/saveResults');
|
|
24
27
|
const processSca = async (config) => {
|
|
25
28
|
config = await settingsHelper.getSettings(config);
|
|
26
29
|
const startTime = performance.now();
|
|
@@ -35,88 +38,114 @@ const processSca = async (config) => {
|
|
|
35
38
|
config.file = pathWithFile
|
|
36
39
|
? rootFile.getDirectoryFromPathGiven(config.file).concat('/')
|
|
37
40
|
: config.file;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
if (config.fingerprint && config.experimental) {
|
|
42
|
+
let fingerprint = await autoDetection.autoDetectFingerprintInfo(config.file);
|
|
43
|
+
let idArray = fingerprint.map(x => x.id);
|
|
44
|
+
await saveResults.writeResultsToFile(fingerprint, 'fingerPrintInfo.json');
|
|
45
|
+
console.log(idArray);
|
|
41
46
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
messageToSend = javaAnalysis.javaAnalysis(config, filesFound[0]);
|
|
47
|
-
config.language = JAVA;
|
|
48
|
-
break;
|
|
49
|
-
case JAVASCRIPT:
|
|
50
|
-
messageToSend = await javascriptAnalysis.jsAnalysis(config, filesFound[0]);
|
|
51
|
-
config.language = NODE;
|
|
52
|
-
break;
|
|
53
|
-
case PYTHON:
|
|
54
|
-
messageToSend = pythonAnalysis(config, filesFound[0]);
|
|
55
|
-
config.language = PYTHON;
|
|
56
|
-
break;
|
|
57
|
-
case RUBY:
|
|
58
|
-
messageToSend = rubyAnalysis(config, filesFound[0]);
|
|
59
|
-
config.language = RUBY;
|
|
60
|
-
break;
|
|
61
|
-
case PHP:
|
|
62
|
-
messageToSend = phpAnalysis.phpAnalysis(config, filesFound[0]);
|
|
63
|
-
config.language = PHP;
|
|
64
|
-
break;
|
|
65
|
-
case GO:
|
|
66
|
-
messageToSend = goAnalysis.goAnalysis(config, filesFound[0]);
|
|
67
|
-
config.language = GO;
|
|
68
|
-
break;
|
|
69
|
-
case DOTNET:
|
|
70
|
-
messageToSend = dotNetAnalysis(config, filesFound[0]);
|
|
71
|
-
config.language = DOTNET;
|
|
72
|
-
break;
|
|
73
|
-
default:
|
|
74
|
-
console.log('No supported language detected in project path');
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
if (!config.applicationId) {
|
|
78
|
-
config.applicationId = await auditController.dealWithNoAppId(config);
|
|
47
|
+
else {
|
|
48
|
+
filesFound = await autoDetection.autoDetectAuditFilesAndLanguages(config.file);
|
|
49
|
+
if (filesFound.length > 1 && pathWithFile) {
|
|
50
|
+
filesFound = filesFound.filter(i => Object.values(i)[0].includes(path.basename(config.fileName)));
|
|
79
51
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
52
|
+
let messageToSend = undefined;
|
|
53
|
+
if (filesFound.length === 1) {
|
|
54
|
+
switch (Object.keys(filesFound[0])[0]) {
|
|
55
|
+
case JAVA:
|
|
56
|
+
config.language = JAVA;
|
|
57
|
+
if (config.mode === 'repo') {
|
|
58
|
+
try {
|
|
59
|
+
return repoMode.buildRepo(config, filesFound[0]);
|
|
60
|
+
}
|
|
61
|
+
catch (e) {
|
|
62
|
+
throw new Error('Unable to build in repository mode. Check your project file');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
messageToSend = await javaAnalysis.javaAnalysis(config, filesFound[0]);
|
|
67
|
+
}
|
|
68
|
+
break;
|
|
69
|
+
case JAVASCRIPT:
|
|
70
|
+
messageToSend = await jsAnalysis.jsAnalysis(config, filesFound[0]);
|
|
71
|
+
config.language = NODE;
|
|
72
|
+
break;
|
|
73
|
+
case PYTHON:
|
|
74
|
+
messageToSend = pythonAnalysis(config, filesFound[0]);
|
|
75
|
+
config.language = PYTHON;
|
|
76
|
+
break;
|
|
77
|
+
case RUBY:
|
|
78
|
+
messageToSend = rubyAnalysis(config, filesFound[0]);
|
|
79
|
+
config.language = RUBY;
|
|
80
|
+
break;
|
|
81
|
+
case PHP:
|
|
82
|
+
messageToSend = phpAnalysis(config, filesFound[0]);
|
|
83
|
+
config.language = PHP;
|
|
84
|
+
break;
|
|
85
|
+
case GO:
|
|
86
|
+
messageToSend = goAnalysis(config, filesFound[0]);
|
|
87
|
+
config.language = GO;
|
|
88
|
+
break;
|
|
89
|
+
case DOTNET:
|
|
90
|
+
messageToSend = dotNetAnalysis(config, filesFound[0]);
|
|
91
|
+
config.language = DOTNET;
|
|
92
|
+
break;
|
|
93
|
+
default:
|
|
94
|
+
console.log('No supported language detected in project path');
|
|
95
|
+
return;
|
|
89
96
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
97
|
+
if (!config.applicationId) {
|
|
98
|
+
config.applicationId = await auditController.dealWithNoAppId(config);
|
|
99
|
+
}
|
|
100
|
+
if (config.experimental) {
|
|
101
|
+
console.log('');
|
|
102
|
+
const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'));
|
|
103
|
+
startSpinner(reportSpinner);
|
|
104
|
+
const [reports, reportId] = await scaUpload.scaTreeUpload(messageToSend, config);
|
|
105
|
+
auditReport.processAuditReport(config, reports[0]);
|
|
106
|
+
succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'));
|
|
107
|
+
if (config.save !== undefined) {
|
|
108
|
+
await auditSave.auditSave(config, reportId);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
console.log('Use contrast audit --save to generate an SBOM');
|
|
112
|
+
}
|
|
113
|
+
const endTime = performance.now() - startTime;
|
|
114
|
+
const scanDurationMs = endTime - startTime;
|
|
115
|
+
console.log(`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
console.log('');
|
|
119
|
+
const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'));
|
|
120
|
+
startSpinner(reportSpinner);
|
|
121
|
+
const snapshotResponse = await treeUpload.commonSendSnapShot(messageToSend, config);
|
|
122
|
+
await pollForSnapshotCompletion(config, snapshotResponse.id, reportSpinner);
|
|
123
|
+
succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'));
|
|
124
|
+
await vulnerabilityReportV2(config, snapshotResponse.id);
|
|
125
|
+
if (config.save !== undefined) {
|
|
126
|
+
await auditSave.auditSave(config);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
console.log('\nUse contrast audit --save to generate an SBOM');
|
|
130
|
+
}
|
|
131
|
+
const endTime = performance.now() - startTime;
|
|
132
|
+
const scanDurationMs = endTime - startTime;
|
|
133
|
+
console.log(`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`);
|
|
104
134
|
}
|
|
105
|
-
const endTime = performance.now() - startTime;
|
|
106
|
-
const scanDurationMs = endTime - startTime;
|
|
107
|
-
console.log(`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
if (filesFound.length === 0) {
|
|
112
|
-
console.log(i18n.__('languageAnalysisNoLanguage'));
|
|
113
|
-
console.log(i18n.__('languageAnalysisNoLanguageHelpLine'));
|
|
114
|
-
throw new Error();
|
|
115
135
|
}
|
|
116
136
|
else {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
137
|
+
if (filesFound.length === 0) {
|
|
138
|
+
console.log(i18n.__('languageAnalysisNoLanguage'));
|
|
139
|
+
console.log(i18n.__('languageAnalysisNoLanguageHelpLine'));
|
|
140
|
+
throw new Error();
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
console.log(chalk.bold(`\nMultiple language files detected \n`));
|
|
144
|
+
filesFound.forEach(file => {
|
|
145
|
+
console.log(`${Object.keys(file)[0]} : `, Object.values(file)[0]);
|
|
146
|
+
});
|
|
147
|
+
throw new Error(`Please use --file to audit one language only. \nExample: contrast audit --file package-lock.json`);
|
|
148
|
+
}
|
|
120
149
|
}
|
|
121
150
|
}
|
|
122
151
|
};
|
|
@@ -34,7 +34,7 @@ HTTPClient.prototype.maybeAddCertsToRequest = function (config) {
|
|
|
34
34
|
if (caCertFilePath) {
|
|
35
35
|
const caFileContent = fs.readFileSync(caCertFilePath);
|
|
36
36
|
if (caFileContent instanceof Error) {
|
|
37
|
-
throw new Error(`Unable to read CA from
|
|
37
|
+
throw new Error(`Unable to read CA from ${caCertFilePath}, msg: ${caFileContent.message}`);
|
|
38
38
|
}
|
|
39
39
|
this.requestOptions.ca = caFileContent;
|
|
40
40
|
}
|
|
@@ -332,7 +332,9 @@ function createSnapshotURL(config) {
|
|
|
332
332
|
return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/snapshots`;
|
|
333
333
|
}
|
|
334
334
|
function createScaServiceReportURL(config, reportId) {
|
|
335
|
-
|
|
335
|
+
let baseUrl = `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/applications/${config.applicationId}/reports/${reportId}`;
|
|
336
|
+
baseUrl = config.ignoreDev ? baseUrl.concat('?nodesToInclude=PROD') : baseUrl;
|
|
337
|
+
return baseUrl;
|
|
336
338
|
}
|
|
337
339
|
function createScaServiceReportStatusURL(config, reportId) {
|
|
338
340
|
return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/ingests/${reportId}/status`;
|
|
@@ -1,19 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
const i18n = require('i18n');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
const commonHelpLinks = () => {
|
|
5
|
+
return [
|
|
6
|
+
{
|
|
7
|
+
header: i18n.__('commonHelpHeader'),
|
|
8
|
+
content: [
|
|
9
|
+
i18n.__('commonHelpCheckOutHeader') + i18n.__('commonHelpCheckOutText'),
|
|
10
|
+
i18n.__('commonHelpLearnMoreHeader') +
|
|
11
|
+
i18n.__('commonHelpLearnMoreText'),
|
|
12
|
+
i18n.__('commonHelpJoinDiscussionHeader') +
|
|
13
|
+
i18n.__('commonHelpJoinDiscussionText')
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
header: i18n.__('commonHelpEnterpriseHeader'),
|
|
18
|
+
content: [
|
|
19
|
+
i18n.__('commonHelpLearnMoreEnterpriseHeader') +
|
|
20
|
+
i18n.__('commonHelpLearnMoreEnterpriseText')
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
];
|
|
24
|
+
};
|
|
25
|
+
const postRunMessage = commandName => {
|
|
26
|
+
console.log('\n' + chalk.underline.bold('Other Features:'));
|
|
27
|
+
if (commandName !== 'scan')
|
|
28
|
+
console.log("'contrast scan' to run Contrasts’ industry leading SAST scanner");
|
|
29
|
+
if (commandName !== 'audit')
|
|
30
|
+
console.log("'contrast audit' to find vulnerabilities in your open source dependencies");
|
|
31
|
+
if (commandName !== 'lambda')
|
|
32
|
+
console.log("'contrast lambda' to secure your AWS serverless functions");
|
|
33
|
+
};
|
|
34
|
+
module.exports = {
|
|
35
|
+
commonHelpLinks,
|
|
36
|
+
postRunMessage
|
|
4
37
|
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.commonHelpLinks = void 0;
|
|
7
|
-
const i18n_1 = __importDefault(require("i18n"));
|
|
8
|
-
function commonHelpLinks() {
|
|
9
|
-
return {
|
|
10
|
-
header: i18n_1.default.__('commonHelpHeader'),
|
|
11
|
-
content: [
|
|
12
|
-
i18n_1.default.__('commonHelpCheckOutHeader') + i18n_1.default.__('commonHelpCheckOutText'),
|
|
13
|
-
i18n_1.default.__('commonHelpLearnMoreHeader') + i18n_1.default.__('commonHelpLearnMoreText'),
|
|
14
|
-
i18n_1.default.__('commonHelpJoinDiscussionHeader') +
|
|
15
|
-
i18n_1.default.__('commonHelpJoinDiscussionText')
|
|
16
|
-
]
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
exports.commonHelpLinks = commonHelpLinks;
|
|
@@ -1,107 +1,63 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.maxAppError = exports.reportFailureError = exports.vulnerabilitiesFailureError = exports.snapshotFailureError = exports.findCommandOnError = exports.libraryAnalysisError = exports.handleResponseErrors = exports.getErrorMessage = exports.generalError = exports.failOptionError = exports.proxyError = exports.forbiddenError = exports.badRequestError = exports.unauthenticatedError = exports.genericError = void 0;
|
|
7
|
-
const i18n_1 = __importDefault(require("i18n"));
|
|
8
|
-
const handleResponseErrors = (res, api) => {
|
|
9
|
-
if (res.statusCode === 400) {
|
|
10
|
-
api === 'catalogue' ? badRequestError(true) : badRequestError(false);
|
|
11
|
-
}
|
|
12
|
-
else if (res.statusCode === 401) {
|
|
13
|
-
unauthenticatedError();
|
|
14
|
-
}
|
|
15
|
-
else if (res.statusCode === 403) {
|
|
16
|
-
forbiddenError();
|
|
17
|
-
}
|
|
18
|
-
else if (res.statusCode === 407) {
|
|
19
|
-
proxyError();
|
|
20
|
-
}
|
|
21
|
-
else {
|
|
22
|
-
if (api === 'snapshot' || api === 'catalogue') {
|
|
23
|
-
snapshotFailureError();
|
|
24
|
-
}
|
|
25
|
-
if (api === 'vulnerabilities') {
|
|
26
|
-
vulnerabilitiesFailureError();
|
|
27
|
-
}
|
|
28
|
-
if (api === 'report') {
|
|
29
|
-
reportFailureError();
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
exports.handleResponseErrors = handleResponseErrors;
|
|
2
|
+
const i18n = require('i18n');
|
|
34
3
|
const libraryAnalysisError = () => {
|
|
35
|
-
console.log(
|
|
4
|
+
console.log(i18n.__('libraryAnalysisError'));
|
|
36
5
|
};
|
|
37
|
-
exports.libraryAnalysisError = libraryAnalysisError;
|
|
38
6
|
const snapshotFailureError = () => {
|
|
39
|
-
console.log(
|
|
7
|
+
console.log(i18n.__('snapshotFailureMessage'));
|
|
40
8
|
};
|
|
41
|
-
exports.snapshotFailureError = snapshotFailureError;
|
|
42
9
|
const vulnerabilitiesFailureError = () => {
|
|
43
|
-
console.log(
|
|
10
|
+
console.log(i18n.__('vulnerabilitiesFailureMessage'));
|
|
44
11
|
};
|
|
45
|
-
exports.vulnerabilitiesFailureError = vulnerabilitiesFailureError;
|
|
46
12
|
const reportFailureError = () => {
|
|
47
|
-
console.log(
|
|
13
|
+
console.log(i18n.__('auditReportFailureMessage'));
|
|
48
14
|
};
|
|
49
|
-
exports.reportFailureError = reportFailureError;
|
|
50
15
|
const genericError = () => {
|
|
51
|
-
console.error(
|
|
16
|
+
console.error(i18n.__('genericErrorMessage'));
|
|
52
17
|
process.exit(1);
|
|
53
18
|
};
|
|
54
|
-
exports.genericError = genericError;
|
|
55
19
|
const unauthenticatedError = () => {
|
|
56
20
|
generalError('unauthenticatedErrorHeader', 'unauthenticatedErrorMessage');
|
|
57
21
|
};
|
|
58
|
-
|
|
59
|
-
const badRequestError = (catalogue) => {
|
|
22
|
+
const badRequestError = catalogue => {
|
|
60
23
|
catalogue === true
|
|
61
24
|
? generalError('badRequestErrorHeader', 'badRequestCatalogueErrorMessage')
|
|
62
25
|
: generalError('badRequestErrorHeader', 'badRequestErrorMessage');
|
|
63
26
|
};
|
|
64
|
-
exports.badRequestError = badRequestError;
|
|
65
27
|
const forbiddenError = () => {
|
|
66
28
|
generalError('forbiddenRequestErrorHeader', 'forbiddenRequestErrorMessage');
|
|
67
29
|
process.exit(1);
|
|
68
30
|
};
|
|
69
|
-
exports.forbiddenError = forbiddenError;
|
|
70
31
|
const proxyError = () => {
|
|
71
32
|
generalError('proxyErrorHeader', 'proxyErrorMessage');
|
|
72
33
|
};
|
|
73
|
-
exports.proxyError = proxyError;
|
|
74
34
|
const maxAppError = () => {
|
|
75
35
|
generalError('No applications remaining', 'You have reached the maximum number of application you can create.');
|
|
76
36
|
process.exit(1);
|
|
77
37
|
};
|
|
78
|
-
exports.maxAppError = maxAppError;
|
|
79
38
|
const failOptionError = () => {
|
|
80
39
|
console.log('\n ******************************** ' +
|
|
81
|
-
|
|
40
|
+
i18n.__('snapshotFailureHeader') +
|
|
82
41
|
' ********************************\n' +
|
|
83
|
-
|
|
42
|
+
i18n.__('failOptionErrorMessage'));
|
|
84
43
|
};
|
|
85
|
-
exports.failOptionError = failOptionError;
|
|
86
44
|
const getErrorMessage = (header, message) => {
|
|
87
|
-
const title = `******************************** ${
|
|
45
|
+
const title = `******************************** ${i18n.__(header)} ********************************`;
|
|
88
46
|
const multiLine = message?.includes('\n');
|
|
89
47
|
let finalMessage = '';
|
|
90
48
|
if (multiLine) {
|
|
91
49
|
finalMessage = `\n${message}`;
|
|
92
50
|
}
|
|
93
51
|
else if (message) {
|
|
94
|
-
finalMessage = `\n${
|
|
52
|
+
finalMessage = `\n${i18n.__(message)}`;
|
|
95
53
|
}
|
|
96
54
|
return `${title}${finalMessage}`;
|
|
97
55
|
};
|
|
98
|
-
exports.getErrorMessage = getErrorMessage;
|
|
99
56
|
const generalError = (header, message) => {
|
|
100
57
|
const finalMessage = getErrorMessage(header, message);
|
|
101
58
|
console.log(finalMessage);
|
|
102
59
|
};
|
|
103
|
-
|
|
104
|
-
const findCommandOnError = (unknownOptions) => {
|
|
60
|
+
const findCommandOnError = unknownOptions => {
|
|
105
61
|
const commandKeywords = {
|
|
106
62
|
auth: 'auth',
|
|
107
63
|
audit: 'audit',
|
|
@@ -115,4 +71,19 @@ const findCommandOnError = (unknownOptions) => {
|
|
|
115
71
|
return foundCommands[0];
|
|
116
72
|
}
|
|
117
73
|
};
|
|
118
|
-
exports
|
|
74
|
+
module.exports = {
|
|
75
|
+
genericError,
|
|
76
|
+
unauthenticatedError,
|
|
77
|
+
badRequestError,
|
|
78
|
+
forbiddenError,
|
|
79
|
+
proxyError,
|
|
80
|
+
failOptionError,
|
|
81
|
+
generalError,
|
|
82
|
+
getErrorMessage,
|
|
83
|
+
libraryAnalysisError,
|
|
84
|
+
findCommandOnError,
|
|
85
|
+
snapshotFailureError,
|
|
86
|
+
vulnerabilitiesFailureError,
|
|
87
|
+
reportFailureError,
|
|
88
|
+
maxAppError
|
|
89
|
+
};
|
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
const boxen_1 = __importDefault(require("boxen"));
|
|
9
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
-
const semver_1 = __importDefault(require("semver"));
|
|
11
|
-
const commonApi_1 = __importDefault(require("../utils/commonApi"));
|
|
12
|
-
const http2_1 = require("http2");
|
|
2
|
+
const { APP_VERSION } = require('../constants/constants');
|
|
3
|
+
const boxen = require('boxen');
|
|
4
|
+
const chalk = require('chalk');
|
|
5
|
+
const semver = require('semver');
|
|
6
|
+
const commonApi = require('../utils/commonApi');
|
|
7
|
+
const { constants } = require('http2');
|
|
13
8
|
const getLatestVersion = async (config) => {
|
|
14
|
-
const client =
|
|
9
|
+
const client = commonApi.getHttpClient(config);
|
|
15
10
|
try {
|
|
16
11
|
const res = await client.getLatestVersion();
|
|
17
|
-
if (res.statusCode ===
|
|
12
|
+
if (res.statusCode === constants.HTTP_STATUS_OK) {
|
|
18
13
|
return res.body;
|
|
19
14
|
}
|
|
20
15
|
}
|
|
@@ -22,24 +17,23 @@ const getLatestVersion = async (config) => {
|
|
|
22
17
|
return undefined;
|
|
23
18
|
}
|
|
24
19
|
};
|
|
25
|
-
|
|
26
|
-
async function findLatestCLIVersion(config) {
|
|
20
|
+
const findLatestCLIVersion = async (config) => {
|
|
27
21
|
const isCI = process.env.CONTRAST_CODESEC_CI
|
|
28
22
|
? JSON.parse(process.env.CONTRAST_CODESEC_CI.toLowerCase())
|
|
29
23
|
: false;
|
|
30
24
|
if (!isCI) {
|
|
31
|
-
let latestCLIVersion = await
|
|
25
|
+
let latestCLIVersion = await getLatestVersion(config);
|
|
32
26
|
if (latestCLIVersion === undefined) {
|
|
33
27
|
config.set('numOfRuns', 0);
|
|
34
28
|
console.log('Failed to retrieve latest version info. Continuing execution.');
|
|
35
29
|
return;
|
|
36
30
|
}
|
|
37
31
|
latestCLIVersion = latestCLIVersion.substring(8).replace('\n', '');
|
|
38
|
-
if (
|
|
39
|
-
const updateAvailableMessage = `Update available ${
|
|
40
|
-
const npmUpdateAvailableCommand = `Run ${
|
|
41
|
-
const homebrewUpdateAvailableCommand = `Run ${
|
|
42
|
-
console.log((
|
|
32
|
+
if (semver.lt(APP_VERSION, latestCLIVersion)) {
|
|
33
|
+
const updateAvailableMessage = `Update available ${chalk.yellow(APP_VERSION)} → ${chalk.green(latestCLIVersion)}`;
|
|
34
|
+
const npmUpdateAvailableCommand = `Run ${chalk.cyan('npm i @contrast/contrast -g')} to update via npm`;
|
|
35
|
+
const homebrewUpdateAvailableCommand = `Run ${chalk.cyan('brew install contrastsecurity/tap/contrast')} to update via brew`;
|
|
36
|
+
console.log(boxen(`${updateAvailableMessage}\n${npmUpdateAvailableCommand}\n\n${homebrewUpdateAvailableCommand}`, {
|
|
43
37
|
titleAlignment: 'center',
|
|
44
38
|
margin: 1,
|
|
45
39
|
padding: 1,
|
|
@@ -47,9 +41,12 @@ async function findLatestCLIVersion(config) {
|
|
|
47
41
|
}));
|
|
48
42
|
}
|
|
49
43
|
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
44
|
+
};
|
|
45
|
+
const isCorrectNodeVersion = async (currentVersion) => {
|
|
46
|
+
return semver.satisfies(currentVersion, '>=16');
|
|
47
|
+
};
|
|
48
|
+
module.exports = {
|
|
49
|
+
getLatestVersion,
|
|
50
|
+
findLatestCLIVersion,
|
|
51
|
+
isCorrectNodeVersion
|
|
52
|
+
};
|
|
@@ -12,7 +12,7 @@ const MEDIUM = 'MEDIUM';
|
|
|
12
12
|
const HIGH = 'HIGH';
|
|
13
13
|
const CRITICAL = 'CRITICAL';
|
|
14
14
|
const APP_NAME = 'contrast';
|
|
15
|
-
const APP_VERSION = '1.0.
|
|
15
|
+
const APP_VERSION = '1.0.17';
|
|
16
16
|
const TIMEOUT = 120000;
|
|
17
17
|
const HIGH_COLOUR = '#ff9900';
|
|
18
18
|
const CRITICAL_COLOUR = '#e35858';
|
|
@@ -90,7 +90,7 @@ const en_locales = () => {
|
|
|
90
90
|
constantsHelp: 'Display this usage guide.',
|
|
91
91
|
constantsGradleMultiProject: 'Specify the sub project within your gradle application.',
|
|
92
92
|
constantsScan: 'Upload java binaries to the static scan service',
|
|
93
|
-
|
|
93
|
+
constantsDoNotWaitForScan: 'Do not wait for the result of the scan',
|
|
94
94
|
constantsProjectName: 'Contrast project name. If not specified, Contrast uses contrast.settings to identify the project or creates a project.',
|
|
95
95
|
constantsProjectId: 'The ID associated with a scan project. Replace <ProjectID> with the ID for the scan project. To find the ID, select a scan project in Contrast and locate the last number in the URL.',
|
|
96
96
|
constantsReport: 'Display vulnerability information for this application',
|
|
@@ -133,38 +133,15 @@ const en_locales = () => {
|
|
|
133
133
|
constantsHowToRunDev1: 'Begin with contrast auth to authenticate the CLI to perform actions',
|
|
134
134
|
constantsHowToRunDev2: 'After successful auth try the following command: contrast scan -f "<file>"',
|
|
135
135
|
constantsHowToRunDev3: 'Allowable languages are java (.jar and .war) and javascript (.js or .zip), if the language is not autodetected please use --language to specify',
|
|
136
|
-
constantsHowToRunContent1: 'You can run the tool on the command line and manually add the parameters, or you can put the parameters in a YAML file.',
|
|
137
|
-
constantsHowToRunContent2: 'If you are assessing an application that has not been instrumented by a Contrast agent you must first use the tool to register the application (Catalogue command). This will give you an application ID that you can then use in the Run Command.',
|
|
138
|
-
constantsHowToRunContent3: 'Allowable language values are JAVA, NODE, PYTHON, RUBY and GO.',
|
|
139
|
-
constantsManualInputHeader: 'Manual Input of Command:',
|
|
140
|
-
constantsManualInputCatalogue: 'Catalogue Command:',
|
|
141
|
-
constantsManualInputCatalogueInstruction: 'To analyse a new application not already instrumented by Contrast, run the following command:',
|
|
142
|
-
constantsManualInputCatalogueRun: 'After you run this command, you are provided a new application ID in the console. Use this ID in the Run command:',
|
|
143
|
-
constantsManualInputCatalogueRunTitle: 'Run Command:',
|
|
144
|
-
constantsManualInputCatalogueRunInstruction: 'To analyse an application catalogued by Contrast, run the following command:',
|
|
145
|
-
constantsYaml: 'Yaml:',
|
|
146
|
-
constantsYamlRunCommand: 'After you catalogue your application go to Run Command above.',
|
|
147
136
|
constantsOptions: 'Options',
|
|
148
|
-
constantsCatalogueCommand: '%s YourApiKey %s YourAuthorizationKey %s YourOrganizationId %s YourHost %s YourApplicationName %s YourApplicationLanguage',
|
|
149
|
-
constantsRunCommand: '%s YourApiKey %s YourAuthorizationKey %s YourOrganizationId %s YourHost %s YourApplicationId',
|
|
150
137
|
constantsSpecialCharacterWarning: 'Please Note: Parameters may need to be quoted to avoid issues with special characters.',
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
TlsHeader: 'TLS',
|
|
155
|
-
TlsBody: 'To enable TLS please use the YAML file with the following parameters:',
|
|
156
|
-
TlsKey: 'key: pathToKey',
|
|
157
|
-
TlsCert: 'cert: pathToCert',
|
|
158
|
-
TlsCaCert: 'cacert: pathToCaCert',
|
|
138
|
+
constantsProxyKey: 'Path to the Certificate Key',
|
|
139
|
+
constantsProxyCert: 'Path to the Cert file',
|
|
140
|
+
constantsProxyCaCert: 'Path to the CaCert file',
|
|
159
141
|
goReadProjectFile: 'Failed to read the project file @ "%s" because: "%s"',
|
|
160
|
-
|
|
161
|
-
goParseProjectFile: 'Failed to parse go mod graph output because: ',
|
|
162
|
-
mavenNotInstalledError: "'mvn' is not available. Please ensure you have Maven installed and available on your path.",
|
|
163
|
-
mavenDependencyTreeNonZero: 'Building maven dependancy tree failed with a non 0 exit code',
|
|
142
|
+
mavenDependencyTreeNonZero: 'Building maven dependency tree failed with a non 0 exit code',
|
|
164
143
|
gradleWrapperUnavailable: 'Gradle wrapper not found in root of project. Please ensure gradlew or gradlew.bat is in root of the project.',
|
|
165
|
-
gradleDependencyTreeNonZero: "Building gradle
|
|
166
|
-
yamlPathCamelCaseError: 'Warning: The "yamlPath" parameter will be deprecated in a future release. Please look at our documentation for further guidance.',
|
|
167
|
-
constantsSbom: 'Generate the Software Bill of Materials (SBOM) for the given application',
|
|
144
|
+
gradleDependencyTreeNonZero: "Building gradle dependency tree failed with a non 0 exit code. \n Please check you have the correct version of Java installed to compile your project? \n If running against a muti module project ensure you are using the '--sub-project' flag",
|
|
168
145
|
constantsMetadata: 'Define a set of key=value pairs (which conforms to RFC 2253) for specifying user-defined metadata associated with the application.',
|
|
169
146
|
constantsTags: 'Apply labels to an application. Labels must be formatted as a comma-delimited list. Example - label1,label2,label3',
|
|
170
147
|
constantsCode: 'Add the application code this application should use in the Contrast UI',
|
|
@@ -174,9 +151,7 @@ const en_locales = () => {
|
|
|
174
151
|
constantsIgnoreDev: 'Excludes developer dependencies from the results. All dependencies are included by default.',
|
|
175
152
|
constantsCommands: 'Commands',
|
|
176
153
|
constantsScanOptions: 'Scan Options',
|
|
177
|
-
sbomError: 'All required parameters are not present.',
|
|
178
154
|
sbomRetrievalError: 'Unable to retrieve Software Bill of Materials (SBOM)',
|
|
179
|
-
ignoreDevDep: 'No private libraries that are not scoped detected',
|
|
180
155
|
foundExistingProjectScan: 'Found existing project...',
|
|
181
156
|
projectCreatedScan: 'Project created',
|
|
182
157
|
uploadingScan: 'Uploading file to scan.',
|
|
@@ -190,7 +165,6 @@ const en_locales = () => {
|
|
|
190
165
|
specifyFileAuditNotFound: 'No files found for library analysis',
|
|
191
166
|
populateProjectIdMessage: 'project ID is %s',
|
|
192
167
|
genericServiceError: 'returned with status code %s',
|
|
193
|
-
projectIdError: 'Your project ID is %s please check this is correct',
|
|
194
168
|
permissionsError: 'You do not have the correct permissions here. \n Contact support@contrastsecurity.com to get this fixed.',
|
|
195
169
|
scanErrorFileMessage: 'We only accept the following file types: \nJava - .jar, .war \nJavaScript - .js or .zip files',
|
|
196
170
|
helpAuthSummary: 'Authenticate Contrast using your Github or Google account',
|
|
@@ -299,6 +273,7 @@ const en_locales = () => {
|
|
|
299
273
|
auditSBOMSaveSuccess: '\n Software Bill of Materials (SBOM) saved successfully',
|
|
300
274
|
auditNoFiletypeSpecifiedForSave: `\n ${chalk.yellow.bold('No file type specified for --save option to save audit results to. Use audit --help to see valid --save options.')}`,
|
|
301
275
|
auditBadFiletypeSpecifiedForSave: `\n ${chalk.yellow.bold('Bad file type specified for --save option. Use audit --help to see valid --save options.')}`,
|
|
276
|
+
auditServicesMessageForTS: 'View your vulnerable library list or full dependency tree in Contrast:',
|
|
302
277
|
auditReportWaiting: 'Waiting for report...',
|
|
303
278
|
auditReportFail: 'Report Retrieval Failed, please try again',
|
|
304
279
|
auditReportSuccessMessage: 'Report successfully retrieved',
|
|
@@ -306,10 +281,13 @@ const en_locales = () => {
|
|
|
306
281
|
auditSCAAnalysisBegins: 'Contrast SCA audit started',
|
|
307
282
|
auditSCAAnalysisComplete: 'Contrast audit complete',
|
|
308
283
|
commonHelpHeader: 'Need More Help?',
|
|
284
|
+
commonHelpEnterpriseHeader: 'Existing Contrast user?',
|
|
309
285
|
commonHelpCheckOutHeader: chalk.hex('#9DC184')('Check out:'),
|
|
310
286
|
commonHelpCheckOutText: ' https://support.contrastsecurity.com',
|
|
311
287
|
commonHelpLearnMoreHeader: chalk.hex('#9DC184')('Learn more at:'),
|
|
312
|
-
|
|
288
|
+
commonHelpLearnMoreEnterpriseHeader: chalk.hex('#9DC184')('Read our docs:'),
|
|
289
|
+
commonHelpLearnMoreText: ' https://www.contrastsecurity.com/developer ',
|
|
290
|
+
commonHelpLearnMoreEnterpriseText: ' https://docs.contrastsecurity.com/en/run-contrast-cli.html ',
|
|
313
291
|
commonHelpJoinDiscussionHeader: chalk.hex('#9DC184')('Join the discussion:'),
|
|
314
292
|
commonHelpJoinDiscussionText: ' https://dev.to/codesec',
|
|
315
293
|
...lambda
|