@contrast/contrast 1.0.6 → 1.0.9

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 (221) hide show
  1. package/.prettierignore +0 -6
  2. package/dist/audit/catalogueApplication/catalogueApplication.js +23 -5
  3. package/dist/audit/languageAnalysisEngine/getProjectRootFilenames.js +10 -19
  4. package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +98 -37
  5. package/dist/audit/languageAnalysisEngine/report/models/reportListModel.js +2 -1
  6. package/dist/audit/languageAnalysisEngine/report/models/reportOutputModel.js +4 -3
  7. package/dist/audit/languageAnalysisEngine/report/models/severityCountModel.js +3 -0
  8. package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +87 -19
  9. package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +46 -16
  10. package/dist/audit/languageAnalysisEngine/sendSnapshot.js +57 -19
  11. package/dist/audit/save.js +37 -0
  12. package/dist/commands/audit/auditConfig.js +0 -16
  13. package/dist/commands/audit/auditController.js +18 -11
  14. package/dist/commands/audit/help.js +31 -25
  15. package/dist/commands/audit/processAudit.js +3 -3
  16. package/dist/commands/audit/saveFile.js +8 -4
  17. package/dist/commands/scan/sca/scaAnalysis.js +55 -10
  18. package/dist/common/HTTPClient.js +64 -23
  19. package/dist/common/errorHandling.js +6 -1
  20. package/dist/common/versionChecker.js +20 -5
  21. package/dist/constants/constants.js +7 -2
  22. package/dist/constants/locales.js +35 -38
  23. package/dist/constants.js +20 -13
  24. package/dist/index.js +55 -45
  25. package/dist/lambda/analytics.js +11 -0
  26. package/dist/lambda/lambda.js +38 -4
  27. package/dist/lambda/types.js +13 -0
  28. package/dist/sbom/generateSbom.js +5 -4
  29. package/dist/scaAnalysis/common/formatMessage.js +44 -1
  30. package/dist/scaAnalysis/common/treeUpload.js +4 -6
  31. package/dist/scaAnalysis/dotnet/analysis.js +43 -0
  32. package/dist/scaAnalysis/dotnet/index.js +10 -0
  33. package/dist/scaAnalysis/go/goReadDepFile.js +1 -3
  34. package/dist/scaAnalysis/java/analysis.js +5 -8
  35. package/dist/scaAnalysis/java/index.js +2 -2
  36. package/dist/scaAnalysis/javascript/analysis.js +107 -0
  37. package/dist/scaAnalysis/javascript/index.js +50 -0
  38. package/dist/scaAnalysis/php/analysis.js +70 -0
  39. package/dist/scaAnalysis/php/index.js +17 -0
  40. package/dist/scaAnalysis/python/analysis.js +42 -0
  41. package/dist/scaAnalysis/python/index.js +10 -0
  42. package/dist/scaAnalysis/ruby/analysis.js +218 -0
  43. package/dist/scaAnalysis/ruby/index.js +10 -0
  44. package/dist/scan/autoDetection.js +23 -22
  45. package/dist/scan/fileUtils.js +57 -20
  46. package/dist/scan/formatScanOutput.js +12 -14
  47. package/dist/scan/models/groupedResultsModel.js +1 -1
  48. package/dist/scan/models/scanResultsModel.js +3 -1
  49. package/dist/scan/populateProjectIdAndProjectName.js +2 -1
  50. package/dist/scan/scan.js +1 -0
  51. package/dist/scan/scanConfig.js +8 -3
  52. package/dist/scan/scanController.js +16 -3
  53. package/dist/scan/scanResults.js +5 -1
  54. package/dist/utils/commonApi.js +4 -1
  55. package/dist/utils/filterProjectPath.js +7 -2
  56. package/dist/utils/getConfig.js +1 -6
  57. package/package.json +12 -9
  58. package/src/audit/catalogueApplication/catalogueApplication.js +28 -7
  59. package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +10 -39
  60. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +183 -68
  61. package/src/audit/languageAnalysisEngine/report/models/reportLibraryModel.ts +3 -3
  62. package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +18 -11
  63. package/src/audit/languageAnalysisEngine/report/models/reportOutputModel.ts +11 -5
  64. package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +6 -1
  65. package/src/audit/languageAnalysisEngine/report/models/severityCountModel.ts +4 -0
  66. package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +86 -32
  67. package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +87 -32
  68. package/src/audit/languageAnalysisEngine/sendSnapshot.js +69 -20
  69. package/src/audit/save.js +48 -0
  70. package/src/commands/audit/auditConfig.ts +0 -25
  71. package/src/commands/audit/auditController.ts +18 -20
  72. package/src/commands/audit/help.ts +31 -25
  73. package/src/commands/audit/processAudit.ts +3 -6
  74. package/src/commands/audit/saveFile.ts +6 -2
  75. package/src/commands/scan/processScan.js +0 -1
  76. package/src/commands/scan/sca/scaAnalysis.js +84 -30
  77. package/src/common/HTTPClient.js +81 -34
  78. package/src/common/errorHandling.ts +10 -1
  79. package/src/common/versionChecker.ts +24 -5
  80. package/src/constants/constants.js +9 -3
  81. package/src/constants/locales.js +58 -43
  82. package/src/constants.js +21 -14
  83. package/src/index.ts +70 -58
  84. package/src/lambda/analytics.ts +9 -0
  85. package/src/lambda/arn.ts +2 -1
  86. package/src/lambda/lambda.ts +40 -17
  87. package/src/lambda/types.ts +36 -0
  88. package/src/lambda/utils.ts +2 -7
  89. package/src/sbom/generateSbom.ts +2 -2
  90. package/src/scaAnalysis/common/formatMessage.js +48 -1
  91. package/src/scaAnalysis/common/treeUpload.js +4 -6
  92. package/src/scaAnalysis/dotnet/analysis.js +54 -0
  93. package/src/scaAnalysis/dotnet/index.js +11 -0
  94. package/src/scaAnalysis/go/goAnalysis.js +2 -3
  95. package/src/scaAnalysis/go/goReadDepFile.js +1 -3
  96. package/src/scaAnalysis/java/analysis.js +7 -8
  97. package/src/scaAnalysis/java/index.js +2 -2
  98. package/src/scaAnalysis/javascript/analysis.js +126 -0
  99. package/src/scaAnalysis/javascript/index.js +72 -0
  100. package/src/scaAnalysis/php/analysis.js +78 -0
  101. package/src/scaAnalysis/php/index.js +22 -0
  102. package/src/scaAnalysis/python/analysis.js +49 -0
  103. package/src/scaAnalysis/python/index.js +11 -0
  104. package/src/scaAnalysis/ruby/analysis.js +273 -0
  105. package/src/scaAnalysis/ruby/index.js +11 -0
  106. package/src/scan/autoDetection.js +24 -26
  107. package/src/scan/fileUtils.js +60 -20
  108. package/src/scan/formatScanOutput.ts +14 -15
  109. package/src/scan/models/groupedResultsModel.ts +3 -3
  110. package/src/scan/models/resultContentModel.ts +1 -1
  111. package/src/scan/models/scanResultsModel.ts +5 -2
  112. package/src/scan/populateProjectIdAndProjectName.js +3 -1
  113. package/src/scan/scan.ts +1 -0
  114. package/src/scan/scanConfig.js +7 -5
  115. package/src/scan/scanController.js +18 -4
  116. package/src/scan/scanResults.js +10 -0
  117. package/src/utils/commonApi.js +4 -1
  118. package/src/utils/filterProjectPath.js +6 -2
  119. package/src/utils/getConfig.ts +1 -12
  120. package/dist/audit/AnalysisEngine.js +0 -37
  121. package/dist/audit/autodetection/autoDetectLanguage.js +0 -32
  122. package/dist/audit/dotnetAnalysisEngine/index.js +0 -25
  123. package/dist/audit/dotnetAnalysisEngine/parseLockFileContents.js +0 -35
  124. package/dist/audit/dotnetAnalysisEngine/parseProjectFileContents.js +0 -15
  125. package/dist/audit/dotnetAnalysisEngine/readLockFileContents.js +0 -18
  126. package/dist/audit/dotnetAnalysisEngine/readProjectFileContents.js +0 -14
  127. package/dist/audit/dotnetAnalysisEngine/sanitizer.js +0 -9
  128. package/dist/audit/goAnalysisEngine/index.js +0 -17
  129. package/dist/audit/goAnalysisEngine/parseProjectFileContents.js +0 -164
  130. package/dist/audit/goAnalysisEngine/readProjectFileContents.js +0 -21
  131. package/dist/audit/goAnalysisEngine/sanitizer.js +0 -5
  132. package/dist/audit/javaAnalysisEngine/index.js +0 -34
  133. package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +0 -153
  134. package/dist/audit/javaAnalysisEngine/parseProjectFileContents.js +0 -353
  135. package/dist/audit/javaAnalysisEngine/readProjectFileContents.js +0 -98
  136. package/dist/audit/javaAnalysisEngine/sanitizer.js +0 -5
  137. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +0 -24
  138. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +0 -24
  139. package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +0 -35
  140. package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +0 -23
  141. package/dist/audit/languageAnalysisEngine/constants.js +0 -20
  142. package/dist/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +0 -25
  143. package/dist/audit/languageAnalysisEngine/index.js +0 -39
  144. package/dist/audit/languageAnalysisEngine/languageAnalysisFactory.js +0 -87
  145. package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +0 -150
  146. package/dist/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +0 -40
  147. package/dist/audit/nodeAnalysisEngine/index.js +0 -31
  148. package/dist/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +0 -18
  149. package/dist/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +0 -18
  150. package/dist/audit/nodeAnalysisEngine/readNPMLockFileContents.js +0 -17
  151. package/dist/audit/nodeAnalysisEngine/readProjectFileContents.js +0 -14
  152. package/dist/audit/nodeAnalysisEngine/readYarnLockFileContents.js +0 -24
  153. package/dist/audit/nodeAnalysisEngine/sanitizer.js +0 -9
  154. package/dist/audit/phpAnalysisEngine/index.js +0 -23
  155. package/dist/audit/phpAnalysisEngine/parseLockFileContents.js +0 -52
  156. package/dist/audit/phpAnalysisEngine/readLockFileContents.js +0 -13
  157. package/dist/audit/phpAnalysisEngine/readProjectFileContents.js +0 -16
  158. package/dist/audit/phpAnalysisEngine/sanitizer.js +0 -5
  159. package/dist/audit/pythonAnalysisEngine/index.js +0 -25
  160. package/dist/audit/pythonAnalysisEngine/parsePipfileLockContents.js +0 -17
  161. package/dist/audit/pythonAnalysisEngine/parseProjectFileContents.js +0 -21
  162. package/dist/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +0 -13
  163. package/dist/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +0 -14
  164. package/dist/audit/pythonAnalysisEngine/sanitizer.js +0 -7
  165. package/dist/audit/rubyAnalysisEngine/index.js +0 -25
  166. package/dist/audit/rubyAnalysisEngine/parseGemfileLockContents.js +0 -176
  167. package/dist/audit/rubyAnalysisEngine/parsedGemfile.js +0 -22
  168. package/dist/audit/rubyAnalysisEngine/readGemfileContents.js +0 -14
  169. package/dist/audit/rubyAnalysisEngine/readGemfileLockContents.js +0 -14
  170. package/dist/audit/rubyAnalysisEngine/sanitizer.js +0 -6
  171. package/src/audit/AnalysisEngine.js +0 -103
  172. package/src/audit/autodetection/autoDetectLanguage.ts +0 -40
  173. package/src/audit/dotnetAnalysisEngine/index.js +0 -26
  174. package/src/audit/dotnetAnalysisEngine/parseLockFileContents.js +0 -47
  175. package/src/audit/dotnetAnalysisEngine/parseProjectFileContents.js +0 -29
  176. package/src/audit/dotnetAnalysisEngine/readLockFileContents.js +0 -30
  177. package/src/audit/dotnetAnalysisEngine/readProjectFileContents.js +0 -26
  178. package/src/audit/dotnetAnalysisEngine/sanitizer.js +0 -11
  179. package/src/audit/goAnalysisEngine/index.js +0 -18
  180. package/src/audit/goAnalysisEngine/parseProjectFileContents.js +0 -209
  181. package/src/audit/goAnalysisEngine/readProjectFileContents.js +0 -31
  182. package/src/audit/goAnalysisEngine/sanitizer.js +0 -7
  183. package/src/audit/javaAnalysisEngine/index.js +0 -41
  184. package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +0 -222
  185. package/src/audit/javaAnalysisEngine/parseProjectFileContents.js +0 -420
  186. package/src/audit/javaAnalysisEngine/readProjectFileContents.js +0 -141
  187. package/src/audit/javaAnalysisEngine/sanitizer.js +0 -6
  188. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +0 -35
  189. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +0 -41
  190. package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +0 -54
  191. package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +0 -32
  192. package/src/audit/languageAnalysisEngine/constants.js +0 -23
  193. package/src/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +0 -41
  194. package/src/audit/languageAnalysisEngine/index.js +0 -45
  195. package/src/audit/languageAnalysisEngine/languageAnalysisFactory.js +0 -116
  196. package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +0 -249
  197. package/src/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +0 -49
  198. package/src/audit/nodeAnalysisEngine/index.js +0 -35
  199. package/src/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +0 -20
  200. package/src/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +0 -26
  201. package/src/audit/nodeAnalysisEngine/readNPMLockFileContents.js +0 -23
  202. package/src/audit/nodeAnalysisEngine/readProjectFileContents.js +0 -27
  203. package/src/audit/nodeAnalysisEngine/readYarnLockFileContents.js +0 -36
  204. package/src/audit/nodeAnalysisEngine/sanitizer.js +0 -11
  205. package/src/audit/phpAnalysisEngine/index.js +0 -27
  206. package/src/audit/phpAnalysisEngine/parseLockFileContents.js +0 -60
  207. package/src/audit/phpAnalysisEngine/readLockFileContents.js +0 -14
  208. package/src/audit/phpAnalysisEngine/readProjectFileContents.js +0 -25
  209. package/src/audit/phpAnalysisEngine/sanitizer.js +0 -4
  210. package/src/audit/pythonAnalysisEngine/index.js +0 -55
  211. package/src/audit/pythonAnalysisEngine/parsePipfileLockContents.js +0 -23
  212. package/src/audit/pythonAnalysisEngine/parseProjectFileContents.js +0 -33
  213. package/src/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +0 -16
  214. package/src/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +0 -22
  215. package/src/audit/pythonAnalysisEngine/sanitizer.js +0 -9
  216. package/src/audit/rubyAnalysisEngine/index.js +0 -30
  217. package/src/audit/rubyAnalysisEngine/parseGemfileLockContents.js +0 -215
  218. package/src/audit/rubyAnalysisEngine/parsedGemfile.js +0 -39
  219. package/src/audit/rubyAnalysisEngine/readGemfileContents.js +0 -18
  220. package/src/audit/rubyAnalysisEngine/readGemfileLockContents.js +0 -17
  221. package/src/audit/rubyAnalysisEngine/sanitizer.js +0 -8
@@ -5,20 +5,17 @@ const i18n = require('i18n');
5
5
  const fs = require('fs');
6
6
  const MAVEN = 'maven';
7
7
  const GRADLE = 'gradle';
8
- const determineProjectTypeAndCwd = (files, projectPath) => {
8
+ const determineProjectTypeAndCwd = (files, file) => {
9
9
  const projectData = {};
10
10
  if (files[0].includes('pom.xml')) {
11
11
  projectData.projectType = MAVEN;
12
- projectData.cwd = projectPath
13
- ? projectPath
14
- : files[0].replace('pom.xml', '');
15
12
  }
16
13
  else if (files[0].includes('build.gradle')) {
17
14
  projectData.projectType = GRADLE;
18
- projectData.cwd = projectPath
19
- ? projectPath
20
- : files[0].replace('pom.xml', '');
21
15
  }
16
+ projectData.cwd = file
17
+ ? file.replace('pom.xml', '').replace('build.gradle', '')
18
+ : file;
22
19
  return projectData;
23
20
  };
24
21
  const buildMaven = (config, projectData, timeout) => {
@@ -89,7 +86,7 @@ const getJavaBuildDeps = (config, files) => {
89
86
  projectType: undefined
90
87
  };
91
88
  try {
92
- const projectData = determineProjectTypeAndCwd(files, config.projectPath);
89
+ const projectData = determineProjectTypeAndCwd(files, config.file);
93
90
  if (projectData.projectType === MAVEN) {
94
91
  output.mvnDependancyTreeOutput = buildMaven(config, projectData, timeout);
95
92
  }
@@ -3,10 +3,10 @@ const analysis = require('./analysis');
3
3
  const { parseBuildDeps } = require('./javaBuildDepsParser');
4
4
  const { createJavaTSMessage } = require('../common/formatMessage');
5
5
  const javaAnalysis = (config, languageFiles) => {
6
- languageFiles.java.forEach(file => {
6
+ languageFiles.JAVA.forEach(file => {
7
7
  file.replace('build.gradle.kts', 'build.gradle');
8
8
  });
9
- const javaDeps = buildJavaTree(config, languageFiles.java);
9
+ const javaDeps = buildJavaTree(config, languageFiles.JAVA);
10
10
  return createJavaTSMessage(javaDeps);
11
11
  };
12
12
  const buildJavaTree = (config, files) => {
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ const fs = require('fs');
3
+ const yarnParser = require('@yarnpkg/lockfile');
4
+ const yaml = require('js-yaml');
5
+ const i18n = require('i18n');
6
+ const { formatKey } = require('../../audit/nodeAnalysisEngine/parseYarn2LockFileContents');
7
+ const readFile = async (config, languageFiles, nameOfFile) => {
8
+ const index = languageFiles.findIndex(v => v.includes(nameOfFile));
9
+ if (config.file) {
10
+ return fs.readFileSync(config.file.concat(languageFiles[index]), 'utf8');
11
+ }
12
+ else {
13
+ throw new Error('could not find file');
14
+ }
15
+ };
16
+ const readYarn = async (config, languageFiles, nameOfFile) => {
17
+ let yarn = {
18
+ yarnVersion: 1,
19
+ rawYarnLockFileContents: ''
20
+ };
21
+ try {
22
+ let rawYarnLockFileContents = await readFile(config, languageFiles, nameOfFile);
23
+ yarn.rawYarnLockFileContents = rawYarnLockFileContents;
24
+ if (!yarn.rawYarnLockFileContents.includes('lockfile v1') ||
25
+ yarn.rawYarnLockFileContents.includes('__metadata')) {
26
+ yarn.rawYarnLockFileContents = yaml.load(rawYarnLockFileContents);
27
+ yarn.yarnVersion = 2;
28
+ }
29
+ return yarn;
30
+ }
31
+ catch (err) {
32
+ throw new Error(i18n.__('nodeReadYarnLockFileError') + `${err.message}`);
33
+ }
34
+ };
35
+ const parseNpmLockFile = async (js) => {
36
+ try {
37
+ js.npmLockFile = JSON.parse(js.rawLockFileContents);
38
+ if (js.npmLockFile && js.npmLockFile.lockfileVersion > 1) {
39
+ const listOfTopDep = Object.keys(js.npmLockFile.dependencies);
40
+ Object.entries(js.npmLockFile.dependencies).forEach(([objKey, value]) => {
41
+ if (value.requires) {
42
+ const listOfRequiresDep = Object.keys(value.requires);
43
+ listOfRequiresDep.forEach(dep => {
44
+ if (!listOfTopDep.includes(dep)) {
45
+ addDepToLockFile(js, value['requires'], dep);
46
+ }
47
+ });
48
+ }
49
+ if (value.dependencies) {
50
+ Object.entries(value.dependencies).forEach(([objChildKey, childValue]) => {
51
+ if (childValue.requires) {
52
+ const listOfRequiresDep = Object.keys(childValue.requires);
53
+ listOfRequiresDep.forEach(dep => {
54
+ if (!listOfTopDep.includes(dep)) {
55
+ addDepToLockFile(js, childValue['requires'], dep);
56
+ }
57
+ });
58
+ }
59
+ });
60
+ }
61
+ });
62
+ return js.npmLockFile;
63
+ }
64
+ else {
65
+ return js.npmLockFile;
66
+ }
67
+ }
68
+ catch (err) {
69
+ throw new Error(i18n.__('NodeParseNPM') + `${err.message}`);
70
+ }
71
+ };
72
+ const addDepToLockFile = (js, depObj, key) => {
73
+ return (js.npmLockFile.dependencies[key] = { version: depObj[key] });
74
+ };
75
+ const parseYarnLockFile = async (js) => {
76
+ try {
77
+ js.yarn.yarnLockFile = {};
78
+ if (js.yarn.yarnVersion === 1) {
79
+ js.yarn.yarnLockFile = yarnParser.parse(js.yarn.rawYarnLockFileContents);
80
+ delete js.yarn.rawYarnLockFileContents;
81
+ return js;
82
+ }
83
+ else {
84
+ js.yarn.yarnLockFile['object'] = js.yarn.rawYarnLockFileContents;
85
+ delete js.yarn.yarnLockFile['object'].__metadata;
86
+ js.yarn.yarnLockFile['type'] = 'success';
87
+ Object.entries(js.yarn.rawYarnLockFileContents).forEach(([key, value]) => {
88
+ const rawKeyNames = key.split(',');
89
+ const keyNames = formatKey(rawKeyNames);
90
+ keyNames.forEach(name => {
91
+ js.yarn.yarnLockFile.object[name] = value;
92
+ });
93
+ });
94
+ return js;
95
+ }
96
+ }
97
+ catch (err) {
98
+ throw new Error(i18n.__('NodeParseYarn', js.yarn.yarnVersion) + `${err.message}`);
99
+ }
100
+ };
101
+ module.exports = {
102
+ readYarn,
103
+ parseYarnLockFile,
104
+ parseNpmLockFile,
105
+ readFile,
106
+ formatKey
107
+ };
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ const analysis = require('./analysis');
3
+ const i18n = require('i18n');
4
+ const formatMessage = require('../common/formatMessage');
5
+ const jsAnalysis = async (config, languageFiles) => {
6
+ checkForCorrectFiles(languageFiles);
7
+ return buildNodeTree(config, languageFiles.JAVASCRIPT);
8
+ };
9
+ const buildNodeTree = async (config, files) => {
10
+ let analysis = await readFiles(config, files);
11
+ const rawNode = await parseFiles(config, files, analysis);
12
+ return formatMessage.createJavaScriptTSMessage(rawNode);
13
+ };
14
+ const readFiles = async (config, files) => {
15
+ let js = {};
16
+ js.packageJSON = JSON.parse(await analysis.readFile(config, files, 'package.json'));
17
+ if (files.includes('package-lock.json')) {
18
+ js.rawLockFileContents = await analysis.readFile(config, files, 'package-lock.json');
19
+ }
20
+ if (files.includes('yarn.lock')) {
21
+ js.yarn = {};
22
+ js.yarn = await analysis.readYarn(config, files, 'yarn.lock');
23
+ }
24
+ return js;
25
+ };
26
+ const parseFiles = async (config, files, js) => {
27
+ if (files.includes('package-lock.json')) {
28
+ js.npmLockFile = await analysis.parseNpmLockFile(js);
29
+ }
30
+ if (files.includes('yarn.lock')) {
31
+ js = await analysis.parseYarnLockFile(js);
32
+ }
33
+ return js;
34
+ };
35
+ const checkForCorrectFiles = languageFiles => {
36
+ if (languageFiles.JAVASCRIPT.includes('package-lock.json') &&
37
+ languageFiles.JAVASCRIPT.includes('yarn.lock')) {
38
+ throw new Error(i18n.__('languageAnalysisHasMultipleLockFiles', 'javascript'));
39
+ }
40
+ if (!languageFiles.JAVASCRIPT.includes('package-lock.json') &&
41
+ !languageFiles.JAVASCRIPT.includes('yarn.lock')) {
42
+ throw new Error(i18n.__('languageAnalysisHasNoLockFile', 'javascript'));
43
+ }
44
+ if (!languageFiles.JAVASCRIPT.includes('package.json')) {
45
+ throw new Error(i18n.__('languageAnalysisHasNoPackageJsonFile'));
46
+ }
47
+ };
48
+ module.exports = {
49
+ jsAnalysis
50
+ };
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ const fs = require('fs');
3
+ const i18n = require('i18n');
4
+ const _ = require('lodash');
5
+ const readFile = (config, nameOfFile) => {
6
+ if (config.file) {
7
+ try {
8
+ return fs.readFileSync(config.file + '/' + nameOfFile);
9
+ }
10
+ catch (error) {
11
+ console.log('Unable to find file');
12
+ console.log(error);
13
+ }
14
+ }
15
+ };
16
+ const parseProjectFiles = php => {
17
+ try {
18
+ php.composerJSON.dependencies = php.composerJSON.require;
19
+ php.composerJSON.devDependencies = php.composerJSON['require-dev'];
20
+ php.lockFile = php.rawLockFileContents;
21
+ let packages = _.keyBy(php.lockFile.packages, 'name');
22
+ let packagesDev = _.keyBy(php.lockFile['packages-dev'], 'name');
23
+ php.lockFile.dependencies = _.merge(packages, packagesDev);
24
+ const listOfTopDep = Object.keys(php.lockFile.dependencies);
25
+ Object.entries(php.lockFile.dependencies).forEach(([key, value]) => {
26
+ if (value.require) {
27
+ const listOfRequiresDep = Object.keys(value.require);
28
+ listOfRequiresDep.forEach(dep => {
29
+ if (!listOfTopDep.includes(dep)) {
30
+ addChildDepToLockFileAsOwnObj(php, value['require'], dep);
31
+ }
32
+ });
33
+ }
34
+ if (value['require-dev']) {
35
+ const listOfRequiresDep = Object.keys(value['require-dev']);
36
+ listOfRequiresDep.forEach(dep => {
37
+ if (!listOfTopDep.includes(dep)) {
38
+ addChildDepToLockFileAsOwnObj(php, value['require-dev'], dep);
39
+ }
40
+ });
41
+ }
42
+ });
43
+ formatParentDepToLockFile(php);
44
+ delete php.rawLockFileContents;
45
+ return php;
46
+ }
47
+ catch (err) {
48
+ return console.log(i18n.__('phpParseComposerLock', php) + `${err.message}`);
49
+ }
50
+ };
51
+ function addChildDepToLockFileAsOwnObj(php, depObj, key) {
52
+ php.lockFile.dependencies[key] = { version: depObj[key] };
53
+ }
54
+ function formatParentDepToLockFile(php) {
55
+ for (const [key, value] of Object.entries(php.lockFile.dependencies)) {
56
+ let requires = {};
57
+ for (const [childKey, childValue] of Object.entries(value)) {
58
+ if (childKey === 'require' || childKey === 'require-dev') {
59
+ requires = _.merge(requires, childValue);
60
+ php.lockFile.dependencies[key].requires = requires;
61
+ delete php.lockFile.dependencies[key].require;
62
+ delete php.lockFile.dependencies[key]['require-dev'];
63
+ }
64
+ }
65
+ }
66
+ }
67
+ module.exports = {
68
+ parseProjectFiles,
69
+ readFile
70
+ };
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ const { readFile, parseProjectFiles } = require('./analysis');
3
+ const { createPhpTSMessage } = require('../common/formatMessage');
4
+ const phpAnalysis = (config, files) => {
5
+ let analysis = readFiles(config, files.PHP);
6
+ const phpDep = parseProjectFiles(analysis);
7
+ return createPhpTSMessage(phpDep);
8
+ };
9
+ const readFiles = (config, files) => {
10
+ let php = {};
11
+ php.composerJSON = JSON.parse(readFile(config, 'composer.json'));
12
+ php.rawLockFileContents = JSON.parse(readFile(config, 'composer.lock'));
13
+ return php;
14
+ };
15
+ module.exports = {
16
+ phpAnalysis
17
+ };
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ const multiReplace = require('string-multiple-replace');
3
+ const fs = require('fs');
4
+ const readAndParseProjectFile = file => {
5
+ const filePath = filePathForWindows(file + '/Pipfile');
6
+ const pipFile = fs.readFileSync(filePath, 'utf8');
7
+ const matcherObj = { '"': '' };
8
+ const sequencer = ['"'];
9
+ const parsedPipfile = multiReplace(pipFile, matcherObj, sequencer);
10
+ const pythonArray = parsedPipfile.split('\n');
11
+ return pythonArray.filter(element => element !== '' && !element.includes('#'));
12
+ };
13
+ const readAndParseLockFile = file => {
14
+ const filePath = filePathForWindows(file + '/Pipfile.lock');
15
+ const lockFile = fs.readFileSync(filePath, 'utf8');
16
+ let parsedPipLock = JSON.parse(lockFile);
17
+ parsedPipLock['defaults'] = parsedPipLock['default'];
18
+ delete parsedPipLock['default'];
19
+ return parsedPipLock;
20
+ };
21
+ const getPythonDeps = config => {
22
+ try {
23
+ const parseProject = readAndParseProjectFile(config.file);
24
+ const parsePip = readAndParseLockFile(config.file);
25
+ return { pipfileLock: parsePip, pipfilDependanceies: parseProject };
26
+ }
27
+ catch (err) {
28
+ console.log(err.message.toString());
29
+ process.exit(1);
30
+ }
31
+ };
32
+ const filePathForWindows = path => {
33
+ if (process.platform === 'win32') {
34
+ path = path.replace(/\//g, '\\');
35
+ }
36
+ return path;
37
+ };
38
+ module.exports = {
39
+ getPythonDeps,
40
+ readAndParseProjectFile,
41
+ readAndParseLockFile
42
+ };
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ const { createPythonTSMessage } = require('../common/formatMessage');
3
+ const { getPythonDeps } = require('./analysis');
4
+ const pythonAnalysis = (config, languageFiles) => {
5
+ const pythonDeps = getPythonDeps(config, languageFiles.PYTHON);
6
+ return createPythonTSMessage(pythonDeps);
7
+ };
8
+ module.exports = {
9
+ pythonAnalysis
10
+ };
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+ const fs = require('fs');
3
+ const readAndParseGemfile = file => {
4
+ const gemFile = fs.readFileSync(file + '/Gemfile', 'utf8');
5
+ const rubyArray = gemFile.split('\n');
6
+ let filteredRubyDep = rubyArray.filter(element => {
7
+ return (!element.includes('#') &&
8
+ element.includes('gem') &&
9
+ !element.includes('source'));
10
+ });
11
+ for (let i = 0; i < filteredRubyDep.length; i++) {
12
+ filteredRubyDep[i] = filteredRubyDep[i].trim();
13
+ }
14
+ return filteredRubyDep;
15
+ };
16
+ const readAndParseGemLockFile = file => {
17
+ const lockFile = fs.readFileSync(file + '/Gemfile.lock', 'utf8');
18
+ const dependencyRegEx = /^\s*([A-Za-z0-9.!@#$%\-^&*_+]*)\s*(\((.*?)\))/;
19
+ const lines = lockFile.split('\n');
20
+ return {
21
+ dependencies: getDirectDependencies(lines, dependencyRegEx),
22
+ runtimeDetails: getLockFileRuntimeInfo(lines),
23
+ sources: getSourceArray(lines, dependencyRegEx)
24
+ };
25
+ };
26
+ const nonDependencyKeys = (line, sourceObject) => {
27
+ const GEMFILE_KEY_VALUE = /^\s*([^:(]*)\s*\:*\s*(.*)/;
28
+ let parts = GEMFILE_KEY_VALUE.exec(line);
29
+ let key = parts[1].trim();
30
+ let value = parts[2] || '';
31
+ sourceObject[key] = value;
32
+ return sourceObject;
33
+ };
34
+ const populateResolveAndPlatform = (version, sourceObject) => {
35
+ const depArr = version.split('-');
36
+ sourceObject.resolved = depArr[0];
37
+ sourceObject.platform = depArr.length > 1 ? depArr[1] : 'UNSPECIFIED';
38
+ return sourceObject;
39
+ };
40
+ const isUpperCase = str => {
41
+ return str === str.toUpperCase();
42
+ };
43
+ const getDirectDependencies = (lines, dependencyRegEx) => {
44
+ const dependencies = {};
45
+ let depIndex = 0;
46
+ for (let i = 0; i < lines.length; i++) {
47
+ if (lines[i] === 'DEPENDENCIES') {
48
+ depIndex = i;
49
+ }
50
+ }
51
+ const getDepArray = lines.slice(depIndex);
52
+ for (let j = 1; j < getDepArray.length; j++) {
53
+ const element = getDepArray[j];
54
+ if (!isUpperCase(element)) {
55
+ const isDependencyWithVersion = dependencyRegEx.test(element);
56
+ if (isDependencyWithVersion) {
57
+ const dependency = dependencyRegEx.exec(element);
58
+ let name = dependency[1];
59
+ name = name.replace('!', '');
60
+ dependencies[name.trim()] = dependency[3];
61
+ }
62
+ else {
63
+ let name = element;
64
+ name = name.replace('!', ' ');
65
+ dependencies[name.trim()] = 'UNSPECIFIED';
66
+ }
67
+ }
68
+ }
69
+ return dependencies;
70
+ };
71
+ const getLockFileRuntimeInfo = lines => {
72
+ let rubVersionIndex = 0;
73
+ for (let i = 0; i < lines.length; i++) {
74
+ if (lines[i] === 'RUBY VERSION') {
75
+ rubVersionIndex = i;
76
+ break;
77
+ }
78
+ }
79
+ const runtimeDetails = {};
80
+ if (rubVersionIndex !== 0) {
81
+ const getRubyVersionArray = lines.slice(rubVersionIndex);
82
+ for (let element of getRubyVersionArray) {
83
+ if (!isUpperCase(element)) {
84
+ runtimeDetails['version'] = getVersion(element);
85
+ runtimeDetails['patchLevel'] = getPatchLevel(element);
86
+ if (element.includes('engine')) {
87
+ let splitElement = element.split(' ');
88
+ runtimeDetails[splitElement[0]] = splitElement[1];
89
+ }
90
+ }
91
+ }
92
+ }
93
+ return runtimeDetails;
94
+ };
95
+ const getVersion = element => {
96
+ const versionRegex = /^([ruby\s0-9.*]+)/;
97
+ if (versionRegex.test(element)) {
98
+ let version = versionRegex.exec(element)[0];
99
+ if (version.includes('ruby')) {
100
+ return trimWhiteSpace(version.replace('ruby', ''));
101
+ }
102
+ }
103
+ };
104
+ const getPatchLevel = element => {
105
+ const patchLevelRegex = /(p\d+)/;
106
+ if (patchLevelRegex.test(element)) {
107
+ return patchLevelRegex.exec(element)[0];
108
+ }
109
+ };
110
+ const formatSourceArr = sourceArr => {
111
+ return sourceArr.map(element => {
112
+ if (element.sourceType === 'GIT') {
113
+ delete element.specs;
114
+ }
115
+ if (element.sourceType === 'GEM') {
116
+ delete element.branch;
117
+ delete element.revision;
118
+ delete element.depthLevel;
119
+ delete element.specs;
120
+ }
121
+ if (element.sourceType === 'PATH') {
122
+ delete element.branch;
123
+ delete element.revision;
124
+ delete element.depthLevel;
125
+ delete element.specs;
126
+ delete element.platform;
127
+ }
128
+ return element;
129
+ });
130
+ };
131
+ const getSourceArray = (lines, dependencyRegEx) => {
132
+ const sourceObject = {
133
+ dependencies: {}
134
+ };
135
+ const whitespaceRegx = /^(\s*)/;
136
+ let index = 0;
137
+ let line = 0;
138
+ const sources = [];
139
+ while ((line = lines[index++]) !== undefined) {
140
+ let currentWS = whitespaceRegx.exec(line)[1].length;
141
+ if (!line.includes(' bundler (')) {
142
+ if (currentWS === 0 && !line.includes(':') && line !== '') {
143
+ sourceObject.sourceType = line;
144
+ }
145
+ if (currentWS !== 0 && line.includes(':')) {
146
+ nonDependencyKeys(line, sourceObject);
147
+ }
148
+ if (currentWS > 2) {
149
+ let nexlineWS = whitespaceRegx.exec(lines[index])[1].length;
150
+ sourceObject.dependencies = buildSourceDependencyWithVersion(whitespaceRegx, dependencyRegEx, line, currentWS, sourceObject.name, sourceObject.dependencies);
151
+ if (currentWS === 4 && sourceObject.depthLevel === undefined) {
152
+ const dependency = dependencyRegEx.exec(line);
153
+ sourceObject.name = dependency[1];
154
+ sourceObject.depthLevel = currentWS;
155
+ populateResolveAndPlatform(dependency[3], sourceObject);
156
+ }
157
+ if (currentWS === 4 && sourceObject.depthLevel) {
158
+ const dependency = dependencyRegEx.exec(line);
159
+ sourceObject.name = dependency[1];
160
+ sourceObject.depthLevel = currentWS;
161
+ populateResolveAndPlatform(dependency[3], sourceObject);
162
+ }
163
+ if ((currentWS === 4 && nexlineWS === 4) ||
164
+ (currentWS === 6 && nexlineWS === 4) ||
165
+ nexlineWS == '') {
166
+ let newObj = {};
167
+ newObj = JSON.parse(JSON.stringify(sourceObject));
168
+ sources.push(newObj);
169
+ sourceObject.dependencies = {};
170
+ }
171
+ }
172
+ }
173
+ }
174
+ return formatSourceArr(sources);
175
+ };
176
+ const buildSourceDependencyWithVersion = (whitespaceRegx, dependencyRegEx, line, currentWhiteSpace, name, dependencies) => {
177
+ const isDependencyWithVersion = dependencyRegEx.test(line);
178
+ if (currentWhiteSpace === 6) {
179
+ const dependency = dependencyRegEx.exec(line);
180
+ if (isDependencyWithVersion) {
181
+ if (name !== dependency[1]) {
182
+ dependencies[dependency[1]] = dependency[3];
183
+ }
184
+ }
185
+ else {
186
+ dependencies[line.trim()] = 'UNSPECIFIED';
187
+ }
188
+ }
189
+ return dependencies;
190
+ };
191
+ const getRubyDeps = config => {
192
+ try {
193
+ const parsedGem = readAndParseGemfile(config.file);
194
+ const parsedLock = readAndParseGemLockFile(config.file);
195
+ return { gemfilesDependanceies: parsedGem, gemfileLock: parsedLock };
196
+ }
197
+ catch (err) {
198
+ console.log(err.message);
199
+ process.exit(1);
200
+ }
201
+ };
202
+ const trimWhiteSpace = string => {
203
+ return string.replace(/\s+/g, '');
204
+ };
205
+ module.exports = {
206
+ getRubyDeps,
207
+ readAndParseGemfile,
208
+ readAndParseGemLockFile,
209
+ nonDependencyKeys,
210
+ populateResolveAndPlatform,
211
+ isUpperCase,
212
+ getDirectDependencies,
213
+ getLockFileRuntimeInfo,
214
+ getVersion,
215
+ getPatchLevel,
216
+ formatSourceArr,
217
+ getSourceArray
218
+ };
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ const analysis = require('./analysis');
3
+ const { createRubyTSMessage } = require('../common/formatMessage');
4
+ const rubyAnalysis = (config, languageFiles) => {
5
+ const rubyDeps = analysis.getRubyDeps(config, languageFiles.RUBY);
6
+ return createRubyTSMessage(rubyDeps);
7
+ };
8
+ module.exports = {
9
+ rubyAnalysis
10
+ };
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  const i18n = require('i18n');
3
3
  const fileFinder = require('./fileUtils');
4
- const languageResolver = require('../audit/languageAnalysisEngine/reduceIdentifiedLanguages');
5
4
  const rootFile = require('../audit/languageAnalysisEngine/getProjectRootFilenames');
6
5
  const autoDetectFileAndLanguage = async (configToUse) => {
7
6
  const entries = await fileFinder.findFile();
@@ -11,6 +10,10 @@ const autoDetectFileAndLanguage = async (configToUse) => {
11
10
  console.log(i18n.__('fileHasWhiteSpacesError'));
12
11
  process.exit(1);
13
12
  }
13
+ if (fileFinder.fileIsEmpty(entries[0])) {
14
+ console.log(i18n.__('scanFileIsEmpty'));
15
+ process.exit(1);
16
+ }
14
17
  configToUse.file = entries[0];
15
18
  if (configToUse.name === undefined) {
16
19
  configToUse.name = entries[0];
@@ -20,30 +23,29 @@ const autoDetectFileAndLanguage = async (configToUse) => {
20
23
  errorOnFileDetection(entries);
21
24
  }
22
25
  };
23
- const autoDetectAuditFilesAndLanguages = async () => {
26
+ const autoDetectAuditFilesAndLanguages = async (file) => {
27
+ const filePath = file;
24
28
  let languagesFound = [];
25
- console.log(i18n.__('searchingAuditFileDirectory', process.cwd()));
26
- await fileFinder.findFilesJava(languagesFound);
27
- await fileFinder.findFilesJavascript(languagesFound);
28
- await fileFinder.findFilesPython(languagesFound);
29
- await fileFinder.findFilesGo(languagesFound);
30
- await fileFinder.findFilesPhp(languagesFound);
31
- await fileFinder.findFilesRuby(languagesFound);
32
- if (languagesFound.length === 1) {
33
- return languagesFound;
29
+ if (filePath) {
30
+ rootFile.getProjectRootFilenames(filePath);
31
+ console.log(i18n.__('searchingAuditFileDirectory', filePath));
34
32
  }
35
33
  else {
36
- console.log('found multiple languages, please specify one using --file to run SCA analysis');
34
+ console.log(i18n.__('searchingAuditFileDirectory', process.cwd()));
37
35
  }
38
- };
39
- const manualDetectAuditFilesAndLanguages = async (projectPath) => {
40
- let projectRootFilenames = await rootFile.getProjectRootFilenames(projectPath);
41
- let identifiedLanguages = languageResolver.deduceLanguageScaAnalysis(projectRootFilenames);
42
- if (Object.keys(identifiedLanguages).length === 0) {
43
- console.log(i18n.__('languageAnalysisNoLanguage', projectPath));
44
- return [];
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
+ if (languagesFound.length <= 1) {
44
+ return languagesFound;
45
+ }
46
+ else {
47
+ console.log('found multiple languages, please specify one using --file to run SCA audit');
45
48
  }
46
- return [identifiedLanguages];
47
49
  };
48
50
  const hasWhiteSpace = s => {
49
51
  const filename = s.split('/').pop();
@@ -84,6 +86,5 @@ module.exports = {
84
86
  autoDetectFileAndLanguage,
85
87
  errorOnFileDetection,
86
88
  autoDetectAuditFilesAndLanguages,
87
- errorOnAuditFileDetection,
88
- manualDetectAuditFilesAndLanguages
89
+ errorOnAuditFileDetection
89
90
  };