@contrast/contrast 1.0.7 → 1.0.10

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 (196) hide show
  1. package/README.md +1 -1
  2. package/dist/audit/catalogueApplication/catalogueApplication.js +23 -5
  3. package/dist/audit/languageAnalysisEngine/getProjectRootFilenames.js +17 -26
  4. package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +98 -37
  5. package/dist/audit/languageAnalysisEngine/report/models/reportListModel.js +2 -1
  6. package/dist/audit/languageAnalysisEngine/report/models/reportOutputModel.js +4 -3
  7. package/dist/audit/languageAnalysisEngine/report/models/severityCountModel.js +3 -0
  8. package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +87 -19
  9. package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +40 -7
  10. package/dist/audit/languageAnalysisEngine/sendSnapshot.js +6 -30
  11. package/dist/audit/save.js +37 -0
  12. package/dist/commands/audit/auditConfig.js +0 -16
  13. package/dist/commands/audit/auditController.js +18 -11
  14. package/dist/commands/audit/help.js +31 -25
  15. package/dist/commands/audit/processAudit.js +2 -2
  16. package/dist/commands/audit/saveFile.js +8 -4
  17. package/dist/commands/scan/sca/scaAnalysis.js +54 -16
  18. package/dist/common/HTTPClient.js +14 -8
  19. package/dist/common/errorHandling.js +2 -2
  20. package/dist/common/versionChecker.js +19 -4
  21. package/dist/constants/constants.js +7 -2
  22. package/dist/constants/locales.js +44 -44
  23. package/dist/constants.js +31 -14
  24. package/dist/index.js +55 -45
  25. package/dist/lambda/lambda.js +5 -2
  26. package/dist/sbom/generateSbom.js +5 -4
  27. package/dist/scaAnalysis/common/formatMessage.js +33 -6
  28. package/dist/scaAnalysis/common/treeUpload.js +4 -6
  29. package/dist/scaAnalysis/dotnet/analysis.js +43 -0
  30. package/dist/scaAnalysis/dotnet/index.js +10 -0
  31. package/dist/scaAnalysis/go/goReadDepFile.js +1 -3
  32. package/dist/scaAnalysis/java/analysis.js +5 -5
  33. package/dist/scaAnalysis/javascript/analysis.js +107 -0
  34. package/dist/scaAnalysis/javascript/index.js +53 -0
  35. package/dist/scaAnalysis/php/analysis.js +70 -0
  36. package/dist/scaAnalysis/php/index.js +17 -0
  37. package/dist/scaAnalysis/python/analysis.js +8 -7
  38. package/dist/scaAnalysis/ruby/analysis.js +8 -16
  39. package/dist/scaAnalysis/ruby/index.js +2 -2
  40. package/dist/scan/autoDetection.js +13 -24
  41. package/dist/scan/fileUtils.js +44 -14
  42. package/dist/scan/formatScanOutput.js +3 -3
  43. package/dist/scan/scanConfig.js +2 -2
  44. package/dist/utils/commonApi.js +1 -1
  45. package/dist/utils/filterProjectPath.js +7 -2
  46. package/dist/utils/getConfig.js +1 -6
  47. package/package.json +2 -3
  48. package/src/audit/catalogueApplication/catalogueApplication.js +28 -6
  49. package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +22 -58
  50. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +157 -47
  51. package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +4 -1
  52. package/src/audit/languageAnalysisEngine/report/models/reportOutputModel.ts +11 -5
  53. package/src/audit/languageAnalysisEngine/report/models/severityCountModel.ts +4 -0
  54. package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +86 -32
  55. package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +44 -5
  56. package/src/audit/languageAnalysisEngine/sendSnapshot.js +6 -32
  57. package/src/audit/save.js +48 -0
  58. package/src/commands/audit/auditConfig.ts +0 -25
  59. package/src/commands/audit/auditController.ts +18 -20
  60. package/src/commands/audit/help.ts +31 -25
  61. package/src/commands/audit/processAudit.ts +2 -5
  62. package/src/commands/audit/saveFile.ts +6 -2
  63. package/src/commands/scan/processScan.js +0 -1
  64. package/src/commands/scan/sca/scaAnalysis.js +87 -32
  65. package/src/common/HTTPClient.js +16 -9
  66. package/src/common/errorHandling.ts +2 -3
  67. package/src/common/versionChecker.ts +23 -4
  68. package/src/constants/constants.js +9 -3
  69. package/src/constants/locales.js +72 -50
  70. package/src/constants.js +32 -15
  71. package/src/index.ts +70 -58
  72. package/src/lambda/lambda.ts +5 -2
  73. package/src/lambda/types.ts +1 -0
  74. package/src/sbom/generateSbom.ts +2 -2
  75. package/src/scaAnalysis/common/formatMessage.js +35 -6
  76. package/src/scaAnalysis/common/treeUpload.js +4 -6
  77. package/src/scaAnalysis/dotnet/analysis.js +54 -0
  78. package/src/scaAnalysis/dotnet/index.js +11 -0
  79. package/src/scaAnalysis/go/goReadDepFile.js +1 -3
  80. package/src/scaAnalysis/java/analysis.js +5 -5
  81. package/src/scaAnalysis/javascript/analysis.js +126 -0
  82. package/src/scaAnalysis/javascript/index.js +75 -0
  83. package/src/scaAnalysis/php/analysis.js +78 -0
  84. package/src/scaAnalysis/php/index.js +22 -0
  85. package/src/scaAnalysis/python/analysis.js +8 -7
  86. package/src/scaAnalysis/ruby/analysis.js +8 -17
  87. package/src/scaAnalysis/ruby/index.js +2 -2
  88. package/src/scan/autoDetection.js +14 -27
  89. package/src/scan/fileUtils.js +46 -14
  90. package/src/scan/formatScanOutput.ts +3 -3
  91. package/src/scan/scanConfig.js +2 -4
  92. package/src/utils/commonApi.js +1 -1
  93. package/src/utils/filterProjectPath.js +6 -2
  94. package/src/utils/getConfig.ts +1 -12
  95. package/dist/audit/AnalysisEngine.js +0 -37
  96. package/dist/audit/autodetection/autoDetectLanguage.js +0 -32
  97. package/dist/audit/dotnetAnalysisEngine/index.js +0 -25
  98. package/dist/audit/dotnetAnalysisEngine/parseLockFileContents.js +0 -35
  99. package/dist/audit/dotnetAnalysisEngine/parseProjectFileContents.js +0 -15
  100. package/dist/audit/dotnetAnalysisEngine/readLockFileContents.js +0 -18
  101. package/dist/audit/dotnetAnalysisEngine/readProjectFileContents.js +0 -14
  102. package/dist/audit/dotnetAnalysisEngine/sanitizer.js +0 -9
  103. package/dist/audit/goAnalysisEngine/index.js +0 -17
  104. package/dist/audit/goAnalysisEngine/parseProjectFileContents.js +0 -164
  105. package/dist/audit/goAnalysisEngine/readProjectFileContents.js +0 -21
  106. package/dist/audit/goAnalysisEngine/sanitizer.js +0 -5
  107. package/dist/audit/javaAnalysisEngine/index.js +0 -34
  108. package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +0 -155
  109. package/dist/audit/javaAnalysisEngine/parseProjectFileContents.js +0 -353
  110. package/dist/audit/javaAnalysisEngine/readProjectFileContents.js +0 -98
  111. package/dist/audit/javaAnalysisEngine/sanitizer.js +0 -5
  112. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +0 -25
  113. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +0 -25
  114. package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +0 -35
  115. package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +0 -24
  116. package/dist/audit/languageAnalysisEngine/constants.js +0 -20
  117. package/dist/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +0 -25
  118. package/dist/audit/languageAnalysisEngine/index.js +0 -39
  119. package/dist/audit/languageAnalysisEngine/languageAnalysisFactory.js +0 -89
  120. package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +0 -159
  121. package/dist/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +0 -40
  122. package/dist/audit/nodeAnalysisEngine/index.js +0 -31
  123. package/dist/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +0 -18
  124. package/dist/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +0 -18
  125. package/dist/audit/nodeAnalysisEngine/readNPMLockFileContents.js +0 -17
  126. package/dist/audit/nodeAnalysisEngine/readProjectFileContents.js +0 -14
  127. package/dist/audit/nodeAnalysisEngine/readYarnLockFileContents.js +0 -24
  128. package/dist/audit/nodeAnalysisEngine/sanitizer.js +0 -9
  129. package/dist/audit/phpAnalysisEngine/index.js +0 -23
  130. package/dist/audit/phpAnalysisEngine/parseLockFileContents.js +0 -52
  131. package/dist/audit/phpAnalysisEngine/readLockFileContents.js +0 -13
  132. package/dist/audit/phpAnalysisEngine/readProjectFileContents.js +0 -16
  133. package/dist/audit/phpAnalysisEngine/sanitizer.js +0 -5
  134. package/dist/audit/pythonAnalysisEngine/index.js +0 -25
  135. package/dist/audit/pythonAnalysisEngine/parsePipfileLockContents.js +0 -17
  136. package/dist/audit/pythonAnalysisEngine/parseProjectFileContents.js +0 -21
  137. package/dist/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +0 -13
  138. package/dist/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +0 -14
  139. package/dist/audit/pythonAnalysisEngine/sanitizer.js +0 -7
  140. package/dist/audit/rubyAnalysisEngine/index.js +0 -25
  141. package/dist/audit/rubyAnalysisEngine/parseGemfileLockContents.js +0 -176
  142. package/dist/audit/rubyAnalysisEngine/parsedGemfile.js +0 -22
  143. package/dist/audit/rubyAnalysisEngine/readGemfileContents.js +0 -14
  144. package/dist/audit/rubyAnalysisEngine/readGemfileLockContents.js +0 -14
  145. package/dist/audit/rubyAnalysisEngine/sanitizer.js +0 -6
  146. package/src/audit/AnalysisEngine.js +0 -103
  147. package/src/audit/autodetection/autoDetectLanguage.ts +0 -40
  148. package/src/audit/dotnetAnalysisEngine/index.js +0 -26
  149. package/src/audit/dotnetAnalysisEngine/parseLockFileContents.js +0 -47
  150. package/src/audit/dotnetAnalysisEngine/parseProjectFileContents.js +0 -29
  151. package/src/audit/dotnetAnalysisEngine/readLockFileContents.js +0 -30
  152. package/src/audit/dotnetAnalysisEngine/readProjectFileContents.js +0 -26
  153. package/src/audit/dotnetAnalysisEngine/sanitizer.js +0 -11
  154. package/src/audit/goAnalysisEngine/index.js +0 -18
  155. package/src/audit/goAnalysisEngine/parseProjectFileContents.js +0 -209
  156. package/src/audit/goAnalysisEngine/readProjectFileContents.js +0 -31
  157. package/src/audit/goAnalysisEngine/sanitizer.js +0 -7
  158. package/src/audit/javaAnalysisEngine/index.js +0 -41
  159. package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +0 -225
  160. package/src/audit/javaAnalysisEngine/parseProjectFileContents.js +0 -420
  161. package/src/audit/javaAnalysisEngine/readProjectFileContents.js +0 -141
  162. package/src/audit/javaAnalysisEngine/sanitizer.js +0 -6
  163. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +0 -36
  164. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +0 -42
  165. package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +0 -54
  166. package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +0 -33
  167. package/src/audit/languageAnalysisEngine/constants.js +0 -23
  168. package/src/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +0 -41
  169. package/src/audit/languageAnalysisEngine/index.js +0 -45
  170. package/src/audit/languageAnalysisEngine/languageAnalysisFactory.js +0 -124
  171. package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +0 -250
  172. package/src/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +0 -49
  173. package/src/audit/nodeAnalysisEngine/index.js +0 -35
  174. package/src/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +0 -20
  175. package/src/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +0 -26
  176. package/src/audit/nodeAnalysisEngine/readNPMLockFileContents.js +0 -23
  177. package/src/audit/nodeAnalysisEngine/readProjectFileContents.js +0 -27
  178. package/src/audit/nodeAnalysisEngine/readYarnLockFileContents.js +0 -36
  179. package/src/audit/nodeAnalysisEngine/sanitizer.js +0 -11
  180. package/src/audit/phpAnalysisEngine/index.js +0 -27
  181. package/src/audit/phpAnalysisEngine/parseLockFileContents.js +0 -60
  182. package/src/audit/phpAnalysisEngine/readLockFileContents.js +0 -14
  183. package/src/audit/phpAnalysisEngine/readProjectFileContents.js +0 -25
  184. package/src/audit/phpAnalysisEngine/sanitizer.js +0 -4
  185. package/src/audit/pythonAnalysisEngine/index.js +0 -55
  186. package/src/audit/pythonAnalysisEngine/parsePipfileLockContents.js +0 -23
  187. package/src/audit/pythonAnalysisEngine/parseProjectFileContents.js +0 -33
  188. package/src/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +0 -16
  189. package/src/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +0 -22
  190. package/src/audit/pythonAnalysisEngine/sanitizer.js +0 -9
  191. package/src/audit/rubyAnalysisEngine/index.js +0 -30
  192. package/src/audit/rubyAnalysisEngine/parseGemfileLockContents.js +0 -215
  193. package/src/audit/rubyAnalysisEngine/parsedGemfile.js +0 -39
  194. package/src/audit/rubyAnalysisEngine/readGemfileContents.js +0 -18
  195. package/src/audit/rubyAnalysisEngine/readGemfileLockContents.js +0 -17
  196. package/src/audit/rubyAnalysisEngine/sanitizer.js +0 -8
@@ -1,24 +1,49 @@
1
1
  const autoDetection = require('../../../scan/autoDetection')
2
2
  const javaAnalysis = require('../../../scaAnalysis/java')
3
3
  const treeUpload = require('../../../scaAnalysis/common/treeUpload')
4
- const {
5
- manualDetectAuditFilesAndLanguages
6
- } = require('../../../scan/autoDetection')
7
4
  const auditController = require('../../audit/auditController')
8
5
  const {
9
- supportedLanguages: { JAVA, GO, RUBY, PYTHON }
10
- } = require('../../../audit/languageAnalysisEngine/constants')
6
+ supportedLanguages: { JAVA, GO, PYTHON, RUBY, JAVASCRIPT, NODE, PHP, DOTNET }
7
+ } = require('../../../constants/constants')
11
8
  const goAnalysis = require('../../../scaAnalysis/go/goAnalysis')
9
+ const phpAnalysis = require('../../../scaAnalysis/php/index')
12
10
  const { rubyAnalysis } = require('../../../scaAnalysis/ruby')
13
11
  const { pythonAnalysis } = require('../../../scaAnalysis/python')
14
-
12
+ const javascriptAnalysis = require('../../../scaAnalysis/javascript')
13
+ const {
14
+ pollForSnapshotCompletition
15
+ } = require('../../../audit/languageAnalysisEngine/sendSnapshot')
16
+ const {
17
+ returnOra,
18
+ startSpinner,
19
+ succeedSpinner
20
+ } = require('../../../utils/oraWrapper')
21
+ const i18n = require('i18n')
22
+ const {
23
+ vulnerabilityReportV2
24
+ } = require('../../../audit/languageAnalysisEngine/report/reportingFeature')
25
+ const auditSave = require('../../../audit/save')
26
+ const { dotNetAnalysis } = require('../../../scaAnalysis/dotnet')
27
+ const rootFile = require('../../../audit/languageAnalysisEngine/getProjectRootFilenames')
28
+ const path = require('path')
15
29
  const processSca = async config => {
30
+ const startTime = performance.now()
16
31
  let filesFound
17
- if (config.projectPath) {
18
- filesFound = manualDetectAuditFilesAndLanguages(config.projectPath)
19
- } else {
20
- filesFound = await autoDetection.autoDetectAuditFilesAndLanguages(config)
21
- config.projectPath = process.cwd()
32
+
33
+ const projectStats = await rootFile.getProjectStats(config.file)
34
+ let pathWithFile = projectStats.isFile()
35
+
36
+ let fileName = config.file
37
+ config.file = pathWithFile
38
+ ? rootFile.getDirectoryFromPathGiven(config.file).concat('/')
39
+ : config.file
40
+
41
+ filesFound = await autoDetection.autoDetectAuditFilesAndLanguages(config.file)
42
+
43
+ if (filesFound.length > 1 && pathWithFile) {
44
+ filesFound = filesFound.filter(i =>
45
+ Object.values(i)[0].includes(path.basename(fileName))
46
+ )
22
47
  }
23
48
 
24
49
  // files found looks like [ { javascript: [ Array ] } ]
@@ -31,48 +56,78 @@ const processSca = async config => {
31
56
  messageToSend = javaAnalysis.javaAnalysis(config, filesFound[0])
32
57
  config.language = JAVA
33
58
  break
34
- // case 'javascript':
35
- // // code block
36
- // break;
37
- // case 'dotnet':
38
- // // code block
39
- // break;
40
- case RUBY:
41
- messageToSend = rubyAnalysis(config, filesFound[0])
42
- config.language = RUBY
59
+ case JAVASCRIPT:
60
+ messageToSend = await javascriptAnalysis.jsAnalysis(
61
+ config,
62
+ filesFound[0]
63
+ )
64
+ config.language = NODE
43
65
  break
44
66
  case PYTHON:
45
67
  messageToSend = pythonAnalysis(config, filesFound[0])
46
68
  config.language = PYTHON
47
69
  break
48
- // case 'ruby':
49
- // // code block
50
- // break;
51
- // case 'php':
52
- // // code block
53
- // break;
70
+ case RUBY:
71
+ messageToSend = rubyAnalysis(config, filesFound[0])
72
+ config.language = RUBY
73
+ break
74
+ case 'PHP':
75
+ messageToSend = phpAnalysis.phpAnalysis(config, filesFound[0])
76
+ config.language = PHP
77
+ break
54
78
  case GO:
55
79
  messageToSend = goAnalysis.goAnalysis(config, filesFound[0])
56
80
  config.language = GO
57
81
  break
82
+ case DOTNET:
83
+ messageToSend = dotNetAnalysis(config, filesFound[0])
84
+ config.language = DOTNET
85
+ break
58
86
  default:
59
87
  //something is wrong
60
- console.log('language detected not supported')
88
+ console.log('No supported language detected in project path')
61
89
  return
62
90
  }
63
91
 
64
92
  if (!config.applicationId) {
65
93
  config.applicationId = await auditController.dealWithNoAppId(config)
66
94
  }
95
+
96
+ console.log('') //empty log for space before spinner
67
97
  //send message to TS
68
- console.log('processing dependencies')
69
- const response = await treeUpload.commonSendSnapShot(messageToSend, config)
98
+ const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
99
+ startSpinner(reportSpinner)
100
+ const snapshotResponse = await treeUpload.commonSendSnapShot(
101
+ messageToSend,
102
+ config
103
+ )
104
+
105
+ //poll for completion
106
+ await pollForSnapshotCompletition(
107
+ config,
108
+ snapshotResponse.id,
109
+ reportSpinner
110
+ )
111
+ succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
112
+
113
+ await vulnerabilityReportV2(config, snapshotResponse.id)
114
+ if (config.save !== undefined) {
115
+ await auditSave.auditSave(config)
116
+ }
117
+ const endTime = performance.now() - startTime
118
+ const scanDurationMs = endTime - startTime
119
+
120
+ console.log(
121
+ `----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
122
+ )
70
123
  } else {
71
124
  if (filesFound.length === 0) {
72
- console.log('no compatible dependency files detected. Continuing...')
125
+ console.log(i18n.__('languageAnalysisNoLanguage'))
126
+ console.log(i18n.__('languageAnalysisNoLanguageHelpLine'))
127
+ throw new Error()
73
128
  } else {
74
- console.log(
75
- 'multiple language files detected, please use --project-path to specify a directory or the file where dependencies are declared'
129
+ throw new Error(
130
+ 'multiple language files detected, please use --file to specify a directory or the file where dependencies are declared'
76
131
  )
77
132
  }
78
133
  }
@@ -333,9 +333,16 @@ HTTPClient.prototype.checkLibrary = function checkLibrary(data) {
333
333
  return requestUtils.sendRequest({ method: 'post', options })
334
334
  }
335
335
 
336
- HTTPClient.prototype.getSbom = function getSbom(config) {
336
+ HTTPClient.prototype.getSbom = function getSbom(config, type) {
337
337
  const options = _.cloneDeep(this.requestOptions)
338
- options.url = createSbomCycloneDXUrl(config)
338
+ options.url = createSbomUrl(config, type)
339
+ return requestUtils.sendRequest({ method: 'get', options })
340
+ }
341
+
342
+ HTTPClient.prototype.getLatestVersion = function getLatestVersion() {
343
+ const options = _.cloneDeep(this.requestOptions)
344
+ options.url =
345
+ 'https://pkg.contrastsecurity.com/artifactory/cli/latest-version.txt'
339
346
  return requestUtils.sendRequest({ method: 'get', options })
340
347
  }
341
348
 
@@ -410,13 +417,13 @@ function createLibraryVulnerabilitiesUrl(config) {
410
417
  return `${config.host}/Contrast/api/ng/${config.organizationId}/libraries/artifactsByGroupNameVersion`
411
418
  }
412
419
 
413
- function createSpecificReportUrl(config, reportId) {
414
- return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/reports/${reportId}`
420
+ function createSpecificReportUrl(config, reportId, includeTree = false) {
421
+ return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/reports/${reportId}?&includeTree=${includeTree}`
415
422
  }
416
423
 
417
- function createSpecificReportWithProdUrl(config, reportId) {
418
- return createSpecificReportUrl(config, reportId).concat(
419
- `?nodesToInclude=PROD`
424
+ function createSpecificReportWithProdUrl(config, reportId, includeTree) {
425
+ return createSpecificReportUrl(config, reportId, includeTree).concat(
426
+ `&nodesToInclude=PROD`
420
427
  )
421
428
  }
422
429
 
@@ -428,8 +435,8 @@ function createDataUrl() {
428
435
  return `https://ardy.contrastsecurity.com/production`
429
436
  }
430
437
 
431
- function createSbomCycloneDXUrl(config) {
432
- return `${config.host}/Contrast/api/ng/${config.organizationId}/applications/${config.applicationId}/libraries/sbom/cyclonedx`
438
+ function createSbomUrl(config, type) {
439
+ return `${config.host}/Contrast/api/ng/${config.organizationId}/applications/${config.applicationId}/libraries/sbom/${type}`
433
440
  }
434
441
 
435
442
  module.exports = HTTPClient
@@ -39,9 +39,8 @@ const reportFailureError = () => {
39
39
  }
40
40
 
41
41
  const genericError = (missingCliOption: string) => {
42
- // prettier-ignore
43
- console.log(`*************************** ${i18n.__('yamlMissingParametersHeader')} ***************************\n${missingCliOption}`)
44
- console.error(i18n.__('yamlMissingParametersMessage'))
42
+ console.log(missingCliOption)
43
+ console.error(i18n.__('genericErrorMessage'))
45
44
  process.exit(1)
46
45
  }
47
46
 
@@ -1,12 +1,31 @@
1
- import latestVersion from 'latest-version'
2
1
  import { APP_VERSION } from '../constants/constants'
3
2
  import boxen from 'boxen'
4
3
  import chalk from 'chalk'
5
4
  import semver from 'semver'
5
+ import commonApi from '../utils/commonApi'
6
+ import { constants } from 'http2'
7
+ import { ContrastConf } from '../utils/getConfig'
6
8
 
7
- export async function findLatestCLIVersion(updateMessageHidden: boolean) {
8
- if (!updateMessageHidden) {
9
- const latestCLIVersion = await latestVersion('@contrast/contrast')
9
+ const getLatestVersion = async (config: any) => {
10
+ const client = commonApi.getHttpClient(config)
11
+ try {
12
+ const res = await client.getLatestVersion()
13
+ if (res.statusCode === constants.HTTP_STATUS_OK) {
14
+ return res.body
15
+ }
16
+ } catch (e) {
17
+ return
18
+ }
19
+ }
20
+
21
+ // @ts-ignore
22
+ export async function findLatestCLIVersion(config: ContrastConf) {
23
+ const messageHidden = config.get('updateMessageHidden') as boolean
24
+
25
+ if (!messageHidden) {
26
+ let latestCLIVersion: string = await getLatestVersion(config)
27
+ //strip key
28
+ latestCLIVersion = latestCLIVersion.substring(8)
10
29
 
11
30
  if (semver.lt(APP_VERSION, latestCLIVersion)) {
12
31
  const updateAvailableMessage = `Update available ${chalk.yellow(
@@ -5,15 +5,16 @@ const JAVA = 'JAVA'
5
5
  const RUBY = 'RUBY'
6
6
  const PYTHON = 'PYTHON'
7
7
  const GO = 'GO'
8
- // we set the langauge as Node instead of PHP since we're using the Node engine in TS
9
8
  const PHP = 'PHP'
10
9
  const JAVASCRIPT = 'JAVASCRIPT'
10
+ // Severity
11
11
  const LOW = 'LOW'
12
12
  const MEDIUM = 'MEDIUM'
13
13
  const HIGH = 'HIGH'
14
14
  const CRITICAL = 'CRITICAL'
15
+ // App
15
16
  const APP_NAME = 'contrast'
16
- const APP_VERSION = '1.0.7'
17
+ const APP_VERSION = '1.0.10'
17
18
  const TIMEOUT = 120000
18
19
  const HIGH_COLOUR = '#ff9900'
19
20
  const CRITICAL_COLOUR = '#e35858'
@@ -29,10 +30,13 @@ const NOTE_PRIORITY = 5
29
30
  const AUTH_UI_URL = 'https://cli-auth.contrastsecurity.com'
30
31
  const AUTH_CALLBACK_URL = 'https://cli-auth-api.contrastsecurity.com'
31
32
  const SARIF_FILE = 'SARIF'
33
+ const SBOM_CYCLONE_DX_FILE = 'cyclonedx'
34
+ const SBOM_SPDX_FILE = 'spdx'
32
35
  const CE_URL = 'https://ce.contrastsecurity.com/'
33
36
 
34
37
  module.exports = {
35
38
  supportedLanguages: { NODE, DOTNET, JAVA, RUBY, PYTHON, GO, PHP, JAVASCRIPT },
39
+ supportedLanguagesScan: { JAVASCRIPT, DOTNET, JAVA },
36
40
  LOW,
37
41
  MEDIUM,
38
42
  HIGH,
@@ -53,5 +57,7 @@ module.exports = {
53
57
  HIGH_PRIORITY,
54
58
  MEDIUM_PRIORITY,
55
59
  LOW_PRIORITY,
56
- NOTE_PRIORITY
60
+ NOTE_PRIORITY,
61
+ SBOM_CYCLONE_DX_FILE,
62
+ SBOM_SPDX_FILE
57
63
  }
@@ -15,13 +15,13 @@ const en_locales = () => {
15
15
  catchErrorMessage: 'Contrast UI error: ',
16
16
  dependenciesNote:
17
17
  'Please Note: We currently only support projects with one .csproj AND *.package.lock.json',
18
- languageAnalysisFailureMessage: 'SCA Analysis Failure',
18
+ languageAnalysisFailureMessage: 'SCA audit Failure',
19
19
  languageAnalysisFactoryFailureHeader: 'FAIL',
20
20
  libraryAnalysisError:
21
21
  'Please ensure the language parameter is set in accordance to the language specified on the project path.\nContrast CLI must be run in the same directory as the project manifest file OR the project_path parameter must be used to identify the directory containing the project manifest file.\n\nFor further information please read our usage guide, which can be accessed with the following command:\n\ncontrast-cli --help',
22
22
  yamlMissingParametersHeader: 'Missing Parameters',
23
- yamlMissingParametersMessage:
24
- 'The following parameters are required: \n \norganization-id \napi-key \nauthorization \nhost \nlanguage \n \nThey must be specified as a command line argument. \nFor further information please read our usage guide, which can be accessed with the following command:\ncontrast audit --help',
23
+ genericErrorMessage:
24
+ 'An error has occur please check your command again. For more information use the --help commands.',
25
25
  unauthenticatedErrorHeader: '401 error - Unauthenticated',
26
26
  unauthenticatedErrorMessage:
27
27
  'Please check the following keys are correct:\n--organization-id, --api-key or --authorization',
@@ -53,8 +53,10 @@ const en_locales = () => {
53
53
  "Identified project language as '%s' but found multiple project files: %s. Please specify which project file you would like analyzed with the %s CLI option.",
54
54
  languageAnalysisHasNoLockFile:
55
55
  "Identified project language as '%s' but no project lock file was found.",
56
+ languageAnalysisHasNoPackageJsonFile:
57
+ 'Identified project language as javascript but no package.json file was found.',
56
58
  languageAnalysisHasMultipleLockFiles:
57
- "Identified project language as '%s' but multiple project lock files were found: %s \n",
59
+ "Identified project language as '%s' but multiple project lock files were found.",
58
60
  languageAnalysisProjectFileError:
59
61
  "Identified project language as '%s' but no project file was found.",
60
62
  languageAnalysisProjectRootFileNameReadError:
@@ -64,17 +66,20 @@ const en_locales = () => {
64
66
  languageAnalysisProjectRootFileNameFailure:
65
67
  'Failed to get information about the file or directory @ %s because: ',
66
68
  languageAnalysisFailure: ' analysis failed because: ',
67
- languageAnalysisNoLanguage: 'No language detected in project path @ %s',
69
+ languageAnalysisNoLanguage:
70
+ 'We cannot detect a project, use -f <path> to specify a file or folder to analyze.',
71
+ languageAnalysisNoLanguageHelpLine: `${chalk.bold(
72
+ 'contrast audit --help'
73
+ )} for more information.`,
68
74
  NodeAnalysisFailure: 'NODE analysis failed because: ',
69
75
  phpAnalysisFailure: 'PHP analysis failed because: ',
70
- NodeParseNPM:
71
- "Failed to parse NODE package-lock.json file @ '%s' because: ",
76
+ NodeParseNPM: 'Failed to parse NODE package-lock.json file because: ',
72
77
  phpParseComposerLock:
73
78
  "Failed to parse PHP composer.lock file @ '%s' because: ",
74
79
  NodeReadNpmError:
75
80
  'Failed to read the package-lock.json file @ "%s" because: ',
76
81
  phpReadError: 'Failed to read the composer.lock file @ "%s" because: ',
77
- NodeParseYarn: "Failed to parse Node yarn.lock version 1 @ '%s' because: ",
82
+ NodeParseYarn: 'Failed to parse yarn.lock version %s because: ',
78
83
  NodeParseYarn2: "Failed to parse Node yarn.lock version 2 @ '%s' because: ",
79
84
  nodeReadProjectFileError:
80
85
  'Failed to read the NODE project file @ "%s" because: ',
@@ -118,8 +123,7 @@ const en_locales = () => {
118
123
  'Provide this if you want to catalogue an application',
119
124
  constantsLanguage:
120
125
  'Valid values are JAVA, DOTNET, NODE, PYTHON and RUBY. If there are multiple project configuration files in the project_path, language is also required. Also, provide this when cataloguing an application',
121
- constantsProjectPath:
122
- 'The directory root of a project/application that you would like analyzed. Defaults to current directory.',
126
+ constantsFilePath: `Path of the file you want to perform an SCA audit on. If no folder is specified, Contrast searches for dependency files in the working directory.`,
123
127
  constantsSilent: 'Silences JSON output.',
124
128
  constantsAppGroups:
125
129
  'Assign your application to one or more pre-existing groups when using the catalogue command. Group lists should be comma separated.',
@@ -137,16 +141,22 @@ const en_locales = () => {
137
141
  '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.',
138
142
  constantsReport: 'Display vulnerability information for this application',
139
143
  constantsFail:
140
- 'Set the process to fail if this option is set in combination with the --report and --cve_severity.',
144
+ 'Set the process to fail if this option is set in combination with --cve_severity.',
141
145
  failOptionErrorMessage:
142
- " FAIL - CVE's have been detected that match at least the cve_severity or cve_threshold option specified.",
146
+ ' FAIL - CVEs have been detected that match at least the cve_severity or cve_threshold option specified.',
143
147
  constantsSeverity:
144
- 'Combined with the --report command, allows the user to report libraries with vulnerabilities above a chosen severity level. For example, cve_severity medium only reports libraries with vulnerabilities at medium or higher severity. Values for level are high, medium or low.',
145
- constantsCount: "The number of CVE's that must be exceeded to fail a build",
148
+ 'Allows the user to report libraries with vulnerabilities above a chosen severity level. For example, cve_severity medium only reports libraries with vulnerabilities at medium or higher severity. Values for level are high, medium or low.',
149
+ constantsCount: 'The number of CVEs that must be exceeded to fail a build',
146
150
  constantsHeader: 'CodeSec by Contrast Security',
147
- constantsPrerequisitesContentScanLanguages: 'Java & JavaScript supported',
151
+ configHeader2: 'Config options',
152
+ clearHeader: '-c, --clear',
153
+ clearContent: 'Removes stored credentials',
154
+ constantsPrerequisitesContentScanLanguages:
155
+ 'Java, Javascript and .NET supported',
148
156
  constantsContrastContent:
149
- "Use the 'contrast' command for fast and accurate security analysis of your applications and APIs (Java, JavaScript and .NET ) as well as serverless functions (AWS lambda, Java and Python).",
157
+ 'Use the contrast command for fast and accurate security analysis of your applications, APIs, serverless functions, and libraries.',
158
+ constantsContrastCategories:
159
+ '\n Code: Java, .NET, .NET Core, JavaScript\n Serverless: AWS Lambda - Java, Python\n Libraries: Java, .NET, Node, Ruby, Python, Go, PHP\n',
150
160
  constantsUsageGuideContentRecommendation:
151
161
  'Our recommendation is that this is invoked as part of a CI pipeline so that running the cli is automated as part of your build process.',
152
162
  constantsPrerequisitesHeader: 'Pre-requisites',
@@ -249,7 +259,7 @@ const en_locales = () => {
249
259
  scanLabel:
250
260
  "adds a label to the scan - defaults to 'Started by CLI tool at current date'",
251
261
  constantsIgnoreDev:
252
- 'Combined with the --report command excludes developer dependencies from the vulnerabilities report. By default all dependencies are included in a report.',
262
+ 'Excludes developer dependencies from the results. All dependencies are included by default.',
253
263
  constantsCommands: 'Commands',
254
264
  constantsScanOptions: 'Scan Options',
255
265
  sbomError: 'All required parameters are not present.',
@@ -277,12 +287,17 @@ const en_locales = () => {
277
287
  'We only accept the following file types: \nJava - .jar, .war \nJavaScript - .js or .zip files',
278
288
  helpAuthSummary:
279
289
  'Authenticate Contrast using your Github or Google account',
280
- helpScanSummary: 'Perform static analysis on binaries / code artifacts',
281
- helpLambdaSummary: 'Perform scan on AWS Lambda functions',
290
+ helpAuditSummary:
291
+ '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).]',
292
+ helpScanSummary:
293
+ '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]',
294
+ helpLambdaSummary:
295
+ 'Performs a static security scan on an AWS lambda function. lambda --help (for options)',
282
296
  helpVersionSummary: 'Displays version of Contrast CLI',
283
297
  helpConfigSummary: 'Displays stored credentials',
284
298
  helpSummary: 'Displays usage guide',
285
299
  authName: 'auth',
300
+ auditName: 'audit',
286
301
  scanName: 'scan',
287
302
  lambdaName: 'lambda',
288
303
  versionName: 'version',
@@ -300,8 +315,7 @@ const en_locales = () => {
300
315
  scanOptionsVerboseSummary: ' Returns extended information to the terminal.',
301
316
  authSuccessMessage: 'Authentication successful',
302
317
  runAuthSuccessMessage:
303
- "Now you can use Contrast CLI \nRun 'contrast scan' on your file \n" +
304
- "or 'contrast help' to learn more about the capabilities.",
318
+ "Now you can use CodeSec by Contrast \nRun: \n'contrast scan' on your file \n'contrast audit' on a file or directory,\n'contrast lambda' on an AWS function.\nor 'contrast help' to learn more about the capabilities.",
305
319
  authWaitingMessage: 'Waiting for auth...',
306
320
  authTimedOutMessage: 'Auth Timed out, try again',
307
321
  zipErrorScan:
@@ -329,7 +343,7 @@ const en_locales = () => {
329
343
  'Supported runtimes: Java & Python',
330
344
  lambdaPrerequisitesContentLambdaDescriptionTitle: 'AWS Requirements\n',
331
345
  lambdaPrerequisitesContentLambdaDescription:
332
- 'Make sure you have the AWS credentials configured on your local environment. \nYou need the following AWS permissions configured on your IAM user:\n - Lambda: GetFunction, GetLayerVersionֿ\n - IAM: GetRolePolicy, GetPolicy, GetPolicyVersion, ListRolePolicies, ListAttachedRolePolicies',
346
+ 'Make sure you have the AWS credentials configured on your local environment. \nYou need the following AWS permissions configured on your IAM user:\n - Lambda: GetFunction, GetLayerVersion, ListFunctions\n - IAM: GetRolePolicy, GetPolicy, GetPolicyVersion, ListRolePolicies, ListAttachedRolePolicies',
333
347
  scanFileNameOption: '-f, --file',
334
348
  lambdaFunctionNameOption: '-f, --function-name',
335
349
  lambdaListFunctionsOption: '-l, --list-functions',
@@ -364,42 +378,49 @@ const en_locales = () => {
364
378
  'An error has occurred when trying to get the Project Id please check your internet connection or provide the Project Id manually',
365
379
  internalServerErrorHeader: '500 error - Internal server error',
366
380
  resourceLockedErrorHeader: '423 error - Resource is locked',
367
- auditHeader: 'Contrast Audit',
368
- auditHeaderMessage: `
369
- Performs software composition analysis (SCA) on your application/code time to show you the dependencies between open source libraries, including where vulnerabilities were introduced.\n
370
- Our recommendation is that this is invoked as part of a CI pipeline so that running the cli is automated as part of your build process.`,
381
+ auditHeader: 'Contrast audit help',
382
+ auditHeaderMessage:
383
+ "Use 'contrast audit' to analyze a project’s dependencies for vulnerabilities.",
371
384
  constantsAuditPrerequisitesContentSupportedLanguages:
372
385
  'Supported languages and their requirements are:',
373
- constantsAuditPrerequisitesContentJava: 'Java: ',
374
- constantsAuditPrerequisitesContentMessage: `
375
- pom.xml AND Maven build platform, including the dependency plugin.
376
- For a Gradle project (v4.8+) use build.gradle. A gradle-wrapper.properties file is also required.
377
- Kotlin is also supported requiring a build.gradle.kts file.`,
378
- constantsAuditPrerequisitesContentDotNet: '.NET framework and .NET core: ',
386
+ constantsAuditPrerequisitesJavaContentMessage: `
387
+ ${chalk.bold('Java:')} pom.xml ${chalk.bold(
388
+ 'and'
389
+ )} Maven build platform including the dependency plugin.
390
+ ${chalk.bold('Or')} build.gradle ${chalk.bold(
391
+ 'and'
392
+ )} gradle dependencies or ./gradlew dependencies must be supported`,
379
393
  constantsAuditPrerequisitesContentDotNetMessage: `
380
- MSBuild 15.0 or greater and have a packages.lock.json file are supported.\n
381
- Note: If the packages.lock.json file is unavailable it can be generated by setting RestorePackagesWithLockFile to true within each *.csproj file and running dotnet build.\n`,
382
- constantsAuditPrerequisitesContentLanguageNode: 'Node: ',
383
- constantsAuditPrerequisitesContentLanguageRuby: 'Ruby: ',
384
- constantsAuditPrerequisitesContentLanguagePython: 'Python: ',
385
- constantsAuditPrerequisitesContentLanguageNodeMessage:
386
- '*.package.json AND a lock file either *.package-lock.json or *.yarn.lock',
387
- constantsAuditPrerequisitesContentLanguageRubyMessage:
388
- 'gemfile AND gemfile.lock',
389
- constantsAuditPrerequisitesContentLanguagePythonMessage:
390
- 'pipfile AND pipfile.lock',
394
+ ${chalk.bold(
395
+ '.NET framework and .NET core:'
396
+ )} MSBuild 15.0 or greater and a packages.lock.json file.
397
+ Note: If the packages.lock.json file is unavailable it can be generated by setting RestorePackagesWithLockFile to true within each *.csproj file and running dotnet build.\n`,
398
+ constantsAuditPrerequisitesContentNodeMessage: `${chalk.bold(
399
+ 'Node:'
400
+ )} package.json and a lock file (either .package-lock.json or .yarn.lock.)\n`,
401
+ constantsAuditPrerequisitesContentRubyMessage: `${chalk.bold(
402
+ 'Ruby:'
403
+ )} gemfile and gemfile.lock\n`,
404
+ constantsAuditPrerequisitesContentPythonMessage: `${chalk.bold(
405
+ 'Python:'
406
+ )} pipfile and pipfile.lock\n`,
407
+ constantsAuditPrerequisitesContentGoMessage: `${chalk.bold(
408
+ 'Go:'
409
+ )} go.mod\n`,
410
+ constantsAuditPrerequisitesContentPHPMessage: `${chalk.bold(
411
+ 'PHP:'
412
+ )} composer.json and composer.lock\n`,
391
413
  constantsAuditOptions: 'Audit Options',
392
- auditOptionsIgnoreDevDependencies: '-igd, --ignore-dev',
393
- auditOptionsIgnoreDevDependenciesDescription: 'ignores DevDependencies',
394
- auditOptionsSave: '-s, --save',
395
414
  auditOptionsSaveDescription:
396
- 'saves the output in specified format Txt text, sbom',
415
+ 'Generate and save an SBOM (Software Bill of Materials)\n',
416
+ auditOptionsSaveOptionsDescription:
417
+ 'Valid options are: spdx, cyclonedx (cycloneDX is the default format)',
397
418
  scanNotCompleted:
398
419
  'Scan not completed. Check for framework and language support here: %s',
399
420
  auditNotCompleted: 'audit not completed. Please try again',
400
- scanNoVulnerabilitiesFound: '👏 No vulnerabilities found',
421
+ scanNoVulnerabilitiesFound: '🎉 No vulnerabilities found.',
401
422
  scanNoVulnerabilitiesFoundSecureCode: '👍 Your code looks secure.',
402
- scanNoVulnerabilitiesFoundGoodWork: '👏 Keep up the good work.',
423
+ scanNoVulnerabilitiesFoundGoodWork: ' Keep up the good work.',
403
424
  scanNoFiletypeSpecifiedForSave:
404
425
  'Please specify file type to save results to, accepted value is SARIF',
405
426
  auditSBOMSaveSuccess:
@@ -414,7 +435,8 @@ const en_locales = () => {
414
435
  auditReportFail: 'Report Retrieval Failed, please try again',
415
436
  auditReportSuccessMessage: 'Report successfully retrieved',
416
437
  auditReportFailureMessage: 'Unable to generate library report',
417
- auditSCAAnalysisBegins: 'Contrast SCA analysis begins',
438
+ auditSCAAnalysisBegins: 'Contrast SCA audit started',
439
+ auditSCAAnalysisComplete: 'Contrast audit complete',
418
440
  ...lambda
419
441
  }
420
442
  }
package/src/constants.js CHANGED
@@ -49,7 +49,6 @@ const scanOptionDefinitions = [
49
49
  },
50
50
  {
51
51
  name: 'project-path',
52
- alias: 'i',
53
52
  description:
54
53
  '{bold ' +
55
54
  i18n.__('constantsOptional') +
@@ -212,13 +211,14 @@ const auditOptionDefinitions = [
212
211
  i18n.__('constantsApplicationName')
213
212
  },
214
213
  {
215
- name: 'project-path',
216
- defaultValue: process.env.PWD,
214
+ name: 'file',
215
+ alias: 'f',
216
+ defaultValue: process.cwd().concat('/'),
217
217
  description:
218
218
  '{bold ' +
219
219
  i18n.__('constantsOptional') +
220
220
  '}: ' +
221
- i18n.__('constantsProjectPath')
221
+ i18n.__('constantsFilePath')
222
222
  },
223
223
  {
224
224
  name: 'app-groups',
@@ -266,15 +266,6 @@ const auditOptionDefinitions = [
266
266
  {
267
267
  name: 'maven-settings-path'
268
268
  },
269
- {
270
- name: 'language',
271
- alias: 'l',
272
- description:
273
- '{bold ' +
274
- i18n.__('constantsRequiredCatalogue') +
275
- '}: ' +
276
- i18n.__('constantsLanguage')
277
- },
278
269
  {
279
270
  name: 'organization-id',
280
271
  alias: 'o',
@@ -333,14 +324,33 @@ const auditOptionDefinitions = [
333
324
  '{bold ' +
334
325
  i18n.__('constantsOptional') +
335
326
  '}: ' +
336
- i18n.__('auditOptionsSaveDescription')
327
+ i18n.__('auditOptionsSaveDescription') +
328
+ i18n.__('auditOptionsSaveOptionsDescription')
329
+ },
330
+ {
331
+ name: 'experimental',
332
+ alias: 'e',
333
+ type: Boolean
334
+ },
335
+ {
336
+ name: 'timeout',
337
+ alias: 't',
338
+ type: Number,
339
+ description:
340
+ '{bold ' +
341
+ i18n.__('constantsOptional') +
342
+ '}: ' +
343
+ i18n.__('scanOptionsTimeoutSummary')
337
344
  }
338
345
  ]
339
346
 
340
347
  const mainUsageGuide = commandLineUsage([
341
348
  {
342
349
  header: i18n.__('constantsHeader'),
343
- content: [i18n.__('constantsContrastContent')]
350
+ content: [
351
+ i18n.__('constantsContrastContent'),
352
+ i18n.__('constantsContrastCategories')
353
+ ]
344
354
  },
345
355
  {
346
356
  header: i18n.__('constantsUsage'),
@@ -352,6 +362,7 @@ const mainUsageGuide = commandLineUsage([
352
362
  { name: i18n.__('authName'), summary: i18n.__('helpAuthSummary') },
353
363
  { name: i18n.__('scanName'), summary: i18n.__('helpScanSummary') },
354
364
  { name: i18n.__('lambdaName'), summary: i18n.__('helpLambdaSummary') },
365
+ { name: i18n.__('auditName'), summary: i18n.__('helpAuditSummary') },
355
366
  { name: i18n.__('versionName'), summary: i18n.__('helpVersionSummary') },
356
367
  { name: i18n.__('configName'), summary: i18n.__('helpConfigSummary') },
357
368
  { name: i18n.__('helpName'), summary: i18n.__('helpSummary') }
@@ -360,6 +371,12 @@ const mainUsageGuide = commandLineUsage([
360
371
  {
361
372
  content:
362
373
  '{underline https://developer.contrastsecurity.com/} \n For technical support head to {underline https://support.contrastsecurity.com}'
374
+ },
375
+ {
376
+ header: i18n.__('configHeader2'),
377
+ content: [
378
+ { name: i18n.__('clearHeader'), summary: i18n.__('clearContent') }
379
+ ]
363
380
  }
364
381
  ])
365
382