@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
@@ -3,12 +3,7 @@ const { createPythonTSMessage } = require('../common/formatMessage');
3
3
  const { getPythonDeps, secondaryParser } = require('./analysis');
4
4
  const pythonAnalysis = (config, languageFiles) => {
5
5
  const pythonDeps = getPythonDeps(config, languageFiles.PYTHON);
6
- if (config.experimental) {
7
- return pythonDeps;
8
- }
9
- else {
10
- return createPythonTSMessage(pythonDeps);
11
- }
6
+ return createPythonTSMessage(pythonDeps);
12
7
  };
13
8
  module.exports = {
14
9
  pythonAnalysis
@@ -6,16 +6,7 @@ const getRubyDeps = (config, languageFiles) => {
6
6
  checkForCorrectFiles(languageFiles);
7
7
  const parsedGem = readAndParseGemfile(config.file);
8
8
  const parsedLock = readAndParseGemLockFile(config.file);
9
- if (config.experimental) {
10
- const rubyArray = removeRedundantAndPopulateDefinedElements(parsedLock.sources);
11
- let rubyTree = createRubyTree(rubyArray);
12
- findChildrenDependencies(rubyTree);
13
- processRootDependencies(parsedLock.dependencies, rubyTree);
14
- return rubyTree;
15
- }
16
- else {
17
- return { gemfilesDependanceies: parsedGem, gemfileLock: parsedLock };
18
- }
9
+ return { gemfilesDependanceies: parsedGem, gemfileLock: parsedLock };
19
10
  }
20
11
  catch (err) {
21
12
  throw err;
@@ -3,12 +3,7 @@ const analysis = require('./analysis');
3
3
  const { createRubyTSMessage } = require('../common/formatMessage');
4
4
  const rubyAnalysis = (config, languageFiles) => {
5
5
  const rubyDeps = analysis.getRubyDeps(config, languageFiles.RUBY);
6
- if (config.experimental) {
7
- return rubyDeps;
8
- }
9
- else {
10
- return createRubyTSMessage(rubyDeps);
11
- }
6
+ return createRubyTSMessage(rubyDeps);
12
7
  };
13
8
  module.exports = {
14
9
  rubyAnalysis
@@ -19,14 +19,8 @@ const { rubyAnalysis } = require('./ruby');
19
19
  const { pythonAnalysis } = require('./python');
20
20
  const javaAnalysis = require('./java');
21
21
  const jsAnalysis = require('./javascript');
22
- const auditReport = require('./common/auditReport');
23
- const scaUpload = require('./common/scaServicesUpload');
24
- const settingsHelper = require('../utils/settingsHelper');
25
22
  const chalk = require('chalk');
26
- const saveResults = require('../scan/saveResults');
27
- const { convertGenericToTypedReportModelSca } = require('./common/utils/reportUtilsSca');
28
23
  const processSca = async (config) => {
29
- config = await settingsHelper.getSettings(config);
30
24
  const startTime = performance.now();
31
25
  let filesFound;
32
26
  if (config.help) {
@@ -49,17 +43,7 @@ const processSca = async (config) => {
49
43
  switch (Object.keys(filesFound[0])[0]) {
50
44
  case JAVA:
51
45
  config.language = JAVA;
52
- if (config.mode === 'repo') {
53
- try {
54
- return repoMode.buildRepo(config, filesFound[0]);
55
- }
56
- catch (e) {
57
- throw new Error('Unable to build in repository mode. Check your project file');
58
- }
59
- }
60
- else {
61
- messageToSend = await javaAnalysis.javaAnalysis(config, filesFound[0]);
62
- }
46
+ messageToSend = await javaAnalysis.javaAnalysis(config, filesFound[0]);
63
47
  break;
64
48
  case JAVASCRIPT:
65
49
  messageToSend = await jsAnalysis.jsAnalysis(config, filesFound[0]);
@@ -82,15 +66,9 @@ const processSca = async (config) => {
82
66
  config.language = GO;
83
67
  break;
84
68
  case DOTNET:
85
- if (config.experimental) {
86
- console.log(`${chalk.bold('\n.NET project found\n')} Language type is unsupported.`);
87
- return;
88
- }
89
- else {
90
- messageToSend = dotNetAnalysis(config, filesFound[0]);
91
- config.language = DOTNET;
92
- break;
93
- }
69
+ messageToSend = dotNetAnalysis(config, filesFound[0]);
70
+ config.language = DOTNET;
71
+ break;
94
72
  default:
95
73
  console.log('No supported language detected in project path');
96
74
  return;
@@ -98,42 +76,22 @@ const processSca = async (config) => {
98
76
  if (!config.applicationId) {
99
77
  config.applicationId = await auditController.dealWithNoAppId(config);
100
78
  }
101
- if (config.experimental) {
102
- console.log('');
103
- const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'));
104
- startSpinner(reportSpinner);
105
- const { reportArray, reportId } = await scaUpload.scaTreeUpload(messageToSend, config);
106
- const reportModelLibraryList = convertGenericToTypedReportModelSca(reportArray);
107
- auditReport.processAuditReport(config, reportModelLibraryList);
108
- succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'));
109
- if (config.save !== undefined) {
110
- await auditSave.auditSave(config, reportId);
111
- }
112
- else {
113
- console.log('Use contrast audit --save to generate an SBOM');
114
- }
115
- const endTime = performance.now() - startTime;
116
- const scanDurationMs = endTime - startTime;
117
- console.log(`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`);
79
+ console.log('');
80
+ const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'));
81
+ startSpinner(reportSpinner);
82
+ const snapshotResponse = await treeUpload.commonSendSnapShot(messageToSend, config);
83
+ await pollForSnapshotCompletion(config, snapshotResponse.id, reportSpinner);
84
+ succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'));
85
+ await vulnerabilityReportV2(config, snapshotResponse.id);
86
+ if (config.save !== undefined) {
87
+ await auditSave.auditSave(config);
118
88
  }
119
89
  else {
120
- console.log('');
121
- const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'));
122
- startSpinner(reportSpinner);
123
- const snapshotResponse = await treeUpload.commonSendSnapShot(messageToSend, config);
124
- await pollForSnapshotCompletion(config, snapshotResponse.id, reportSpinner);
125
- succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'));
126
- await vulnerabilityReportV2(config, snapshotResponse.id);
127
- if (config.save !== undefined) {
128
- await auditSave.auditSave(config);
129
- }
130
- else {
131
- console.log('\nUse contrast audit --save to generate an SBOM');
132
- }
133
- const endTime = performance.now() - startTime;
134
- const scanDurationMs = endTime - startTime;
135
- console.log(`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`);
90
+ console.log('\nUse contrast audit --save to generate an SBOM');
136
91
  }
92
+ const endTime = performance.now() - startTime;
93
+ const scanDurationMs = endTime - startTime;
94
+ console.log(`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`);
137
95
  }
138
96
  else {
139
97
  if (filesFound.length === 0) {
package/dist/scan/help.js CHANGED
@@ -4,6 +4,9 @@ const i18n = require('i18n');
4
4
  const constants = require('../cliConstants');
5
5
  const { commonHelpLinks } = require('../common/commonHelp');
6
6
  const scanUsageGuide = commandLineUsage([
7
+ {
8
+ header: i18n.__('constantsHeader')
9
+ },
7
10
  {
8
11
  header: i18n.__('scanHeader')
9
12
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/contrast",
3
- "version": "1.0.21",
3
+ "version": "1.0.23",
4
4
  "description": "Contrast Security's command line tool",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -27,12 +27,9 @@
27
27
  "test": "jest --testPathIgnorePatterns=./test-integration/",
28
28
  "test-int": "jest ./test-integration/",
29
29
  "test-int-scan": "jest ./test-integration/scan",
30
- "test-int-audit": "jest test-integration/audit",
31
- "test-int-audit-reports": "jest test-integration/audit/audit-language-reports.spec.js",
32
30
  "test-int-scan-errors": "jest test-integration/scan/scanLocalErrors.spec.js",
33
31
  "test-int-scan-reports": "jest test-integration/scan/scanReport.spec.js",
34
- "test-int-audit-features": "jest test-integration/audit/auditFeatures/",
35
- "test-int-audit-experimental": "jest test-integration/audit/audit-experimental.spec.js",
32
+ "test-int-audit-features": "jest test-integration/audit/auditFeatures",
36
33
  "format": "prettier --write \"**/*.{ts,tsx,js,json,md,yml}\" .eslintrc.*",
37
34
  "check-format": "prettier --check \"**/*.{ts,tsx,js,json,md,yml}\" .eslintrc.*",
38
35
  "coverage-local": "nyc --reporter=text mocha './test/**/*.spec.js'",
@@ -247,7 +247,7 @@ function buildBody(cveArray, advice) {
247
247
  //todo different advice based on remediationGuidance being available or now
248
248
  // console.log(advice)
249
249
 
250
- const minOrMax = advice.maximum ? advice.maximum : advice.minimum
250
+ const minOrMax = advice.minimum ? advice.minimum : advice.maximum
251
251
  const displayAdvice = minOrMax
252
252
  ? `Change to version ${chalk.bold(minOrMax)}`
253
253
  : 'No recommendation is available according to our data. Upgrade to the latest stable is the best advice we can give.'
package/src/audit/save.js CHANGED
@@ -23,18 +23,20 @@ async function auditSave(config, reportId) {
23
23
  }
24
24
 
25
25
  if (fileFormat) {
26
- if (config.experimental) {
27
- save.saveFile(
26
+ if (config.legacy === false) {
27
+ const sbomResponse = await sbom.generateSCASbom(
28
28
  config,
29
29
  fileFormat,
30
- await sbom.generateSCASbom(config, fileFormat, reportId)
30
+ reportId
31
31
  )
32
+ if (sbomResponse) {
33
+ save.saveFile(config, fileFormat, sbomResponse)
34
+ }
32
35
  } else {
33
- save.saveFile(
34
- config,
35
- fileFormat,
36
- await sbom.generateSbom(config, fileFormat)
37
- )
36
+ const sbomResponse = await sbom.generateSbom(config, fileFormat)
37
+ if (sbomResponse) {
38
+ save.saveFile(config, fileFormat, sbomResponse)
39
+ }
38
40
  }
39
41
  const filename = `${config.applicationId}-sbom-${fileFormat}.json`
40
42
  if (fs.existsSync(filename)) {
@@ -42,7 +44,7 @@ async function auditSave(config, reportId) {
42
44
  } else {
43
45
  console.log(
44
46
  chalk.yellow.bold(
45
- `\n Unable to save ${filename} Software Bill of Materials (SBOM)`
47
+ `\nUnable to save ${filename} Software Bill of Materials (SBOM)`
46
48
  )
47
49
  )
48
50
  }
@@ -212,6 +212,7 @@ const scanOptionDefinitions = [
212
212
 
213
213
  const authOptionDefinitions = [
214
214
  ...sharedConnectionOptionDefinitions,
215
+ ...sharedCertOptionDefinitions,
215
216
  {
216
217
  name: 'help',
217
218
  alias: 'h',
@@ -427,11 +428,11 @@ const mainUsageGuide = commandLineUsage([
427
428
  header: i18n.__('constantsCommands'),
428
429
  content: [
429
430
  { name: i18n.__('authName'), summary: i18n.__('helpAuthSummary') },
431
+ { name: i18n.__('configName'), summary: i18n.__('helpConfigSummary') },
432
+ { name: i18n.__('versionName'), summary: i18n.__('helpVersionSummary') },
433
+ { name: i18n.__('auditName'), summary: i18n.__('helpAuditSummary') },
430
434
  { name: i18n.__('scanName'), summary: i18n.__('helpScanSummary') },
431
435
  { name: i18n.__('lambdaName'), summary: i18n.__('helpLambdaSummary') },
432
- { name: i18n.__('auditName'), summary: i18n.__('helpAuditSummary') },
433
- { name: i18n.__('versionName'), summary: i18n.__('helpVersionSummary') },
434
- { name: i18n.__('configName'), summary: i18n.__('helpConfigSummary') },
435
436
  { name: i18n.__('helpName'), summary: i18n.__('helpSummary') },
436
437
  { name: i18n.__('learnName'), summary: i18n.__('helpLearnSummary') }
437
438
  ]
@@ -4,6 +4,9 @@ const constants = require('../../cliConstants')
4
4
  const { commonHelpLinks } = require('../../common/commonHelp')
5
5
 
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',
@@ -10,11 +10,8 @@ const processAudit = async (contrastConf, argvMain) => {
10
10
  process.exit(0)
11
11
  }
12
12
 
13
- const config = await auditConfig.getAuditConfig(
14
- contrastConf,
15
- 'audit',
16
- argvMain
17
- )
13
+ let config = await auditConfig.getAuditConfig(contrastConf, 'audit', argvMain)
14
+
18
15
  await scaController.processSca(config)
19
16
  if (!config.fingerprint) {
20
17
  postRunMessage('audit')
@@ -101,6 +101,11 @@ const authUsageGuide = commandLineUsage([
101
101
  {
102
102
  header: i18n.__('constantsAuthUsageHeader'),
103
103
  content: [i18n.__('constantsAuthUsageContents')]
104
+ },
105
+ {
106
+ header: i18n.__('constantsAdvancedOptions'),
107
+ optionList: constants.commandLineDefinitions.authOptionDefinitions,
108
+ hide: ['organization-id', 'api-key', 'authorization', 'host']
104
109
  }
105
110
  ])
106
111
 
@@ -1,7 +1,7 @@
1
1
  const { openLearnPage } = require('./learn')
2
2
 
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(
6
6
  'If the page does not open you can open it directly via https://www.contrastsecurity.com/developer/learn'
7
7
  )
@@ -254,6 +254,13 @@ HTTPClient.prototype.scaServiceIngests = function scaServiceIngests(config) {
254
254
  return requestUtils.sendRequest({ method: 'get', options })
255
255
  }
256
256
 
257
+ HTTPClient.prototype.scaServiceHealth = function scaServiceIngests(config) {
258
+ const options = _.cloneDeep(this.requestOptions)
259
+ let url = createScaServiceHealthURL(config)
260
+ options.url = url
261
+ return requestUtils.sendRequest({ method: 'get', options })
262
+ }
263
+
257
264
  HTTPClient.prototype.getReportById = function getReportById(config, reportId) {
258
265
  const options = _.cloneDeep(this.requestOptions)
259
266
  if (config.ignoreDev) {
@@ -474,6 +481,10 @@ function createScaServiceIngestsURL(config) {
474
481
  return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/applications/${config.applicationId}/libraries/ingests`
475
482
  }
476
483
 
484
+ function createScaServiceHealthURL(config) {
485
+ return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/health`
486
+ }
487
+
477
488
  function createScaServiceIngestURL(config) {
478
489
  let baseUrl = `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/applications/${config.applicationId}/libraries/ingests/tree`
479
490
  baseUrl = config.track ? baseUrl.concat('?persist=true') : baseUrl
@@ -14,7 +14,7 @@ const HIGH = 'HIGH'
14
14
  const CRITICAL = 'CRITICAL'
15
15
  // App
16
16
  const APP_NAME = 'contrast'
17
- const APP_VERSION = '1.0.21'
17
+ const APP_VERSION = '1.0.23'
18
18
  const TIMEOUT = 120000
19
19
  const HIGH_COLOUR = '#ff9900'
20
20
  const CRITICAL_COLOUR = '#e35858'
@@ -66,6 +66,7 @@ const lambda = {
66
66
  'Scanning a function of an inactive account is not supported',
67
67
  not_supported_runtime:
68
68
  'Scanning resource of runtime "{{runtime}}" is not supported.\nSupported runtimes: {{supportedRuntimes}}',
69
+ not_supported_lambda: 'This function cannot be scanned',
69
70
  not_supported_onboard_account:
70
71
  'Scanning a function of onboard account is not supported',
71
72
  scan_lock:
@@ -1,5 +1,6 @@
1
1
  const { lambda } = require('./lambda')
2
2
  const chalk = require('chalk')
3
+ const { APP_VERSION } = require('./constants')
3
4
 
4
5
  const en_locales = () => {
5
6
  return {
@@ -83,7 +84,7 @@ const en_locales = () => {
83
84
  ' FAIL - Results detected vulnerabilities over accepted severity level',
84
85
  constantsSeverity:
85
86
  '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.',
86
- constantsHeader: 'Contrast CLI',
87
+ constantsHeader: `Contrast CLI @ v${APP_VERSION}`,
87
88
  configHeader2: 'Config options',
88
89
  clearHeader: '-c, --clear',
89
90
  clearContent: 'Removes stored credentials',
@@ -160,13 +161,13 @@ const en_locales = () => {
160
161
  scanErrorFileMessage:
161
162
  'We only accept the following file types: \nJava - .jar, .war \nJavaScript - .js or .zip files',
162
163
  helpAuthSummary:
163
- 'Authenticate Contrast using your Github or Google account',
164
+ 'Authenticate Contrast using your Github or Google account OR include credentials if you are an existing licensed Contrast user.',
164
165
  helpAuditSummary:
165
- '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).]',
166
+ '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. ',
166
167
  helpScanSummary:
167
- '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]',
168
+ '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. ',
168
169
  helpLambdaSummary:
169
- 'Performs a static security scan on an AWS lambda function. lambda --help (for options)',
170
+ 'Performs a static security scan on an AWS lambda function. [lambda --help for options] AWS Lambda - Java & Python are supported. ',
170
171
  helpVersionSummary: 'Displays version of Contrast CLI',
171
172
  helpConfigSummary: 'Displays stored credentials',
172
173
  helpSummary: 'Displays usage guide',
@@ -178,7 +179,7 @@ const en_locales = () => {
178
179
  configName: 'config',
179
180
  helpName: 'help',
180
181
  learnName: 'learn',
181
- helpLearnSummary: 'launches Contrast’s Secure Code Learning Hub.',
182
+ helpLearnSummary: 'Launches Contrast’s Secure Code Learning Hub.',
182
183
  fingerprintName:
183
184
  'assess repo to see how many languages it can detect. For use in pipeline only.',
184
185
  depthOption:
@@ -202,7 +203,7 @@ const en_locales = () => {
202
203
  chalk.bold('\ncontrast audit') +
203
204
  ' to find vulnerabilities in your open source dependencies.' +
204
205
  '\nSupports Java, .NET, Node, Ruby, Python, Go and PHP.' +
205
- '\nOur CLI runs native build tools to generate a complete dependency tree.' +
206
+ '\n\nOur CLI runs native build tools to generate a complete dependency tree.' +
206
207
  '\nIf you are running on untrusted code, consider running in a sandbox.\n' +
207
208
  chalk.bold('\ncontrast lambda') +
208
209
  ' to secure your AWS serverless functions. \nSupports Java and Python \n' +
@@ -216,7 +217,7 @@ const en_locales = () => {
216
217
  searchingScanFileDirectory: 'Searching for file to scan from %s...',
217
218
  searchingAuditFileDirectory:
218
219
  'Searching for package manager files from %s...',
219
- scanHeader: 'Contrast Scan CLI',
220
+ scanHeader: `Contrast Scan CLI`,
220
221
  authHeader: 'Auth',
221
222
  lambdaHeader: 'Contrast Lambda CLI',
222
223
  lambdaSummary:
@@ -257,7 +258,7 @@ const en_locales = () => {
257
258
  'An error has occurred when trying to get the Project Id please check your internet connection or provide the Project Id manually',
258
259
  internalServerErrorHeader: '500 error - Internal server error',
259
260
  resourceLockedErrorHeader: '423 error - Resource is locked',
260
- auditHeader: 'Contrast audit help',
261
+ auditHeader: 'Contrast Audit CLI',
261
262
  auditHeaderMessage:
262
263
  "Use 'contrast audit' to analyze a project’s dependencies for vulnerabilities.",
263
264
  constantsAuditPrerequisitesContentSupportedLanguages:
@@ -329,18 +330,18 @@ const en_locales = () => {
329
330
  commonHelpJoinDiscussionText:
330
331
  ' https://www.contrastsecurity.com/developer/community',
331
332
  commonHelpLearnHeader:
332
- chalk.hex('#ffe599')('\rWant to UP your game?') +
333
+ chalk.hex('#ffe599')('\r Want to UP your game?') +
333
334
  " type 'contrast learn'",
334
- commonHelpLearnText: `\n🎓 Advance your security knowledge and become an ${chalk.hex(
335
+ commonHelpLearnText: `\n💰 Advance your security knowledge and become an ${chalk.hex(
335
336
  '#ffd966'
336
337
  )('All-star coder')} ⭐ with ${chalk.bold(
337
338
  'Contrast Secure Code Learning Hub.'
338
339
  )} 😺`,
339
340
  authCommand: {
340
341
  credentialsAccepted: {
341
- title: 'Credentials accepted',
342
- body: 'Now run contrast audit, lambda or scan',
343
- extra: 'Or contrast help for full list of commands'
342
+ title: 'Credentials successfully saved',
343
+ body: `\n${chalk.bold('Contrast CLI')}`,
344
+ extra: 'Scan, secure and ship your code in minutes.'
344
345
  },
345
346
  credentialsMissing: {
346
347
  title: 'Credentials missing',
package/src/index.ts CHANGED
@@ -16,7 +16,6 @@ import {
16
16
  } from './common/versionChecker'
17
17
  import { findCommandOnError } from './common/errorHandling'
18
18
  import { sendTelemetryConfigAsConfObj } from './telemetry/telemetry'
19
- import { openLearnPage } from './commands/learn/learn'
20
19
  import { processLearn } from './commands/learn/processLearn'
21
20
  const {
22
21
  commandLineDefinitions: { mainUsageGuide, mainDefinition }
@@ -3,6 +3,9 @@ import i18n from 'i18n'
3
3
  import { commonHelpLinks } from '../common/commonHelp'
4
4
 
5
5
  const lambdaUsageGuide = commandLineUsage([
6
+ {
7
+ header: i18n.__('constantsHeader')
8
+ },
6
9
  {
7
10
  header: i18n.__('lambdaHeader'),
8
11
  content: [i18n.__('lambdaSummary')]
@@ -14,12 +14,22 @@ import { ApiParams, LambdaOptions } from './lambda'
14
14
  import { log, prettyPrintJson } from './logUtils'
15
15
  import { CliError } from './cliError'
16
16
  import { ERRORS } from './constants'
17
+ import { sleep } from '../utils/requestUtils'
17
18
 
18
- const sendScanPostRequest = async (
19
+ const MAX_RETRIES = 2
20
+
21
+ const sendScanPostRequest: (
19
22
  config: any,
20
23
  params: ApiParams,
21
24
  functionsEvent: unknown,
22
- showProgress = false
25
+ showProgress?: boolean,
26
+ retryNumber?: number
27
+ ) => any = async (
28
+ config,
29
+ params,
30
+ functionsEvent,
31
+ showProgress = false,
32
+ retryNumber = 0
23
33
  ) => {
24
34
  const client = getHttpClient(config)
25
35
 
@@ -50,6 +60,21 @@ const sendScanPostRequest = async (
50
60
  })
51
61
  errorCode = false
52
62
  break
63
+ case 'not_supported_lambda':
64
+ description = i18n.__(errorCode)
65
+ errorCode = false
66
+ break
67
+ default:
68
+ if (retryNumber < MAX_RETRIES) {
69
+ await sleep(3 * 1000)
70
+ return sendScanPostRequest(
71
+ config,
72
+ params,
73
+ functionsEvent,
74
+ showProgress,
75
+ retryNumber + 1
76
+ )
77
+ }
53
78
  }
54
79
 
55
80
  throw new CliError(ERRORS.FAILED_TO_START_SCAN, {
@@ -7,8 +7,15 @@ export const generateSbom = (config: any, type: string) => {
7
7
  .then((res: { statusCode: number; body: any }) => {
8
8
  if (res.statusCode === 200) {
9
9
  return res.body
10
+ } else if (res.statusCode === 403) {
11
+ console.log('\nUnable to retrieve Software Bill of Materials (SBOM)')
12
+ console.log(
13
+ `Please ensure OSS is enabled for your organization - org-id ${config.organizationId} and app ${config.applicationId}`
14
+ )
15
+ return undefined
10
16
  } else {
11
17
  console.log('Unable to retrieve Software Bill of Materials (SBOM)')
18
+ return undefined
12
19
  }
13
20
  })
14
21
  .catch((err: any) => {
@@ -29,6 +36,7 @@ export const generateSCASbom = (
29
36
  return res.body
30
37
  } else {
31
38
  console.log('Unable to retrieve Software Bill of Materials (SBOM)')
39
+ return undefined
32
40
  }
33
41
  })
34
42
  .catch((err: any) => {
@@ -217,9 +217,9 @@ function getIssueRow(cveArray) {
217
217
  }
218
218
 
219
219
  function getAdviceRow(advice) {
220
- const latestOrClosest = advice.latestStableVersion
221
- ? advice.latestStableVersion
222
- : advice.closestStableVersion
220
+ const latestOrClosest = advice.closestStableVersion
221
+ ? advice.closestStableVersion
222
+ : advice.latestStableVersion
223
223
  const displayAdvice = latestOrClosest
224
224
  ? `Change to version ${chalk.bold(latestOrClosest)}`
225
225
  : '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 { APP_VERSION } = require('../../constants/constants')
3
3
 
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
 
14
12
  const client = commonApi.getHttpClient(config)
15
13
  return client
@@ -18,6 +16,13 @@ const commonSendSnapShot = async (analysis, config) => {
18
16
  if (res.statusCode === 201) {
19
17
  return res.body
20
18
  } else {
19
+ if (res.statusCode === 403) {
20
+ throw new Error(
21
+ `🛑 Contrast audit failed \nPlease check you have the right permissions and the application ${
22
+ config.applicationName ? config.applicationName : ''
23
+ } has not been archived.`.replace(/ +(?= )/g, '')
24
+ )
25
+ }
21
26
  throw new Error(res.statusCode + ` error processing dependencies`)
22
27
  }
23
28
  })
@@ -26,19 +31,6 @@ const commonSendSnapShot = async (analysis, config) => {
26
31
  })
27
32
  }
28
33
 
29
- const sendToSCAServices = (config, analysis) => {
30
- return {
31
- applicationId: config.applicationId,
32
- dependencyTree: analysis,
33
- organizationId: config.organizationId,
34
- language: config.language,
35
- tool: {
36
- name: 'Contrast Codesec',
37
- version: APP_VERSION
38
- }
39
- }
40
- }
41
-
42
34
  module.exports = {
43
35
  commonSendSnapShot
44
36
  }
@@ -10,12 +10,7 @@ const goAnalysis = config => {
10
10
  const rawGoDependencies = goReadDepFile.getGoDependencies(config)
11
11
  const parsedGoDependencies =
12
12
  goParseDeps.parseGoDependencies(rawGoDependencies)
13
-
14
- if (config.experimental) {
15
- return parseDependenciesForSCAServices(parsedGoDependencies)
16
- } else {
17
- return createGoTSMessage(parsedGoDependencies)
18
- }
13
+ return createGoTSMessage(parsedGoDependencies)
19
14
  } catch (e) {
20
15
  console.log(e.message.toString())
21
16
  }