@contrast/contrast 1.0.15 → 1.0.16

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 (47) hide show
  1. package/dist/audit/languageAnalysisEngine/sendSnapshot.js +2 -2
  2. package/dist/audit/report/commonReportingFunctions.js +1 -19
  3. package/dist/{constants.js → cliConstants.js} +41 -31
  4. package/dist/commands/audit/auditConfig.js +2 -2
  5. package/dist/commands/audit/help.js +2 -2
  6. package/dist/commands/auth/auth.js +1 -1
  7. package/dist/commands/config/config.js +1 -1
  8. package/dist/commands/scan/sca/scaAnalysis.js +33 -20
  9. package/dist/common/HTTPClient.js +4 -2
  10. package/dist/constants/constants.js +1 -1
  11. package/dist/constants/locales.js +5 -30
  12. package/dist/index.js +5 -5
  13. package/dist/scaAnalysis/common/auditReport.js +3 -2
  14. package/dist/scaAnalysis/common/scaParserForGoAndJava.js +1 -1
  15. package/dist/scaAnalysis/javascript/scaServiceParser.js +2 -2
  16. package/dist/scaAnalysis/php/phpNewServicesMapper.js +3 -3
  17. package/dist/scaAnalysis/python/analysis.js +1 -1
  18. package/dist/scaAnalysis/repoMode/gradleParser.js +75 -0
  19. package/dist/scaAnalysis/repoMode/index.js +21 -0
  20. package/dist/scaAnalysis/repoMode/mavenParser.js +76 -0
  21. package/dist/scaAnalysis/ruby/analysis.js +4 -4
  22. package/dist/scan/help.js +1 -1
  23. package/dist/scan/scanConfig.js +1 -1
  24. package/package.json +2 -1
  25. package/src/audit/languageAnalysisEngine/sendSnapshot.js +2 -6
  26. package/src/audit/report/commonReportingFunctions.js +1 -23
  27. package/src/{constants.js → cliConstants.js} +47 -35
  28. package/src/commands/audit/auditConfig.ts +1 -1
  29. package/src/commands/audit/help.ts +1 -1
  30. package/src/commands/auth/auth.js +1 -1
  31. package/src/commands/config/config.js +1 -1
  32. package/src/commands/scan/sca/scaAnalysis.js +35 -25
  33. package/src/common/HTTPClient.js +4 -2
  34. package/src/constants/constants.js +1 -1
  35. package/src/constants/locales.js +6 -44
  36. package/src/index.ts +1 -1
  37. package/src/scaAnalysis/common/auditReport.js +3 -4
  38. package/src/scaAnalysis/common/scaParserForGoAndJava.js +1 -1
  39. package/src/scaAnalysis/javascript/scaServiceParser.js +8 -2
  40. package/src/scaAnalysis/php/phpNewServicesMapper.js +3 -3
  41. package/src/scaAnalysis/python/analysis.js +1 -1
  42. package/src/scaAnalysis/repoMode/gradleParser.js +88 -0
  43. package/src/scaAnalysis/repoMode/index.js +21 -0
  44. package/src/scaAnalysis/repoMode/mavenParser.js +89 -0
  45. package/src/scaAnalysis/ruby/analysis.js +4 -4
  46. package/src/scan/help.js +1 -1
  47. package/src/scan/scanConfig.js +1 -1
@@ -28,7 +28,7 @@ const getTimeout = config => {
28
28
  return 300;
29
29
  }
30
30
  };
31
- const pollForSnapshotCompletition = async (config, snapshotId, reportSpinner) => {
31
+ const pollForSnapshotCompletion = async (config, snapshotId, reportSpinner) => {
32
32
  const client = commonApi.getHttpClient(config);
33
33
  const startTime = performance.now();
34
34
  const timeout = getTimeout(config);
@@ -63,5 +63,5 @@ const pollForSnapshotCompletition = async (config, snapshotId, reportSpinner) =>
63
63
  }
64
64
  };
65
65
  module.exports = {
66
- pollForSnapshotCompletition: pollForSnapshotCompletition
66
+ pollForSnapshotCompletion
67
67
  };
@@ -132,13 +132,7 @@ function buildBody(cveArray, advice) {
132
132
  function getIssueRow(cveArray) {
133
133
  orderByHighestPriority(cveArray);
134
134
  const cveMessagesList = getIssueCveMsgList(cveArray);
135
- const cveNumbers = getSeverityCounts(cveArray);
136
- const numAndSeverityTypeDesc = getNumOfAndSeverityType(cveNumbers);
137
- return [
138
- chalk.bold('Issue'),
139
- ':',
140
- `${numAndSeverityTypeDesc} ${cveMessagesList.join(', ')}`
141
- ];
135
+ return [chalk.bold('Issue'), ':', `${cveMessagesList.join(', ')}`];
142
136
  }
143
137
  function gatherRemediationAdvice(guidance, libraryName, libraryVersion) {
144
138
  const guidanceModel = new ReportGuidanceModel();
@@ -152,17 +146,6 @@ function gatherRemediationAdvice(guidance, libraryName, libraryVersion) {
152
146
  function buildFormattedHeaderNum(contrastHeaderNum) {
153
147
  return `CONTRAST-${contrastHeaderNum.toString().padStart(3, '0')}`;
154
148
  }
155
- function getNumOfAndSeverityType(cveNumbers) {
156
- const { critical, high, medium, low, note } = cveNumbers;
157
- const criticalMsg = critical > 0 ? `${critical} Critical | ` : '';
158
- const highMsg = high > 0 ? `${high} High | ` : '';
159
- const mediumMsg = medium > 0 ? `${medium} Medium | ` : '';
160
- const lowMsg = low > 0 ? `${low} Low | ` : '';
161
- const noteMsg = note > 0 ? `${note} Note` : '';
162
- return `${criticalMsg} ${highMsg} ${mediumMsg} ${lowMsg} ${noteMsg}`
163
- .replace(/\s+/g, ' ')
164
- .trim();
165
- }
166
149
  const buildFooter = reportModelStructure => {
167
150
  const { critical, high, medium, low, note } = countVulnerableLibrariesBySeverity(reportModelStructure);
168
151
  const criticalMessage = chalk
@@ -257,7 +240,6 @@ module.exports = {
257
240
  getIssueRow,
258
241
  gatherRemediationAdvice,
259
242
  buildFormattedHeaderNum,
260
- getNumOfAndSeverityType,
261
243
  getIssueCveMsgList,
262
244
  getSeverityCounts,
263
245
  printNoVulnFoundMsg,
@@ -10,7 +10,46 @@ i18n.configure({
10
10
  },
11
11
  defaultLocale: 'en'
12
12
  });
13
+ const sharedOptionDefinitions = [
14
+ {
15
+ name: 'proxy',
16
+ description: '{bold ' +
17
+ i18n.__('constantsOptional') +
18
+ '}: ' +
19
+ i18n.__('constantsProxyServer')
20
+ },
21
+ {
22
+ name: 'key',
23
+ description: '{bold ' +
24
+ i18n.__('constantsOptional') +
25
+ '}: ' +
26
+ i18n.__('constantsProxyKey')
27
+ },
28
+ {
29
+ name: 'cacert',
30
+ description: '{bold ' +
31
+ i18n.__('constantsOptional') +
32
+ '}: ' +
33
+ i18n.__('constantsProxyCaCert')
34
+ },
35
+ {
36
+ name: 'cert',
37
+ description: '{bold ' +
38
+ i18n.__('constantsOptional') +
39
+ '}: ' +
40
+ i18n.__('constantsProxyCert')
41
+ },
42
+ {
43
+ name: 'ignore-cert-errors',
44
+ type: Boolean,
45
+ description: '{bold ' +
46
+ i18n.__('constantsOptional') +
47
+ '}:' +
48
+ i18n.__('constantsIgnoreCertErrors')
49
+ }
50
+ ];
13
51
  const scanOptionDefinitions = [
52
+ ...sharedOptionDefinitions,
14
53
  {
15
54
  name: 'name',
16
55
  alias: 'n',
@@ -88,13 +127,6 @@ const scanOptionDefinitions = [
88
127
  '}: ' +
89
128
  i18n.__('constantsHostId')
90
129
  },
91
- {
92
- name: 'proxy',
93
- description: '{bold ' +
94
- i18n.__('constantsOptional') +
95
- '}: ' +
96
- i18n.__('constantsProxyServer')
97
- },
98
130
  {
99
131
  name: 'fail',
100
132
  type: Boolean,
@@ -117,15 +149,7 @@ const scanOptionDefinitions = [
117
149
  description: '{bold ' +
118
150
  i18n.__('constantsOptional') +
119
151
  '}: ' +
120
- i18n.__('constantsProxyServer')
121
- },
122
- {
123
- name: 'ignore-cert-errors',
124
- type: Boolean,
125
- description: '{bold ' +
126
- i18n.__('constantsOptional') +
127
- '}:' +
128
- i18n.__('constantsIgnoreCertErrors')
152
+ i18n.__('constantsDoNotWaitForScan')
129
153
  },
130
154
  {
131
155
  name: 'verbose',
@@ -190,6 +214,7 @@ const configOptionDefinitions = [
190
214
  }
191
215
  ];
192
216
  const auditOptionDefinitions = [
217
+ ...sharedOptionDefinitions,
193
218
  {
194
219
  name: 'application-id',
195
220
  description: '{bold ' +
@@ -299,21 +324,6 @@ const auditOptionDefinitions = [
299
324
  '}: ' +
300
325
  i18n.__('constantsHostId')
301
326
  },
302
- {
303
- name: 'proxy',
304
- description: '{bold ' +
305
- i18n.__('constantsOptional') +
306
- '}: ' +
307
- i18n.__('constantsProxyServer')
308
- },
309
- {
310
- name: 'ignore-cert-errors',
311
- type: Boolean,
312
- description: '{bold ' +
313
- i18n.__('constantsOptional') +
314
- '}:' +
315
- i18n.__('constantsIgnoreCertErrors')
316
- },
317
327
  {
318
328
  name: 'save',
319
329
  alias: 's',
@@ -5,10 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getAuditConfig = void 0;
7
7
  const paramHandler_1 = __importDefault(require("../../utils/paramsUtil/paramHandler"));
8
- const constants_1 = __importDefault(require("../../constants"));
8
+ const cliConstants_1 = __importDefault(require("../../cliConstants"));
9
9
  const parsedCLIOptions_1 = require("../../utils/parsedCLIOptions");
10
10
  const getAuditConfig = async (contrastConf, command, argv) => {
11
- const auditParameters = await (0, parsedCLIOptions_1.getCommandLineArgsCustom)(contrastConf, command, argv, constants_1.default.commandLineDefinitions.auditOptionDefinitions);
11
+ const auditParameters = await (0, parsedCLIOptions_1.getCommandLineArgsCustom)(contrastConf, command, argv, cliConstants_1.default.commandLineDefinitions.auditOptionDefinitions);
12
12
  const paramsAuth = paramHandler_1.default.getAuth(auditParameters);
13
13
  return { ...paramsAuth, ...auditParameters };
14
14
  };
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.auditUsageGuide = void 0;
7
7
  const command_line_usage_1 = __importDefault(require("command-line-usage"));
8
8
  const i18n_1 = __importDefault(require("i18n"));
9
- const constants_1 = __importDefault(require("../../constants"));
9
+ const cliConstants_1 = __importDefault(require("../../cliConstants"));
10
10
  const commonHelp_1 = require("../../common/commonHelp");
11
11
  const auditUsageGuide = (0, command_line_usage_1.default)([
12
12
  {
@@ -30,7 +30,7 @@ const auditUsageGuide = (0, command_line_usage_1.default)([
30
30
  },
31
31
  {
32
32
  header: i18n_1.default.__('constantsAuditOptions'),
33
- optionList: constants_1.default.commandLineDefinitions.auditOptionDefinitions,
33
+ optionList: cliConstants_1.default.commandLineDefinitions.auditOptionDefinitions,
34
34
  hide: [
35
35
  'application-id',
36
36
  'application-name',
@@ -8,7 +8,7 @@ const i18n = require('i18n');
8
8
  const { returnOra, startSpinner, failSpinner, succeedSpinner } = require('../../utils/oraWrapper');
9
9
  const { TIMEOUT, AUTH_UI_URL } = require('../../constants/constants');
10
10
  const parsedCLIOptions = require('../../utils/parsedCLIOptions');
11
- const constants = require('../../constants');
11
+ const constants = require('../../cliConstants');
12
12
  const commandLineUsage = require('command-line-usage');
13
13
  const processAuth = async (argv, config) => {
14
14
  let authParams = await parsedCLIOptions.getCommandLineArgsCustom(config, 'auth', argv, constants.commandLineDefinitions.authOptionDefinitions);
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  const parsedCLIOptions = require('../../utils/parsedCLIOptions');
3
- const constants = require('../../constants');
3
+ const constants = require('../../cliConstants');
4
4
  const commandLineUsage = require('command-line-usage');
5
5
  const i18n = require('i18n');
6
6
  const processConfig = async (argv, config) => {
@@ -1,26 +1,28 @@
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 { supportedLanguages: { JAVA, GO, PYTHON, RUBY, JAVASCRIPT, NODE, PHP, DOTNET } } = require('../../../constants/constants');
7
- const goAnalysis = require('../../../scaAnalysis/go/goAnalysis');
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 rootFile = require('../../../audit/languageAnalysisEngine/getProjectRootFilenames');
20
- const path = require('path');
14
+ const { buildRepo } = 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');
24
26
  const processSca = async (config) => {
25
27
  config = await settingsHelper.getSettings(config);
26
28
  const startTime = performance.now();
@@ -39,6 +41,15 @@ const processSca = async (config) => {
39
41
  if (filesFound.length > 1 && pathWithFile) {
40
42
  filesFound = filesFound.filter(i => Object.values(i)[0].includes(path.basename(config.fileName)));
41
43
  }
44
+ if (config.mode === 'repo') {
45
+ try {
46
+ return buildRepo(config, filesFound[0]);
47
+ }
48
+ catch (e) {
49
+ console.log('Unable to build in repository mode. Check your project file');
50
+ process.exit(0);
51
+ }
52
+ }
42
53
  let messageToSend = undefined;
43
54
  if (filesFound.length === 1) {
44
55
  switch (Object.keys(filesFound[0])[0]) {
@@ -47,7 +58,7 @@ const processSca = async (config) => {
47
58
  config.language = JAVA;
48
59
  break;
49
60
  case JAVASCRIPT:
50
- messageToSend = await javascriptAnalysis.jsAnalysis(config, filesFound[0]);
61
+ messageToSend = await jsAnalysis.jsAnalysis(config, filesFound[0]);
51
62
  config.language = NODE;
52
63
  break;
53
64
  case PYTHON:
@@ -59,11 +70,11 @@ const processSca = async (config) => {
59
70
  config.language = RUBY;
60
71
  break;
61
72
  case PHP:
62
- messageToSend = phpAnalysis.phpAnalysis(config, filesFound[0]);
73
+ messageToSend = phpAnalysis(config, filesFound[0]);
63
74
  config.language = PHP;
64
75
  break;
65
76
  case GO:
66
- messageToSend = goAnalysis.goAnalysis(config, filesFound[0]);
77
+ messageToSend = goAnalysis(config, filesFound[0]);
67
78
  config.language = GO;
68
79
  break;
69
80
  case DOTNET:
@@ -96,7 +107,7 @@ const processSca = async (config) => {
96
107
  const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'));
97
108
  startSpinner(reportSpinner);
98
109
  const snapshotResponse = await treeUpload.commonSendSnapShot(messageToSend, config);
99
- await pollForSnapshotCompletition(config, snapshotResponse.id, reportSpinner);
110
+ await pollForSnapshotCompletion(config, snapshotResponse.id, reportSpinner);
100
111
  succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'));
101
112
  await vulnerabilityReportV2(config, snapshotResponse.id);
102
113
  if (config.save !== undefined) {
@@ -114,9 +125,11 @@ const processSca = async (config) => {
114
125
  throw new Error();
115
126
  }
116
127
  else {
117
- throw new Error(`multiple language files detected \n` +
118
- JSON.stringify(filesFound) +
119
- `\nplease use --file to audit one language only. Example: contrast audit --file package-lock.json`);
128
+ console.log(chalk.bold(`\nMultiple language files detected \n`));
129
+ filesFound.forEach(file => {
130
+ console.log(`${Object.keys(file)[0]} : `, Object.values(file)[0]);
131
+ });
132
+ throw new Error(`Please use --file to audit one language only. \nExample: contrast audit --file package-lock.json`);
120
133
  }
121
134
  }
122
135
  };
@@ -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 config option contrast.api.certificate.ca_file='${caCertFilePath}', msg: ${caFileContent.message}`);
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
- return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/applications/${config.applicationId}/reports/${reportId}`;
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`;
@@ -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';
15
+ const APP_VERSION = '1.0.16';
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
- constantsWaitForScan: 'Waits for the result of the scan',
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
- yamlCatalogueCommand: '%s PathToYaml',
152
- yamlCommand: '%s PathToYaml',
153
- agentProxyAndTlsEnabledError: 'Please Note: We currently do not support having a proxy server and TLS enabled at the same time.',
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
- goAnalysisError: 'GO analysis failed because: ',
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
142
  mavenDependencyTreeNonZero: 'Building maven dependancy 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
144
  gradleDependencyTreeNonZero: "Building gradle dependancy 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",
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',
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',
package/dist/index.js CHANGED
@@ -9,15 +9,15 @@ const processAudit_1 = require("./commands/audit/processAudit");
9
9
  const auth_1 = require("./commands/auth/auth");
10
10
  const config_1 = require("./commands/config/config");
11
11
  const processScan_1 = require("./commands/scan/processScan");
12
- const constants_1 = __importDefault(require("./constants"));
13
- const constants_2 = require("./constants/constants");
12
+ const cliConstants_1 = __importDefault(require("./cliConstants"));
13
+ const constants_1 = require("./constants/constants");
14
14
  const lambda_1 = require("./lambda/lambda");
15
15
  const getConfig_1 = require("./utils/getConfig");
16
16
  const versionChecker_1 = require("./common/versionChecker");
17
17
  const errorHandling_1 = require("./common/errorHandling");
18
18
  const telemetry_1 = require("./telemetry/telemetry");
19
- const { commandLineDefinitions: { mainUsageGuide, mainDefinition } } = constants_1.default;
20
- const config = (0, getConfig_1.localConfig)(constants_2.APP_NAME, constants_2.APP_VERSION);
19
+ const { commandLineDefinitions: { mainUsageGuide, mainDefinition } } = cliConstants_1.default;
20
+ const config = (0, getConfig_1.localConfig)(constants_1.APP_NAME, constants_1.APP_VERSION);
21
21
  const getMainOption = () => {
22
22
  const mainOptions = (0, command_line_args_1.default)(mainDefinition, {
23
23
  stopAtFirstUnknown: true,
@@ -40,7 +40,7 @@ const start = async () => {
40
40
  if (command === 'version' ||
41
41
  argvMain.includes('--v') ||
42
42
  argvMain.includes('--version')) {
43
- console.log(constants_2.APP_VERSION);
43
+ console.log(constants_1.APP_VERSION);
44
44
  await (0, versionChecker_1.findLatestCLIVersion)(config);
45
45
  return;
46
46
  }
@@ -5,6 +5,7 @@ const { assignBySeverity } = require('../../scan/formatScanOutput');
5
5
  const chalk = require('chalk');
6
6
  const { CE_URL } = require('../../constants/constants');
7
7
  const common = require('../../common/fail');
8
+ const i18n = require('i18n');
8
9
  const processAuditReport = (config, results) => {
9
10
  let severityCounts = {};
10
11
  if (results !== undefined) {
@@ -66,8 +67,8 @@ const formatScaServicesReport = (config, results) => {
66
67
  console.log(table.toString() + '\n');
67
68
  printVulnInfo(projectOverviewCount);
68
69
  if (config.host !== CE_URL) {
69
- console.log('\n' + chalk.bold('View your full dependency tree in Contrast:'));
70
- console.log(`${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/applications/${config.applicationId}/libs/dependency-tree`);
70
+ console.log('\n' + chalk.bold(i18n.__('auditServicesMessageForTS')));
71
+ console.log(`${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/applications/${config.applicationId}/libs`);
71
72
  }
72
73
  return projectOverviewCount;
73
74
  }
@@ -11,7 +11,7 @@ const parseDependenciesForSCAServices = dependencyTreeObject => {
11
11
  group: unParsedDependencyTree[dependency].group,
12
12
  version: unParsedDependencyTree[dependency].version,
13
13
  directDependency: unParsedDependencyTree[dependency].type === 'direct',
14
- isProduction: true,
14
+ productionDependency: true,
15
15
  dependencies: subDeps
16
16
  };
17
17
  parsedDependencyTree[dependency] = parsedDependency;
@@ -20,7 +20,7 @@ const npmCreateDepTree = (dependencyTree, combinedPackageJSONDep, packageLock, r
20
20
  name: key,
21
21
  version: getResolvedVersion(key, packageLock),
22
22
  group: null,
23
- isProduction: checkIfInPackageJSON(rawNode.packageJSON.dependencies, key),
23
+ productionDependency: checkIfInPackageJSON(rawNode.packageJSON.dependencies, key),
24
24
  directDependency: checkIfInPackageJSON(combinedPackageJSONDep, key),
25
25
  dependencies: createNPMChildDependencies(packageLock, key)
26
26
  };
@@ -35,7 +35,7 @@ const yarnCreateDepTree = (dependencyTree, combinedPackageJSONDep, packageLock,
35
35
  name: gav,
36
36
  version: getResolvedVersion(key, packageLock),
37
37
  group: null,
38
- isProduction: checkIfInPackageJSON(rawNode.packageJSON.dependencies, nag),
38
+ productionDependency: checkIfInPackageJSON(rawNode.packageJSON.dependencies, nag),
39
39
  directDependency: checkIfInPackageJSON(combinedPackageJSONDep, nag),
40
40
  dependencies: createChildDependencies(packageLock, key)
41
41
  };
@@ -5,7 +5,7 @@ const parsePHPLockFileForScaServices = phpLockFile => {
5
5
  const packagesDev = keyBy(phpLockFile['packages-dev'], 'name');
6
6
  return merge(buildDepTree(packages, true), buildDepTree(packagesDev, false));
7
7
  };
8
- const buildDepTree = (packages, isProduction) => {
8
+ const buildDepTree = (packages, productionDependency) => {
9
9
  const dependencyTree = {};
10
10
  for (const packagesKey in packages) {
11
11
  const currentObj = packages[packagesKey];
@@ -16,7 +16,7 @@ const buildDepTree = (packages, isProduction) => {
16
16
  name: name,
17
17
  version: currentObj.version,
18
18
  directDependency: true,
19
- isProduction: isProduction,
19
+ productionDependency: productionDependency,
20
20
  dependencies: []
21
21
  };
22
22
  const mergedChildDeps = merge(buildSubDepsIntoFlatStructure(currentObj.require), buildSubDepsIntoFlatStructure(currentObj['require-dev']));
@@ -39,7 +39,7 @@ const buildSubDepsIntoFlatStructure = childDeps => {
39
39
  name: name,
40
40
  version: version,
41
41
  directDependency: false,
42
- isProduction: false,
42
+ productionDependency: false,
43
43
  dependencies: []
44
44
  };
45
45
  }
@@ -32,7 +32,7 @@ const scaPythonParser = pythonDependencies => {
32
32
  pythonParsedDeps[key].version = pythonDependencies[key].version.replace('==', '');
33
33
  pythonParsedDeps[key].group = null;
34
34
  pythonParsedDeps[key].name = key;
35
- pythonParsedDeps[key].isProduction = true;
35
+ pythonParsedDeps[key].productionDependency = true;
36
36
  pythonParsedDeps[key].dependencies = [];
37
37
  pythonParsedDeps[key].directDependency = true;
38
38
  }
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ const g2js = require('gradle-to-js/lib/parser');
3
+ const readBuildGradleFile = async (project) => {
4
+ const gradleFilePath = project.cwd + '/build.gradle';
5
+ return await g2js.parseFile(gradleFilePath);
6
+ };
7
+ const filterGav = (groupId, artifactId, version, gradleJson) => {
8
+ if (groupId === '') {
9
+ if (artifactId.includes(':')) {
10
+ groupId = artifactId.split(':')[0].replace("'", '');
11
+ }
12
+ }
13
+ if (version === '') {
14
+ if (artifactId.includes(':')) {
15
+ artifactId.split(':').length > 2
16
+ ? (version = artifactId.split(':')[2].replace("'", ''))
17
+ : (version = null);
18
+ }
19
+ }
20
+ if (artifactId.split(':').length > 1) {
21
+ artifactId = artifactId.split(':')[1].replace("'", '');
22
+ }
23
+ if (version === null) {
24
+ version = getVersion(gradleJson, groupId);
25
+ }
26
+ return { groupId, artifactId, version };
27
+ };
28
+ const parseGradleJson = gradleJson => {
29
+ let deps = gradleJson.dependencies;
30
+ let dependencyTree = {};
31
+ if (deps === undefined) {
32
+ console.log('Unable to find any dependencies in your project file.');
33
+ process.exit(0);
34
+ }
35
+ for (let a in deps) {
36
+ let dependencyType = deps[a].type;
37
+ if (dependencyType === 'implementation') {
38
+ let groupId = deps[a].group;
39
+ let artifactId = deps[a].name;
40
+ let version = deps[a].version;
41
+ let filteredGav = filterGav(groupId, artifactId, version, gradleJson);
42
+ let depName = filteredGav.groupId +
43
+ '/' +
44
+ filteredGav.artifactId +
45
+ '@' +
46
+ filteredGav.version;
47
+ let parsedDependency = {
48
+ name: filteredGav.artifactId,
49
+ group: filteredGav.groupId,
50
+ version: filteredGav.version,
51
+ directDependency: true,
52
+ isProduction: true,
53
+ dependencies: []
54
+ };
55
+ dependencyTree[depName] = parsedDependency;
56
+ }
57
+ }
58
+ return dependencyTree;
59
+ };
60
+ const getVersion = (gradleJson, dependencyWithoutVersion) => {
61
+ let parentVersion = gradleJson.plugins[0].version;
62
+ let parentGroupName = gradleJson.plugins[0].id;
63
+ if (parentGroupName === dependencyWithoutVersion) {
64
+ return parentVersion;
65
+ }
66
+ else {
67
+ return null;
68
+ }
69
+ };
70
+ module.exports = {
71
+ readBuildGradleFile,
72
+ parseGradleJson,
73
+ getVersion,
74
+ filterGav
75
+ };
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ const mavenParser = require('./mavenParser');
3
+ const gradleParser = require('./gradleParser');
4
+ const { determineProjectTypeAndCwd } = require('../java/analysis');
5
+ const buildRepo = async (config, languageFiles) => {
6
+ const project = determineProjectTypeAndCwd(languageFiles.JAVA, config);
7
+ if (project.projectType === 'maven') {
8
+ let jsonPomFile = mavenParser.readPomFile(project);
9
+ mavenParser.parsePomFile(jsonPomFile);
10
+ }
11
+ else if (project.projectType === 'gradle') {
12
+ const gradleJson = gradleParser.readBuildGradleFile(project);
13
+ gradleParser.parseGradleJson(await gradleJson);
14
+ }
15
+ else {
16
+ console.log('Unable to read project files.');
17
+ }
18
+ };
19
+ module.exports = {
20
+ buildRepo
21
+ };