@contrast/contrast 2.0.2-beta.0 → 2.0.2-beta.1

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.
@@ -12,7 +12,7 @@ const MEDIUM = 'MEDIUM';
12
12
  const HIGH = 'HIGH';
13
13
  const CRITICAL = 'CRITICAL';
14
14
  const APP_NAME = 'contrast';
15
- const APP_VERSION = '2.0.2-beta.0';
15
+ const APP_VERSION = '2.0.2-beta.1';
16
16
  const TIMEOUT = 120000;
17
17
  const HIGH_COLOUR = '#ff9900';
18
18
  const CRITICAL_COLOUR = '#e35858';
@@ -1,94 +1,118 @@
1
1
  "use strict";
2
2
  const fs = require('fs');
3
- const xml2js = require('xml2js');
3
+ const { XMLParser } = require('fast-xml-parser');
4
4
  const readPomFile = project => {
5
5
  const mavenFilePath = project.cwd + '/pom.xml';
6
6
  const projectFile = fs.readFileSync(mavenFilePath);
7
- let jsonPomFile;
8
- xml2js.parseString(projectFile, (err, result) => {
9
- if (err) {
10
- throw err;
11
- }
12
- const json = JSON.stringify(result, null);
13
- jsonPomFile = JSON.parse(json);
14
- });
15
- return jsonPomFile;
16
- };
17
- const getFromVersionsTag = (dependencyName, versionIdentifier, jsonPomFile) => {
18
- let formattedVersion = versionIdentifier.replace(/[{}]/g, '').replace('$', '');
19
- if (jsonPomFile.project.properties[0].hasOwnProperty([formattedVersion])) {
20
- return jsonPomFile.project.properties[0][formattedVersion][0];
21
- }
22
- else {
23
- return null;
24
- }
7
+ const parser = new XMLParser();
8
+ return parser.parse(projectFile);
25
9
  };
26
10
  const parsePomFile = jsonPomFile => {
11
+ console.log(JSON.stringify(jsonPomFile));
27
12
  let dependencyTree = {};
28
- let parsedVersion;
29
- let dependencies;
30
- jsonPomFile.project.hasOwnProperty('dependencies')
31
- ? (dependencies = jsonPomFile.project.dependencies[0].dependency)
32
- : (dependencies =
33
- jsonPomFile.project.dependencyManagement[0].dependencies[0].dependency);
34
- for (let x in dependencies) {
35
- let dependencyObject = dependencies[x];
36
- if (!dependencyObject.hasOwnProperty('version')) {
37
- parsedVersion = getVersion(jsonPomFile, dependencyObject);
38
- }
39
- else {
40
- dependencyObject.version[0].includes('${versions.')
41
- ? (parsedVersion = getFromVersionsTag(dependencyObject.artifactId[0], dependencyObject.version[0], jsonPomFile))
42
- : (parsedVersion = dependencyObject.version[0]);
43
- }
44
- let depName = dependencyObject.groupId +
45
- '/' +
46
- dependencyObject.artifactId +
47
- '@' +
48
- parsedVersion;
49
- let parsedDependency = {
50
- name: dependencyObject.artifactId[0],
51
- group: dependencyObject.groupId[0],
52
- version: parsedVersion,
53
- directDependency: true,
54
- productionDependency: true,
55
- dependencies: []
56
- };
57
- dependencyTree[depName] = parsedDependency;
13
+ let dependencies = [];
14
+ let dependencyManagement = [];
15
+ if (jsonPomFile.project && jsonPomFile.project.dependencies) {
16
+ dependencies = jsonPomFile.project.dependencies.dependency;
17
+ }
18
+ if (jsonPomFile.project && jsonPomFile.project.dependencyManagement) {
19
+ dependencyManagement =
20
+ jsonPomFile.project.dependencyManagement.dependencies.dependency;
58
21
  }
59
- const retrieveParent = getParentDependency(jsonPomFile);
22
+ const mergedAndFilteredDeps = dependencies.map(obj1 => {
23
+ const obj2 = dependencyManagement.find(obj2 => obj2.groupId === obj1.groupId && obj2.artifactId === obj1.artifactId);
24
+ return obj2 ? { ...obj1, ...obj2 } : obj1;
25
+ });
26
+ buildDependencies(mergedAndFilteredDeps, dependencyTree, jsonPomFile);
60
27
  return {
61
- parentPom: retrieveParent,
28
+ parentPom: getParentDependency(jsonPomFile),
62
29
  dependencyTree
63
30
  };
64
31
  };
65
32
  const getParentDependency = jsonPomFile => {
66
- let parent = {};
67
- jsonPomFile.project.hasOwnProperty('parent')
68
- ? (parent = buildParent(jsonPomFile.project.parent))
69
- : (parent = undefined);
70
- return parent;
33
+ if (jsonPomFile.project && jsonPomFile.project.parent) {
34
+ return buildParent(jsonPomFile.project.parent);
35
+ }
36
+ else {
37
+ return undefined;
38
+ }
71
39
  };
72
40
  const buildParent = parent => {
73
41
  return {
74
- group: parent[0].groupId[0],
75
- name: parent[0].artifactId[0],
76
- version: parent[0].version[0]
42
+ group: parent.groupId,
43
+ name: parent.artifactId,
44
+ version: parent.version
77
45
  };
78
46
  };
79
- const getVersion = (pomFile, dependencyWithoutVersion) => {
80
- let parentVersion = pomFile.project.parent[0].version[0];
81
- let parentGroupName = pomFile.project.parent[0].groupId[0];
82
- if (parentGroupName === dependencyWithoutVersion.groupId[0]) {
83
- return parentVersion;
47
+ const getVersionFromParent = (parentObj, dependencyWithoutVersion) => {
48
+ const { groupId, version } = parentObj;
49
+ if (groupId === dependencyWithoutVersion.groupId) {
50
+ return version;
84
51
  }
85
52
  else {
86
53
  return null;
87
54
  }
88
55
  };
56
+ const getVersionFromProperties = (properties, dep) => {
57
+ if (properties && dep.version.includes('${')) {
58
+ const currentDepVersionPlaceholder = dep.version
59
+ .replace('${', '')
60
+ .replace('}', '');
61
+ for (const prop in properties) {
62
+ if (prop === currentDepVersionPlaceholder) {
63
+ return properties[prop];
64
+ }
65
+ }
66
+ }
67
+ };
68
+ const buildDependencies = (dependencies, dependencyTree, jsonPomFile) => {
69
+ const parent = getParentDependency(jsonPomFile);
70
+ for (const dep of dependencies) {
71
+ const versionAsString = dep.version ? dep.version.toString() : dep.version;
72
+ if (versionAsString && !versionAsString.includes('${')) {
73
+ const depName = dep.groupId + '/' + dep.artifactId + '@' + versionAsString;
74
+ dependencyTree[depName] = buildDep(dep, dep.version);
75
+ }
76
+ else if (jsonPomFile.project.properties &&
77
+ dep.version &&
78
+ dep.version.includes('${')) {
79
+ searchAndBuildFromProperties(jsonPomFile, dep, dependencyTree);
80
+ }
81
+ else if (!dep.version) {
82
+ if (parent && parent.version) {
83
+ const { parent } = jsonPomFile.project;
84
+ const parsedVersion = getVersionFromParent(parent, dep);
85
+ const depName = dep.groupId + '/' + dep.artifactId + '@' + parsedVersion;
86
+ dependencyTree[depName] = buildDep(dep, parsedVersion);
87
+ }
88
+ }
89
+ }
90
+ };
91
+ const searchAndBuildFromProperties = (jsonPomFile, dep, dependencyTree) => {
92
+ const { properties } = jsonPomFile.project;
93
+ let versionFromProperties = getVersionFromProperties(properties, dep);
94
+ if (versionFromProperties) {
95
+ versionFromProperties = versionFromProperties.toString();
96
+ const depName = dep.groupId + '/' + dep.artifactId + '@' + versionFromProperties;
97
+ dependencyTree[depName] = buildDep(dep, versionFromProperties);
98
+ }
99
+ else {
100
+ const depName = dep.groupId + '/' + dep.artifactId + '@' + null;
101
+ dependencyTree[depName] = buildDep(dep, null);
102
+ }
103
+ };
104
+ const buildDep = (dep, version) => {
105
+ return {
106
+ name: dep.artifactId,
107
+ group: dep.groupId,
108
+ version: version,
109
+ directDependency: true,
110
+ productionDependency: true,
111
+ dependencies: []
112
+ };
113
+ };
89
114
  module.exports = {
90
115
  readPomFile,
91
- getVersion,
92
- parsePomFile,
93
- getFromVersionsTag
116
+ getVersionFromParent,
117
+ parsePomFile
94
118
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/contrast",
3
- "version": "2.0.2-beta.0",
3
+ "version": "2.0.2-beta.1",
4
4
  "description": "Contrast Security's command line tool",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -61,6 +61,7 @@
61
61
  "cross-spawn": "^7.0.3",
62
62
  "dotenv": "^16.0.0",
63
63
  "fast-glob": "^3.2.11",
64
+ "fast-xml-parser": "^4.2.2",
64
65
  "got": "11.8.6",
65
66
  "gradle-to-js": "^2.0.1",
66
67
  "hpagent": "^1.2.0",
@@ -14,7 +14,7 @@ const HIGH = 'HIGH'
14
14
  const CRITICAL = 'CRITICAL'
15
15
  // App
16
16
  const APP_NAME = 'contrast'
17
- const APP_VERSION = '2.0.2-beta.0'
17
+ const APP_VERSION = '2.0.2-beta.1'
18
18
  const TIMEOUT = 120000
19
19
  const HIGH_COLOUR = '#ff9900'
20
20
  const CRITICAL_COLOUR = '#e35858'
@@ -1,112 +1,139 @@
1
1
  const fs = require('fs')
2
- const xml2js = require('xml2js')
2
+ const { XMLParser } = require('fast-xml-parser')
3
3
 
4
4
  const readPomFile = project => {
5
5
  const mavenFilePath = project.cwd + '/pom.xml'
6
6
  const projectFile = fs.readFileSync(mavenFilePath)
7
- let jsonPomFile
8
- xml2js.parseString(projectFile, (err, result) => {
9
- if (err) {
10
- throw err
11
- }
12
- const json = JSON.stringify(result, null)
13
- jsonPomFile = JSON.parse(json)
14
- })
15
- return jsonPomFile
16
- }
17
-
18
- const getFromVersionsTag = (dependencyName, versionIdentifier, jsonPomFile) => {
19
- // reading:
20
- // <!-- DEPENDENCY VERSIONS -->
21
- // <versions.animal-sniffer>1.16</versions.animal-sniffer>
22
- let formattedVersion = versionIdentifier.replace(/[{}]/g, '').replace('$', '')
23
-
24
- if (jsonPomFile.project.properties[0].hasOwnProperty([formattedVersion])) {
25
- return jsonPomFile.project.properties[0][formattedVersion][0]
26
- } else {
27
- return null
28
- }
7
+ const parser = new XMLParser()
8
+ return parser.parse(projectFile)
29
9
  }
30
10
 
31
11
  const parsePomFile = jsonPomFile => {
12
+ console.log(JSON.stringify(jsonPomFile))
32
13
  let dependencyTree = {}
33
- let parsedVersion
34
- let dependencies
35
-
36
- jsonPomFile.project.hasOwnProperty('dependencies')
37
- ? (dependencies = jsonPomFile.project.dependencies[0].dependency)
38
- : (dependencies =
39
- jsonPomFile.project.dependencyManagement[0].dependencies[0].dependency)
40
-
41
- for (let x in dependencies) {
42
- let dependencyObject = dependencies[x]
43
- if (!dependencyObject.hasOwnProperty('version')) {
44
- parsedVersion = getVersion(jsonPomFile, dependencyObject)
45
- } else {
46
- dependencyObject.version[0].includes('${versions.')
47
- ? (parsedVersion = getFromVersionsTag(
48
- dependencyObject.artifactId[0],
49
- dependencyObject.version[0],
50
- jsonPomFile
51
- ))
52
- : (parsedVersion = dependencyObject.version[0])
53
- }
14
+ let dependencies = []
15
+ let dependencyManagement = []
54
16
 
55
- let depName =
56
- dependencyObject.groupId +
57
- '/' +
58
- dependencyObject.artifactId +
59
- '@' +
60
- parsedVersion
61
-
62
- let parsedDependency = {
63
- name: dependencyObject.artifactId[0],
64
- group: dependencyObject.groupId[0],
65
- version: parsedVersion,
66
- directDependency: true,
67
- productionDependency: true,
68
- dependencies: []
69
- }
70
- dependencyTree[depName] = parsedDependency
17
+ if (jsonPomFile.project && jsonPomFile.project.dependencies) {
18
+ dependencies = jsonPomFile.project.dependencies.dependency
19
+ }
20
+
21
+ if (jsonPomFile.project && jsonPomFile.project.dependencyManagement) {
22
+ dependencyManagement =
23
+ jsonPomFile.project.dependencyManagement.dependencies.dependency
71
24
  }
72
25
 
73
- const retrieveParent = getParentDependency(jsonPomFile)
26
+ //merge dependencies with dependencyManagement deps
27
+ //filter out any that don't appear in both by groupId and artifactId
28
+ const mergedAndFilteredDeps = dependencies.map(obj1 => {
29
+ const obj2 = dependencyManagement.find(
30
+ obj2 =>
31
+ obj2.groupId === obj1.groupId && obj2.artifactId === obj1.artifactId
32
+ )
33
+ return obj2 ? { ...obj1, ...obj2 } : obj1
34
+ })
74
35
 
36
+ buildDependencies(mergedAndFilteredDeps, dependencyTree, jsonPomFile)
75
37
  return {
76
- parentPom: retrieveParent,
38
+ parentPom: getParentDependency(jsonPomFile),
77
39
  dependencyTree
78
40
  }
79
41
  }
80
42
 
81
43
  const getParentDependency = jsonPomFile => {
82
- let parent = {}
83
- jsonPomFile.project.hasOwnProperty('parent')
84
- ? (parent = buildParent(jsonPomFile.project.parent))
85
- : (parent = undefined)
86
- return parent
44
+ if (jsonPomFile.project && jsonPomFile.project.parent) {
45
+ return buildParent(jsonPomFile.project.parent)
46
+ } else {
47
+ return undefined
48
+ }
87
49
  }
88
50
 
89
51
  const buildParent = parent => {
90
52
  return {
91
- group: parent[0].groupId[0],
92
- name: parent[0].artifactId[0],
93
- version: parent[0].version[0]
53
+ group: parent.groupId,
54
+ name: parent.artifactId,
55
+ version: parent.version
94
56
  }
95
57
  }
96
58
 
97
- const getVersion = (pomFile, dependencyWithoutVersion) => {
98
- let parentVersion = pomFile.project.parent[0].version[0]
99
- let parentGroupName = pomFile.project.parent[0].groupId[0]
100
- if (parentGroupName === dependencyWithoutVersion.groupId[0]) {
101
- return parentVersion
59
+ const getVersionFromParent = (parentObj, dependencyWithoutVersion) => {
60
+ const { groupId, version } = parentObj
61
+ if (groupId === dependencyWithoutVersion.groupId) {
62
+ return version
102
63
  } else {
103
64
  return null
104
65
  }
105
66
  }
106
67
 
68
+ const getVersionFromProperties = (properties, dep) => {
69
+ if (properties && dep.version.includes('${')) {
70
+ const currentDepVersionPlaceholder = dep.version
71
+ .replace('${', '')
72
+ .replace('}', '')
73
+
74
+ for (const prop in properties) {
75
+ if (prop === currentDepVersionPlaceholder) {
76
+ return properties[prop]
77
+ }
78
+ }
79
+ }
80
+ }
81
+
82
+ const buildDependencies = (dependencies, dependencyTree, jsonPomFile) => {
83
+ const parent = getParentDependency(jsonPomFile)
84
+ for (const dep of dependencies) {
85
+ //sometimes versions are parsed as numbers, convert to string
86
+ const versionAsString = dep.version ? dep.version.toString() : dep.version
87
+ if (versionAsString && !versionAsString.includes('${')) {
88
+ const depName = dep.groupId + '/' + dep.artifactId + '@' + versionAsString
89
+ dependencyTree[depName] = buildDep(dep, dep.version)
90
+ } else if (
91
+ jsonPomFile.project.properties &&
92
+ dep.version &&
93
+ dep.version.includes('${')
94
+ ) {
95
+ searchAndBuildFromProperties(jsonPomFile, dep, dependencyTree)
96
+ } else if (!dep.version) {
97
+ if (parent && parent.version) {
98
+ //get version where group matches from parent tag
99
+ const { parent } = jsonPomFile.project
100
+ const parsedVersion = getVersionFromParent(parent, dep)
101
+ const depName = dep.groupId + '/' + dep.artifactId + '@' + parsedVersion
102
+ dependencyTree[depName] = buildDep(dep, parsedVersion)
103
+ }
104
+ }
105
+ }
106
+ }
107
+
108
+ const searchAndBuildFromProperties = (jsonPomFile, dep, dependencyTree) => {
109
+ //get version from properties tag
110
+ const { properties } = jsonPomFile.project
111
+ let versionFromProperties = getVersionFromProperties(properties, dep)
112
+
113
+ if (versionFromProperties) {
114
+ versionFromProperties = versionFromProperties.toString()
115
+ const depName =
116
+ dep.groupId + '/' + dep.artifactId + '@' + versionFromProperties
117
+ dependencyTree[depName] = buildDep(dep, versionFromProperties)
118
+ } else {
119
+ const depName = dep.groupId + '/' + dep.artifactId + '@' + null
120
+ dependencyTree[depName] = buildDep(dep, null)
121
+ }
122
+ }
123
+
124
+ const buildDep = (dep, version) => {
125
+ return {
126
+ name: dep.artifactId,
127
+ group: dep.groupId,
128
+ version: version,
129
+ directDependency: true,
130
+ productionDependency: true,
131
+ dependencies: []
132
+ }
133
+ }
134
+
107
135
  module.exports = {
108
136
  readPomFile,
109
- getVersion,
110
- parsePomFile,
111
- getFromVersionsTag
137
+ getVersionFromParent,
138
+ parsePomFile
112
139
  }