@contrast/contrast 1.0.5 → 1.0.8
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.
- package/.prettierignore +0 -5
- package/dist/audit/autodetection/autoDetectLanguage.js +3 -3
- package/dist/audit/catalogueApplication/catalogueApplication.js +23 -5
- package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +4 -2
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +2 -1
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +2 -1
- package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +2 -1
- package/dist/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +5 -5
- package/dist/audit/languageAnalysisEngine/getProjectRootFilenames.js +9 -9
- package/dist/audit/languageAnalysisEngine/index.js +2 -2
- package/dist/audit/languageAnalysisEngine/languageAnalysisFactory.js +6 -27
- package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +25 -5
- package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +99 -20
- package/dist/audit/languageAnalysisEngine/report/models/reportListModel.js +2 -1
- package/dist/audit/languageAnalysisEngine/report/models/reportOutputModel.js +24 -0
- package/dist/audit/languageAnalysisEngine/report/models/reportSeverityModel.js +3 -1
- package/dist/audit/languageAnalysisEngine/report/models/severityCountModel.js +16 -0
- package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +35 -14
- package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +58 -47
- package/dist/audit/languageAnalysisEngine/sendSnapshot.js +65 -3
- package/dist/audit/save.js +29 -0
- package/dist/commands/audit/auditController.js +22 -6
- package/dist/commands/audit/help.js +24 -1
- package/dist/commands/audit/processAudit.js +8 -2
- package/dist/commands/audit/saveFile.js +7 -3
- package/dist/commands/scan/processScan.js +1 -1
- package/dist/commands/scan/sca/scaAnalysis.js +48 -11
- package/dist/common/HTTPClient.js +56 -15
- package/dist/common/errorHandling.js +6 -1
- package/dist/common/versionChecker.js +20 -5
- package/dist/constants/constants.js +13 -3
- package/dist/constants/locales.js +15 -12
- package/dist/constants.js +9 -4
- package/dist/index.js +4 -3
- package/dist/lambda/analytics.js +11 -0
- package/dist/lambda/lambda.js +35 -4
- package/dist/lambda/types.js +13 -0
- package/dist/sbom/generateSbom.js +4 -3
- package/dist/scaAnalysis/common/formatMessage.js +46 -1
- package/dist/scaAnalysis/common/treeUpload.js +1 -3
- package/dist/scaAnalysis/go/goAnalysis.js +17 -0
- package/dist/scaAnalysis/go/goParseDeps.js +158 -0
- package/dist/scaAnalysis/go/goReadDepFile.js +21 -0
- package/dist/scaAnalysis/java/analysis.js +11 -22
- package/dist/scaAnalysis/java/index.js +6 -6
- package/dist/scaAnalysis/java/javaBuildDepsParser.js +14 -1
- package/dist/scaAnalysis/javascript/analysis.js +110 -0
- package/dist/scaAnalysis/javascript/index.js +41 -0
- package/dist/scaAnalysis/php/analysis.js +89 -0
- package/dist/scaAnalysis/php/index.js +10 -0
- package/dist/scaAnalysis/python/analysis.js +42 -0
- package/dist/scaAnalysis/python/index.js +10 -0
- package/dist/scaAnalysis/ruby/analysis.js +226 -0
- package/dist/scaAnalysis/ruby/index.js +10 -0
- package/dist/scan/autoDetection.js +8 -4
- package/dist/scan/fileUtils.js +26 -8
- package/dist/scan/formatScanOutput.js +18 -17
- package/dist/scan/models/groupedResultsModel.js +1 -1
- package/dist/scan/models/scanResultsModel.js +3 -1
- package/dist/scan/populateProjectIdAndProjectName.js +2 -1
- package/dist/scan/scan.js +5 -3
- package/dist/scan/scanConfig.js +6 -1
- package/dist/scan/scanController.js +26 -6
- package/dist/scan/scanResults.js +20 -6
- package/dist/utils/commonApi.js +4 -1
- package/dist/utils/filterProjectPath.js +7 -2
- package/dist/utils/oraWrapper.js +5 -1
- package/package.json +13 -9
- package/src/audit/autodetection/autoDetectLanguage.ts +3 -3
- package/src/audit/catalogueApplication/catalogueApplication.js +28 -7
- package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +11 -8
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +2 -1
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +2 -1
- package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +2 -1
- package/src/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +5 -5
- package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +11 -11
- package/src/audit/languageAnalysisEngine/index.js +2 -2
- package/src/audit/languageAnalysisEngine/languageAnalysisFactory.js +11 -31
- package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +35 -32
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +179 -25
- package/src/audit/languageAnalysisEngine/report/models/reportLibraryModel.ts +3 -3
- package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +18 -11
- package/src/audit/languageAnalysisEngine/report/models/reportOutputModel.ts +29 -0
- package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +12 -3
- package/src/audit/languageAnalysisEngine/report/models/severityCountModel.ts +20 -0
- package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +50 -18
- package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +88 -66
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +78 -3
- package/src/audit/save.js +32 -0
- package/src/commands/audit/auditController.ts +23 -15
- package/src/commands/audit/help.ts +24 -1
- package/src/commands/audit/processAudit.ts +7 -4
- package/src/commands/audit/saveFile.ts +5 -1
- package/src/commands/scan/processScan.js +2 -1
- package/src/commands/scan/sca/scaAnalysis.js +70 -29
- package/src/common/HTTPClient.js +72 -25
- package/src/common/errorHandling.ts +10 -1
- package/src/common/versionChecker.ts +24 -5
- package/src/constants/constants.js +13 -3
- package/src/constants/locales.js +15 -12
- package/src/constants.js +9 -4
- package/src/index.ts +5 -3
- package/src/lambda/analytics.ts +9 -0
- package/src/lambda/arn.ts +2 -1
- package/src/lambda/lambda.ts +37 -17
- package/src/lambda/types.ts +35 -0
- package/src/lambda/utils.ts +2 -7
- package/src/sbom/generateSbom.ts +1 -1
- package/src/scaAnalysis/common/formatMessage.js +51 -1
- package/src/scaAnalysis/common/treeUpload.js +1 -6
- package/src/scaAnalysis/go/goAnalysis.js +19 -0
- package/src/scaAnalysis/go/goParseDeps.js +203 -0
- package/src/scaAnalysis/go/goReadDepFile.js +30 -0
- package/src/scaAnalysis/java/analysis.js +15 -32
- package/src/scaAnalysis/java/index.js +6 -6
- package/src/scaAnalysis/java/javaBuildDepsParser.js +15 -2
- package/src/scaAnalysis/javascript/analysis.js +127 -0
- package/src/scaAnalysis/javascript/index.js +56 -0
- package/src/scaAnalysis/php/analysis.js +98 -0
- package/src/scaAnalysis/php/index.js +11 -0
- package/src/scaAnalysis/python/analysis.js +49 -0
- package/src/scaAnalysis/python/index.js +11 -0
- package/src/scaAnalysis/ruby/analysis.js +282 -0
- package/src/scaAnalysis/ruby/index.js +11 -0
- package/src/scan/autoDetection.js +11 -7
- package/src/scan/fileUtils.js +27 -8
- package/src/scan/formatScanOutput.ts +26 -18
- package/src/scan/models/groupedResultsModel.ts +3 -3
- package/src/scan/models/resultContentModel.ts +1 -1
- package/src/scan/models/scanResultsModel.ts +5 -2
- package/src/scan/populateProjectIdAndProjectName.js +3 -1
- package/src/scan/scan.ts +8 -6
- package/src/scan/scanConfig.js +5 -1
- package/src/scan/scanController.js +30 -9
- package/src/scan/scanResults.js +31 -10
- package/src/utils/commonApi.js +4 -1
- package/src/utils/filterProjectPath.js +6 -2
- package/src/utils/oraWrapper.js +6 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export enum StatusType {
|
|
2
|
+
FAILED = 'failed',
|
|
3
|
+
SUCCESS = 'success'
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export enum EventType {
|
|
7
|
+
START = 'start_command_session',
|
|
8
|
+
END = 'end_command_session'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type LambdaOptions = {
|
|
12
|
+
functionName?: string
|
|
13
|
+
listFunctions?: boolean
|
|
14
|
+
region?: string
|
|
15
|
+
endpointUrl?: string
|
|
16
|
+
profile?: string
|
|
17
|
+
help?: boolean
|
|
18
|
+
verbose?: boolean
|
|
19
|
+
jsonOutput?: boolean
|
|
20
|
+
_unknown?: string[]
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
type ScanFunctionData = {
|
|
24
|
+
functionArn: string
|
|
25
|
+
scanId: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type AnalyticsOption = {
|
|
29
|
+
sessionId: string
|
|
30
|
+
eventType: EventType
|
|
31
|
+
arguments?: LambdaOptions
|
|
32
|
+
scanFunctionData?: ScanFunctionData
|
|
33
|
+
status?: StatusType
|
|
34
|
+
errorMsg?: string
|
|
35
|
+
}
|
package/src/lambda/utils.ts
CHANGED
|
@@ -19,13 +19,8 @@ class PrintVulnerability {
|
|
|
19
19
|
whatHappened: string
|
|
20
20
|
|
|
21
21
|
constructor(index: number, vulnerability: any, group?: any[]) {
|
|
22
|
-
const {
|
|
23
|
-
|
|
24
|
-
title,
|
|
25
|
-
description,
|
|
26
|
-
remediation,
|
|
27
|
-
categoryText
|
|
28
|
-
} = vulnerability
|
|
22
|
+
const { severityText, title, description, remediation, categoryText } =
|
|
23
|
+
vulnerability
|
|
29
24
|
|
|
30
25
|
this.group = group
|
|
31
26
|
this.vulnerability = vulnerability
|
package/src/sbom/generateSbom.ts
CHANGED
|
@@ -5,6 +5,56 @@ const createJavaTSMessage = javaTree => {
|
|
|
5
5
|
}
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
|
+
|
|
9
|
+
const createJavaScriptTSMessage = js => {
|
|
10
|
+
let message = {
|
|
11
|
+
node: {
|
|
12
|
+
packageJSON: js.packageJSON
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
if (js.yarn !== undefined) {
|
|
16
|
+
message.node.yarnLockFile = js.yarn.yarnLockFile
|
|
17
|
+
message.node.yarnVersion = js.yarn.yarnVersion
|
|
18
|
+
} else {
|
|
19
|
+
message.node.npmLockFile = js.npmLockFile
|
|
20
|
+
}
|
|
21
|
+
return message
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const createGoTSMessage = goTree => {
|
|
25
|
+
return {
|
|
26
|
+
go: {
|
|
27
|
+
goDependencyTrees: goTree
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const createRubyTSMessage = rubyTree => {
|
|
33
|
+
return {
|
|
34
|
+
ruby: rubyTree
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const createPythonTSMessage = pythonTree => {
|
|
39
|
+
return {
|
|
40
|
+
python: pythonTree
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const createPhpTSMessage = phpTree => {
|
|
45
|
+
return {
|
|
46
|
+
php: {
|
|
47
|
+
composerJSON: phpTree.composerJSON,
|
|
48
|
+
lockFile: phpTree.lockFile
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
8
53
|
module.exports = {
|
|
9
|
-
|
|
54
|
+
createJavaScriptTSMessage,
|
|
55
|
+
createJavaTSMessage,
|
|
56
|
+
createGoTSMessage,
|
|
57
|
+
createPhpTSMessage,
|
|
58
|
+
createRubyTSMessage,
|
|
59
|
+
createPythonTSMessage
|
|
10
60
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const { getHttpClient } = require('../../utils/commonApi')
|
|
2
|
-
const { handleResponseErrors } = require('../../common/errorHandling')
|
|
3
2
|
const { APP_VERSION } = require('../../constants/constants')
|
|
4
3
|
|
|
5
4
|
const commonSendSnapShot = async (analysis, config) => {
|
|
@@ -9,19 +8,15 @@ const commonSendSnapShot = async (analysis, config) => {
|
|
|
9
8
|
snapshot: analysis
|
|
10
9
|
}
|
|
11
10
|
|
|
12
|
-
//console.log(JSON.stringify(analysis))
|
|
13
|
-
|
|
14
|
-
//console.log(JSON.stringify(requestBody))
|
|
15
11
|
const client = getHttpClient(config)
|
|
16
12
|
return client
|
|
17
13
|
.sendSnapshot(requestBody, config)
|
|
18
14
|
.then(res => {
|
|
19
15
|
if (res.statusCode === 201) {
|
|
20
|
-
console.log('snapshot processed successfully')
|
|
21
16
|
return res.body
|
|
22
17
|
} else {
|
|
23
18
|
console.log(res.statusCode)
|
|
24
|
-
|
|
19
|
+
console.log('error processing dependencies')
|
|
25
20
|
}
|
|
26
21
|
})
|
|
27
22
|
.catch(err => {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const { createGoTSMessage } = require('../common/formatMessage')
|
|
2
|
+
const goReadDepFile = require('./goReadDepFile')
|
|
3
|
+
const goParseDeps = require('./goParseDeps')
|
|
4
|
+
|
|
5
|
+
const goAnalysis = (config, languageFiles) => {
|
|
6
|
+
try {
|
|
7
|
+
const rawGoDependencies = goReadDepFile.getGoDependencies(config)
|
|
8
|
+
const parsedGoDependencies =
|
|
9
|
+
goParseDeps.parseGoDependencies(rawGoDependencies)
|
|
10
|
+
|
|
11
|
+
return createGoTSMessage(parsedGoDependencies)
|
|
12
|
+
} catch (e) {
|
|
13
|
+
console.log(e.message.toString())
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
module.exports = {
|
|
18
|
+
goAnalysis
|
|
19
|
+
}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
const crypto = require('crypto')
|
|
2
|
+
|
|
3
|
+
const parseGoDependencies = goDeps => {
|
|
4
|
+
return parseGo(goDeps)
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const parseGo = modGraphOutput => {
|
|
8
|
+
let splitLines = splitAllLinesIntoArray(modGraphOutput)
|
|
9
|
+
const directDepNames = getDirectDepNames(splitLines)
|
|
10
|
+
const uniqueTransitiveDepNames = getAllUniqueTransitiveDepNames(
|
|
11
|
+
splitLines,
|
|
12
|
+
directDepNames
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
let rootNodes = createRootNodes(splitLines)
|
|
16
|
+
|
|
17
|
+
createTransitiveDeps(uniqueTransitiveDepNames, splitLines, rootNodes)
|
|
18
|
+
|
|
19
|
+
return rootNodes
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const splitAllLinesIntoArray = modGraphOutput => {
|
|
23
|
+
return modGraphOutput.split(/\r\n|\r|\n/)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const getAllDepsOfADepAsEdge = (dep, deps) => {
|
|
27
|
+
let edges = {}
|
|
28
|
+
|
|
29
|
+
const depRows = deps.filter(line => {
|
|
30
|
+
return line.startsWith(dep)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
depRows.forEach(dep => {
|
|
34
|
+
const edgeName = dep.split(' ')[1]
|
|
35
|
+
edges[edgeName] = edgeName
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
return edges
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const getAllDepsOfADepAsName = (dep, deps) => {
|
|
42
|
+
let edges = []
|
|
43
|
+
|
|
44
|
+
const depRows = deps.filter(line => {
|
|
45
|
+
return line.startsWith(dep)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
depRows.forEach(dep => {
|
|
49
|
+
const edgeName = dep.split(' ')[1]
|
|
50
|
+
edges.push(edgeName)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
return edges
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const createRootNodes = deps => {
|
|
57
|
+
let rootDep = {}
|
|
58
|
+
const rootDeps = getRootDeps(deps)
|
|
59
|
+
|
|
60
|
+
const edges = rootDeps.map(dep => {
|
|
61
|
+
return dep.split(' ')[1]
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
rootDep[rootDeps[0].split(' ')[0]] = {}
|
|
65
|
+
|
|
66
|
+
edges.forEach(edge => {
|
|
67
|
+
const splitEdge = edge.split('@')
|
|
68
|
+
const splitGroupName = splitEdge[0].split('/')
|
|
69
|
+
const name = splitGroupName.pop()
|
|
70
|
+
const lastSlash = splitEdge[0].lastIndexOf('/')
|
|
71
|
+
let group = splitEdge[0].substring(0, lastSlash)
|
|
72
|
+
const hash = getHash(splitEdge[0])
|
|
73
|
+
|
|
74
|
+
group = checkGroupExists(group, name)
|
|
75
|
+
|
|
76
|
+
//get the edges of the root dependency
|
|
77
|
+
const edgesOfDep = getAllDepsOfADepAsEdge(edge, deps)
|
|
78
|
+
|
|
79
|
+
rootDep[rootDeps[0].split(' ')[0]][edge] = {
|
|
80
|
+
artifactID: name,
|
|
81
|
+
group: group,
|
|
82
|
+
version: splitEdge[1],
|
|
83
|
+
scope: '"compile',
|
|
84
|
+
type: 'direct',
|
|
85
|
+
hash: hash,
|
|
86
|
+
edges: edgesOfDep
|
|
87
|
+
}
|
|
88
|
+
})
|
|
89
|
+
return rootDep
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const getRootDeps = deps => {
|
|
93
|
+
const rootDeps = deps.filter(dep => {
|
|
94
|
+
const parentDep = dep.split(' ')[0]
|
|
95
|
+
if (parentDep.split('@v').length === 1) {
|
|
96
|
+
return dep
|
|
97
|
+
}
|
|
98
|
+
})
|
|
99
|
+
return rootDeps
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const getHash = library => {
|
|
103
|
+
let shaSum = crypto.createHash('sha1')
|
|
104
|
+
shaSum.update(library)
|
|
105
|
+
return shaSum.digest('hex')
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const getDirectDepNames = deps => {
|
|
109
|
+
const directDepNames = []
|
|
110
|
+
|
|
111
|
+
deps.forEach(dep => {
|
|
112
|
+
const parentDep = dep.split(' ')[0]
|
|
113
|
+
if (parentDep.split('@v').length === 1) {
|
|
114
|
+
dep.split(' ')[1] !== undefined
|
|
115
|
+
? directDepNames.push(dep.split(' ')[1])
|
|
116
|
+
: null
|
|
117
|
+
}
|
|
118
|
+
})
|
|
119
|
+
return directDepNames
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const getAllUniqueTransitiveDepNames = (deps, directDepNames) => {
|
|
123
|
+
let uniqueDeps = []
|
|
124
|
+
|
|
125
|
+
deps.forEach(dep => {
|
|
126
|
+
const parentDep = dep.split(' ')[0]
|
|
127
|
+
if (parentDep.split('@v').length !== 1) {
|
|
128
|
+
if (!directDepNames.includes(parentDep)) {
|
|
129
|
+
if (!uniqueDeps.includes(parentDep)) {
|
|
130
|
+
parentDep.length > 1 ? uniqueDeps.push(parentDep) : null
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
})
|
|
135
|
+
return uniqueDeps
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const checkGroupExists = (group, name) => {
|
|
139
|
+
if (group === null || group === '') {
|
|
140
|
+
return name
|
|
141
|
+
}
|
|
142
|
+
return group
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const createTransitiveDeps = (transitiveDeps, splitLines, rootNodes) => {
|
|
146
|
+
transitiveDeps.forEach(dep => {
|
|
147
|
+
//create transitive dep
|
|
148
|
+
const splitEdge = dep.split('@')
|
|
149
|
+
const splitGroupName = splitEdge[0].split('/')
|
|
150
|
+
const name = splitGroupName.pop()
|
|
151
|
+
const lastSlash = splitEdge[0].lastIndexOf('/')
|
|
152
|
+
let group = splitEdge[0].substring(0, lastSlash)
|
|
153
|
+
const hash = getHash(splitEdge[0])
|
|
154
|
+
|
|
155
|
+
group = checkGroupExists(group, name)
|
|
156
|
+
|
|
157
|
+
const transitiveDep = {
|
|
158
|
+
artifactID: name,
|
|
159
|
+
group: group,
|
|
160
|
+
version: splitEdge[1],
|
|
161
|
+
scope: 'compile',
|
|
162
|
+
type: 'transitive',
|
|
163
|
+
hash: hash,
|
|
164
|
+
edges: {}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
//add edges to transitiveDep
|
|
168
|
+
const edges = getAllDepsOfADepAsEdge(dep, splitLines)
|
|
169
|
+
transitiveDep.edges = edges
|
|
170
|
+
|
|
171
|
+
//add all edges as a transitive dependency to rootNodes
|
|
172
|
+
const edgesAsName = getAllDepsOfADepAsName(dep, splitLines)
|
|
173
|
+
|
|
174
|
+
edgesAsName.forEach(dep => {
|
|
175
|
+
const splitEdge = dep.split('@')
|
|
176
|
+
const splitGroupName = splitEdge[0].split('/')
|
|
177
|
+
const name = splitGroupName.pop()
|
|
178
|
+
const lastSlash = splitEdge[0].lastIndexOf('/')
|
|
179
|
+
let group = splitEdge[0].substring(0, lastSlash)
|
|
180
|
+
const hash = getHash(splitEdge[0])
|
|
181
|
+
|
|
182
|
+
group = checkGroupExists(group, name)
|
|
183
|
+
|
|
184
|
+
const transitiveDep = {
|
|
185
|
+
artifactID: name,
|
|
186
|
+
group: group,
|
|
187
|
+
version: splitEdge[1],
|
|
188
|
+
scope: 'compile',
|
|
189
|
+
type: 'transitive',
|
|
190
|
+
hash: hash,
|
|
191
|
+
edges: {}
|
|
192
|
+
}
|
|
193
|
+
rootNodes[Object.keys(rootNodes)[0]][dep] = transitiveDep
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
//add transitive dependency to rootNodes
|
|
197
|
+
rootNodes[Object.keys(rootNodes)[0]][dep] = transitiveDep
|
|
198
|
+
})
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
module.exports = {
|
|
202
|
+
parseGoDependencies
|
|
203
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const child_process = require('child_process')
|
|
2
|
+
const i18n = require('i18n')
|
|
3
|
+
|
|
4
|
+
const getGoDependencies = config => {
|
|
5
|
+
let cmdStdout
|
|
6
|
+
let cwd = config.file ? config.file.replace('go.mod', '') : process.cwd()
|
|
7
|
+
|
|
8
|
+
try {
|
|
9
|
+
// A sample of this output can be found
|
|
10
|
+
// in the go test folder data/goModGraphResults.text
|
|
11
|
+
cmdStdout = child_process.execSync('go mod graph', { cwd })
|
|
12
|
+
|
|
13
|
+
return cmdStdout.toString()
|
|
14
|
+
} catch (err) {
|
|
15
|
+
if (err.message === 'spawnSync /bin/sh ENOENT') {
|
|
16
|
+
err.message =
|
|
17
|
+
'\n\n*************** No transitive dependencies ***************\n\nWe are unable to build a dependency tree view from your repository as there were no transitive dependencies found.'
|
|
18
|
+
}
|
|
19
|
+
console.log(
|
|
20
|
+
i18n.__('goReadProjectFile', cwd, `${err.message ? err.message : ''}`)
|
|
21
|
+
)
|
|
22
|
+
// throw new Error(
|
|
23
|
+
// i18n.__('goReadProjectFile', cwd, `${err.message ? err.message : ''}`)
|
|
24
|
+
// )
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
module.exports = {
|
|
29
|
+
getGoDependencies
|
|
30
|
+
}
|
|
@@ -6,25 +6,24 @@ const fs = require('fs')
|
|
|
6
6
|
const MAVEN = 'maven'
|
|
7
7
|
const GRADLE = 'gradle'
|
|
8
8
|
|
|
9
|
-
const determineProjectTypeAndCwd = (files,
|
|
9
|
+
const determineProjectTypeAndCwd = (files, file) => {
|
|
10
10
|
const projectData = {}
|
|
11
11
|
|
|
12
12
|
if (files[0].includes('pom.xml')) {
|
|
13
13
|
projectData.projectType = MAVEN
|
|
14
|
-
projectData.cwd = projectPath
|
|
15
|
-
? projectPath
|
|
16
|
-
: files[0].replace('pom.xml', '')
|
|
17
14
|
} else if (files[0].includes('build.gradle')) {
|
|
18
15
|
projectData.projectType = GRADLE
|
|
19
|
-
projectData.cwd = projectPath
|
|
20
|
-
? projectPath
|
|
21
|
-
: files[0].replace('pom.xml', '')
|
|
22
16
|
}
|
|
23
17
|
|
|
18
|
+
//clean up the path to be a folder not a file
|
|
19
|
+
projectData.cwd = file
|
|
20
|
+
? file.replace('pom.xml', '').replace('build.gradle', '')
|
|
21
|
+
: file
|
|
22
|
+
|
|
24
23
|
return projectData
|
|
25
24
|
}
|
|
26
25
|
|
|
27
|
-
const buildMaven =
|
|
26
|
+
const buildMaven = (config, projectData, timeout) => {
|
|
28
27
|
let cmdStdout
|
|
29
28
|
let mvn_settings = ''
|
|
30
29
|
|
|
@@ -40,23 +39,11 @@ const buildMaven = async (config, projectData, timeout) => {
|
|
|
40
39
|
timeout
|
|
41
40
|
}
|
|
42
41
|
)
|
|
43
|
-
// output.mvnDependancyTreeOutput = cmdStdout.toString()
|
|
44
|
-
// console.log(cmdStdout.toString())
|
|
45
42
|
return cmdStdout.toString()
|
|
46
43
|
} catch (err) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
timeout
|
|
51
|
-
})
|
|
52
|
-
throw new Error(
|
|
53
|
-
i18n.__('mavenDependencyTreeNonZero', projectData.cwd, `${err.message}`)
|
|
54
|
-
)
|
|
55
|
-
} catch (mvnErr) {
|
|
56
|
-
throw new Error(
|
|
57
|
-
i18n.__('mavenNotInstalledError', projectData.cwd, `${mvnErr.message}`)
|
|
58
|
-
)
|
|
59
|
-
}
|
|
44
|
+
throw new Error(
|
|
45
|
+
i18n.__('mavenDependencyTreeNonZero', projectData.cwd, `${err.message}`)
|
|
46
|
+
)
|
|
60
47
|
}
|
|
61
48
|
}
|
|
62
49
|
|
|
@@ -107,7 +94,7 @@ const buildGradle = (config, projectData, timeout) => {
|
|
|
107
94
|
}
|
|
108
95
|
)
|
|
109
96
|
}
|
|
110
|
-
output
|
|
97
|
+
output = cmdStdout.toString()
|
|
111
98
|
return output
|
|
112
99
|
} catch (err) {
|
|
113
100
|
if (
|
|
@@ -129,7 +116,7 @@ const buildGradle = (config, projectData, timeout) => {
|
|
|
129
116
|
}
|
|
130
117
|
}
|
|
131
118
|
|
|
132
|
-
const getJavaBuildDeps =
|
|
119
|
+
const getJavaBuildDeps = (config, files) => {
|
|
133
120
|
const timeout = 960000
|
|
134
121
|
let output = {
|
|
135
122
|
mvnDependancyTreeOutput: undefined,
|
|
@@ -137,20 +124,16 @@ const getJavaBuildDeps = async (config, files) => {
|
|
|
137
124
|
}
|
|
138
125
|
|
|
139
126
|
try {
|
|
140
|
-
const projectData = determineProjectTypeAndCwd(files, config.
|
|
127
|
+
const projectData = determineProjectTypeAndCwd(files, config.file)
|
|
141
128
|
if (projectData.projectType === MAVEN) {
|
|
142
|
-
output.mvnDependancyTreeOutput =
|
|
143
|
-
config,
|
|
144
|
-
projectData,
|
|
145
|
-
timeout
|
|
146
|
-
)
|
|
129
|
+
output.mvnDependancyTreeOutput = buildMaven(config, projectData, timeout)
|
|
147
130
|
} else if (projectData.projectType === GRADLE) {
|
|
148
131
|
output.mvnDependancyTreeOutput = buildGradle(config, projectData, timeout)
|
|
149
132
|
}
|
|
150
133
|
output.projectType = projectData.projectType
|
|
151
134
|
return output
|
|
152
135
|
} catch (err) {
|
|
153
|
-
|
|
136
|
+
console.log(err.message.toString())
|
|
154
137
|
}
|
|
155
138
|
}
|
|
156
139
|
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
const
|
|
1
|
+
const analysis = require('./analysis')
|
|
2
2
|
const { parseBuildDeps } = require('./javaBuildDepsParser')
|
|
3
3
|
const { createJavaTSMessage } = require('../common/formatMessage')
|
|
4
4
|
|
|
5
|
-
const javaAnalysis =
|
|
6
|
-
languageFiles.
|
|
5
|
+
const javaAnalysis = (config, languageFiles) => {
|
|
6
|
+
languageFiles.JAVA.forEach(file => {
|
|
7
7
|
file.replace('build.gradle.kts', 'build.gradle')
|
|
8
8
|
})
|
|
9
9
|
|
|
10
|
-
const javaDeps =
|
|
10
|
+
const javaDeps = buildJavaTree(config, languageFiles.JAVA)
|
|
11
11
|
return createJavaTSMessage(javaDeps)
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
const buildJavaTree =
|
|
15
|
-
const javaBuildDeps =
|
|
14
|
+
const buildJavaTree = (config, files) => {
|
|
15
|
+
const javaBuildDeps = analysis.getJavaBuildDeps(config, files)
|
|
16
16
|
return parseBuildDeps(config, javaBuildDeps)
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -4,13 +4,13 @@ let sb = new StringBuilder()
|
|
|
4
4
|
|
|
5
5
|
const parseBuildDeps = (config, input) => {
|
|
6
6
|
const { mvnDependancyTreeOutput, projectType } = input
|
|
7
|
-
// console.log(projectType)
|
|
8
7
|
try {
|
|
9
8
|
return parseGradle(mvnDependancyTreeOutput, config, projectType)
|
|
10
9
|
} catch (err) {
|
|
11
10
|
throw new Error(i18n.__('javaParseProjectFile') + `${err.message}`)
|
|
12
11
|
}
|
|
13
12
|
}
|
|
13
|
+
|
|
14
14
|
const preParser = shavedOutput => {
|
|
15
15
|
let obj = []
|
|
16
16
|
for (let dep in shavedOutput) {
|
|
@@ -387,5 +387,18 @@ const parseGradle = (gradleDependencyTreeOutput, config, projectType) => {
|
|
|
387
387
|
}
|
|
388
388
|
|
|
389
389
|
module.exports = {
|
|
390
|
-
parseBuildDeps
|
|
390
|
+
parseBuildDeps,
|
|
391
|
+
shaveOutput,
|
|
392
|
+
validateIndentation,
|
|
393
|
+
calculateLevels,
|
|
394
|
+
lastChild,
|
|
395
|
+
hasChildren,
|
|
396
|
+
getElementHeader,
|
|
397
|
+
createElement,
|
|
398
|
+
stripElement,
|
|
399
|
+
checkVersion,
|
|
400
|
+
computeRelationToLastElement,
|
|
401
|
+
addIndentation,
|
|
402
|
+
computeLevel,
|
|
403
|
+
computeIndentation
|
|
391
404
|
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const yarnParser = require('@yarnpkg/lockfile')
|
|
3
|
+
const yaml = require('js-yaml')
|
|
4
|
+
const i18n = require('i18n')
|
|
5
|
+
const {
|
|
6
|
+
formatKey
|
|
7
|
+
} = require('../../audit/nodeAnalysisEngine/parseYarn2LockFileContents')
|
|
8
|
+
|
|
9
|
+
const readFile = async (config, languageFiles, nameOfFile) => {
|
|
10
|
+
const index = languageFiles.findIndex(v => v.includes(nameOfFile))
|
|
11
|
+
|
|
12
|
+
if (config.file) {
|
|
13
|
+
return fs.readFileSync(config.file.concat(languageFiles[index]), 'utf8')
|
|
14
|
+
} else {
|
|
15
|
+
console.log('could not find file')
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const readYarn = async (config, languageFiles, nameOfFile) => {
|
|
20
|
+
let yarn = {
|
|
21
|
+
yarnVersion: 1,
|
|
22
|
+
rawYarnLockFileContents: ''
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
let rawYarnLockFileContents = await readFile(
|
|
27
|
+
config,
|
|
28
|
+
languageFiles,
|
|
29
|
+
nameOfFile
|
|
30
|
+
)
|
|
31
|
+
yarn.rawYarnLockFileContents = rawYarnLockFileContents
|
|
32
|
+
|
|
33
|
+
if (
|
|
34
|
+
!yarn.rawYarnLockFileContents.includes('lockfile v1') ||
|
|
35
|
+
yarn.rawYarnLockFileContents.includes('__metadata')
|
|
36
|
+
) {
|
|
37
|
+
yarn.rawYarnLockFileContents = yaml.load(rawYarnLockFileContents)
|
|
38
|
+
yarn.yarnVersion = 2
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return yarn
|
|
42
|
+
} catch (err) {
|
|
43
|
+
console.log(i18n.__('nodeReadYarnLockFileError') + `${err.message}`)
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const parseNpmLockFile = async js => {
|
|
49
|
+
try {
|
|
50
|
+
js.npmLockFile = JSON.parse(js.rawLockFileContents)
|
|
51
|
+
if (js.npmLockFile && js.npmLockFile.lockfileVersion > 1) {
|
|
52
|
+
const listOfTopDep = Object.keys(js.npmLockFile.dependencies)
|
|
53
|
+
Object.entries(js.npmLockFile.dependencies).forEach(([objKey, value]) => {
|
|
54
|
+
if (value.requires) {
|
|
55
|
+
const listOfRequiresDep = Object.keys(value.requires)
|
|
56
|
+
listOfRequiresDep.forEach(dep => {
|
|
57
|
+
if (!listOfTopDep.includes(dep)) {
|
|
58
|
+
addDepToLockFile(js, value['requires'], dep)
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (value.dependencies) {
|
|
64
|
+
Object.entries(value.dependencies).forEach(
|
|
65
|
+
([objChildKey, childValue]) => {
|
|
66
|
+
if (childValue.requires) {
|
|
67
|
+
const listOfRequiresDep = Object.keys(childValue.requires)
|
|
68
|
+
listOfRequiresDep.forEach(dep => {
|
|
69
|
+
if (!listOfTopDep.includes(dep)) {
|
|
70
|
+
addDepToLockFile(js, childValue['requires'], dep)
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
return js.npmLockFile
|
|
79
|
+
} else {
|
|
80
|
+
return js.npmLockFile
|
|
81
|
+
}
|
|
82
|
+
} catch (err) {
|
|
83
|
+
console.log(i18n.__('NodeParseNPM') + `${err.message}`)
|
|
84
|
+
return
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const addDepToLockFile = (js, depObj, key) => {
|
|
89
|
+
return (js.npmLockFile.dependencies[key] = { version: depObj[key] })
|
|
90
|
+
}
|
|
91
|
+
const parseYarnLockFile = async js => {
|
|
92
|
+
try {
|
|
93
|
+
js.yarn.yarnLockFile = {}
|
|
94
|
+
if (js.yarn.yarnVersion === 1) {
|
|
95
|
+
js.yarn.yarnLockFile = yarnParser.parse(js.yarn.rawYarnLockFileContents)
|
|
96
|
+
delete js.yarn.rawYarnLockFileContents
|
|
97
|
+
return js
|
|
98
|
+
} else {
|
|
99
|
+
js.yarn.yarnLockFile['object'] = js.yarn.rawYarnLockFileContents
|
|
100
|
+
delete js.yarn.yarnLockFile['object'].__metadata
|
|
101
|
+
js.yarn.yarnLockFile['type'] = 'success'
|
|
102
|
+
|
|
103
|
+
Object.entries(js.yarn.rawYarnLockFileContents).forEach(
|
|
104
|
+
([key, value]) => {
|
|
105
|
+
const rawKeyNames = key.split(',')
|
|
106
|
+
const keyNames = formatKey(rawKeyNames)
|
|
107
|
+
|
|
108
|
+
keyNames.forEach(name => {
|
|
109
|
+
js.yarn.yarnLockFile.object[name] = value
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
)
|
|
113
|
+
return js
|
|
114
|
+
}
|
|
115
|
+
} catch (err) {
|
|
116
|
+
console.log(i18n.__('NodeParseYarn') + `${err.message}`)
|
|
117
|
+
return
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
module.exports = {
|
|
122
|
+
readYarn,
|
|
123
|
+
parseYarnLockFile,
|
|
124
|
+
parseNpmLockFile,
|
|
125
|
+
readFile,
|
|
126
|
+
formatKey
|
|
127
|
+
}
|