@contrast/contrast 1.0.0 → 1.0.3

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 (213) hide show
  1. package/.prettierignore +3 -0
  2. package/README.md +115 -78
  3. package/dist/audit/AnalysisEngine.js +37 -0
  4. package/dist/audit/catalogueApplication/catalogueApplication.js +36 -0
  5. package/dist/audit/dotnetAnalysisEngine/index.js +25 -0
  6. package/dist/audit/dotnetAnalysisEngine/parseLockFileContents.js +35 -0
  7. package/dist/audit/dotnetAnalysisEngine/parseProjectFileContents.js +15 -0
  8. package/dist/audit/dotnetAnalysisEngine/readLockFileContents.js +18 -0
  9. package/dist/audit/dotnetAnalysisEngine/readProjectFileContents.js +14 -0
  10. package/dist/audit/dotnetAnalysisEngine/sanitizer.js +9 -0
  11. package/dist/audit/goAnalysisEngine/index.js +17 -0
  12. package/dist/audit/goAnalysisEngine/parseProjectFileContents.js +164 -0
  13. package/dist/audit/goAnalysisEngine/readProjectFileContents.js +21 -0
  14. package/dist/audit/goAnalysisEngine/sanitizer.js +5 -0
  15. package/dist/audit/javaAnalysisEngine/index.js +34 -0
  16. package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +153 -0
  17. package/dist/audit/javaAnalysisEngine/parseProjectFileContents.js +353 -0
  18. package/dist/audit/javaAnalysisEngine/readProjectFileContents.js +98 -0
  19. package/dist/audit/javaAnalysisEngine/sanitizer.js +5 -0
  20. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +24 -0
  21. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +24 -0
  22. package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +35 -0
  23. package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +23 -0
  24. package/dist/audit/languageAnalysisEngine/commonApi.js +18 -0
  25. package/dist/audit/languageAnalysisEngine/constants.js +20 -0
  26. package/dist/audit/languageAnalysisEngine/filterProjectPath.js +20 -0
  27. package/dist/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +25 -0
  28. package/dist/audit/languageAnalysisEngine/getProjectRootFilenames.js +39 -0
  29. package/dist/audit/languageAnalysisEngine/index.js +39 -0
  30. package/dist/audit/languageAnalysisEngine/langugageAnalysisFactory.js +95 -0
  31. package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +121 -0
  32. package/dist/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +17 -0
  33. package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +257 -0
  34. package/dist/audit/languageAnalysisEngine/report/newReportingFeature.js +81 -0
  35. package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +133 -0
  36. package/dist/audit/languageAnalysisEngine/sendSnapshot.js +41 -0
  37. package/dist/audit/languageAnalysisEngine/util/capabilities.js +11 -0
  38. package/dist/audit/languageAnalysisEngine/util/generalAPI.js +39 -0
  39. package/dist/audit/languageAnalysisEngine/util/requestUtils.js +14 -0
  40. package/dist/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +40 -0
  41. package/dist/audit/nodeAnalysisEngine/index.js +31 -0
  42. package/dist/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +18 -0
  43. package/dist/audit/nodeAnalysisEngine/parseYarn2LockFileContents.js +51 -0
  44. package/dist/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +18 -0
  45. package/dist/audit/nodeAnalysisEngine/readNPMLockFileContents.js +17 -0
  46. package/dist/audit/nodeAnalysisEngine/readProjectFileContents.js +14 -0
  47. package/dist/audit/nodeAnalysisEngine/readYarnLockFileContents.js +24 -0
  48. package/dist/audit/nodeAnalysisEngine/sanitizer.js +9 -0
  49. package/dist/audit/phpAnalysisEngine/index.js +23 -0
  50. package/dist/audit/phpAnalysisEngine/parseLockFileContents.js +52 -0
  51. package/dist/audit/phpAnalysisEngine/readLockFileContents.js +13 -0
  52. package/dist/audit/phpAnalysisEngine/readProjectFileContents.js +16 -0
  53. package/dist/audit/phpAnalysisEngine/sanitizer.js +5 -0
  54. package/dist/audit/pythonAnalysisEngine/index.js +25 -0
  55. package/dist/audit/pythonAnalysisEngine/parsePipfileLockContents.js +17 -0
  56. package/dist/audit/pythonAnalysisEngine/parseProjectFileContents.js +21 -0
  57. package/dist/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +13 -0
  58. package/dist/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +14 -0
  59. package/dist/audit/pythonAnalysisEngine/sanitizer.js +7 -0
  60. package/dist/audit/rubyAnalysisEngine/index.js +25 -0
  61. package/dist/audit/rubyAnalysisEngine/parseGemfileLockContents.js +176 -0
  62. package/dist/audit/rubyAnalysisEngine/parsedGemfile.js +22 -0
  63. package/dist/audit/rubyAnalysisEngine/readGemfileContents.js +14 -0
  64. package/dist/audit/rubyAnalysisEngine/readGemfileLockContents.js +14 -0
  65. package/dist/audit/rubyAnalysisEngine/sanitizer.js +6 -0
  66. package/dist/commands/audit/auditConfig.js +25 -0
  67. package/dist/commands/audit/auditController.js +31 -0
  68. package/dist/commands/audit/help.js +52 -0
  69. package/dist/commands/audit/processAudit.js +18 -0
  70. package/dist/commands/audit/saveFile.js +11 -0
  71. package/dist/commands/auth/auth.js +20 -2
  72. package/dist/commands/config/config.js +19 -8
  73. package/dist/commands/scan/processScan.js +9 -13
  74. package/dist/common/HTTPClient.js +112 -13
  75. package/dist/common/errorHandling.js +65 -1
  76. package/dist/common/versionChecker.js +30 -0
  77. package/dist/constants/constants.js +4 -2
  78. package/dist/constants/lambda.js +32 -4
  79. package/dist/constants/locales.js +60 -21
  80. package/dist/constants.js +181 -21
  81. package/dist/index.js +50 -23
  82. package/dist/lambda/aws.js +14 -11
  83. package/dist/lambda/help.js +4 -0
  84. package/dist/lambda/lambda.js +50 -27
  85. package/dist/lambda/lambdaUtils.js +72 -0
  86. package/dist/lambda/logUtils.js +11 -1
  87. package/dist/lambda/scanDetailCompletion.js +4 -4
  88. package/dist/lambda/scanRequest.js +11 -5
  89. package/dist/lambda/utils.js +110 -53
  90. package/dist/sbom/generateSbom.js +20 -0
  91. package/dist/scan/autoDetection.js +0 -32
  92. package/dist/scan/fileUtils.js +1 -1
  93. package/dist/scan/help.js +14 -40
  94. package/dist/scan/populateProjectIdAndProjectName.js +5 -0
  95. package/dist/scan/saveResults.js +14 -0
  96. package/dist/scan/scan.js +105 -40
  97. package/dist/scan/scanConfig.js +39 -0
  98. package/dist/scan/scanController.js +19 -16
  99. package/dist/scan/scanResults.js +24 -16
  100. package/dist/utils/commonApi.js +3 -3
  101. package/dist/utils/paramsUtil/commandlineParams.js +1 -20
  102. package/dist/utils/paramsUtil/paramHandler.js +3 -6
  103. package/dist/utils/parsedCLIOptions.js +14 -8
  104. package/dist/utils/requestUtils.js +1 -1
  105. package/dist/utils/saveFile.js +19 -0
  106. package/package.json +26 -21
  107. package/src/audit/AnalysisEngine.js +103 -0
  108. package/src/audit/catalogueApplication/catalogueApplication.js +42 -0
  109. package/src/audit/dotnetAnalysisEngine/index.js +26 -0
  110. package/src/audit/dotnetAnalysisEngine/parseLockFileContents.js +47 -0
  111. package/src/audit/dotnetAnalysisEngine/parseProjectFileContents.js +29 -0
  112. package/src/audit/dotnetAnalysisEngine/readLockFileContents.js +30 -0
  113. package/src/audit/dotnetAnalysisEngine/readProjectFileContents.js +26 -0
  114. package/src/audit/dotnetAnalysisEngine/sanitizer.js +11 -0
  115. package/src/audit/goAnalysisEngine/index.js +18 -0
  116. package/src/audit/goAnalysisEngine/parseProjectFileContents.js +209 -0
  117. package/src/audit/goAnalysisEngine/readProjectFileContents.js +31 -0
  118. package/src/audit/goAnalysisEngine/sanitizer.js +7 -0
  119. package/src/audit/javaAnalysisEngine/index.js +41 -0
  120. package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +222 -0
  121. package/src/audit/javaAnalysisEngine/parseProjectFileContents.js +420 -0
  122. package/src/audit/javaAnalysisEngine/readProjectFileContents.js +141 -0
  123. package/src/audit/javaAnalysisEngine/sanitizer.js +6 -0
  124. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +35 -0
  125. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +41 -0
  126. package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +54 -0
  127. package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +32 -0
  128. package/src/audit/languageAnalysisEngine/commonApi.js +20 -0
  129. package/src/audit/languageAnalysisEngine/constants.js +23 -0
  130. package/src/audit/languageAnalysisEngine/filterProjectPath.js +21 -0
  131. package/src/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +41 -0
  132. package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +72 -0
  133. package/src/audit/languageAnalysisEngine/index.js +45 -0
  134. package/src/audit/languageAnalysisEngine/langugageAnalysisFactory.js +126 -0
  135. package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +177 -0
  136. package/src/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +27 -0
  137. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.js +303 -0
  138. package/src/audit/languageAnalysisEngine/report/newReportingFeature.js +124 -0
  139. package/src/audit/languageAnalysisEngine/report/reportingFeature.js +190 -0
  140. package/src/audit/languageAnalysisEngine/sendSnapshot.js +51 -0
  141. package/src/audit/languageAnalysisEngine/util/capabilities.js +12 -0
  142. package/src/audit/languageAnalysisEngine/util/generalAPI.js +43 -0
  143. package/src/audit/languageAnalysisEngine/util/requestUtils.js +17 -0
  144. package/src/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +49 -0
  145. package/src/audit/nodeAnalysisEngine/index.js +35 -0
  146. package/src/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +20 -0
  147. package/src/audit/nodeAnalysisEngine/parseYarn2LockFileContents.js +63 -0
  148. package/src/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +26 -0
  149. package/src/audit/nodeAnalysisEngine/readNPMLockFileContents.js +23 -0
  150. package/src/audit/nodeAnalysisEngine/readProjectFileContents.js +27 -0
  151. package/src/audit/nodeAnalysisEngine/readYarnLockFileContents.js +36 -0
  152. package/src/audit/nodeAnalysisEngine/sanitizer.js +11 -0
  153. package/src/audit/phpAnalysisEngine/index.js +27 -0
  154. package/src/audit/phpAnalysisEngine/parseLockFileContents.js +60 -0
  155. package/src/audit/phpAnalysisEngine/readLockFileContents.js +14 -0
  156. package/src/audit/phpAnalysisEngine/readProjectFileContents.js +25 -0
  157. package/src/audit/phpAnalysisEngine/sanitizer.js +4 -0
  158. package/src/audit/pythonAnalysisEngine/index.js +55 -0
  159. package/src/audit/pythonAnalysisEngine/parsePipfileLockContents.js +23 -0
  160. package/src/audit/pythonAnalysisEngine/parseProjectFileContents.js +33 -0
  161. package/src/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +16 -0
  162. package/src/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +22 -0
  163. package/src/audit/pythonAnalysisEngine/sanitizer.js +9 -0
  164. package/src/audit/rubyAnalysisEngine/index.js +30 -0
  165. package/src/audit/rubyAnalysisEngine/parseGemfileLockContents.js +215 -0
  166. package/src/audit/rubyAnalysisEngine/parsedGemfile.js +39 -0
  167. package/src/audit/rubyAnalysisEngine/readGemfileContents.js +18 -0
  168. package/src/audit/rubyAnalysisEngine/readGemfileLockContents.js +17 -0
  169. package/src/audit/rubyAnalysisEngine/sanitizer.js +8 -0
  170. package/src/commands/audit/auditConfig.ts +30 -0
  171. package/src/commands/audit/auditController.ts +31 -0
  172. package/src/commands/audit/help.ts +48 -0
  173. package/src/commands/audit/processAudit.ts +18 -0
  174. package/src/commands/audit/saveFile.ts +6 -0
  175. package/src/commands/auth/auth.js +26 -2
  176. package/src/commands/config/config.js +22 -8
  177. package/src/commands/scan/processScan.js +9 -13
  178. package/src/common/HTTPClient.js +149 -14
  179. package/src/common/errorHandling.ts +85 -2
  180. package/src/common/versionChecker.ts +39 -0
  181. package/src/constants/constants.js +5 -4
  182. package/src/constants/lambda.js +45 -4
  183. package/src/constants/locales.js +76 -26
  184. package/src/constants.js +204 -23
  185. package/src/index.ts +67 -27
  186. package/src/lambda/aws.ts +13 -12
  187. package/src/lambda/help.ts +4 -0
  188. package/src/lambda/lambda.ts +53 -34
  189. package/src/lambda/lambdaUtils.ts +111 -0
  190. package/src/lambda/logUtils.ts +19 -1
  191. package/src/lambda/scanDetailCompletion.ts +4 -4
  192. package/src/lambda/scanRequest.ts +13 -11
  193. package/src/lambda/utils.ts +149 -81
  194. package/src/sbom/generateSbom.ts +17 -0
  195. package/src/scan/autoDetection.js +0 -29
  196. package/src/scan/fileUtils.js +1 -1
  197. package/src/scan/help.js +14 -45
  198. package/src/scan/populateProjectIdAndProjectName.js +5 -0
  199. package/src/scan/saveResults.js +14 -0
  200. package/src/scan/scan.js +127 -58
  201. package/src/scan/scanConfig.js +54 -0
  202. package/src/scan/scanController.js +22 -15
  203. package/src/scan/scanResults.js +32 -19
  204. package/src/utils/commonApi.js +2 -3
  205. package/src/utils/getConfig.ts +2 -0
  206. package/src/utils/paramsUtil/commandlineParams.js +1 -26
  207. package/src/utils/paramsUtil/paramHandler.js +3 -7
  208. package/src/utils/parsedCLIOptions.js +11 -9
  209. package/src/utils/requestUtils.js +1 -1
  210. package/src/utils/saveFile.js +19 -0
  211. package/dist/lambda/scanDetail.js +0 -30
  212. package/dist/scan/fileFinder.js +0 -15
  213. package/dist/utils/paramsUtil/yamlParams.js +0 -6
@@ -0,0 +1,48 @@
1
+ import commandLineUsage from 'command-line-usage'
2
+ import i18n from 'i18n'
3
+ import constants from '../../constants'
4
+
5
+ const auditUsageGuide = commandLineUsage([
6
+ {
7
+ header: i18n.__('auditHeader'),
8
+ content: [i18n.__('auditHeaderMessage')]
9
+ },
10
+ {
11
+ header: i18n.__('constantsPrerequisitesHeader'),
12
+ content: [
13
+ '{bold ' +
14
+ i18n.__('constantsAuditPrerequisitesContentSupportedLanguages') +
15
+ '}',
16
+ '{bold ' +
17
+ i18n.__('constantsAuditPrerequisitesContentJava') +
18
+ '}' +
19
+ i18n.__('constantsAuditPrerequisitesContentMessage'),
20
+ '',
21
+ '{italic ' + i18n.__('constantsJavaNote') + '}',
22
+ '{italic ' + i18n.__('constantsJavaNoteGradle') + '}',
23
+ '',
24
+ '{bold ' +
25
+ i18n.__('constantsAuditPrerequisitesContentDotNet') +
26
+ '}' +
27
+ i18n.__('constantsAuditPrerequisitesContentDotNetMessage'),
28
+ '{bold ' +
29
+ i18n.__('constantsAuditPrerequisitesContentLanguageNode') +
30
+ '}' +
31
+ i18n.__('constantsAuditPrerequisitesContentLanguageNodeMessage'),
32
+ '{bold ' +
33
+ i18n.__('constantsAuditPrerequisitesContentLanguageRuby') +
34
+ '}' +
35
+ i18n.__('constantsAuditPrerequisitesContentLanguageRubyMessage'),
36
+ '{bold ' +
37
+ i18n.__('constantsAuditPrerequisitesContentLanguagePython') +
38
+ '}' +
39
+ i18n.__('constantsAuditPrerequisitesContentLanguagePythonMessage')
40
+ ]
41
+ },
42
+ {
43
+ header: i18n.__('constantsAuditOptions'),
44
+ optionList: constants.commandLineDefinitions.auditOptionDefinitions
45
+ }
46
+ ])
47
+
48
+ export { auditUsageGuide }
@@ -0,0 +1,18 @@
1
+ import { startAudit } from './auditController'
2
+ import { getAuditConfig } from './auditConfig'
3
+ import { auditUsageGuide } from './help'
4
+
5
+ export type parameterInput = string[]
6
+
7
+ export const processAudit = async (argv: parameterInput) => {
8
+ if (argv.indexOf('--help') != -1) {
9
+ printHelpMessage()
10
+ process.exit(1)
11
+ }
12
+ const config = getAuditConfig(argv)
13
+ const auditResults = await startAudit(config)
14
+ }
15
+
16
+ const printHelpMessage = () => {
17
+ console.log(auditUsageGuide)
18
+ }
@@ -0,0 +1,6 @@
1
+ import fs from 'fs'
2
+
3
+ export default function saveFile(config: any, rawResults: any) {
4
+ const fileName = `${config.applicationId}-sbom-cyclonedx.json`
5
+ fs.writeFileSync(fileName, JSON.stringify(rawResults))
6
+ }
@@ -11,8 +11,21 @@ const {
11
11
  succeedSpinner
12
12
  } = require('../../utils/oraWrapper')
13
13
  const { TIMEOUT, AUTH_UI_URL } = require('../../constants/constants')
14
+ const parsedCLIOptions = require('../../utils/parsedCLIOptions')
15
+ const constants = require('../../constants')
16
+ const commandLineUsage = require('command-line-usage')
17
+
18
+ const processAuth = async (argv, config) => {
19
+ let authParams = parsedCLIOptions.getCommandLineArgsCustom(
20
+ argv,
21
+ constants.commandLineDefinitions.authOptionDefinitions
22
+ )
23
+
24
+ if (authParams.help) {
25
+ console.log(authUsageGuide)
26
+ process.exit(0)
27
+ }
14
28
 
15
- const processAuth = async config => {
16
29
  const token = uuidv4()
17
30
  const url = `${AUTH_UI_URL}/?token=${token}`
18
31
 
@@ -44,7 +57,7 @@ const isAuthComplete = async (token, timeout, config) => {
44
57
  let result = await pollAuthResult(token, client)
45
58
  if (result.statusCode === 200) {
46
59
  succeedSpinner(authSpinner, i18n.__('authSuccessMessage'))
47
- console.log(i18n.__('runScanMessage'))
60
+ console.log(i18n.__('runAuthSuccessMessage'))
48
61
  return result.body
49
62
  }
50
63
  let endTime = new Date() - startTime
@@ -68,6 +81,17 @@ const pollAuthResult = async (token, client) => {
68
81
  })
69
82
  }
70
83
 
84
+ const authUsageGuide = commandLineUsage([
85
+ {
86
+ header: i18n.__('authHeader'),
87
+ content: [i18n.__('constantsAuthHeaderContents')]
88
+ },
89
+ {
90
+ header: i18n.__('constantsAuthUsageHeader'),
91
+ content: [i18n.__('constantsAuthUsageContents')]
92
+ }
93
+ ])
94
+
71
95
  module.exports = {
72
96
  processAuth: processAuth
73
97
  }
@@ -1,15 +1,19 @@
1
- const commandLineArgs = require('command-line-args')
1
+ const parsedCLIOptions = require('../../utils/parsedCLIOptions')
2
+ const constants = require('../../constants')
3
+ const commandLineUsage = require('command-line-usage')
4
+ const i18n = require('i18n')
2
5
 
3
6
  const processConfig = (argv, config) => {
4
- const options = [{ name: 'clear', alias: 'c', type: Boolean }]
5
-
6
7
  try {
7
- const configOptions = commandLineArgs(options, {
8
+ let configParams = parsedCLIOptions.getCommandLineArgsCustom(
8
9
  argv,
9
- caseInsensitive: true,
10
- camelCase: true
11
- })
12
- if (configOptions.clear) {
10
+ constants.commandLineDefinitions.configOptionDefinitions
11
+ )
12
+ if (configParams.help) {
13
+ console.log(configUsageGuide)
14
+ process.exit(0)
15
+ }
16
+ if (configParams.clear) {
13
17
  config.clear()
14
18
  } else {
15
19
  console.log(JSON.parse(JSON.stringify(config.store)))
@@ -20,6 +24,16 @@ const processConfig = (argv, config) => {
20
24
  }
21
25
  }
22
26
 
27
+ const configUsageGuide = commandLineUsage([
28
+ {
29
+ header: i18n.__('configHeader')
30
+ },
31
+ {
32
+ content: [i18n.__('constantsConfigUsageContents')],
33
+ optionList: constants.commandLineDefinitions.configOptionDefinitions
34
+ }
35
+ ])
36
+
23
37
  module.exports = {
24
38
  processConfig: processConfig
25
39
  }
@@ -1,29 +1,25 @@
1
1
  const { startScan } = require('../../scan/scanController')
2
- const paramHandler = require('../../utils/paramsUtil/paramHandler')
3
2
  const { formatScanOutput } = require('../../scan/scan')
4
3
  const { scanUsageGuide } = require('../../scan/help')
4
+ const scanConfig = require('../../scan/scanConfig')
5
+ const { saveScanFile } = require('../../utils/saveFile')
5
6
 
6
- const processScan = async () => {
7
- let getScanSubCommands = paramHandler.getScanSubCommands()
8
- if (getScanSubCommands.help) {
9
- printHelpMessage()
10
- process.exit(1)
11
- }
7
+ const processScan = async argvMain => {
8
+ let config = scanConfig.getScanConfig(argvMain)
12
9
 
13
- let scanResults = await startScan()
10
+ let scanResults = await startScan(config)
14
11
  if (scanResults) {
15
12
  formatScanOutput(
16
13
  scanResults?.projectOverview,
17
14
  scanResults?.scanResultsInstances
18
15
  )
19
16
  }
20
- }
21
17
 
22
- const printHelpMessage = () => {
23
- console.log(scanUsageGuide)
18
+ if (config.save !== undefined) {
19
+ await saveScanFile(config, scanResults)
20
+ }
24
21
  }
25
22
 
26
23
  module.exports = {
27
- processScan,
28
- printHelpMessage
24
+ processScan
29
25
  }
@@ -6,10 +6,10 @@ const { AUTH_CALLBACK_URL } = require('../constants/constants')
6
6
  function HTTPClient(config) {
7
7
  const apiKey = config.apiKey
8
8
  const authToken = config.authorization
9
- // this.rejectUnauthorized = !additionalParams.ignore_cert_errors
9
+ this.rejectUnauthorized = !config.ignoreCertErrors
10
10
 
11
- const superApiKey = config.super_api_key
12
- const superAuthToken = config.super_authorization
11
+ const superApiKey = config.superApiKey
12
+ const superAuthToken = config.superAuthorization
13
13
 
14
14
  this.requestOptions = {
15
15
  forever: true,
@@ -91,6 +91,15 @@ HTTPClient.prototype.getSpecificScanResult = function getSpecificScanResult(
91
91
  return requestUtils.sendRequest({ method: 'get', options })
92
92
  }
93
93
 
94
+ HTTPClient.prototype.getSpecificScanResultSarif = function getSpecificScanResultSarif(
95
+ config,
96
+ scanId
97
+ ) {
98
+ const options = _.cloneDeep(this.requestOptions)
99
+ options.url = createRawOutputURL(config, scanId)
100
+ return requestUtils.sendRequest({ method: 'get', options })
101
+ }
102
+
94
103
  HTTPClient.prototype.getScanId = function getScanId(config, codeArtifactId) {
95
104
  const options = _.cloneDeep(this.requestOptions)
96
105
  let url = createGetScanIdURL(config)
@@ -119,8 +128,10 @@ HTTPClient.prototype.createProjectId = function createProjectId(config) {
119
128
 
120
129
  options.body = {
121
130
  name: config.name,
122
- archived: 'false',
123
- language: config.language
131
+ archived: 'false'
132
+ }
133
+ if (config.language) {
134
+ options.body.language = config.language
124
135
  }
125
136
  options.url = createHarmonyProjectsUrl(config)
126
137
  return requestUtils.sendRequest({ method: 'post', options })
@@ -159,6 +170,80 @@ HTTPClient.prototype.pollForAuth = function pollForAuth(token) {
159
170
  return requestUtils.sendRequest({ method: 'post', options })
160
171
  }
161
172
 
173
+ HTTPClient.prototype.catalogueCommand = function catalogueCommand(config) {
174
+ const options = _.cloneDeep(this.requestOptions)
175
+ let url = createAppCreateURL(config)
176
+ options.url = url
177
+
178
+ let requestBody = {}
179
+ requestBody.name = config.applicationName
180
+ requestBody.language = config.language.toUpperCase()
181
+ requestBody.appGroups = config.appGroups
182
+ requestBody.metadata = config.metadata
183
+ requestBody.tags = config.tags
184
+ requestBody.code = config.code
185
+ options.body = requestBody
186
+
187
+ return requestUtils.sendRequest({ method: 'post', options })
188
+ }
189
+
190
+ HTTPClient.prototype.sendSnapshot = function sendSnapshot(requestBody, config) {
191
+ const options = _.cloneDeep(this.requestOptions)
192
+ let url = createSnapshotURL(config)
193
+ options.url = url
194
+ options.body = requestBody
195
+ return requestUtils.sendRequest({ method: 'post', options })
196
+ }
197
+
198
+ HTTPClient.prototype.getReport = function getReport(config) {
199
+ const options = _.cloneDeep(this.requestOptions)
200
+ let url = createReportUrl(config)
201
+ options.url = url
202
+
203
+ return requestUtils.sendRequest({ method: 'get', options })
204
+ }
205
+
206
+ HTTPClient.prototype.getSpecificReport = function getSpecificReport(
207
+ config,
208
+ reportId
209
+ ) {
210
+ const options = _.cloneDeep(this.requestOptions)
211
+ let url = createSpecificReportUrl(config, reportId)
212
+ options.url = url
213
+
214
+ return requestUtils.sendRequest({ method: 'get', options })
215
+ }
216
+
217
+ HTTPClient.prototype.getLibraryVulnerabilities = function getLibraryVulnerabilities(
218
+ requestBody,
219
+ config
220
+ ) {
221
+ const options = _.cloneDeep(this.requestOptions)
222
+ let url = createLibraryVulnerabilitiesUrl(config)
223
+ options.url = url
224
+ options.body = requestBody
225
+
226
+ return requestUtils.sendRequest({ method: 'put', options })
227
+ }
228
+
229
+ HTTPClient.prototype.getAppId = function getAppId(config) {
230
+ const options = _.cloneDeep(this.requestOptions)
231
+ let url = createAppNameUrl(config)
232
+ options.url = url
233
+ return requestUtils.sendRequest({ method: 'get', options })
234
+ }
235
+
236
+ HTTPClient.prototype.getDependencyTree = function getReport(
237
+ orgUuid,
238
+ appId,
239
+ reportId
240
+ ) {
241
+ const options = _.cloneDeep(this.requestOptions)
242
+ let url = createGetDependencyTree(options.uri, orgUuid, appId, reportId)
243
+ options.url = url
244
+ return requestUtils.sendRequest({ method: 'get', options })
245
+ }
246
+
162
247
  // serverless - lambda
163
248
  function getServerlessHost(config = {}) {
164
249
  const originalHost = config?.host || config?.get('host')
@@ -195,10 +280,10 @@ function createScanResultsGetUrl(config, params, scanId, functionArn) {
195
280
 
196
281
  HTTPClient.prototype.postFunctionScan = async function postFunctionScan(
197
282
  config,
198
- parameters,
283
+ params,
199
284
  body
200
285
  ) {
201
- const url = createScanFunctionPostUrl(config, parameters)
286
+ const url = createScanFunctionPostUrl(config, params)
202
287
  const options = { ...this.requestOptions, body, url }
203
288
 
204
289
  return requestUtils.sendRequest({ method: 'post', options })
@@ -206,10 +291,10 @@ HTTPClient.prototype.postFunctionScan = async function postFunctionScan(
206
291
 
207
292
  HTTPClient.prototype.getScanResources = async function getScanResources(
208
293
  config,
209
- parameters,
294
+ params,
210
295
  scanId
211
296
  ) {
212
- const url = createScanResourcesGetUrl(config, parameters, scanId)
297
+ const url = createScanResourcesGetUrl(config, params, scanId)
213
298
  const options = { ...this.requestOptions, url }
214
299
 
215
300
  return requestUtils.sendRequest({ method: 'get', options })
@@ -217,27 +302,41 @@ HTTPClient.prototype.getScanResources = async function getScanResources(
217
302
 
218
303
  HTTPClient.prototype.getFunctionScanResults = async function getFunctionScanResults(
219
304
  config,
220
- parameters,
305
+ params,
221
306
  scanId,
222
307
  functionArn
223
308
  ) {
224
- const url = createScanResultsGetUrl(config, parameters, scanId, functionArn)
309
+ const url = createScanResultsGetUrl(config, params, scanId, functionArn)
225
310
  const options = { ...this.requestOptions, url }
226
311
 
227
312
  return requestUtils.sendRequest({ method: 'get', options })
228
313
  }
229
314
 
315
+ HTTPClient.prototype.checkLibrary = function checkLibrary(data) {
316
+ const options = _.cloneDeep(this.requestOptions)
317
+ let url = createDataUrl()
318
+ options.url = url
319
+ options.body = data
320
+ return requestUtils.sendRequest({ method: 'post', options })
321
+ }
322
+
323
+ HTTPClient.prototype.getSbom = function getSbom(config) {
324
+ const options = _.cloneDeep(this.requestOptions)
325
+ options.url = createSbomCycloneDXUrl(config)
326
+ return requestUtils.sendRequest({ method: 'get', options })
327
+ }
328
+
230
329
  // scan
231
330
  const createGetScanIdURL = config => {
232
331
  return `${config.host}/Contrast/api/sast/v1/organizations/${config.organizationId}/projects/${config.projectId}/scans/`
233
332
  }
234
333
 
235
334
  const createScanResultsInstancesURL = (config, scanId) => {
236
- return `${config.host}/Contrast/api/sast/v1/organizations/${config.organizationId}/projects/${config.projectId}/scans/${scanId}/result-instances?sort=severity,asc`
335
+ return `${config.host}/Contrast/api/sast/v1/organizations/${config.organizationId}/projects/${config.projectId}/scans/${scanId}/result-instances/info?size=50&page=0&last=false&sort=severity,asc`
237
336
  }
238
337
 
239
- const createRawOutputURL = (config, codeArtifactId) => {
240
- return `${config.host}/Contrast/api/sast/v1/organizations/${config.organizationId}/projects/${config.projectId}/scans/${codeArtifactId}/raw-output`
338
+ const createRawOutputURL = (config, scanId) => {
339
+ return `${config.host}/Contrast/api/sast/v1/organizations/${config.organizationId}/projects/${config.projectId}/scans/${scanId}/raw-output`
241
340
  }
242
341
 
243
342
  const createSpecificScanResultURL = (config, scanId) => {
@@ -264,6 +363,42 @@ const pollForAuthUrl = () => {
264
363
  return `${AUTH_CALLBACK_URL}/auth/credentials`
265
364
  }
266
365
 
366
+ function createSnapshotURL(config) {
367
+ return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/snapshots`
368
+ }
369
+
370
+ const createAppCreateURL = config => {
371
+ return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/create`
372
+ }
373
+
374
+ const createAppNameUrl = config => {
375
+ return `${config.host}/Contrast/api/ng/${config.organizationId}/applications/name?filterText=${config.applicationName}`
376
+ }
377
+
378
+ function createLibraryVulnerabilitiesUrl(config) {
379
+ return `${config.host}/Contrast/api/ng/${config.organizationId}/libraries/artifactsByGroupNameVersion`
380
+ }
381
+
382
+ function createReportUrl(config) {
383
+ return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/reports`
384
+ }
385
+
386
+ function createSpecificReportUrl(config, reportId) {
387
+ return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/reports/${reportId}?nodesToInclude=PROD`
388
+ }
389
+
390
+ function createDataUrl() {
391
+ return `https://ardy.contrastsecurity.com/production`
392
+ }
393
+
394
+ const createGetDependencyTree = (protocol, orgUuid, appId, reportId) => {
395
+ return `${protocol}/Contrast/api/ng/sca/organizations/${orgUuid}/applications/${appId}/reports/${reportId}`
396
+ }
397
+
398
+ function createSbomCycloneDXUrl(config) {
399
+ return `${config.host}/Contrast/api/ng/${config.organizationId}/applications/${config.applicationId}/libraries/sbom/cyclonedx`
400
+ }
401
+
267
402
  module.exports = HTTPClient
268
403
  module.exports.pollForAuthUrl = pollForAuthUrl
269
404
  module.exports.getServerlessHost = getServerlessHost
@@ -1,4 +1,58 @@
1
1
  import i18n from 'i18n'
2
+ import { sortBy } from 'lodash'
3
+
4
+ const handleResponseErrors = (res: any, api: string) => {
5
+ if (res.statusCode === 400) {
6
+ api === 'catalogue' ? badRequestError(true) : badRequestError(false)
7
+ } else if (res.statusCode === 401) {
8
+ unauthenticatedError()
9
+ } else if (res.statusCode === 403) {
10
+ forbiddenError()
11
+ } else if (res.statusCode === 407) {
12
+ proxyError()
13
+ } else {
14
+ if (api === 'snapshot' || api === 'catalogue') {
15
+ snapshotFailureError()
16
+ }
17
+ if (api === 'vulnerabilities') {
18
+ vulnerabilitiesFailureError()
19
+ }
20
+ if (api === 'report') {
21
+ reportFailureError()
22
+ }
23
+ }
24
+ }
25
+
26
+ const libraryAnalysisError = () => {
27
+ console.log(i18n.__('libraryAnalysisError'))
28
+ }
29
+
30
+ const snapshotFailureError = () => {
31
+ console.log(
32
+ '\n ******************************** ' +
33
+ i18n.__('snapshotFailureHeader') +
34
+ ' *********************************\n' +
35
+ i18n.__('snapshotFailureMessage')
36
+ )
37
+ }
38
+
39
+ const vulnerabilitiesFailureError = () => {
40
+ console.log(
41
+ '\n ******************************** ' +
42
+ i18n.__('snapshotFailureHeader') +
43
+ ' *********************************\n' +
44
+ i18n.__('vulnerabilitiesFailureMessage')
45
+ )
46
+ }
47
+
48
+ const reportFailureError = () => {
49
+ console.log(
50
+ '\n ******************************** ' +
51
+ i18n.__('snapshotFailureHeader') +
52
+ ' *********************************\n' +
53
+ i18n.__('reportFailureMessage')
54
+ )
55
+ }
2
56
 
3
57
  const genericError = (missingCliOption: string) => {
4
58
  // prettier-ignore
@@ -19,6 +73,7 @@ const badRequestError = (catalogue: boolean) => {
19
73
 
20
74
  const forbiddenError = () => {
21
75
  generalError('forbiddenRequestErrorHeader', 'forbiddenRequestErrorMessage')
76
+ process.exit(1)
22
77
  }
23
78
 
24
79
  const proxyError = () => {
@@ -51,7 +106,7 @@ const getErrorMessage = (header: string, message?: string) => {
51
106
  const multiLine = message?.includes('\n')
52
107
  let finalMessage = ''
53
108
 
54
- // i18n split the line if it includes "\n"
109
+ // i18n split the line if it includes '\n'
55
110
  if (multiLine) {
56
111
  finalMessage = `\n${message}`
57
112
  } else if (message) {
@@ -66,6 +121,31 @@ const generalError = (header: string, message?: string) => {
66
121
  console.log(finalMessage)
67
122
  }
68
123
 
124
+ const findCommandOnError = (unknownOptions: string[]) => {
125
+ const commandKeywords = {
126
+ auth: 'auth',
127
+ audit: 'audit',
128
+ scan: 'scan',
129
+ lambda: 'lambda',
130
+ config: 'config'
131
+ }
132
+
133
+ const containsCommandKeyword = unknownOptions.some(
134
+ // @ts-ignore
135
+ command => commandKeywords[command]
136
+ )
137
+
138
+ if (containsCommandKeyword) {
139
+ const foundCommands = unknownOptions.filter(
140
+ // @ts-ignore
141
+ command => commandKeywords[command]
142
+ )
143
+
144
+ //return the first command found
145
+ return foundCommands[0]
146
+ }
147
+ }
148
+
69
149
  export {
70
150
  genericError,
71
151
  unauthenticatedError,
@@ -75,5 +155,8 @@ export {
75
155
  failOptionError,
76
156
  hostWarningError,
77
157
  generalError,
78
- getErrorMessage
158
+ getErrorMessage,
159
+ handleResponseErrors,
160
+ libraryAnalysisError,
161
+ findCommandOnError
79
162
  }
@@ -0,0 +1,39 @@
1
+ import latestVersion from 'latest-version'
2
+ import { APP_VERSION } from '../constants/constants'
3
+ import boxen from 'boxen'
4
+ import chalk from 'chalk'
5
+ import semver from 'semver'
6
+
7
+ export async function findLatestCLIVersion() {
8
+ const latestCLIVersion = await latestVersion('@contrast/contrast')
9
+
10
+ if (semver.lt(APP_VERSION, latestCLIVersion)) {
11
+ const updateAvailableMessage = `Update available ${chalk.yellow(
12
+ APP_VERSION
13
+ )} → ${chalk.green(latestCLIVersion)}`
14
+
15
+ const npmUpdateAvailableCommand = `Run ${chalk.cyan(
16
+ 'npm i @contrast/contrast -g'
17
+ )} to update via npm`
18
+
19
+ const homebrewUpdateAvailableCommand = `Run ${chalk.cyan(
20
+ 'brew install contrastsecurity/tap/contrast'
21
+ )} to update via brew`
22
+
23
+ console.log(
24
+ boxen(
25
+ `${updateAvailableMessage}\n${npmUpdateAvailableCommand}\n\n${homebrewUpdateAvailableCommand}`,
26
+ {
27
+ titleAlignment: 'center',
28
+ margin: 1,
29
+ padding: 1,
30
+ align: 'center'
31
+ }
32
+ )
33
+ )
34
+ }
35
+ }
36
+
37
+ export async function isCorrectNodeVersion(currentVersion: string) {
38
+ return semver.satisfies(currentVersion, '>=16.13.2 <17')
39
+ }
@@ -8,17 +8,17 @@ const GO = 'GO'
8
8
  // we set the langauge as Node instead of PHP since we're using the Node engine in TS
9
9
  const PHP = 'PHP'
10
10
  const JAVASCRIPT = 'JAVASCRIPT'
11
-
12
11
  const LOW = 'LOW'
13
12
  const MEDIUM = 'MEDIUM'
14
13
  const HIGH = 'HIGH'
15
14
  const CRITICAL = 'CRITICAL'
16
-
17
15
  const APP_NAME = 'contrast'
18
- const APP_VERSION = '1.0.0'
16
+ const APP_VERSION = '1.0.3'
19
17
  const TIMEOUT = 120000
18
+
20
19
  const AUTH_UI_URL = 'https://cli-auth.contrastsecurity.com'
21
20
  const AUTH_CALLBACK_URL = 'https://cli-auth-api.contrastsecurity.com'
21
+ const SARIF_FILE = 'SARIF'
22
22
 
23
23
  module.exports = {
24
24
  supportedLanguages: { NODE, DOTNET, JAVA, RUBY, PYTHON, GO, PHP, JAVASCRIPT },
@@ -30,5 +30,6 @@ module.exports = {
30
30
  APP_NAME,
31
31
  TIMEOUT,
32
32
  AUTH_UI_URL,
33
- AUTH_CALLBACK_URL
33
+ AUTH_CALLBACK_URL,
34
+ SARIF_FILE
34
35
  }