@contrast/contrast 1.0.21 → 1.0.23

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 (62) hide show
  1. package/dist/audit/report/commonReportingFunctions.js +1 -1
  2. package/dist/audit/save.js +10 -4
  3. package/dist/cliConstants.js +4 -3
  4. package/dist/commands/audit/help.js +3 -1
  5. package/dist/commands/audit/processAudit.js +1 -1
  6. package/dist/commands/auth/auth.js +5 -0
  7. package/dist/commands/learn/processLearn.js +1 -1
  8. package/dist/common/HTTPClient.js +9 -0
  9. package/dist/constants/constants.js +1 -1
  10. package/dist/constants/lambda.js +1 -0
  11. package/dist/constants/locales.js +15 -14
  12. package/dist/lambda/help.js +3 -0
  13. package/dist/lambda/scanRequest.js +12 -1
  14. package/dist/sbom/generateSbom.js +7 -0
  15. package/dist/scaAnalysis/common/commonReportingFunctionsSca.js +3 -3
  16. package/dist/scaAnalysis/common/treeUpload.js +8 -19
  17. package/dist/scaAnalysis/go/goAnalysis.js +1 -6
  18. package/dist/scaAnalysis/java/analysis.js +24 -32
  19. package/dist/scaAnalysis/java/index.js +1 -6
  20. package/dist/scaAnalysis/javascript/analysis.js +11 -33
  21. package/dist/scaAnalysis/javascript/index.js +14 -4
  22. package/dist/scaAnalysis/javascript/scaServiceParser.js +3 -3
  23. package/dist/scaAnalysis/php/index.js +2 -8
  24. package/dist/scaAnalysis/python/analysis.js +4 -10
  25. package/dist/scaAnalysis/python/index.js +1 -6
  26. package/dist/scaAnalysis/ruby/analysis.js +1 -10
  27. package/dist/scaAnalysis/ruby/index.js +1 -6
  28. package/dist/scaAnalysis/scaAnalysis.js +17 -59
  29. package/dist/scan/help.js +3 -0
  30. package/package.json +2 -5
  31. package/src/audit/report/commonReportingFunctions.js +1 -1
  32. package/src/audit/save.js +11 -9
  33. package/src/cliConstants.js +4 -3
  34. package/src/commands/audit/help.js +3 -1
  35. package/src/commands/audit/processAudit.js +2 -5
  36. package/src/commands/auth/auth.js +5 -0
  37. package/src/commands/learn/processLearn.js +1 -1
  38. package/src/common/HTTPClient.js +11 -0
  39. package/src/constants/constants.js +1 -1
  40. package/src/constants/lambda.js +1 -0
  41. package/src/constants/locales.js +15 -14
  42. package/src/index.ts +0 -1
  43. package/src/lambda/help.ts +3 -0
  44. package/src/lambda/scanRequest.ts +27 -2
  45. package/src/sbom/generateSbom.ts +8 -0
  46. package/src/scaAnalysis/common/commonReportingFunctionsSca.js +3 -3
  47. package/src/scaAnalysis/common/treeUpload.js +12 -20
  48. package/src/scaAnalysis/go/goAnalysis.js +1 -6
  49. package/src/scaAnalysis/java/analysis.js +29 -34
  50. package/src/scaAnalysis/java/index.js +1 -6
  51. package/src/scaAnalysis/javascript/analysis.js +19 -34
  52. package/src/scaAnalysis/javascript/index.js +27 -4
  53. package/src/scaAnalysis/javascript/scaServiceParser.js +3 -3
  54. package/src/scaAnalysis/php/index.js +2 -8
  55. package/src/scaAnalysis/python/analysis.js +4 -10
  56. package/src/scaAnalysis/python/index.js +1 -6
  57. package/src/scaAnalysis/ruby/analysis.js +1 -11
  58. package/src/scaAnalysis/ruby/index.js +1 -6
  59. package/src/scaAnalysis/scaAnalysis.js +25 -85
  60. package/src/scan/help.js +3 -0
  61. package/dist/utils/settingsHelper.js +0 -24
  62. package/src/utils/settingsHelper.js +0 -26
@@ -122,7 +122,7 @@ function buildHeader(highestSeverity, contrastHeaderNum, libraryName, version, n
122
122
  function buildBody(cveArray, advice) {
123
123
  const orderedCvesWithSeverityAssigned = orderByHighestPriority(cveArray.map(cve => findCVESeverity(cve)));
124
124
  const issueMessage = getIssueRow(orderedCvesWithSeverityAssigned);
125
- const minOrMax = advice.maximum ? advice.maximum : advice.minimum;
125
+ const minOrMax = advice.minimum ? advice.minimum : advice.maximum;
126
126
  const displayAdvice = minOrMax
127
127
  ? `Change to version ${chalk.bold(minOrMax)}`
128
128
  : 'No recommendation is available according to our data. Upgrade to the latest stable is the best advice we can give.';
@@ -19,18 +19,24 @@ async function auditSave(config, reportId) {
19
19
  break;
20
20
  }
21
21
  if (fileFormat) {
22
- if (config.experimental) {
23
- save.saveFile(config, fileFormat, await sbom.generateSCASbom(config, fileFormat, reportId));
22
+ if (config.legacy === false) {
23
+ const sbomResponse = await sbom.generateSCASbom(config, fileFormat, reportId);
24
+ if (sbomResponse) {
25
+ save.saveFile(config, fileFormat, sbomResponse);
26
+ }
24
27
  }
25
28
  else {
26
- save.saveFile(config, fileFormat, await sbom.generateSbom(config, fileFormat));
29
+ const sbomResponse = await sbom.generateSbom(config, fileFormat);
30
+ if (sbomResponse) {
31
+ save.saveFile(config, fileFormat, sbomResponse);
32
+ }
27
33
  }
28
34
  const filename = `${config.applicationId}-sbom-${fileFormat}.json`;
29
35
  if (fs.existsSync(filename)) {
30
36
  console.log(i18n.__('auditSBOMSaveSuccess') + ` - ${filename}`);
31
37
  }
32
38
  else {
33
- console.log(chalk.yellow.bold(`\n Unable to save ${filename} Software Bill of Materials (SBOM)`));
39
+ console.log(chalk.yellow.bold(`\nUnable to save ${filename} Software Bill of Materials (SBOM)`));
34
40
  }
35
41
  }
36
42
  else {
@@ -186,6 +186,7 @@ const scanOptionDefinitions = [
186
186
  ];
187
187
  const authOptionDefinitions = [
188
188
  ...sharedConnectionOptionDefinitions,
189
+ ...sharedCertOptionDefinitions,
189
190
  {
190
191
  name: 'help',
191
192
  alias: 'h',
@@ -378,11 +379,11 @@ const mainUsageGuide = commandLineUsage([
378
379
  header: i18n.__('constantsCommands'),
379
380
  content: [
380
381
  { name: i18n.__('authName'), summary: i18n.__('helpAuthSummary') },
382
+ { name: i18n.__('configName'), summary: i18n.__('helpConfigSummary') },
383
+ { name: i18n.__('versionName'), summary: i18n.__('helpVersionSummary') },
384
+ { name: i18n.__('auditName'), summary: i18n.__('helpAuditSummary') },
381
385
  { name: i18n.__('scanName'), summary: i18n.__('helpScanSummary') },
382
386
  { name: i18n.__('lambdaName'), summary: i18n.__('helpLambdaSummary') },
383
- { name: i18n.__('auditName'), summary: i18n.__('helpAuditSummary') },
384
- { name: i18n.__('versionName'), summary: i18n.__('helpVersionSummary') },
385
- { name: i18n.__('configName'), summary: i18n.__('helpConfigSummary') },
386
387
  { name: i18n.__('helpName'), summary: i18n.__('helpSummary') },
387
388
  { name: i18n.__('learnName'), summary: i18n.__('helpLearnSummary') }
388
389
  ]
@@ -4,6 +4,9 @@ const i18n = require('i18n');
4
4
  const constants = require('../../cliConstants');
5
5
  const { commonHelpLinks } = require('../../common/commonHelp');
6
6
  const auditUsageGuide = commandLineUsage([
7
+ {
8
+ header: i18n.__('constantsHeader')
9
+ },
7
10
  {
8
11
  header: i18n.__('auditHeader'),
9
12
  content: [i18n.__('auditHeaderMessage')]
@@ -48,7 +51,6 @@ const auditUsageGuide = commandLineUsage([
48
51
  'code',
49
52
  'maven-settings-path',
50
53
  'language',
51
- 'experimental',
52
54
  'app-groups',
53
55
  'metadata',
54
56
  'track',
@@ -9,7 +9,7 @@ const processAudit = async (contrastConf, argvMain) => {
9
9
  printHelpMessage();
10
10
  process.exit(0);
11
11
  }
12
- const config = await auditConfig.getAuditConfig(contrastConf, 'audit', argvMain);
12
+ let config = await auditConfig.getAuditConfig(contrastConf, 'audit', argvMain);
13
13
  await scaController.processSca(config);
14
14
  if (!config.fingerprint) {
15
15
  postRunMessage('audit');
@@ -81,6 +81,11 @@ const authUsageGuide = commandLineUsage([
81
81
  {
82
82
  header: i18n.__('constantsAuthUsageHeader'),
83
83
  content: [i18n.__('constantsAuthUsageContents')]
84
+ },
85
+ {
86
+ header: i18n.__('constantsAdvancedOptions'),
87
+ optionList: constants.commandLineDefinitions.authOptionDefinitions,
88
+ hide: ['organization-id', 'api-key', 'authorization', 'host']
84
89
  }
85
90
  ]);
86
91
  const checkForCustomCredentials = authParams => {
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  const { openLearnPage } = require('./learn');
3
3
  async function processLearn() {
4
- console.log('Opening develop central...');
4
+ console.log('Opening Contrast’s Secure Code Learning Hub...');
5
5
  console.log('If the page does not open you can open it directly via https://www.contrastsecurity.com/developer/learn');
6
6
  return openLearnPage();
7
7
  }
@@ -191,6 +191,12 @@ HTTPClient.prototype.scaServiceIngests = function scaServiceIngests(config) {
191
191
  options.url = url;
192
192
  return requestUtils.sendRequest({ method: 'get', options });
193
193
  };
194
+ HTTPClient.prototype.scaServiceHealth = function scaServiceIngests(config) {
195
+ const options = _.cloneDeep(this.requestOptions);
196
+ let url = createScaServiceHealthURL(config);
197
+ options.url = url;
198
+ return requestUtils.sendRequest({ method: 'get', options });
199
+ };
194
200
  HTTPClient.prototype.getReportById = function getReportById(config, reportId) {
195
201
  const options = _.cloneDeep(this.requestOptions);
196
202
  if (config.ignoreDev) {
@@ -342,6 +348,9 @@ function createScaServiceReportStatusURL(config, reportId) {
342
348
  function createScaServiceIngestsURL(config) {
343
349
  return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/applications/${config.applicationId}/libraries/ingests`;
344
350
  }
351
+ function createScaServiceHealthURL(config) {
352
+ return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/health`;
353
+ }
345
354
  function createScaServiceIngestURL(config) {
346
355
  let baseUrl = `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/applications/${config.applicationId}/libraries/ingests/tree`;
347
356
  baseUrl = config.track ? baseUrl.concat('?persist=true') : baseUrl;
@@ -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.21';
15
+ const APP_VERSION = '1.0.23';
16
16
  const TIMEOUT = 120000;
17
17
  const HIGH_COLOUR = '#ff9900';
18
18
  const CRITICAL_COLOUR = '#e35858';
@@ -48,6 +48,7 @@ const lambda = {
48
48
  internal_error: 'Internal error',
49
49
  inactive_account: 'Scanning a function of an inactive account is not supported',
50
50
  not_supported_runtime: 'Scanning resource of runtime "{{runtime}}" is not supported.\nSupported runtimes: {{supportedRuntimes}}',
51
+ not_supported_lambda: 'This function cannot be scanned',
51
52
  not_supported_onboard_account: 'Scanning a function of onboard account is not supported',
52
53
  scan_lock: 'Other scan is still running. Please wait until the previous scan finishes',
53
54
  unsupported: 'unsupported',
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  const { lambda } = require('./lambda');
3
3
  const chalk = require('chalk');
4
+ const { APP_VERSION } = require('./constants');
4
5
  const en_locales = () => {
5
6
  return {
6
7
  snapshotFailureHeader: 'FAIL',
@@ -52,7 +53,7 @@ const en_locales = () => {
52
53
  failThresholdOptionErrorMessage: 'More than 0 vulnerabilities found',
53
54
  failSeverityOptionErrorMessage: ' FAIL - Results detected vulnerabilities over accepted severity level',
54
55
  constantsSeverity: 'Use with "contrast scan --fail --severity high" or "contrast audit --fail --severity high". Set the severity level to detect vulnerabilities or dependencies. Severity levels are critical, high, medium, low or note.',
55
- constantsHeader: 'Contrast CLI',
56
+ constantsHeader: `Contrast CLI @ v${APP_VERSION}`,
56
57
  configHeader2: 'Config options',
57
58
  clearHeader: '-c, --clear',
58
59
  clearContent: 'Removes stored credentials',
@@ -107,10 +108,10 @@ const en_locales = () => {
107
108
  genericServiceError: 'returned with status code %s',
108
109
  permissionsError: 'You do not have the correct permissions here. \n Contact support@contrastsecurity.com to get this fixed.',
109
110
  scanErrorFileMessage: 'We only accept the following file types: \nJava - .jar, .war \nJavaScript - .js or .zip files',
110
- helpAuthSummary: 'Authenticate Contrast using your Github or Google account',
111
- helpAuditSummary: 'Searches for a suitable file in the working directory to perform a security audit of dependencies and returns the results. [Contrast audit --help (for options).]',
112
- helpScanSummary: 'Searches for a .jar, .war, .js, or .zip file in the working directory, uploads files for analysis, and returns the results. [For further help/options, enter scan --help]',
113
- helpLambdaSummary: 'Performs a static security scan on an AWS lambda function. lambda --help (for options)',
111
+ helpAuthSummary: 'Authenticate Contrast using your Github or Google account OR include credentials if you are an existing licensed Contrast user.',
112
+ helpAuditSummary: 'Searches for a suitable file in the working directory to perform a security audit of dependencies and returns the results. \n[audit --help for options] Java, .NET, Node, Ruby, Python, Go, PHP are supported. ',
113
+ helpScanSummary: 'Searches for a .jar, .war, .js, or .zip file in the working directory, uploads files for analysis, and returns the results. \n[scan --help for options] Java, .NET, .NET Core, JavaScript are supported. ',
114
+ helpLambdaSummary: 'Performs a static security scan on an AWS lambda function. [lambda --help for options] AWS Lambda - Java & Python are supported. ',
114
115
  helpVersionSummary: 'Displays version of Contrast CLI',
115
116
  helpConfigSummary: 'Displays stored credentials',
116
117
  helpSummary: 'Displays usage guide',
@@ -122,7 +123,7 @@ const en_locales = () => {
122
123
  configName: 'config',
123
124
  helpName: 'help',
124
125
  learnName: 'learn',
125
- helpLearnSummary: 'launches Contrast’s Secure Code Learning Hub.',
126
+ helpLearnSummary: 'Launches Contrast’s Secure Code Learning Hub.',
126
127
  fingerprintName: 'assess repo to see how many languages it can detect. For use in pipeline only.',
127
128
  depthOption: 'can set how deep in the file system the cli looks for language files',
128
129
  scanOptionsLanguageSummary: 'Valid values are JAVA, JAVASCRIPT and DOTNET',
@@ -140,7 +141,7 @@ const en_locales = () => {
140
141
  chalk.bold('\ncontrast audit') +
141
142
  ' to find vulnerabilities in your open source dependencies.' +
142
143
  '\nSupports Java, .NET, Node, Ruby, Python, Go and PHP.' +
143
- '\nOur CLI runs native build tools to generate a complete dependency tree.' +
144
+ '\n\nOur CLI runs native build tools to generate a complete dependency tree.' +
144
145
  '\nIf you are running on untrusted code, consider running in a sandbox.\n' +
145
146
  chalk.bold('\ncontrast lambda') +
146
147
  ' to secure your AWS serverless functions. \nSupports Java and Python \n' +
@@ -152,7 +153,7 @@ const en_locales = () => {
152
153
  foundDetailedVulnerabilities: chalk.bold('%s') + ' | ' + chalk.bold('%s') + ' | %s | %s | %s ',
153
154
  searchingScanFileDirectory: 'Searching for file to scan from %s...',
154
155
  searchingAuditFileDirectory: 'Searching for package manager files from %s...',
155
- scanHeader: 'Contrast Scan CLI',
156
+ scanHeader: `Contrast Scan CLI`,
156
157
  authHeader: 'Auth',
157
158
  lambdaHeader: 'Contrast Lambda CLI',
158
159
  lambdaSummary: 'Performs static security scan on an AWS Lambda Function.\nProduces CVE (Vulnerable Dependencies) and Least Privilege violations/remediation results.',
@@ -183,7 +184,7 @@ const en_locales = () => {
183
184
  connectionError: 'An error has occurred when trying to get the Project Id please check your internet connection or provide the Project Id manually',
184
185
  internalServerErrorHeader: '500 error - Internal server error',
185
186
  resourceLockedErrorHeader: '423 error - Resource is locked',
186
- auditHeader: 'Contrast audit help',
187
+ auditHeader: 'Contrast Audit CLI',
187
188
  auditHeaderMessage: "Use 'contrast audit' to analyze a project’s dependencies for vulnerabilities.",
188
189
  constantsAuditPrerequisitesContentSupportedLanguages: 'Supported languages and their requirements are:',
189
190
  constantsAuditPrerequisitesJavaContentMessage: `
@@ -224,14 +225,14 @@ const en_locales = () => {
224
225
  commonHelpLearnMoreEnterpriseText: ' https://docs.contrastsecurity.com/en/run-contrast-cli.html ',
225
226
  commonHelpJoinDiscussionHeader: chalk.hex('#9DC184')('Join the discussion:'),
226
227
  commonHelpJoinDiscussionText: ' https://www.contrastsecurity.com/developer/community',
227
- commonHelpLearnHeader: chalk.hex('#ffe599')('\rWant to UP your game?') +
228
+ commonHelpLearnHeader: chalk.hex('#ffe599')('\r Want to UP your game?') +
228
229
  " type 'contrast learn'",
229
- commonHelpLearnText: `\n🎓 Advance your security knowledge and become an ${chalk.hex('#ffd966')('All-star coder')} ⭐ with ${chalk.bold('Contrast Secure Code Learning Hub.')} 😺`,
230
+ commonHelpLearnText: `\n💰 Advance your security knowledge and become an ${chalk.hex('#ffd966')('All-star coder')} ⭐ with ${chalk.bold('Contrast Secure Code Learning Hub.')} 😺`,
230
231
  authCommand: {
231
232
  credentialsAccepted: {
232
- title: 'Credentials accepted',
233
- body: 'Now run contrast audit, lambda or scan',
234
- extra: 'Or contrast help for full list of commands'
233
+ title: 'Credentials successfully saved',
234
+ body: `\n${chalk.bold('Contrast CLI')}`,
235
+ extra: 'Scan, secure and ship your code in minutes.'
235
236
  },
236
237
  credentialsMissing: {
237
238
  title: 'Credentials missing',
@@ -8,6 +8,9 @@ const command_line_usage_1 = __importDefault(require("command-line-usage"));
8
8
  const i18n_1 = __importDefault(require("i18n"));
9
9
  const commonHelp_1 = require("../common/commonHelp");
10
10
  const lambdaUsageGuide = (0, command_line_usage_1.default)([
11
+ {
12
+ header: i18n_1.default.__('constantsHeader')
13
+ },
11
14
  {
12
15
  header: i18n_1.default.__('lambdaHeader'),
13
16
  content: [i18n_1.default.__('lambdaSummary')]
@@ -14,7 +14,9 @@ const commonApi_1 = require("../utils/commonApi");
14
14
  const logUtils_1 = require("./logUtils");
15
15
  const cliError_1 = require("./cliError");
16
16
  const constants_1 = require("./constants");
17
- const sendScanPostRequest = async (config, params, functionsEvent, showProgress = false) => {
17
+ const requestUtils_1 = require("../utils/requestUtils");
18
+ const MAX_RETRIES = 2;
19
+ const sendScanPostRequest = async (config, params, functionsEvent, showProgress = false, retryNumber = 0) => {
18
20
  const client = (0, commonApi_1.getHttpClient)(config);
19
21
  if (showProgress) {
20
22
  (0, logUtils_1.log)(i18n_1.default.__('sendingScanRequest', { icon: log_symbols_1.default.success }));
@@ -38,6 +40,15 @@ const sendScanPostRequest = async (config, params, functionsEvent, showProgress
38
40
  });
39
41
  errorCode = false;
40
42
  break;
43
+ case 'not_supported_lambda':
44
+ description = i18n_1.default.__(errorCode);
45
+ errorCode = false;
46
+ break;
47
+ default:
48
+ if (retryNumber < MAX_RETRIES) {
49
+ await (0, requestUtils_1.sleep)(3 * 1000);
50
+ return sendScanPostRequest(config, params, functionsEvent, showProgress, retryNumber + 1);
51
+ }
41
52
  }
42
53
  throw new cliError_1.CliError(constants_1.ERRORS.FAILED_TO_START_SCAN, {
43
54
  statusCode,
@@ -10,8 +10,14 @@ const generateSbom = (config, type) => {
10
10
  if (res.statusCode === 200) {
11
11
  return res.body;
12
12
  }
13
+ else if (res.statusCode === 403) {
14
+ console.log('\nUnable to retrieve Software Bill of Materials (SBOM)');
15
+ console.log(`Please ensure OSS is enabled for your organization - org-id ${config.organizationId} and app ${config.applicationId}`);
16
+ return undefined;
17
+ }
13
18
  else {
14
19
  console.log('Unable to retrieve Software Bill of Materials (SBOM)');
20
+ return undefined;
15
21
  }
16
22
  })
17
23
  .catch((err) => {
@@ -29,6 +35,7 @@ const generateSCASbom = (config, type, reportId) => {
29
35
  }
30
36
  else {
31
37
  console.log('Unable to retrieve Software Bill of Materials (SBOM)');
38
+ return undefined;
32
39
  }
33
40
  })
34
41
  .catch((err) => {
@@ -104,9 +104,9 @@ function getIssueRow(cveArray) {
104
104
  return [chalk.bold('Issue'), ':', `${cveMessagesList.join(', ')}`];
105
105
  }
106
106
  function getAdviceRow(advice) {
107
- const latestOrClosest = advice.latestStableVersion
108
- ? advice.latestStableVersion
109
- : advice.closestStableVersion;
107
+ const latestOrClosest = advice.closestStableVersion
108
+ ? advice.closestStableVersion
109
+ : advice.latestStableVersion;
110
110
  const displayAdvice = latestOrClosest
111
111
  ? `Change to version ${chalk.bold(latestOrClosest)}`
112
112
  : 'No recommendation is available according to our data. Upgrade to the latest stable is the best advice we can give.';
@@ -3,13 +3,11 @@ const commonApi = require('../../utils/commonApi');
3
3
  const { APP_VERSION } = require('../../constants/constants');
4
4
  const commonSendSnapShot = async (analysis, config) => {
5
5
  let requestBody = {};
6
- config.experimental === true
7
- ? (requestBody = sendToSCAServices(config, analysis))
8
- : (requestBody = {
9
- appID: config.applicationId,
10
- cliVersion: APP_VERSION,
11
- snapshot: analysis
12
- });
6
+ requestBody = {
7
+ appID: config.applicationId,
8
+ cliVersion: APP_VERSION,
9
+ snapshot: analysis
10
+ };
13
11
  const client = commonApi.getHttpClient(config);
14
12
  return client
15
13
  .sendSnapshot(requestBody, config)
@@ -18,6 +16,9 @@ const commonSendSnapShot = async (analysis, config) => {
18
16
  return res.body;
19
17
  }
20
18
  else {
19
+ if (res.statusCode === 403) {
20
+ throw new Error(`🛑 Contrast audit failed \nPlease check you have the right permissions and the application ${config.applicationName ? config.applicationName : ''} has not been archived.`.replace(/ +(?= )/g, ''));
21
+ }
21
22
  throw new Error(res.statusCode + ` error processing dependencies`);
22
23
  }
23
24
  })
@@ -25,18 +26,6 @@ const commonSendSnapShot = async (analysis, config) => {
25
26
  throw err;
26
27
  });
27
28
  };
28
- const sendToSCAServices = (config, analysis) => {
29
- return {
30
- applicationId: config.applicationId,
31
- dependencyTree: analysis,
32
- organizationId: config.organizationId,
33
- language: config.language,
34
- tool: {
35
- name: 'Contrast Codesec',
36
- version: APP_VERSION
37
- }
38
- };
39
- };
40
29
  module.exports = {
41
30
  commonSendSnapShot
42
31
  };
@@ -7,12 +7,7 @@ const goAnalysis = config => {
7
7
  try {
8
8
  const rawGoDependencies = goReadDepFile.getGoDependencies(config);
9
9
  const parsedGoDependencies = goParseDeps.parseGoDependencies(rawGoDependencies);
10
- if (config.experimental) {
11
- return parseDependenciesForSCAServices(parsedGoDependencies);
12
- }
13
- else {
14
- return createGoTSMessage(parsedGoDependencies);
15
- }
10
+ return createGoTSMessage(parsedGoDependencies);
16
11
  }
17
12
  catch (e) {
18
13
  console.log(e.message.toString());
@@ -4,8 +4,6 @@ const spawn = require('cross-spawn');
4
4
  const path = require('path');
5
5
  const i18n = require('i18n');
6
6
  const fs = require('fs');
7
- const readLine = require('readline');
8
- const paramHandler = require('../../utils/paramsUtil/paramHandler');
9
7
  const MAVEN = 'maven';
10
8
  const GRADLE = 'gradle';
11
9
  const determineProjectTypeAndCwd = (files, config) => {
@@ -25,26 +23,25 @@ const determineProjectTypeAndCwd = (files, config) => {
25
23
  return projectData;
26
24
  };
27
25
  const buildMaven = (config, projectData, timeout) => {
28
- let cmdStdout;
29
- try {
30
- let command = 'mvn';
31
- let args = ['dependency:tree', '-B'];
32
- if (config.mavenSettingsPath) {
33
- args.push('-s');
34
- args.push(config.mavenSettingsPath);
35
- }
36
- cmdStdout = spawn
37
- .sync(command, args, {
38
- env: process.env,
39
- cwd: projectData.cwd,
40
- timeout
41
- })
42
- .stdout.toString();
43
- return cmdStdout.toString();
26
+ let command = 'mvn';
27
+ let args = ['dependency:tree', '-B'];
28
+ if (config.mavenSettingsPath) {
29
+ args.push('-s');
30
+ args.push(config.mavenSettingsPath);
44
31
  }
45
- catch (err) {
46
- throw new Error(i18n.__('mavenDependencyTreeNonZero', projectData.cwd, `${err.message}`));
32
+ const cmdDepTree = spawn.sync(command, args, {
33
+ env: process.env,
34
+ cwd: projectData.cwd,
35
+ timeout
36
+ });
37
+ if (cmdDepTree.status !== 0) {
38
+ if (config.debug && cmdDepTree.error.code === 'ENOENT') {
39
+ console.log(`ERROR: mvn not found`);
40
+ console.log('Please make sure mvn is installed and accessible');
41
+ }
42
+ throw new Error(i18n.__('mavenDependencyTreeNonZero', projectData.cwd));
47
43
  }
44
+ return cmdDepTree.stdout.toString();
48
45
  };
49
46
  const buildGradle = (config, projectData, timeout) => {
50
47
  let cmdStdout;
@@ -96,20 +93,15 @@ const getJavaBuildDeps = (config, files) => {
96
93
  mvnDependancyTreeOutput: undefined,
97
94
  projectType: undefined
98
95
  };
99
- try {
100
- const projectData = determineProjectTypeAndCwd(files, config);
101
- if (projectData.projectType === MAVEN) {
102
- output.mvnDependancyTreeOutput = buildMaven(config, projectData, timeout);
103
- }
104
- else if (projectData.projectType === GRADLE) {
105
- output.mvnDependancyTreeOutput = buildGradle(config, projectData, timeout);
106
- }
107
- output.projectType = projectData.projectType;
108
- return output;
96
+ const projectData = determineProjectTypeAndCwd(files, config);
97
+ if (projectData.projectType === MAVEN) {
98
+ output.mvnDependancyTreeOutput = buildMaven(config, projectData, timeout);
109
99
  }
110
- catch (err) {
111
- console.log(err.message.toString());
100
+ else if (projectData.projectType === GRADLE) {
101
+ output.mvnDependancyTreeOutput = buildGradle(config, projectData, timeout);
112
102
  }
103
+ output.projectType = projectData.projectType;
104
+ return output;
113
105
  };
114
106
  module.exports = {
115
107
  getJavaBuildDeps,
@@ -8,12 +8,7 @@ const javaAnalysis = async (config, languageFiles) => {
8
8
  file.replace('build.gradle.kts', 'build.gradle');
9
9
  });
10
10
  const javaDeps = buildJavaTree(config, languageFiles.JAVA);
11
- if (config.experimental) {
12
- return parseDependenciesForSCAServices(javaDeps);
13
- }
14
- else {
15
- return createJavaTSMessage(javaDeps);
16
- }
11
+ return createJavaTSMessage(javaDeps);
17
12
  };
18
13
  const buildJavaTree = (config, files) => {
19
14
  const javaBuildDeps = analysis.getJavaBuildDeps(config, files);
@@ -32,46 +32,24 @@ const readYarn = async (config, languageFiles, nameOfFile) => {
32
32
  throw new Error(i18n.__('nodeReadYarnLockFileError') + `${err.message}`);
33
33
  }
34
34
  };
35
- const parseNpmLockFile = async (js) => {
35
+ const parseNpmLockFile = async (npmLockFile) => {
36
36
  try {
37
- js.npmLockFile = JSON.parse(js.rawLockFileContents);
38
- if (js.npmLockFile && js.npmLockFile.lockfileVersion > 1) {
39
- const listOfTopDep = Object.keys(js.npmLockFile.dependencies);
40
- Object.entries(js.npmLockFile.dependencies).forEach(([objKey, value]) => {
41
- if (value.requires) {
42
- const listOfRequiresDep = Object.keys(value.requires);
43
- listOfRequiresDep.forEach(dep => {
44
- if (!listOfTopDep.includes(dep)) {
45
- addDepToLockFile(js, value['requires'], dep);
46
- }
47
- });
48
- }
49
- if (value.dependencies) {
50
- Object.entries(value.dependencies).forEach(([objChildKey, childValue]) => {
51
- if (childValue.requires) {
52
- const listOfRequiresDep = Object.keys(childValue.requires);
53
- listOfRequiresDep.forEach(dep => {
54
- if (!listOfTopDep.includes(dep)) {
55
- addDepToLockFile(js, childValue['requires'], dep);
56
- }
57
- });
58
- }
59
- });
60
- }
61
- });
62
- return js.npmLockFile;
63
- }
64
- else {
65
- return js.npmLockFile;
37
+ if (!npmLockFile.parsedPackages) {
38
+ npmLockFile.parsedPackages = {};
66
39
  }
40
+ Object.entries(npmLockFile.packages).forEach(([packageKey, packageValue]) => {
41
+ if (packageKey.includes('node_modules/')) {
42
+ packageKey = packageKey.replace(/(node_modules\/)+/g, '');
43
+ }
44
+ npmLockFile.parsedPackages[packageKey] = packageValue;
45
+ });
46
+ delete npmLockFile.parsedPackages[''];
47
+ return npmLockFile;
67
48
  }
68
49
  catch (err) {
69
50
  throw new Error(i18n.__('NodeParseNPM') + `${err.message}`);
70
51
  }
71
52
  };
72
- const addDepToLockFile = (js, depObj, key) => {
73
- return (js.npmLockFile.dependencies[key] = { version: depObj[key] });
74
- };
75
53
  const parseYarnLockFile = async (js) => {
76
54
  try {
77
55
  js.yarn.yarnLockFile = {};
@@ -13,9 +13,6 @@ const jsAnalysis = async (config, languageFiles) => {
13
13
  const buildNodeTree = async (config, files) => {
14
14
  let analysis = await readFiles(config, files);
15
15
  const rawNode = await parseFiles(config, files, analysis);
16
- if (config.experimental) {
17
- return scaServiceParser.parseJS(rawNode);
18
- }
19
16
  return formatMessage.createJavaScriptTSMessage(rawNode);
20
17
  };
21
18
  const readFiles = async (config, files) => {
@@ -32,7 +29,20 @@ const readFiles = async (config, files) => {
32
29
  };
33
30
  const parseFiles = async (config, files, js) => {
34
31
  if (files.includes('package-lock.json')) {
35
- js.npmLockFile = await analysis.parseNpmLockFile(js);
32
+ const npmLockFile = JSON.parse(js.rawLockFileContents);
33
+ const currentLockFileVersion = npmLockFile.lockfileVersion;
34
+ const generalRebuildMessage = '\nPlease update to Node 16+ & NPM 8+ or 9+ and then rebuild your package files.' +
35
+ '\nMore info here: https://docs.npmjs.com/cli/v9/configuring-npm/package-lock-json';
36
+ if (currentLockFileVersion === 1) {
37
+ throw new Error(`NPM lockfileVersion 1 is no longer supported. \n ${generalRebuildMessage}`);
38
+ }
39
+ if (!currentLockFileVersion || !npmLockFile.packages) {
40
+ throw new Error(`package-lock.json needs to be in the NPM v2 or v3 format. \n ${generalRebuildMessage}`);
41
+ }
42
+ if (currentLockFileVersion === 3) {
43
+ throw new Error(`NPM lockfileVersion 3 is only supported when using the '-e' flag.`);
44
+ }
45
+ js.npmLockFile = await analysis.parseNpmLockFile(npmLockFile);
36
46
  }
37
47
  if (files.includes('yarn.lock')) {
38
48
  js = await analysis.parseYarnLockFile(js);
@@ -47,7 +47,7 @@ const chooseLockFile = rawNode => {
47
47
  return { lockFile: rawNode?.yarn?.yarnLockFile?.object, type: 'yarn' };
48
48
  }
49
49
  else if (rawNode.npmLockFile !== undefined) {
50
- return { lockFile: rawNode?.npmLockFile?.dependencies, type: 'npm' };
50
+ return { lockFile: rawNode?.npmLockFile?.parsedPackages, type: 'npm' };
51
51
  }
52
52
  else {
53
53
  return undefined;
@@ -70,8 +70,8 @@ const createChildDependencies = (lockFileDep, currentDep) => {
70
70
  };
71
71
  const createNPMChildDependencies = (lockFileDep, currentDep) => {
72
72
  let depArray = [];
73
- if (lockFileDep[currentDep]?.requires) {
74
- for (const [key, value] of Object.entries(lockFileDep[currentDep]?.requires)) {
73
+ if (lockFileDep[currentDep]?.dependencies) {
74
+ for (const [key, value] of Object.entries(lockFileDep[currentDep]?.dependencies)) {
75
75
  depArray.push(key);
76
76
  }
77
77
  }
@@ -1,16 +1,10 @@
1
1
  "use strict";
2
2
  const { readFile, parseProjectFiles } = require('./analysis');
3
3
  const { createPhpTSMessage } = require('../common/formatMessage');
4
- const { parsePHPLockFileForScaServices } = require('./phpNewServicesMapper');
5
4
  const phpAnalysis = config => {
6
5
  let analysis = readFiles(config);
7
- if (config.experimental) {
8
- return parsePHPLockFileForScaServices(analysis.rawLockFileContents);
9
- }
10
- else {
11
- const phpDep = parseProjectFiles(analysis);
12
- return createPhpTSMessage(phpDep);
13
- }
6
+ const phpDep = parseProjectFiles(analysis);
7
+ return createPhpTSMessage(phpDep);
14
8
  };
15
9
  const readFiles = config => {
16
10
  let php = {};
@@ -48,16 +48,10 @@ const checkForCorrectFiles = languageFiles => {
48
48
  };
49
49
  const getPythonDeps = (config, languageFiles) => {
50
50
  try {
51
- if (config.experimental) {
52
- let pythonLockFileContents = readLockFile(config.file);
53
- return scaPythonParser(pythonLockFileContents);
54
- }
55
- else {
56
- checkForCorrectFiles(languageFiles);
57
- const parseProject = readAndParseProjectFile(config.file);
58
- const parsePip = readAndParseLockFile(config.file);
59
- return { pipfileLock: parsePip, pipfilDependanceies: parseProject };
60
- }
51
+ checkForCorrectFiles(languageFiles);
52
+ const parseProject = readAndParseProjectFile(config.file);
53
+ const parsePip = readAndParseLockFile(config.file);
54
+ return { pipfileLock: parsePip, pipfilDependanceies: parseProject };
61
55
  }
62
56
  catch (err) {
63
57
  console.log(err.message.toString());