@contrast/contrast 1.0.8 → 1.0.11

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 (217) hide show
  1. package/README.md +2 -2
  2. package/dist/audit/languageAnalysisEngine/getProjectRootFilenames.js +16 -25
  3. package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +103 -57
  4. package/dist/audit/languageAnalysisEngine/report/models/reportGuidanceModel.js +6 -0
  5. package/dist/audit/languageAnalysisEngine/report/models/reportOutputModel.js +3 -3
  6. package/dist/audit/languageAnalysisEngine/report/models/severityCountModel.js +1 -0
  7. package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +68 -17
  8. package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +39 -7
  9. package/dist/audit/languageAnalysisEngine/sendSnapshot.js +6 -30
  10. package/dist/audit/save.js +21 -13
  11. package/dist/commands/audit/auditConfig.js +3 -19
  12. package/dist/commands/audit/auditController.js +1 -10
  13. package/dist/commands/audit/help.js +7 -24
  14. package/dist/commands/audit/processAudit.js +5 -9
  15. package/dist/commands/audit/saveFile.js +2 -2
  16. package/dist/commands/auth/auth.js +1 -1
  17. package/dist/commands/config/config.js +2 -2
  18. package/dist/commands/scan/processScan.js +11 -4
  19. package/dist/commands/scan/sca/scaAnalysis.js +37 -13
  20. package/dist/common/HTTPClient.js +17 -8
  21. package/dist/common/errorHandling.js +2 -2
  22. package/dist/common/fail.js +66 -0
  23. package/dist/common/versionChecker.js +1 -1
  24. package/dist/constants/constants.js +7 -2
  25. package/dist/constants/locales.js +40 -38
  26. package/dist/constants.js +62 -12
  27. package/dist/index.js +57 -45
  28. package/dist/lambda/lambda.js +5 -2
  29. package/dist/sbom/generateSbom.js +2 -2
  30. package/dist/scaAnalysis/common/formatMessage.js +7 -1
  31. package/dist/scaAnalysis/common/scaParserForGoAndJava.js +32 -0
  32. package/dist/scaAnalysis/common/treeUpload.js +24 -10
  33. package/dist/scaAnalysis/dotnet/analysis.js +55 -0
  34. package/dist/scaAnalysis/dotnet/index.js +10 -0
  35. package/dist/scaAnalysis/go/goAnalysis.js +8 -2
  36. package/dist/scaAnalysis/java/analysis.js +10 -6
  37. package/dist/scaAnalysis/java/index.js +7 -1
  38. package/dist/scaAnalysis/java/javaBuildDepsParser.js +19 -3
  39. package/dist/scaAnalysis/javascript/analysis.js +4 -7
  40. package/dist/scaAnalysis/javascript/index.js +16 -4
  41. package/dist/scaAnalysis/php/analysis.js +14 -33
  42. package/dist/scaAnalysis/php/index.js +11 -4
  43. package/dist/scaAnalysis/python/analysis.js +43 -5
  44. package/dist/scaAnalysis/python/index.js +7 -2
  45. package/dist/scaAnalysis/ruby/analysis.js +16 -14
  46. package/dist/scan/autoDetection.js +13 -24
  47. package/dist/scan/fileUtils.js +31 -12
  48. package/dist/scan/formatScanOutput.js +9 -8
  49. package/dist/scan/populateProjectIdAndProjectName.js +5 -0
  50. package/dist/scan/scan.js +4 -0
  51. package/dist/scan/scanConfig.js +5 -5
  52. package/dist/scan/scanResults.js +39 -3
  53. package/dist/telemetry/telemetry.js +137 -0
  54. package/dist/utils/commonApi.js +1 -1
  55. package/dist/utils/getConfig.js +3 -8
  56. package/dist/utils/parsedCLIOptions.js +3 -1
  57. package/dist/utils/requestUtils.js +7 -1
  58. package/package.json +2 -3
  59. package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +21 -57
  60. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +155 -77
  61. package/src/audit/languageAnalysisEngine/report/models/reportGuidanceModel.ts +5 -0
  62. package/src/audit/languageAnalysisEngine/report/models/reportOutputModel.ts +5 -5
  63. package/src/audit/languageAnalysisEngine/report/models/severityCountModel.ts +2 -0
  64. package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +56 -27
  65. package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +45 -6
  66. package/src/audit/languageAnalysisEngine/sendSnapshot.js +6 -32
  67. package/src/audit/save.js +32 -16
  68. package/src/commands/audit/auditConfig.ts +10 -28
  69. package/src/commands/audit/auditController.ts +0 -11
  70. package/src/commands/audit/help.ts +7 -24
  71. package/src/commands/audit/processAudit.ts +16 -8
  72. package/src/commands/audit/saveFile.ts +2 -2
  73. package/src/commands/auth/auth.js +3 -1
  74. package/src/commands/config/config.js +4 -2
  75. package/src/commands/scan/processScan.js +18 -5
  76. package/src/commands/scan/sca/scaAnalysis.js +50 -18
  77. package/src/common/HTTPClient.js +23 -9
  78. package/src/common/errorHandling.ts +2 -3
  79. package/src/common/fail.js +75 -0
  80. package/src/common/versionChecker.ts +1 -1
  81. package/src/constants/constants.js +9 -3
  82. package/src/constants/locales.js +70 -45
  83. package/src/constants.js +67 -13
  84. package/src/index.ts +91 -66
  85. package/src/lambda/lambda.ts +5 -2
  86. package/src/lambda/types.ts +1 -0
  87. package/src/sbom/generateSbom.ts +2 -2
  88. package/src/scaAnalysis/common/formatMessage.js +8 -1
  89. package/src/scaAnalysis/common/scaParserForGoAndJava.js +41 -0
  90. package/src/scaAnalysis/common/treeUpload.js +25 -11
  91. package/src/scaAnalysis/dotnet/analysis.js +72 -0
  92. package/src/scaAnalysis/dotnet/index.js +11 -0
  93. package/src/scaAnalysis/go/goAnalysis.js +9 -2
  94. package/src/scaAnalysis/java/analysis.js +11 -6
  95. package/src/scaAnalysis/java/index.js +9 -1
  96. package/src/scaAnalysis/java/javaBuildDepsParser.js +25 -6
  97. package/src/scaAnalysis/javascript/analysis.js +6 -7
  98. package/src/scaAnalysis/javascript/index.js +25 -6
  99. package/src/scaAnalysis/php/analysis.js +15 -35
  100. package/src/scaAnalysis/php/index.js +15 -4
  101. package/src/scaAnalysis/python/analysis.js +49 -5
  102. package/src/scaAnalysis/python/index.js +7 -2
  103. package/src/scaAnalysis/ruby/analysis.js +18 -15
  104. package/src/scan/autoDetection.js +14 -27
  105. package/src/scan/fileUtils.js +33 -12
  106. package/src/scan/formatScanOutput.ts +10 -8
  107. package/src/scan/populateProjectIdAndProjectName.js +5 -1
  108. package/src/scan/scan.ts +4 -0
  109. package/src/scan/scanConfig.js +7 -7
  110. package/src/scan/scanResults.js +46 -3
  111. package/src/telemetry/telemetry.ts +154 -0
  112. package/src/utils/commonApi.js +1 -1
  113. package/src/utils/getConfig.ts +5 -18
  114. package/src/utils/parsedCLIOptions.js +14 -1
  115. package/src/utils/requestUtils.js +8 -1
  116. package/dist/audit/AnalysisEngine.js +0 -37
  117. package/dist/audit/autodetection/autoDetectLanguage.js +0 -32
  118. package/dist/audit/dotnetAnalysisEngine/index.js +0 -25
  119. package/dist/audit/dotnetAnalysisEngine/parseLockFileContents.js +0 -35
  120. package/dist/audit/dotnetAnalysisEngine/parseProjectFileContents.js +0 -15
  121. package/dist/audit/dotnetAnalysisEngine/readLockFileContents.js +0 -18
  122. package/dist/audit/dotnetAnalysisEngine/readProjectFileContents.js +0 -14
  123. package/dist/audit/dotnetAnalysisEngine/sanitizer.js +0 -9
  124. package/dist/audit/goAnalysisEngine/index.js +0 -17
  125. package/dist/audit/goAnalysisEngine/parseProjectFileContents.js +0 -164
  126. package/dist/audit/goAnalysisEngine/readProjectFileContents.js +0 -21
  127. package/dist/audit/goAnalysisEngine/sanitizer.js +0 -5
  128. package/dist/audit/javaAnalysisEngine/index.js +0 -34
  129. package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +0 -155
  130. package/dist/audit/javaAnalysisEngine/parseProjectFileContents.js +0 -353
  131. package/dist/audit/javaAnalysisEngine/readProjectFileContents.js +0 -98
  132. package/dist/audit/javaAnalysisEngine/sanitizer.js +0 -5
  133. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +0 -25
  134. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +0 -25
  135. package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +0 -35
  136. package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +0 -24
  137. package/dist/audit/languageAnalysisEngine/constants.js +0 -20
  138. package/dist/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +0 -25
  139. package/dist/audit/languageAnalysisEngine/index.js +0 -39
  140. package/dist/audit/languageAnalysisEngine/languageAnalysisFactory.js +0 -66
  141. package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +0 -166
  142. package/dist/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +0 -40
  143. package/dist/audit/nodeAnalysisEngine/index.js +0 -31
  144. package/dist/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +0 -18
  145. package/dist/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +0 -18
  146. package/dist/audit/nodeAnalysisEngine/readNPMLockFileContents.js +0 -17
  147. package/dist/audit/nodeAnalysisEngine/readProjectFileContents.js +0 -14
  148. package/dist/audit/nodeAnalysisEngine/readYarnLockFileContents.js +0 -24
  149. package/dist/audit/nodeAnalysisEngine/sanitizer.js +0 -9
  150. package/dist/audit/phpAnalysisEngine/index.js +0 -23
  151. package/dist/audit/phpAnalysisEngine/parseLockFileContents.js +0 -52
  152. package/dist/audit/phpAnalysisEngine/readLockFileContents.js +0 -13
  153. package/dist/audit/phpAnalysisEngine/readProjectFileContents.js +0 -16
  154. package/dist/audit/phpAnalysisEngine/sanitizer.js +0 -5
  155. package/dist/audit/pythonAnalysisEngine/index.js +0 -25
  156. package/dist/audit/pythonAnalysisEngine/parsePipfileLockContents.js +0 -17
  157. package/dist/audit/pythonAnalysisEngine/parseProjectFileContents.js +0 -21
  158. package/dist/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +0 -13
  159. package/dist/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +0 -14
  160. package/dist/audit/pythonAnalysisEngine/sanitizer.js +0 -7
  161. package/dist/audit/rubyAnalysisEngine/index.js +0 -25
  162. package/dist/audit/rubyAnalysisEngine/parseGemfileLockContents.js +0 -176
  163. package/dist/audit/rubyAnalysisEngine/parsedGemfile.js +0 -22
  164. package/dist/audit/rubyAnalysisEngine/readGemfileContents.js +0 -14
  165. package/dist/audit/rubyAnalysisEngine/readGemfileLockContents.js +0 -14
  166. package/dist/audit/rubyAnalysisEngine/sanitizer.js +0 -6
  167. package/src/audit/AnalysisEngine.js +0 -103
  168. package/src/audit/autodetection/autoDetectLanguage.ts +0 -40
  169. package/src/audit/dotnetAnalysisEngine/index.js +0 -26
  170. package/src/audit/dotnetAnalysisEngine/parseLockFileContents.js +0 -47
  171. package/src/audit/dotnetAnalysisEngine/parseProjectFileContents.js +0 -29
  172. package/src/audit/dotnetAnalysisEngine/readLockFileContents.js +0 -30
  173. package/src/audit/dotnetAnalysisEngine/readProjectFileContents.js +0 -26
  174. package/src/audit/dotnetAnalysisEngine/sanitizer.js +0 -11
  175. package/src/audit/goAnalysisEngine/index.js +0 -18
  176. package/src/audit/goAnalysisEngine/parseProjectFileContents.js +0 -209
  177. package/src/audit/goAnalysisEngine/readProjectFileContents.js +0 -31
  178. package/src/audit/goAnalysisEngine/sanitizer.js +0 -7
  179. package/src/audit/javaAnalysisEngine/index.js +0 -41
  180. package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +0 -225
  181. package/src/audit/javaAnalysisEngine/parseProjectFileContents.js +0 -420
  182. package/src/audit/javaAnalysisEngine/readProjectFileContents.js +0 -141
  183. package/src/audit/javaAnalysisEngine/sanitizer.js +0 -6
  184. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +0 -36
  185. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +0 -42
  186. package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +0 -54
  187. package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +0 -33
  188. package/src/audit/languageAnalysisEngine/constants.js +0 -23
  189. package/src/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +0 -41
  190. package/src/audit/languageAnalysisEngine/index.js +0 -45
  191. package/src/audit/languageAnalysisEngine/languageAnalysisFactory.js +0 -96
  192. package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +0 -251
  193. package/src/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +0 -49
  194. package/src/audit/nodeAnalysisEngine/index.js +0 -35
  195. package/src/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +0 -20
  196. package/src/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +0 -26
  197. package/src/audit/nodeAnalysisEngine/readNPMLockFileContents.js +0 -23
  198. package/src/audit/nodeAnalysisEngine/readProjectFileContents.js +0 -27
  199. package/src/audit/nodeAnalysisEngine/readYarnLockFileContents.js +0 -36
  200. package/src/audit/nodeAnalysisEngine/sanitizer.js +0 -11
  201. package/src/audit/phpAnalysisEngine/index.js +0 -27
  202. package/src/audit/phpAnalysisEngine/parseLockFileContents.js +0 -60
  203. package/src/audit/phpAnalysisEngine/readLockFileContents.js +0 -14
  204. package/src/audit/phpAnalysisEngine/readProjectFileContents.js +0 -25
  205. package/src/audit/phpAnalysisEngine/sanitizer.js +0 -4
  206. package/src/audit/pythonAnalysisEngine/index.js +0 -55
  207. package/src/audit/pythonAnalysisEngine/parsePipfileLockContents.js +0 -23
  208. package/src/audit/pythonAnalysisEngine/parseProjectFileContents.js +0 -33
  209. package/src/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +0 -16
  210. package/src/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +0 -22
  211. package/src/audit/pythonAnalysisEngine/sanitizer.js +0 -9
  212. package/src/audit/rubyAnalysisEngine/index.js +0 -30
  213. package/src/audit/rubyAnalysisEngine/parseGemfileLockContents.js +0 -215
  214. package/src/audit/rubyAnalysisEngine/parsedGemfile.js +0 -39
  215. package/src/audit/rubyAnalysisEngine/readGemfileContents.js +0 -18
  216. package/src/audit/rubyAnalysisEngine/readGemfileLockContents.js +0 -17
  217. package/src/audit/rubyAnalysisEngine/sanitizer.js +0 -8
@@ -1,7 +1,7 @@
1
1
  const i18n = require('i18n')
2
2
  const fileFinder = require('./fileUtils')
3
- const languageResolver = require('../audit/languageAnalysisEngine/reduceIdentifiedLanguages')
4
3
  const rootFile = require('../audit/languageAnalysisEngine/getProjectRootFilenames')
4
+ const path = require('path')
5
5
 
6
6
  const autoDetectFileAndLanguage = async configToUse => {
7
7
  const entries = await fileFinder.findFile()
@@ -28,36 +28,24 @@ const autoDetectFileAndLanguage = async configToUse => {
28
28
  }
29
29
  }
30
30
 
31
- const autoDetectAuditFilesAndLanguages = async () => {
31
+ const autoDetectAuditFilesAndLanguages = async filePath => {
32
32
  let languagesFound = []
33
- console.log(i18n.__('searchingAuditFileDirectory', process.cwd()))
34
33
 
35
- await fileFinder.findFilesJava(languagesFound)
36
- await fileFinder.findFilesJavascript(languagesFound)
37
- await fileFinder.findFilesPython(languagesFound)
38
- await fileFinder.findFilesGo(languagesFound)
39
- await fileFinder.findFilesPhp(languagesFound)
40
- await fileFinder.findFilesRuby(languagesFound)
34
+ console.log(i18n.__('searchingAuditFileDirectory', filePath))
41
35
 
42
- if (languagesFound.length === 1) {
36
+ await fileFinder.findFilesJava(languagesFound, filePath)
37
+ await fileFinder.findFilesJavascript(languagesFound, filePath)
38
+ await fileFinder.findFilesPython(languagesFound, filePath)
39
+ await fileFinder.findFilesGo(languagesFound, filePath)
40
+ await fileFinder.findFilesPhp(languagesFound, filePath)
41
+ await fileFinder.findFilesRuby(languagesFound, filePath)
42
+ await fileFinder.findFilesDotNet(languagesFound, filePath)
43
+
44
+ if (languagesFound) {
43
45
  return languagesFound
44
- } else {
45
- console.log(
46
- 'found multiple languages, please specify one using --file to run SCA audit'
47
- )
48
46
  }
49
- }
50
47
 
51
- const manualDetectAuditFilesAndLanguages = file => {
52
- let projectRootFilenames = rootFile.getProjectRootFilenames(file)
53
- let identifiedLanguages =
54
- languageResolver.deduceLanguageScaAnalysis(projectRootFilenames)
55
-
56
- if (Object.keys(identifiedLanguages).length === 0) {
57
- console.log(i18n.__('languageAnalysisNoLanguage', file))
58
- return []
59
- }
60
- return [identifiedLanguages]
48
+ return []
61
49
  }
62
50
 
63
51
  const hasWhiteSpace = s => {
@@ -100,6 +88,5 @@ module.exports = {
100
88
  autoDetectFileAndLanguage,
101
89
  errorOnFileDetection,
102
90
  autoDetectAuditFilesAndLanguages,
103
- errorOnAuditFileDetection,
104
- manualDetectAuditFilesAndLanguages
91
+ errorOnAuditFileDetection
105
92
  }
@@ -11,13 +11,14 @@ const findFile = async () => {
11
11
  })
12
12
  }
13
13
 
14
- const findFilesJava = async languagesFound => {
14
+ const findFilesJava = async (languagesFound, filePath) => {
15
15
  const result = await fg(
16
16
  ['**/pom.xml', '**/build.gradle', '**/build.gradle.kts'],
17
17
  {
18
18
  dot: false,
19
19
  deep: 1,
20
- onlyFiles: true
20
+ onlyFiles: true,
21
+ cwd: filePath ? filePath : process.cwd()
21
22
  }
22
23
  )
23
24
 
@@ -27,13 +28,14 @@ const findFilesJava = async languagesFound => {
27
28
  return languagesFound
28
29
  }
29
30
 
30
- const findFilesJavascript = async languagesFound => {
31
+ const findFilesJavascript = async (languagesFound, filePath) => {
31
32
  const result = await fg(
32
33
  ['**/package.json', '**/yarn.lock', '**/package-lock.json'],
33
34
  {
34
35
  dot: false,
35
36
  deep: 1,
36
- onlyFiles: true
37
+ onlyFiles: true,
38
+ cwd: filePath ? filePath : process.cwd()
37
39
  }
38
40
  )
39
41
 
@@ -43,11 +45,12 @@ const findFilesJavascript = async languagesFound => {
43
45
  return languagesFound
44
46
  }
45
47
 
46
- const findFilesPython = async languagesFound => {
48
+ const findFilesPython = async (languagesFound, filePath) => {
47
49
  const result = await fg(['**/Pipfile.lock', '**/Pipfile'], {
48
50
  dot: false,
49
51
  deep: 3,
50
- onlyFiles: true
52
+ onlyFiles: true,
53
+ cwd: filePath ? filePath : process.cwd()
51
54
  })
52
55
 
53
56
  if (result.length > 0) {
@@ -56,11 +59,12 @@ const findFilesPython = async languagesFound => {
56
59
  return languagesFound
57
60
  }
58
61
 
59
- const findFilesGo = async languagesFound => {
62
+ const findFilesGo = async (languagesFound, filePath) => {
60
63
  const result = await fg(['**/go.mod'], {
61
64
  dot: false,
62
65
  deep: 3,
63
- onlyFiles: true
66
+ onlyFiles: true,
67
+ cwd: filePath ? filePath : process.cwd()
64
68
  })
65
69
 
66
70
  if (result.length > 0) {
@@ -69,11 +73,12 @@ const findFilesGo = async languagesFound => {
69
73
  return languagesFound
70
74
  }
71
75
 
72
- const findFilesRuby = async languagesFound => {
76
+ const findFilesRuby = async (languagesFound, filePath) => {
73
77
  const result = await fg(['**/Gemfile', '**/Gemfile.lock'], {
74
78
  dot: false,
75
79
  deep: 3,
76
- onlyFiles: true
80
+ onlyFiles: true,
81
+ cwd: filePath ? filePath : process.cwd()
77
82
  })
78
83
 
79
84
  if (result.length > 0) {
@@ -82,11 +87,12 @@ const findFilesRuby = async languagesFound => {
82
87
  return languagesFound
83
88
  }
84
89
 
85
- const findFilesPhp = async languagesFound => {
90
+ const findFilesPhp = async (languagesFound, filePath) => {
86
91
  const result = await fg(['**/composer.json', '**/composer.lock'], {
87
92
  dot: false,
88
93
  deep: 3,
89
- onlyFiles: true
94
+ onlyFiles: true,
95
+ cwd: filePath ? filePath : process.cwd()
90
96
  })
91
97
 
92
98
  if (result.length > 0) {
@@ -95,6 +101,20 @@ const findFilesPhp = async languagesFound => {
95
101
  return languagesFound
96
102
  }
97
103
 
104
+ const findFilesDotNet = async (languagesFound, filePath) => {
105
+ const result = await fg(['**/*.csproj', '**/packages.lock.json'], {
106
+ dot: false,
107
+ deep: 3,
108
+ onlyFiles: true,
109
+ cwd: filePath ? filePath : process.cwd()
110
+ })
111
+
112
+ if (result.length > 0) {
113
+ return languagesFound.push({ DOTNET: result })
114
+ }
115
+ return languagesFound
116
+ }
117
+
98
118
  const checkFilePermissions = file => {
99
119
  let readableFile = false
100
120
  try {
@@ -138,5 +158,6 @@ module.exports = {
138
158
  findFilesGo,
139
159
  findFilesPhp,
140
160
  findFilesRuby,
161
+ findFilesDotNet,
141
162
  fileIsEmpty
142
163
  }
@@ -34,8 +34,9 @@ export function formatScanOutput(scanResults: ScanResultsModel) {
34
34
 
35
35
  let defaultView = getDefaultView(scanResultsInstances.content)
36
36
 
37
- let count = defaultView.length
37
+ let count = 0
38
38
  defaultView.forEach(entry => {
39
+ count++
39
40
  let table = new Table({
40
41
  chars: {
41
42
  top: '',
@@ -61,12 +62,12 @@ export function formatScanOutput(scanResults: ScanResultsModel) {
61
62
  })
62
63
  let learnRow: string[] = []
63
64
  let adviceRow = []
65
+ const headerColour = chalk.hex(entry.colour)
64
66
  const headerRow = [
65
- chalk
66
- .hex(entry.colour)
67
- .bold(`CONTRAST-${count.toString().padStart(3, '0')}`),
68
- chalk.hex(entry.colour).bold('-'),
69
- chalk.hex(entry.colour).bold(`[${entry.severity}] ${entry.ruleId}`) +
67
+ headerColour(`CONTRAST-${count.toString().padStart(3, '0')}`),
68
+ headerColour(`-`),
69
+ headerColour(`[${entry.severity}] `) +
70
+ headerColour.bold(`${entry.ruleId}`) +
70
71
  entry.message
71
72
  ]
72
73
 
@@ -98,12 +99,13 @@ export function formatScanOutput(scanResults: ScanResultsModel) {
98
99
  ]
99
100
  table.push(learnRow)
100
101
  }
101
- count--
102
102
  console.log(table.toString())
103
103
  console.log()
104
104
  })
105
105
  }
106
106
  printVulnInfo(projectOverview)
107
+
108
+ return projectOverview
107
109
  }
108
110
 
109
111
  function printVulnInfo(projectOverview: any) {
@@ -179,7 +181,7 @@ export function getDefaultView(content: ResultContent[]) {
179
181
  assignBySeverity(resultEntry, groupResultsObj)
180
182
  })
181
183
 
182
- return sortBy(groupTypeResults, ['priority']).reverse()
184
+ return sortBy(groupTypeResults, ['priority'])
183
185
  }
184
186
  export function editVulName(message: string) {
185
187
  return message.substring(message.indexOf(' in '))
@@ -28,7 +28,11 @@ const createProjectId = async (config, client) => {
28
28
  process.exit(1)
29
29
  return
30
30
  }
31
-
31
+ if (res.statusCode === 429) {
32
+ console.log(i18n.__('exceededFreeTier'))
33
+ process.exit(1)
34
+ return
35
+ }
32
36
  if (res.statusCode === 201) {
33
37
  console.log(i18n.__('projectCreatedScan'))
34
38
  if (config.verbose) {
package/src/scan/scan.ts CHANGED
@@ -47,6 +47,10 @@ export const sendScan = async (config: any) => {
47
47
  )
48
48
  console.log(i18n.__('genericServiceError', res.statusCode))
49
49
  }
50
+ if (res.statusCode === 429) {
51
+ console.log(i18n.__('exceededFreeTier'))
52
+ process.exit(1)
53
+ }
50
54
  if (res.statusCode === 403) {
51
55
  console.log(i18n.__('permissionsError'))
52
56
  process.exit(1)
@@ -1,15 +1,15 @@
1
1
  const paramHandler = require('../utils/paramsUtil/paramHandler')
2
2
  const constants = require('../../src/constants.js')
3
- const parsedCLIOptions = require('../../src/utils/parsedCLIOptions')
4
3
  const path = require('path')
5
- const {
6
- supportedLanguages
7
- } = require('../audit/languageAnalysisEngine/constants')
4
+ const { supportedLanguagesScan } = require('../constants/constants')
8
5
  const i18n = require('i18n')
9
6
  const { scanUsageGuide } = require('./help')
7
+ const parsedCLIOptions = require('../utils/parsedCLIOptions')
10
8
 
11
- const getScanConfig = argv => {
12
- let scanParams = parsedCLIOptions.getCommandLineArgsCustom(
9
+ const getScanConfig = async (contrastConf, command, argv) => {
10
+ let scanParams = await parsedCLIOptions.getCommandLineArgsCustom(
11
+ contrastConf,
12
+ command,
13
13
  argv,
14
14
  constants.commandLineDefinitions.scanOptionDefinitions
15
15
  )
@@ -23,7 +23,7 @@ const getScanConfig = argv => {
23
23
 
24
24
  if (scanParams.language) {
25
25
  scanParams.language = scanParams.language.toUpperCase()
26
- if (!Object.values(supportedLanguages).includes(scanParams.language)) {
26
+ if (!Object.values(supportedLanguagesScan).includes(scanParams.language)) {
27
27
  console.log(`Did not recognise --language ${scanParams.language}`)
28
28
  console.log(i18n.__('constantsHowToRunDev3'))
29
29
  process.exit(1)
@@ -4,11 +4,15 @@ const oraFunctions = require('../utils/oraWrapper')
4
4
  const _ = require('lodash')
5
5
  const i18n = require('i18n')
6
6
  const oraWrapper = require('../utils/oraWrapper')
7
+ const readLine = require('readline')
7
8
 
8
9
  const getScanId = async (config, codeArtifactId, client) => {
9
10
  return client
10
11
  .getScanId(config, codeArtifactId)
11
12
  .then(res => {
13
+ if (res.statusCode == 429) {
14
+ throw new Error(i18n.__('exceededFreeTier'))
15
+ }
12
16
  return res.body.id
13
17
  })
14
18
  .catch(err => {
@@ -88,13 +92,51 @@ const returnScanResults = async (
88
92
  startScanSpinner,
89
93
  'Contrast Scan timed out at the specified ' + timeout + ' seconds.'
90
94
  )
91
- console.log('Please try again, allowing more time.')
92
- process.exit(1)
95
+
96
+ if (!config.isCI) {
97
+ const retry = await retryScanPrompt()
98
+ timeout = retry.timeout
99
+ }
93
100
  }
94
101
  }
95
102
  }
96
103
  }
97
104
 
105
+ const retryScanPrompt = async () => {
106
+ const rl = readLine.createInterface({
107
+ input: process.stdin,
108
+ output: process.stdout
109
+ })
110
+
111
+ return new Promise((resolve, reject) => {
112
+ requestUtils.timeOutError(30000, reject)
113
+
114
+ rl.question(
115
+ '🔁 Do you want to continue waiting on Scan? [Y/N]\n',
116
+ async input => {
117
+ if (input.toLowerCase() === 'yes' || input.toLowerCase() === 'y') {
118
+ console.log('Continuing wait for Scan')
119
+ rl.close()
120
+ resolve({ timeout: 300 })
121
+ } else if (
122
+ input.toLowerCase() === 'no' ||
123
+ input.toLowerCase() === 'n'
124
+ ) {
125
+ rl.close()
126
+ console.log('Contrast Scan Retry Cancelled: Exiting')
127
+ resolve(process.exit(1))
128
+ } else {
129
+ rl.close()
130
+ console.log('Invalid Input: Exiting')
131
+ resolve(process.exit(1))
132
+ }
133
+ }
134
+ )
135
+ }).catch(e => {
136
+ throw e
137
+ })
138
+ }
139
+
98
140
  const returnScanResultsInstances = async (config, scanId) => {
99
141
  const client = commonApi.getHttpClient(config)
100
142
  let result
@@ -118,5 +160,6 @@ module.exports = {
118
160
  getScanId: getScanId,
119
161
  returnScanResults: returnScanResults,
120
162
  pollScanResults: pollScanResults,
121
- returnScanResultsInstances: returnScanResultsInstances
163
+ returnScanResultsInstances: returnScanResultsInstances,
164
+ retryScanPrompt
122
165
  }
@@ -0,0 +1,154 @@
1
+ import { getHttpClient } from '../utils/commonApi'
2
+ import * as crypto from 'crypto'
3
+ import { ContrastConf } from '../utils/getConfig'
4
+
5
+ export const TELEMETRY_CLI_COMMANDS_EVENT = 'CLI_COMMANDS'
6
+ export const TELEMETRY_CLI_TIME_TO_AUTH_EVENT = 'CLI_TIME_TO_AUTH'
7
+
8
+ export const sendTelemetryConfigAsConfObj = async (
9
+ config: ContrastConf,
10
+ command: string,
11
+ argv: string[],
12
+ result: string,
13
+ language: string
14
+ ) => {
15
+ const hostParam = '--host'
16
+ const hostParamAlias = '-h'
17
+ const orgIdParam = '--organization-id'
18
+ const orgIdParamAlias = '-o'
19
+ const authParam = '--authorization'
20
+ const apiKeyParam = '--api-key'
21
+
22
+ let configToUse
23
+
24
+ if (
25
+ paramExists(argv, hostParam, hostParamAlias) &&
26
+ paramExists(argv, orgIdParam, orgIdParamAlias) &&
27
+ paramExists(argv, authParam, null) &&
28
+ paramExists(argv, apiKeyParam, null)
29
+ ) {
30
+ //if the user has passed the values as params
31
+ configToUse = {
32
+ host: findParamValueFromArgs(argv, hostParam, hostParamAlias),
33
+ organizationId: findParamValueFromArgs(argv, orgIdParam, orgIdParamAlias),
34
+ authorization: findParamValueFromArgs(argv, authParam, null),
35
+ apiKey: findParamValueFromArgs(argv, apiKeyParam, null)
36
+ }
37
+ } else if (
38
+ config &&
39
+ config.get('host') &&
40
+ config.get('organizationId') &&
41
+ config.get('authorization') &&
42
+ config.get('apiKey')
43
+ ) {
44
+ configToUse = {
45
+ host: config.get('host')?.slice(0, -1), //slice off extra / in url, will 404 on teamserver if we don't
46
+ organizationId: config.get('organizationId'),
47
+ authorization: config.get('authorization'),
48
+ apiKey: config.get('apiKey')
49
+ }
50
+ } else {
51
+ //return when unable to get config
52
+ return
53
+ }
54
+
55
+ return await sendTelemetryConfigAsObject(
56
+ configToUse,
57
+ command,
58
+ argv,
59
+ result,
60
+ language
61
+ )
62
+ }
63
+
64
+ export const sendTelemetryConfigAsObject = async (
65
+ config: any,
66
+ command: string,
67
+ argv: string[],
68
+ result: string,
69
+ language: string
70
+ ) => {
71
+ const obfuscatedParams = obfuscateParams(argv)
72
+
73
+ const requestBody = {
74
+ event: TELEMETRY_CLI_COMMANDS_EVENT,
75
+ details: {
76
+ ip_address: '',
77
+ account_name: '',
78
+ account_host: '',
79
+ company_domain: '',
80
+ command: `contrast ${command} ${obfuscatedParams}`,
81
+ app_id:
82
+ config && config.applicationId
83
+ ? sha1Base64Value(config.applicationId)
84
+ : 'undefined',
85
+ project_id:
86
+ config && config.projectId
87
+ ? sha1Base64Value(config.projectId)
88
+ : 'undefined',
89
+ language: language,
90
+ result: result,
91
+ additional_info: '',
92
+ timestamp: new Date().toUTCString()
93
+ }
94
+ }
95
+
96
+ return await sendTelemetryRequest(config, requestBody)
97
+ }
98
+
99
+ export const sendTelemetryRequest = async (config: any, requestBody: any) => {
100
+ const client = getHttpClient(config)
101
+ return client
102
+ .postTelemetry(config, requestBody)
103
+ .then((res: any) => {
104
+ if (res.statusCode !== 200 && config.debug === true) {
105
+ console.log('Telemetry failed to send with status', res.statusCode)
106
+ }
107
+ return { statusCode: res.statusCode, statusMessage: res.statusMessage }
108
+ })
109
+ .catch((err: any) => {
110
+ return
111
+ })
112
+ }
113
+
114
+ export const obfuscateParams = (argv: string[]) => {
115
+ return argv
116
+ .join(' ')
117
+ .replace(/--(authorization [A-Z0-9]+)/gi, '--authorization *****')
118
+ .replace(/-(o [A-Z0-9-]+)/gi, '-o *****')
119
+ .replace(/--(organization-id [A-Z0-9-]+)/gi, '--organization-id *****')
120
+ .replace(/--(api-key [A-Z0-9]+)/gi, '--api-key *****')
121
+ }
122
+
123
+ export const paramExists = (
124
+ argv: string[],
125
+ param: string,
126
+ paramAlias: string | null
127
+ ) => {
128
+ return argv.find((arg: string) => arg === param || arg === paramAlias)
129
+ }
130
+
131
+ export const findParamValueFromArgs = (
132
+ argv: string[],
133
+ param: string,
134
+ paramAlias: string | null
135
+ ) => {
136
+ let paramAsValue
137
+
138
+ argv.forEach((arg: string, index: number) => {
139
+ if (
140
+ arg === param ||
141
+ (arg === paramAlias &&
142
+ argv[index + 1] !== undefined &&
143
+ argv[index + 1] !== null)
144
+ ) {
145
+ paramAsValue = argv[index + 1]
146
+ }
147
+ })
148
+
149
+ return paramAsValue
150
+ }
151
+
152
+ export const sha1Base64Value = (value: any) => {
153
+ return crypto.createHash('sha1').update(value).digest('base64')
154
+ }
@@ -20,7 +20,7 @@ const handleResponseErrors = (res, api) => {
20
20
  } else if (res.statusCode === 412) {
21
21
  maxAppError()
22
22
  } else {
23
- genericError()
23
+ genericError(res)
24
24
  }
25
25
  }
26
26
 
@@ -7,7 +7,7 @@ type ContrastConfOptions = Partial<{
7
7
  orgId: string
8
8
  authHeader: string
9
9
  numOfRuns: number
10
- updateMessageHidden: boolean
10
+ isCI: boolean
11
11
  }>
12
12
 
13
13
  type ContrastConf = Conf<ContrastConfOptions>
@@ -18,12 +18,10 @@ const localConfig = (name: string, version: string) => {
18
18
  })
19
19
  config.set('version', version)
20
20
 
21
- if (process.env.CONTRAST_CODSEC_DISABLE_UPDATE_MESSAGE) {
21
+ if (process.env.CONTRAST_CODSEC_CI) {
22
22
  config.set(
23
- 'updateMessageHidden',
24
- JSON.parse(
25
- process.env.CONTRAST_CODSEC_DISABLE_UPDATE_MESSAGE.toLowerCase()
26
- )
23
+ 'isCI',
24
+ JSON.parse(process.env.CONTRAST_CODSEC_CI.toLowerCase()) as boolean
27
25
  )
28
26
  }
29
27
 
@@ -33,11 +31,6 @@ const localConfig = (name: string, version: string) => {
33
31
  return config
34
32
  }
35
33
 
36
- const createConfigFromYaml = (yamlPath: string) => {
37
- const yamlConfig = {}
38
- return yamlConfig
39
- }
40
-
41
34
  const setConfigValues = (config: ContrastConf, values: ContrastConfOptions) => {
42
35
  config.set('apiKey', values.apiKey)
43
36
  config.set('organizationId', values.orgId)
@@ -45,10 +38,4 @@ const setConfigValues = (config: ContrastConf, values: ContrastConfOptions) => {
45
38
  values.host ? config.set('host', values.host) : null
46
39
  }
47
40
 
48
- export {
49
- localConfig,
50
- createConfigFromYaml,
51
- setConfigValues,
52
- ContrastConf,
53
- ContrastConfOptions
54
- }
41
+ export { localConfig, setConfigValues, ContrastConf, ContrastConfOptions }
@@ -1,6 +1,12 @@
1
1
  const commandLineArgs = require('command-line-args')
2
+ const { sendTelemetryConfigAsConfObj } = require('../telemetry/telemetry')
2
3
 
3
- const getCommandLineArgsCustom = (parameterList, optionDefinitions) => {
4
+ const getCommandLineArgsCustom = async (
5
+ contrastConf,
6
+ command,
7
+ parameterList,
8
+ optionDefinitions
9
+ ) => {
4
10
  try {
5
11
  return commandLineArgs(optionDefinitions, {
6
12
  argv: parameterList,
@@ -9,6 +15,13 @@ const getCommandLineArgsCustom = (parameterList, optionDefinitions) => {
9
15
  caseInsensitive: true
10
16
  })
11
17
  } catch (e) {
18
+ await sendTelemetryConfigAsConfObj(
19
+ contrastConf,
20
+ command,
21
+ parameterList,
22
+ 'FAILURE',
23
+ 'undefined'
24
+ )
12
25
  console.log(e.message.toString())
13
26
  process.exit(1)
14
27
  }
@@ -15,8 +15,15 @@ const sleep = ms => {
15
15
  return new Promise(resolve => setTimeout(resolve, ms))
16
16
  }
17
17
 
18
+ const timeOutError = (ms, reject) => {
19
+ return setTimeout(() => {
20
+ reject(new Error(`No input detected after 30s`))
21
+ }, ms)
22
+ }
23
+
18
24
  module.exports = {
19
25
  sendRequest: sendRequest,
20
26
  sleep: sleep,
21
- millisToSeconds: millisToSeconds
27
+ millisToSeconds: millisToSeconds,
28
+ timeOutError: timeOutError
22
29
  }
@@ -1,37 +0,0 @@
1
- "use strict";
2
- class AnalysisEngine {
3
- constructor(initAnalysis = {}) {
4
- this.analyzers = [];
5
- this.analysis = { ...initAnalysis };
6
- }
7
- use(analyzer) {
8
- if (Array.isArray(analyzer)) {
9
- this.analyzers = [...this.analyzers, ...analyzer];
10
- return;
11
- }
12
- this.analyzers.push(analyzer);
13
- }
14
- analyze(callback, config) {
15
- let i = 0;
16
- const next = err => {
17
- if (err) {
18
- return setImmediate(() => callback(err, this.analysis));
19
- }
20
- if (i >= this.analyzers.length) {
21
- return setImmediate(() => callback(null, this.analysis));
22
- }
23
- const analyzer = this.analyzers[i];
24
- i++;
25
- setImmediate(() => {
26
- try {
27
- analyzer(this.analysis, next, config);
28
- }
29
- catch (uncaughtErr) {
30
- next(uncaughtErr);
31
- }
32
- });
33
- };
34
- next();
35
- }
36
- }
37
- module.exports = exports = AnalysisEngine;