@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,141 @@
1
+ const child_process = require('child_process')
2
+ const fs = require('fs')
3
+ const i18n = require('i18n')
4
+ const path = require('path')
5
+
6
+ module.exports = exports = (
7
+ { language: { projectFilePath }, java },
8
+ next,
9
+ config
10
+ ) => {
11
+ let cmdStdout
12
+ let cwd
13
+ let timeout
14
+ let javaProject = ''
15
+ let mvn_settings = ''
16
+ const maven = 'Maven'
17
+ const gradle = 'Gradle'
18
+
19
+ try {
20
+ if (projectFilePath.includes('pom.xml')) {
21
+ javaProject = maven
22
+ cwd = projectFilePath.replace('pom.xml', '')
23
+ } else if (projectFilePath.includes('build.gradle')) {
24
+ javaProject = gradle
25
+ cwd = projectFilePath.replace('build.gradle', '')
26
+ }
27
+
28
+ // timeout is in milliseconds and 2.30 mintues was choses as when tested against
29
+ // Spring-boot (https://github.com/spring-projects/spring-boot) a complex project that was the
30
+ // average time for a first run when it had to download projects then build tree
31
+ timeout = 960000
32
+
33
+ // A sample of this output can be found
34
+ // in the java test data/mvnCmdResults.text
35
+ if (javaProject === maven) {
36
+ // Allow users to provide a custom location for their settings.xml
37
+ if (config.mavenSettingsPath) {
38
+ mvn_settings = ' -s ' + config.mavenSettingsPath
39
+ }
40
+
41
+ if (config.betaUnifiedJavaParser) {
42
+ cmdStdout = child_process.execSync(
43
+ 'mvn dependency:tree -B' + mvn_settings,
44
+ {
45
+ cwd,
46
+ timeout
47
+ }
48
+ )
49
+ } else {
50
+ cmdStdout = child_process.execSync(
51
+ 'mvn dependency:tree -DoutputType=dot -B' + mvn_settings,
52
+ {
53
+ cwd,
54
+ timeout
55
+ }
56
+ )
57
+ }
58
+ java.mvnDependancyTreeOutput = cmdStdout.toString()
59
+ } else if (javaProject === gradle) {
60
+ // path.sep is user here to either execute as "./gradlew" for UNIX/Linux/MacOS
61
+ // & ".\gradlew" for Windows
62
+ // Check if the user has specified a sub-project
63
+ if (config.subProject) {
64
+ cmdStdout = child_process.execSync(
65
+ '.' +
66
+ path.sep +
67
+ 'gradlew :' +
68
+ config.subProject +
69
+ ':dependencies --configuration runtimeClasspath',
70
+ {
71
+ cwd,
72
+ timeout
73
+ }
74
+ )
75
+ } else {
76
+ cmdStdout = child_process.execSync(
77
+ '.' +
78
+ path.sep +
79
+ 'gradlew dependencies --configuration runtimeClasspath',
80
+ {
81
+ cwd,
82
+ timeout
83
+ }
84
+ )
85
+ }
86
+ if (
87
+ cmdStdout
88
+ .toString()
89
+ .includes(
90
+ "runtimeClasspath - Runtime classpath of source set 'main'.\n" +
91
+ 'No dependencies'
92
+ )
93
+ ) {
94
+ cmdStdout = child_process.execSync(
95
+ '.' + path.sep + 'gradlew dependencies',
96
+ {
97
+ cwd,
98
+ timeout
99
+ }
100
+ )
101
+ }
102
+ java.mvnDependancyTreeOutput = cmdStdout.toString()
103
+ }
104
+ next()
105
+ } catch (err) {
106
+ if (javaProject === maven) {
107
+ try {
108
+ child_process.execSync('mvn --version', {
109
+ cwd,
110
+ timeout
111
+ })
112
+
113
+ next(
114
+ new Error(
115
+ i18n.__('mavenDependencyTreeNonZero', cwd, `${err.message}`)
116
+ )
117
+ )
118
+ } catch (mvnErr) {
119
+ next(
120
+ new Error(i18n.__('mavenNotInstalledError', cwd, `${mvnErr.message}`))
121
+ )
122
+ }
123
+ } else if (javaProject === gradle) {
124
+ if (
125
+ fs.existsSync(cwd + 'gradlew') ||
126
+ fs.existsSync(cwd + 'gradlew.bat')
127
+ ) {
128
+ next(
129
+ new Error(
130
+ i18n.__('gradleDependencyTreeNonZero', cwd, `${err.message}`)
131
+ )
132
+ )
133
+ } else {
134
+ next(
135
+ new Error(i18n.__('gradleWrapperUnavailable', cwd, `${err.message}`))
136
+ )
137
+ }
138
+ }
139
+ return
140
+ }
141
+ }
@@ -0,0 +1,6 @@
1
+ module.exports = exports = ({ java }, next) => {
2
+ // Remove anything sensitive or unnecessary from being sent to the backend as
3
+ // a result of our Java project analysis
4
+ delete java.mvnDependancyTreeOutput
5
+ next()
6
+ }
@@ -0,0 +1,35 @@
1
+ const i18n = require('i18n')
2
+ /**
3
+ * Checks that the list of languages and files that has been reduced doesn't
4
+ * contain more than one identified language.
5
+ */
6
+ module.exports = exports = (analysis, next) => {
7
+ const { languageAnalysis } = analysis
8
+ try {
9
+ checkForMultipleIdentifiedLanguages(languageAnalysis.identifiedLanguages)
10
+ } catch (err) {
11
+ next(err)
12
+ return
13
+ }
14
+ next()
15
+ }
16
+
17
+ const checkForMultipleIdentifiedLanguages = identifiedLanguages => {
18
+ if (Object.keys(identifiedLanguages).length > 1) {
19
+ // Handle the error case where multiple languages have been identified
20
+ let errMsg = i18n.__('languageAnalysisMultipleLanguages1')
21
+
22
+ for (const [language, { projectFilenames }] of Object.entries(
23
+ identifiedLanguages
24
+ )) {
25
+ errMsg += `\t${language}: ${projectFilenames.join(', ')}\n`
26
+ }
27
+
28
+ errMsg += i18n.__('languageAnalysisMultipleLanguages2', "'project_path'")
29
+
30
+ throw new Error(errMsg)
31
+ }
32
+ }
33
+
34
+ //For testing purposes
35
+ exports.checkForMultipleIdentifiedLanguages = checkForMultipleIdentifiedLanguages
@@ -0,0 +1,41 @@
1
+ const i18n = require('i18n')
2
+ /**
3
+ * Checks that the list of languages and files that has been reduced doesn't
4
+ * contain more than one project file for any identified language.
5
+ */
6
+ module.exports = exports = (analysis, next) => {
7
+ const { languageAnalysis } = analysis
8
+ try {
9
+ checkForMultipleIdentifiedProjectFiles(languageAnalysis.identifiedLanguages)
10
+ } catch (err) {
11
+ next(err)
12
+ return
13
+ }
14
+ next()
15
+ }
16
+
17
+ const checkForMultipleIdentifiedProjectFiles = identifiedLanguages => {
18
+ // Handle the error case where only a single language has been identified...
19
+ if (Object.keys(identifiedLanguages).length == 1) {
20
+ let { projectFilenames } = Object.values(identifiedLanguages)[0]
21
+
22
+ // ...but multiple project files for that language have been found
23
+ if (projectFilenames.length > 1) {
24
+ const [language] = Object.keys(identifiedLanguages)
25
+ projectFilenames = projectFilenames.join(', ')
26
+
27
+ // NOTE : Quotation marks for language needs to be added back in (this includes tests)
28
+ throw new Error(
29
+ i18n.__(
30
+ 'languageAnalysisProjectFiles',
31
+ language,
32
+ projectFilenames,
33
+ "'project_path'"
34
+ )
35
+ )
36
+ }
37
+ }
38
+ }
39
+
40
+ //For testing purposes
41
+ exports.checkForMultipleIdentifiedProjectFiles = checkForMultipleIdentifiedProjectFiles
@@ -0,0 +1,54 @@
1
+ const i18n = require('i18n')
2
+
3
+ /**
4
+ * Checks that a project has a lock file
5
+ */
6
+ module.exports = exports = (analysis, next) => {
7
+ try {
8
+ const { languageAnalysis } = analysis
9
+ //.NET and NODE both need lock files. currently JAVA and GO do not
10
+ // need a lock file so if lang is JAVA / GO just go to next
11
+ if (
12
+ Object.getOwnPropertyNames(languageAnalysis.identifiedLanguages)[0] ===
13
+ 'JAVA' ||
14
+ Object.getOwnPropertyNames(languageAnalysis.identifiedLanguages)[0] ===
15
+ 'GO'
16
+ ) {
17
+ next()
18
+ return
19
+ }
20
+ checkForLockFile(languageAnalysis.identifiedLanguages)
21
+ } catch (err) {
22
+ next(err)
23
+ return
24
+ }
25
+ next()
26
+ return
27
+ }
28
+
29
+ const checkForLockFile = identifiedLanguages => {
30
+ // Handle the error case where only a single language has been identified...
31
+ if (Object.keys(identifiedLanguages).length == 1) {
32
+ let { lockFilenames } = Object.values(identifiedLanguages)[0]
33
+
34
+ // ...but no lock files for that language have been found
35
+ if (lockFilenames.length == 0) {
36
+ const [language] = Object.keys(identifiedLanguages)
37
+ throw new Error(i18n.__('languageAnalysisHasNoLockFile', language))
38
+ }
39
+
40
+ if (lockFilenames.length > 1) {
41
+ const [language] = Object.keys(identifiedLanguages)
42
+ throw new Error(
43
+ i18n.__(
44
+ 'languageAnalysisHasMultipleLockFiles',
45
+ language,
46
+ String(lockFilenames)
47
+ )
48
+ )
49
+ }
50
+ }
51
+ }
52
+
53
+ //For testing purposes
54
+ exports.checkForLockFile = checkForLockFile
@@ -0,0 +1,32 @@
1
+ const i18n = require('i18n')
2
+ /**
3
+ * Checks that a single identified language in the list of languages and files
4
+ * that has been reduced has a single project file. This is important in the
5
+ * (uncommon) case that a project has a lock file without a project file.
6
+ */
7
+ module.exports = exports = (analysis, next) => {
8
+ const { languageAnalysis } = analysis
9
+ try {
10
+ checkIdentifiedLanguageHasProjectFile(languageAnalysis.identifiedLanguages)
11
+ } catch (err) {
12
+ next(err)
13
+ return
14
+ }
15
+ next()
16
+ }
17
+
18
+ const checkIdentifiedLanguageHasProjectFile = identifiedLanguages => {
19
+ // Handle the error case where only a single language has been identified...
20
+ if (Object.keys(identifiedLanguages).length == 1) {
21
+ let { projectFilenames } = Object.values(identifiedLanguages)[0]
22
+
23
+ // ...but no project files for that language have been found
24
+ if (projectFilenames.length == 0) {
25
+ const [language] = Object.keys(identifiedLanguages)
26
+ throw new Error(i18n.__('languageAnalysisProjectFileError', language))
27
+ }
28
+ }
29
+ }
30
+
31
+ //For testing purposes
32
+ exports.checkIdentifiedLanguageHasProjectFile = checkIdentifiedLanguageHasProjectFile
@@ -0,0 +1,20 @@
1
+ const { getHttpClient } = require('../../utils/commonApi')
2
+
3
+ const returnAppId = async config => {
4
+ const client = getHttpClient(config)
5
+ let appId
6
+
7
+ await client.getAppId(config).then(res => {
8
+ if (res.body) {
9
+ let obj = res.body['applications']
10
+ if (obj) {
11
+ appId = obj.length === 0 ? '' : obj[0].app_id
12
+ }
13
+ }
14
+ })
15
+ return appId
16
+ }
17
+
18
+ module.exports = {
19
+ returnAppId: returnAppId
20
+ }
@@ -0,0 +1,23 @@
1
+ // Language identifiers
2
+ const NODE = 'NODE'
3
+ const JAVASCRIPT = 'JAVASCRIPT'
4
+ const DOTNET = 'DOTNET'
5
+ const JAVA = 'JAVA'
6
+ const RUBY = 'RUBY'
7
+ const PYTHON = 'PYTHON'
8
+ const GO = 'GO'
9
+ // we set the langauge as Node instead of PHP since we're using the Node engine in TS
10
+ const PHP = 'PHP'
11
+
12
+ const LOW = 'LOW'
13
+ const MEDIUM = 'MEDIUM'
14
+ const HIGH = 'HIGH'
15
+ const CRITICAL = 'CRITICAL'
16
+
17
+ module.exports = {
18
+ supportedLanguages: { NODE, DOTNET, JAVA, RUBY, PYTHON, GO, PHP, JAVASCRIPT },
19
+ LOW: LOW,
20
+ MEDIUM: MEDIUM,
21
+ HIGH: HIGH,
22
+ CRITICAL: CRITICAL
23
+ }
@@ -0,0 +1,21 @@
1
+ const path = require('path')
2
+
3
+ function resolveFilePath(filepath) {
4
+ if (filepath[0] === '~') {
5
+ return path.join(process.env.HOME, filepath.slice(1))
6
+ }
7
+ return filepath
8
+ }
9
+
10
+ const returnProjectPath = () => {
11
+ if (process.env.PWD !== (undefined || null || 'undefined')) {
12
+ return process.env.PWD
13
+ } else {
14
+ return process.argv[process.argv.indexOf('--project_path') + 1]
15
+ }
16
+ }
17
+
18
+ module.exports = {
19
+ returnProjectPath: returnProjectPath,
20
+ resolveFilePath: resolveFilePath
21
+ }
@@ -0,0 +1,41 @@
1
+ const path = require('path')
2
+
3
+ /**
4
+ * Assemble analysis results into a common object to provide
5
+ * language, project file name and paths
6
+ */
7
+ module.exports = exports = (analysis, next) => {
8
+ const { projectPath, languageAnalysis } = analysis
9
+ languageAnalysis.identifiedLanguageInfo = getIdentifiedLanguageInfo(
10
+ projectPath,
11
+ languageAnalysis.identifiedLanguages
12
+ )
13
+ next()
14
+ }
15
+
16
+ const getIdentifiedLanguageInfo = (projectPath, identifiedLanguages) => {
17
+ const [language] = Object.keys(identifiedLanguages)
18
+ const {
19
+ projectFilenames: [projectFilename],
20
+ lockFilenames: [lockFilename]
21
+ } = Object.values(identifiedLanguages)[0]
22
+
23
+ let identifiedLanguageInfo = {
24
+ language,
25
+ projectFilename,
26
+ projectFilePath: path.join(projectPath, projectFilename)
27
+ }
28
+
29
+ if (lockFilename) {
30
+ identifiedLanguageInfo = {
31
+ ...identifiedLanguageInfo,
32
+ lockFilename,
33
+ lockFilePath: path.join(projectPath, lockFilename)
34
+ }
35
+ }
36
+
37
+ return identifiedLanguageInfo
38
+ }
39
+
40
+ //For testing purposes
41
+ exports.getIdentifiedLanguageInfo = getIdentifiedLanguageInfo
@@ -0,0 +1,72 @@
1
+ const fs = require('fs')
2
+ const path = require('path')
3
+ const i18n = require('i18n')
4
+ /**
5
+ * Will get the filenames from the project path provided to the SCA CLI tool. If
6
+ * the project path points to a file and not a directory will return the
7
+ * filename in the same fashion as if a directory had been read.
8
+ *
9
+ * Will fail and throw for a manner of reasons when doing file/directory
10
+ * inspection.
11
+ *
12
+ * @param {string} projectPath - The path to a projects root directory or a
13
+ * specific project file
14
+ *
15
+ * @return {string[]} List of filenames associated with a projects root
16
+ * directory or the name of the specific project file if that was provided to
17
+ * the 'projectPath' parameter
18
+ *
19
+ * @throws {Error} If the project path doesn't exist
20
+ * @throws {Error} If the project path information can't be collected
21
+ * @throws {Error} If a non-file or non-directory inspected
22
+ */
23
+ module.exports = exports = (analysis, next) => {
24
+ const { projectPath, languageAnalysis } = analysis
25
+ try {
26
+ languageAnalysis.projectRootFilenames = getProjectRootFilenames(projectPath)
27
+ } catch (err) {
28
+ next(err)
29
+ return
30
+ }
31
+ next()
32
+ }
33
+
34
+ const getProjectRootFilenames = projectPath => {
35
+ let projectStats = null
36
+ try {
37
+ projectStats = fs.statSync(projectPath)
38
+ } catch (err) {
39
+ throw new Error(
40
+ i18n.__('languageAnalysisProjectRootFileNameFailure', projectPath) +
41
+ `${err.message}`
42
+ )
43
+ }
44
+
45
+ // Return the contents of a directory...
46
+ if (projectStats.isDirectory()) {
47
+ try {
48
+ return fs.readdirSync(projectPath)
49
+ } catch (err) {
50
+ throw new Error(
51
+ i18n.__('languageAnalysisProjectRootFileNameReadError', projectPath) +
52
+ `${err.message}`
53
+ )
54
+ }
55
+ }
56
+
57
+ // If we are working with a file return it in a list as we do when we work
58
+ // with a directory...
59
+ if (projectStats.isFile()) {
60
+ return [path.basename(projectPath)]
61
+ }
62
+
63
+ // Error out if we are working with something like a socket file or some
64
+ // other craziness...
65
+ throw new Error(
66
+ i18n.__('languageAnalysisProjectRootFileNameMissingError'),
67
+ projectPath
68
+ )
69
+ }
70
+
71
+ //For testing purposes
72
+ exports.getProjectRootFilenames = getProjectRootFilenames
@@ -0,0 +1,45 @@
1
+ const AnalysisEngine = require('./../AnalysisEngine')
2
+ const i18n = require('i18n')
3
+
4
+ const getProjectRootFilenames = require('./getProjectRootFilenames')
5
+ const reduceIdentifiedLanguages = require('./reduceIdentifiedLanguages')
6
+ const checkForMultipleIdentifiedLanguages = require('./checkForMultipleIdentifiedLanguages')
7
+ const checkForMultipleIdentifiedProjectFiles = require('./checkForMultipleIdentifiedProjectFiles')
8
+ const checkIdentifiedLanguageHasProjectFile = require('./checkIdentifiedLanguageHasProjectFile')
9
+ const checkIdentifiedLanguageHasLockFile = require('./checkIdentifiedLanguageHasLockFile')
10
+ const getIdentifiedLanguageInfo = require('./getIdentifiedLanguageInfo')
11
+ const { libraryAnalysisError } = require('../../common/errorHandling')
12
+
13
+ module.exports = exports = (projectPath, callback, appId, config) => {
14
+ // Create an analysis engine to identify the project language
15
+ const ae = new AnalysisEngine({
16
+ projectPath,
17
+ appId,
18
+ languageAnalysis: { appId: appId },
19
+ config
20
+ })
21
+
22
+ ae.use([
23
+ getProjectRootFilenames,
24
+ reduceIdentifiedLanguages,
25
+ checkForMultipleIdentifiedLanguages,
26
+ checkForMultipleIdentifiedProjectFiles,
27
+ checkIdentifiedLanguageHasProjectFile,
28
+ checkIdentifiedLanguageHasLockFile,
29
+ getIdentifiedLanguageInfo
30
+ ])
31
+
32
+ ae.analyze((err, analysis) => {
33
+ if (err) {
34
+ console.log(
35
+ '*******************' +
36
+ i18n.__('languageAnalysisFailureMessage') +
37
+ '****************'
38
+ )
39
+ console.error(`${err.message}`)
40
+ libraryAnalysisError()
41
+ process.exit(1)
42
+ }
43
+ callback(null, analysis)
44
+ })
45
+ }
@@ -0,0 +1,126 @@
1
+ const {
2
+ supportedLanguages: { DOTNET, NODE, JAVA, RUBY, PYTHON, GO, PHP }
3
+ } = require('../languageAnalysisEngine/constants')
4
+ const i18n = require('i18n')
5
+ const dotnetAE = require('../dotnetAnalysisEngine')
6
+ const nodeAE = require('../nodeAnalysisEngine')
7
+ const javaAE = require('../javaAnalysisEngine')
8
+ const rubyAE = require('../rubyAnalysisEngine')
9
+ const pythonAE = require('../pythonAnalysisEngine')
10
+ const phpAE = require('../phpAnalysisEngine')
11
+ const goAE = require('../goAnalysisEngine')
12
+ const { vulnerabilityReport } = require('./report/reportingFeature')
13
+ const { vulnReportWithoutDevDep } = require('./report/newReportingFeature')
14
+ const { checkDevDeps } = require('./report/checkIgnoreDevDep')
15
+ const { newSendSnapShot } = require('../languageAnalysisEngine/sendSnapshot')
16
+ const fs = require('fs')
17
+ const chalk = require('chalk')
18
+ const saveFile = require('../../commands/audit/saveFile').default
19
+ const generateSbom = require('../../sbom/generateSbom').default
20
+
21
+ module.exports = exports = (err, analysis) => {
22
+ const { identifiedLanguageInfo } = analysis.languageAnalysis
23
+ const catalogueAppId = analysis.languageAnalysis.appId
24
+
25
+ if (err) {
26
+ console.error(err)
27
+ return
28
+ }
29
+
30
+ // this callback is the end of the chain
31
+ const langCallback = async (err, analysis) => {
32
+ const config = analysis.config
33
+ if (err) {
34
+ console.log()
35
+ console.log(
36
+ '***********' +
37
+ i18n.__('languageAnalysisFactoryFailureHeader') +
38
+ '****************'
39
+ )
40
+ console.log(identifiedLanguageInfo.language)
41
+ console.log()
42
+ console.error(
43
+ `${identifiedLanguageInfo.language}` +
44
+ i18n.__('languageAnalysisFailure') +
45
+ err
46
+ )
47
+ return process.exit(5)
48
+ }
49
+
50
+ console.log('\n **************CONTRAST OSS ANALYSIS BEGINS**************')
51
+ const snapshotResponse = await newSendSnapShot(analysis, catalogueAppId)
52
+
53
+ if (config.report) {
54
+ const ignoreDevUrl = await checkDevDeps(config)
55
+ if (ignoreDevUrl) {
56
+ await vulnReportWithoutDevDep(
57
+ analysis,
58
+ catalogueAppId,
59
+ snapshotResponse.id,
60
+ config
61
+ )
62
+ } else {
63
+ await vulnerabilityReport(analysis, catalogueAppId, config)
64
+ }
65
+ }
66
+
67
+ //should be moved to processAudit.ts once promises implemented
68
+ await auditSave(config)
69
+
70
+ console.log(
71
+ '\n ***************CONTRAST OSS ANALYSIS COMPLETE************** \n'
72
+ )
73
+ }
74
+
75
+ if (identifiedLanguageInfo.language === DOTNET) {
76
+ dotnetAE(identifiedLanguageInfo, analysis.config, langCallback)
77
+ }
78
+
79
+ if (identifiedLanguageInfo.language === NODE) {
80
+ nodeAE(identifiedLanguageInfo, analysis.config, langCallback)
81
+ }
82
+
83
+ if (identifiedLanguageInfo.language === JAVA) {
84
+ javaAE(identifiedLanguageInfo, analysis.config, langCallback)
85
+ }
86
+
87
+ if (identifiedLanguageInfo.language === RUBY) {
88
+ rubyAE(identifiedLanguageInfo, analysis.config, langCallback)
89
+ }
90
+
91
+ if (identifiedLanguageInfo.language === PYTHON) {
92
+ pythonAE(identifiedLanguageInfo, analysis.config, langCallback)
93
+ }
94
+
95
+ if (identifiedLanguageInfo.language === PHP) {
96
+ phpAE(identifiedLanguageInfo, analysis.config, langCallback)
97
+ }
98
+
99
+ if (identifiedLanguageInfo.language === GO) {
100
+ goAE(identifiedLanguageInfo, analysis.config, langCallback)
101
+ }
102
+ }
103
+
104
+ async function auditSave(config) {
105
+ //should be moved to processAudit.ts once promises implemented
106
+ if (config.save) {
107
+ if (config.save.toLowerCase() === 'sbom') {
108
+ saveFile(config, await generateSbom(config))
109
+
110
+ const filename = `${config.applicationId}-sbom-cyclonedx.json`
111
+ if (fs.existsSync(filename)) {
112
+ console.log(i18n.__('auditSBOMSaveSuccess') + ` - ${filename}`)
113
+ } else {
114
+ console.log(
115
+ chalk.yellow.bold(
116
+ `\n Unable to save ${filename} Software Bill of Materials (SBOM)`
117
+ )
118
+ )
119
+ }
120
+ } else {
121
+ console.log(i18n.__('auditBadFiletypeSpecifiedForSave'))
122
+ }
123
+ } else {
124
+ console.log(i18n.__('auditNoFiletypeSpecifiedForSave'))
125
+ }
126
+ }