@contrast/contrast 2.0.1 → 2.0.2-beta.0

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 (49) hide show
  1. package/dist/audit/report/reportingFeature.js +7 -0
  2. package/dist/cliConstants.js +9 -8
  3. package/dist/commands/audit/processAudit.js +0 -2
  4. package/dist/commands/github/fingerprintConfig.js +2 -1
  5. package/dist/commands/github/processFingerprint.js +17 -7
  6. package/dist/commands/github/projectGroup.js +110 -30
  7. package/dist/commands/github/repoServices.js +42 -4
  8. package/dist/common/HTTPClient.js +37 -16
  9. package/dist/common/baseRequest.js +74 -0
  10. package/dist/constants/constants.js +1 -1
  11. package/dist/scaAnalysis/common/auditReport.js +8 -1
  12. package/dist/scaAnalysis/common/scaServicesUpload.js +3 -1
  13. package/dist/scaAnalysis/go/goReadDepFile.js +5 -1
  14. package/dist/scaAnalysis/java/analysis.js +1 -1
  15. package/dist/scaAnalysis/java/javaBuildDepsParser.js +11 -1
  16. package/dist/scaAnalysis/legacy/legacyFlow.js +0 -6
  17. package/dist/scaAnalysis/processServicesFlow.js +38 -17
  18. package/dist/scaAnalysis/repoMode/mavenParser.js +19 -1
  19. package/dist/scaAnalysis/scaAnalysis.js +4 -8
  20. package/dist/scan/autoDetection.js +12 -5
  21. package/dist/scan/fileUtils.js +33 -19
  22. package/dist/utils/paramsUtil/paramHandler.js +11 -2
  23. package/dist/utils/validationCheck.js +5 -1
  24. package/package.json +6 -3
  25. package/src/audit/report/reportingFeature.ts +7 -0
  26. package/src/cliConstants.js +9 -8
  27. package/src/commands/audit/processAudit.js +0 -2
  28. package/src/commands/github/fingerprintConfig.js +2 -2
  29. package/src/commands/github/processFingerprint.js +21 -11
  30. package/src/commands/github/projectGroup.js +131 -35
  31. package/src/commands/github/repoServices.js +46 -4
  32. package/src/common/HTTPClient.js +46 -17
  33. package/src/common/baseRequest.ts +83 -0
  34. package/src/constants/constants.js +1 -1
  35. package/src/scaAnalysis/common/auditReport.js +8 -1
  36. package/src/scaAnalysis/common/scaServicesUpload.js +5 -1
  37. package/src/scaAnalysis/go/goReadDepFile.js +5 -1
  38. package/src/scaAnalysis/java/analysis.js +1 -1
  39. package/src/scaAnalysis/java/javaBuildDepsParser.js +17 -1
  40. package/src/scaAnalysis/legacy/legacyFlow.js +0 -5
  41. package/src/scaAnalysis/processServicesFlow.js +82 -24
  42. package/src/scaAnalysis/repoMode/mavenParser.js +24 -1
  43. package/src/scaAnalysis/scaAnalysis.js +9 -8
  44. package/src/scan/autoDetection.js +12 -5
  45. package/src/scan/fileUtils.js +33 -19
  46. package/src/utils/paramsUtil/paramHandler.js +16 -2
  47. package/src/utils/validationCheck.js +6 -1
  48. package/dist/utils/settingsHelper.js +0 -14
  49. package/src/utils/settingsHelper.js +0 -16
@@ -17,25 +17,41 @@ const getProjectIdByOrg = async config => {
17
17
 
18
18
  const createNewProjectGroupBody = async config => {
19
19
  let body = {
20
- organizationId: config.organizationId,
21
- name: config.name ? config.name : config.file //has to be unique per project
20
+ organizationId: config.organizationId
22
21
  }
23
22
  if (config.repo || config?.repositoryId) {
24
23
  body.repositoryId = config.repositoryId
25
24
  body.type = 'REPOSITORY'
25
+ body.name = getProjectGroupNameRepo(config)
26
26
  } else {
27
27
  body.repositoryId = null
28
28
  body.type = 'CLI'
29
+ body.name = getProjectGroupNameCLI(config)
29
30
  }
30
31
  return body
31
32
  }
32
33
 
34
+ const getProjectGroupNameRepo = config => {
35
+ return config.repositoryName
36
+ }
37
+ const getProjectGroupNameCLI = config => {
38
+ // file here is actually folder name
39
+ return config.name ? config.name : config.file
40
+ }
41
+
42
+ const getProjectName = config => {
43
+ return config.name ? config.name : config.fileName
44
+ }
45
+
33
46
  const registerNewProjectGroup = async config => {
34
47
  let body = await createNewProjectGroupBody(config)
35
48
 
36
49
  const client = await commonApi.getHttpClient(config)
37
- body.projects = createProjects([config])
38
-
50
+ if (config.repositoryId) {
51
+ body.projects = []
52
+ } else {
53
+ body.projects = createProjectsArray([config])
54
+ }
39
55
  let projectGroupInfo = await client
40
56
  .registerProjectGroup(config, body)
41
57
  .then(res => {
@@ -53,7 +69,7 @@ const registerNewProjectGroup = async config => {
53
69
  }
54
70
 
55
71
  if (res.statusCode === 409) {
56
- return []
72
+ return ''
57
73
  }
58
74
  })
59
75
  .catch(err => {
@@ -64,30 +80,33 @@ const registerNewProjectGroup = async config => {
64
80
  return projectGroupInfo
65
81
  }
66
82
 
67
- const createProjects = params => {
83
+ const createProjectsArray = params => {
68
84
  let projectsArray = []
69
85
  let projects = {}
70
-
71
86
  params.forEach(param => {
72
- projects = {
73
- path: param.file,
74
- name: param.name ? param.name : param.file,
75
- source: 'SCA',
76
- language: param.language,
77
- packageManager: 'MAVEN',
78
- target: 'SCA',
79
- sourceId: '' // this is appID at the moment and scaID in future
80
- }
87
+ projects = createProject(param)
81
88
  projectsArray.push(projects)
82
89
  })
83
90
 
84
91
  return projectsArray
85
92
  }
86
93
 
94
+ const createProject = param => {
95
+ return {
96
+ path: param.fileName,
97
+ name: param.repo ? param.fileName : getProjectName(param),
98
+ source: 'SCA',
99
+ language: param.language,
100
+ packageManager: param.packageManager,
101
+ target: 'SCA',
102
+ sourceId: ''
103
+ }
104
+ }
105
+
87
106
  const getExistingGroupProjectId = (config, projectGroupsInfoEx) => {
88
107
  let existingGroupProjectId = ''
89
108
  projectGroupsInfoEx.forEach(i => {
90
- if (i.name === config.name) {
109
+ if (i.repositoryId === config.repositoryId) {
91
110
  existingGroupProjectId = i.projectGroupId
92
111
  }
93
112
  })
@@ -95,21 +114,46 @@ const getExistingGroupProjectId = (config, projectGroupsInfoEx) => {
95
114
  }
96
115
 
97
116
  const getProjectIdFromArray = (config, array) => {
98
- let projectId = ''
99
- array?.forEach(i => {
100
- if (i.name === config.name) {
101
- projectId = i.projectId
117
+ if (array.length === 1) {
118
+ return array[0].projectId
119
+ }
120
+
121
+ if (config.name) {
122
+ for (const i of array) {
123
+ //match on name
124
+ if (i.name === config.name) return i.projectId
102
125
  }
103
- })
104
- return projectId
126
+ }
127
+
128
+ for (const i of array) {
129
+ //match on fileName
130
+ if (i.name === config.fileName) return i.projectId
131
+ }
132
+
133
+ return ''
134
+ }
135
+
136
+ const addAdditionalData = (body, data) => {
137
+ body.projectGroupId = data.projectGroupId ? data.projectGroupId : null
138
+ body.projectGroupName = data.projectGroupName ? data.projectGroupName : null
139
+ body.projectLanguage = data.projectLanguage ? data.projectLanguage : null
140
+ body.projectType = data.projectType ? data.projectType : null
105
141
  }
106
142
 
107
- const registerProjectIdOnCliServices = async (config, projectId) => {
143
+ const registerProjectIdOnCliServices = async (
144
+ config,
145
+ projectId,
146
+ additionalData = undefined
147
+ ) => {
108
148
  const client = commonApi.getHttpClient(config)
109
149
 
110
150
  let cliServicesBody = {
111
151
  projectId: projectId,
112
- name: config.name
152
+ name: config.repo ? config.fileName : getProjectName(config)
153
+ }
154
+
155
+ if (additionalData) {
156
+ addAdditionalData(cliServicesBody, additionalData)
113
157
  }
114
158
 
115
159
  let result = await client
@@ -117,24 +161,48 @@ const registerProjectIdOnCliServices = async (config, projectId) => {
117
161
  .then(res => {
118
162
  if (config.debug || config.verbose) {
119
163
  console.log('\nregistration on cli services')
120
- console.log(res.statusCode)
164
+ console.log('request body', cliServicesBody)
165
+ console.log('response code', res.statusCode)
121
166
  }
122
167
  if (res.statusCode === 201 || res.statusCode === 200) {
123
168
  return res.body
124
169
  } else {
125
- return []
170
+ console.log('Failed to Register On Cli Services')
171
+ console.log(res.statusCode)
172
+ process.exit(1)
126
173
  }
127
174
  })
128
175
 
129
176
  return result
130
177
  }
131
178
 
179
+ const registerProjectWithGroupProjectId = async config => {
180
+ const client = commonApi.getHttpClient(config)
181
+ config.language = config.language === 'NODE' ? 'JAVASCRIPT' : config.language
182
+
183
+ let body = createProject(config)
184
+ let result = await client.registerProject(config, body).then(res => {
185
+ if (config.debug || config.verbose) {
186
+ console.log('\nregister Project With Group ProjectId')
187
+ console.log(res.statusCode)
188
+ console.log(res.body)
189
+ }
190
+ if (res.statusCode === 201 || res.statusCode === 200) {
191
+ return res.body
192
+ } else {
193
+ return []
194
+ }
195
+ })
196
+
197
+ return result
198
+ }
199
+
132
200
  const retrieveExistingProjectIdWithProjectGroupId = async (
133
201
  config,
134
202
  client,
135
203
  projectGroupId
136
204
  ) => {
137
- let groups = await client
205
+ return await client
138
206
  .retrieveExistingProjectIdByProjectGroupId(config, projectGroupId)
139
207
  .then(res => {
140
208
  if (config.debug || config.verbose) {
@@ -146,11 +214,9 @@ const retrieveExistingProjectIdWithProjectGroupId = async (
146
214
  if (res.statusCode === 200) {
147
215
  return res.body
148
216
  } else {
149
- return []
217
+ return ''
150
218
  }
151
219
  })
152
-
153
- return getProjectIdFromArray(config, groups)
154
220
  }
155
221
 
156
222
  const retrieveProjectByOrganization = async (config, client) => {
@@ -169,16 +235,41 @@ const retrieveProjectByOrganization = async (config, client) => {
169
235
  })
170
236
  }
171
237
 
172
- const retrieveExistingProjectGroups = async (config, client) => {
238
+ const retrieveExistingProjectGroups = async config => {
239
+ const client = commonApi.getHttpClient(config)
173
240
  return await client.retrieveExistingProjectGroupsByOrg(config).then(res => {
241
+ if (config.debug || config.verbose) {
242
+ console.log('retrieve Existing ProjectGroups By Org')
243
+ console.log(res.statusCode)
244
+ console.log(res.body)
245
+ }
174
246
  if (res.statusCode === 201 || res.statusCode === 200) {
175
- return res.body
247
+ let correctGroupID = res?.body?.filter(
248
+ i => i.repositoryId === config.repositoryId
249
+ )
250
+
251
+ if (correctGroupID.length > 0) {
252
+ return correctGroupID[0].projectGroupId
253
+ }
254
+ return ''
176
255
  } else {
177
- return []
256
+ return ''
178
257
  }
179
258
  })
180
259
  }
181
260
 
261
+ const getProjectGroupId = async config => {
262
+ let projectGroupId = ''
263
+ if (config.projectGroupId === '' || config.projectGroupId === undefined) {
264
+ projectGroupId = await retrieveExistingProjectGroups(config)
265
+ }
266
+
267
+ if (projectGroupId === '') {
268
+ projectGroupId = await registerNewProjectGroup(config)
269
+ }
270
+ return projectGroupId
271
+ }
272
+
182
273
  const dealWithNoName = async config => {
183
274
  try {
184
275
  config.name = getAppName(config.file)
@@ -194,5 +285,10 @@ module.exports = {
194
285
  registerProjectIdOnCliServices,
195
286
  dealWithNoName,
196
287
  registerNewProjectGroup,
197
- createNewProjectGroupBody
288
+ createNewProjectGroupBody,
289
+ registerProjectWithGroupProjectId,
290
+ getExistingGroupProjectId,
291
+ getProjectGroupId,
292
+ retrieveExistingProjectGroups,
293
+ createProject
198
294
  }
@@ -23,12 +23,16 @@ const retrieveRepoId = async config => {
23
23
 
24
24
  const registerNewRepo = async config => {
25
25
  let body = {
26
- externalScmUrl: config.repoUrl ? config.repoUrl : '',
27
- externalScmName: config.repoName,
28
- externalId: config.externalId ? config.externalId : '',
26
+ externalScmUrl: config.repositoryUrl,
27
+ externalScmName: config.repositoryName,
28
+ externalId: config.externalId,
29
29
  primaryLanguage: config.language,
30
30
  defaultBranch: 'develop'
31
31
  }
32
+ if (config.debug || config.verbose) {
33
+ console.log('registerNewRepo')
34
+ console.log(body)
35
+ }
32
36
 
33
37
  const client = await commonApi.getHttpClient(config)
34
38
 
@@ -51,10 +55,47 @@ const registerNewRepo = async config => {
51
55
  if (res.statusCode === 409) {
52
56
  return ''
53
57
  }
58
+ if (res.statusCode === 400) {
59
+ if (config.debug || config.verbose) {
60
+ console.log('\nError Registering Repository - Bad request')
61
+ console.log(res.statusCode)
62
+ console.log(res.message)
63
+ }
64
+ process.exit(1)
65
+ }
54
66
  })
55
67
  .catch(err => {
56
68
  console.log('\nError Registering Repository')
57
69
  console.log(err.statusCode)
70
+ console.log(err.message)
71
+ process.exit(1)
72
+ })
73
+
74
+ return result
75
+ }
76
+
77
+ const retrieveProjectInfoViaRepoId = async config => {
78
+ const client = await commonApi.getHttpClient(config)
79
+
80
+ let result = await client
81
+ .retrieveProjectByRepoId(config)
82
+ .then(res => {
83
+ if (config.debug || config.verbose) {
84
+ console.log('\nRetrieve Project By RepoId')
85
+ console.log(res.statusCode)
86
+ console.log(res.body)
87
+ }
88
+ if (res.statusCode === 201 || res.statusCode === 200) {
89
+ return res?.body
90
+ }
91
+
92
+ if (res.statusCode === 409) {
93
+ return []
94
+ }
95
+ })
96
+ .catch(err => {
97
+ console.log('\nError Retrieve Project By RepoId')
98
+ console.log(err.statusCode)
58
99
  })
59
100
 
60
101
  return result
@@ -76,5 +117,6 @@ const getRepoId = async config => {
76
117
  module.exports = {
77
118
  retrieveRepoId,
78
119
  registerNewRepo,
79
- getRepoId
120
+ getRepoId,
121
+ retrieveProjectInfoViaRepoId
80
122
  }
@@ -225,12 +225,6 @@ HTTPClient.prototype.scaServiceIngest = function scaServiceIngest(
225
225
  options.url = url
226
226
  options.body = requestBody
227
227
 
228
- if (config.debug || config.verbose) {
229
- console.log('scaServiceIngest')
230
- console.log('url', options.url)
231
- console.log('body', options.body)
232
- }
233
-
234
228
  return requestUtils.sendRequest({ method: 'post', options })
235
229
  }
236
230
 
@@ -346,6 +340,17 @@ HTTPClient.prototype.registerRepo = function registerRepo(config, requestBody) {
346
340
  return requestUtils.sendRequest({ method: 'post', options })
347
341
  }
348
342
 
343
+ HTTPClient.prototype.retrieveProjectByRepoId = function retrieveProjectByRepoId(
344
+ config,
345
+ requestBody
346
+ ) {
347
+ const options = _.cloneDeep(this.requestOptions)
348
+ let url = createRepoProjectUrl(config)
349
+ options.url = url
350
+ options.body = requestBody
351
+ return requestUtils.sendRequest({ method: 'get', options })
352
+ }
353
+
349
354
  HTTPClient.prototype.registerProjectGroup = function (config, requestBody) {
350
355
  const options = _.cloneDeep(this.requestOptions)
351
356
  let url = registerProjectGroupUrl(config)
@@ -355,17 +360,18 @@ HTTPClient.prototype.registerProjectGroup = function (config, requestBody) {
355
360
  if (config.debug || config.verbose) {
356
361
  console.log('registerProjectGroup')
357
362
  console.log('url', options.url)
358
- console.log('body', options.body)
363
+ // console.log('body', options.body)
359
364
  }
360
365
 
361
366
  return requestUtils.sendRequest({ method: 'post', options })
362
367
  }
363
368
 
364
- HTTPClient.prototype.registerProject = function (config, projectGroupId) {
369
+ HTTPClient.prototype.registerProject = function (config, body) {
365
370
  const options = _.cloneDeep(this.requestOptions)
366
- let url = registerProjectUrl(config, projectGroupId)
371
+ let url = registerProjectUrl(config)
367
372
  options.url = url
368
- return requestUtils.sendRequest({ method: 'get', options })
373
+ options.body = body
374
+ return requestUtils.sendRequest({ method: 'post', options })
369
375
  }
370
376
  HTTPClient.prototype.retrieveSourcesViaRepositoryId = function (
371
377
  config,
@@ -405,6 +411,9 @@ HTTPClient.prototype.retrieveProjectByOrganizationId = function registerRepo(
405
411
  const options = _.cloneDeep(this.requestOptions)
406
412
  let url = retrieveProjectByOrganizationIdUrl(config)
407
413
  options.url = url
414
+ if (config.debug || config.verbose) {
415
+ console.log(url)
416
+ }
408
417
  return requestUtils.sendRequest({ method: 'get', options })
409
418
  }
410
419
 
@@ -412,8 +421,15 @@ HTTPClient.prototype.retrieveExistingProjectGroupsByOrg = function registerRepo(
412
421
  config
413
422
  ) {
414
423
  const options = _.cloneDeep(this.requestOptions)
415
- let url = retrieveExistingGroupProjectsByOrgUrl(config)
424
+ let url =
425
+ retrieveExistingGroupProjectsByOrgUrl(config) +
426
+ '?name=' +
427
+ config.repositoryName +
428
+ '&type=REPOSITORY'
416
429
  options.url = url
430
+ if (config.debug || config.verbose) {
431
+ console.log(options.url)
432
+ }
417
433
  return requestUtils.sendRequest({ method: 'get', options })
418
434
  }
419
435
 
@@ -622,7 +638,9 @@ function createScaServiceReportStatusURL(config, reportId) {
622
638
  function createScaServiceNoProjectIdURL(config) {
623
639
  return `${config.host}/Contrast/api/sca/organizations/${
624
640
  config.organizationId
625
- }/libraries/ingests/tree${config.repo ? '?incomplete=true' : ''}`
641
+ }/libraries/ingests/tree${
642
+ config.repo && config.language === 'JAVA?' ? 'incomplete=true' : ''
643
+ }`
626
644
  }
627
645
 
628
646
  // function createScaServiceIngestsURL(config) {
@@ -635,7 +653,9 @@ function createScaServiceHealthURL(config) {
635
653
 
636
654
  function createScaServiceIngestURL(config) {
637
655
  let optionalParams = []
638
- config.repo ? optionalParams.push('incomplete=true') : null
656
+ config.repo && config.language === 'JAVA'
657
+ ? optionalParams.push('incomplete=true')
658
+ : null
639
659
  config.track ? optionalParams.push('persist=true') : null
640
660
 
641
661
  let params = '?'
@@ -664,8 +684,8 @@ const registerProjectGroupUrl = config => {
664
684
  return `${config.host}/api/v4/organizations/${config.organizationId}/project-groups`
665
685
  }
666
686
 
667
- const registerProjectUrl = (config, projectGroupId) => {
668
- return `${config.host}/api/v4/organizations/${config.organizationId}/project-groups/${projectGroupId}/projects`
687
+ const registerProjectUrl = config => {
688
+ return `${config.host}/api/v4/organizations/${config.organizationId}/project-groups/${config.projectGroupId}/projects`
669
689
  }
670
690
 
671
691
  const retrieveRegisterOnCliServicesUrl = config => {
@@ -677,16 +697,21 @@ const retrieveSourcesUrl = (config, repositoryId) => {
677
697
  }
678
698
 
679
699
  const retrieveRepoByOrgAndGitURL = config => {
680
- return `${config.host}/api/v4/organizations/${config.organizationId}/repositories/external-url?externalRepoUrl=${config.repoUrl}`
700
+ return `${config.host}/api/v4/organizations/${config.organizationId}/repositories/external-url?externalRepoUrl=${config.repositoryUrl}`
681
701
  }
682
702
 
683
703
  const retrieveProjectByOrganizationIdUrl = config => {
684
704
  let baseUrl = `${config.host}/api/v4/organizations/${config.organizationId}/projects`
685
- baseUrl = config.name ? baseUrl.concat(`?name=${config.name}`) : baseUrl
705
+ baseUrl = config.name
706
+ ? baseUrl.concat(`?name=${config.name}`)
707
+ : baseUrl.concat(`?name=${config.fileName}`)
686
708
  baseUrl = config.language
687
709
  ? baseUrl.concat(`&language=${config.language}`)
688
710
  : baseUrl
689
711
  baseUrl = config.language ? baseUrl.concat(`&source=SCA`) : baseUrl
712
+ baseUrl = config.repo
713
+ ? baseUrl.concat(`&type=REPOSITORY`)
714
+ : baseUrl.concat(`&type=CLI`)
690
715
  return baseUrl
691
716
  }
692
717
 
@@ -705,6 +730,10 @@ function createRepositoryUrl(config) {
705
730
  return `${config.host}/api/v4/organizations/${config.organizationId}/repositories`
706
731
  }
707
732
 
733
+ function createRepoProjectUrl(config) {
734
+ return `${config.host}/api/v4/organizations/${config.organizationId}/repositories/${config.repositoryId}/projects`
735
+ }
736
+
708
737
  function createLibraryVulnerabilitiesUrl(config) {
709
738
  return `${config.host}/Contrast/api/ng/${config.organizationId}/libraries/artifactsByGroupNameVersion`
710
739
  }
@@ -0,0 +1,83 @@
1
+ import { HttpsProxyAgent } from 'hpagent'
2
+ import fs from 'fs'
3
+ import got, { Options } from 'got'
4
+ import { Agents, HTTPSOptions } from 'got/dist/source/core'
5
+
6
+ export function gotInstance(config: any) {
7
+ return got.extend({ retry: { limit: 0 }, ...buildBaseRequestOptions(config) })
8
+ }
9
+
10
+ export function buildBaseRequestOptions(config: any) {
11
+ const { apiKey, authorization } = config
12
+ const rejectUnauthorized = !config.certSelfSigned
13
+
14
+ const superApiKey = config.superApiKey
15
+ const superAuthToken = config.superAuthorization
16
+
17
+ const requestOptions = {
18
+ responseType: 'json',
19
+ forever: true,
20
+ uri: config.host,
21
+ followRedirect: false,
22
+ headers: {
23
+ 'Content-Type': 'application/json; charset=utf-8',
24
+ Authorization: authorization,
25
+ 'API-Key': apiKey,
26
+ SuperAuthorization: superAuthToken,
27
+ 'Super-API-Key': superApiKey,
28
+ 'User-Agent': 'contrast-cli-v2'
29
+ },
30
+ agent: getAgent(config)
31
+ } as Options
32
+
33
+ requestOptions.https = {
34
+ rejectUnauthorized: rejectUnauthorized
35
+ }
36
+
37
+ maybeAddCertsToRequest(config, requestOptions.https)
38
+ return requestOptions
39
+ }
40
+
41
+ function getAgent(config: any) {
42
+ return config.proxy
43
+ ? (new HttpsProxyAgent({ proxy: config.proxy }) as Agents)
44
+ : false
45
+ }
46
+
47
+ function maybeAddCertsToRequest(config: any, https: HTTPSOptions) {
48
+ // cacert
49
+ const caCertFilePath = config.cacert
50
+ if (caCertFilePath) {
51
+ try {
52
+ https.certificateAuthority = fs.readFileSync(caCertFilePath)
53
+ } catch (error: any) {
54
+ throw new Error(
55
+ `Unable to read CA from ${caCertFilePath}, msg: ${error.message}`
56
+ )
57
+ }
58
+ }
59
+
60
+ // cert
61
+ const certPath = config.cert
62
+ if (certPath) {
63
+ try {
64
+ https.certificate = fs.readFileSync(certPath)
65
+ } catch (error: any) {
66
+ throw new Error(
67
+ `Unable to read Certificate PEM file from config option contrast.api.certificate.cert_file='${certPath}', msg: ${error.message}`
68
+ )
69
+ }
70
+ }
71
+
72
+ // key
73
+ const keyPath = config.key
74
+ if (keyPath) {
75
+ try {
76
+ https.key = fs.readFileSync(keyPath)
77
+ } catch (error: any) {
78
+ throw new Error(
79
+ `Unable to read Key PEM file from config option contrast.api.certificate.key_file='${keyPath}', msg: ${error.message}`
80
+ )
81
+ }
82
+ }
83
+ }
@@ -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.1'
17
+ const APP_VERSION = '2.0.2-beta.0'
18
18
  const TIMEOUT = 120000
19
19
  const HIGH_COLOUR = '#ff9900'
20
20
  const CRITICAL_COLOUR = '#e35858'
@@ -4,13 +4,20 @@ const {
4
4
  } = require('../../audit/report/commonReportingFunctions')
5
5
  const common = require('../../common/fail')
6
6
  const { printFormattedOutputSca } = require('./commonReportingFunctionsSca')
7
+ const { auditSave } = require('../../audit/save')
7
8
 
8
- const processAuditReport = (config, reportModelList) => {
9
+ const processAuditReport = async (config, reportModelList, reportId) => {
9
10
  let severityCounts = {}
10
11
  if (reportModelList !== undefined) {
11
12
  severityCounts = formatScaServicesReport(config, reportModelList)
12
13
  }
13
14
 
15
+ if (config.save !== undefined) {
16
+ await auditSave(config, reportId)
17
+ } else {
18
+ console.log('Use contrast audit --save to generate an SBOM')
19
+ }
20
+
14
21
  if (config.fail) {
15
22
  common.processFail(config, severityCounts)
16
23
  }
@@ -14,8 +14,12 @@ const scaTreeUpload = async (analysis, config, reportSpinner) => {
14
14
  config.language = config.language === 'JAVASCRIPT' ? 'NODE' : config.language
15
15
  const startTime = performance.now()
16
16
  const timeout = commonApi.getTimeout(config)
17
+
18
+ const doINeedParent = config.repositoryId && config.language === 'JAVA'
19
+
17
20
  const requestBody = {
18
- dependencyTree: analysis,
21
+ parentPom: doINeedParent ? analysis.parentPom : null,
22
+ dependencyTree: doINeedParent ? analysis.dependencyTree : analysis,
19
23
  organizationId: config.organizationId,
20
24
  language: config.language,
21
25
  tool: {
@@ -8,7 +8,10 @@ const getGoDependencies = config => {
8
8
  try {
9
9
  // A sample of this output can be found
10
10
  // in the go test folder data/goModGraphResults.text
11
- cmdStdout = child_process.execSync('go mod graph', { cwd })
11
+ cmdStdout = child_process.execSync('go mod graph', {
12
+ cwd: cwd,
13
+ maxBuffer: 50 * 1024 * 1024
14
+ })
12
15
 
13
16
  return cmdStdout.toString()
14
17
  } catch (err) {
@@ -22,6 +25,7 @@ const getGoDependencies = config => {
22
25
  // throw new Error(
23
26
  // i18n.__('goReadProjectFile', cwd, `${err.message ? err.message : ''}`)
24
27
  // )
28
+ process.exit(1)
25
29
  }
26
30
  }
27
31
 
@@ -30,7 +30,7 @@ const determineProjectTypeAndCwd = (files, config) => {
30
30
 
31
31
  const buildMaven = (config, projectData, timeout) => {
32
32
  let command = 'mvn'
33
- let args = ['dependency:tree', '-B']
33
+ let args = ['dependency:tree', '-B', '-Dscope=runtime']
34
34
  if (config.mavenSettingsPath) {
35
35
  args.push('-s')
36
36
  args.push(config.mavenSettingsPath)
@@ -140,7 +140,7 @@ const computeRelationToLastElement = element => {
140
140
  }
141
141
 
142
142
  const stripElement = element => {
143
- return element
143
+ const initialStrippedElement = element
144
144
  .replace(/[|]/g, '')
145
145
  .replace('+---', '')
146
146
  .replace('\\---', '')
@@ -148,6 +148,22 @@ const stripElement = element => {
148
148
  .replace('(c)', '')
149
149
  .replace('->', '@')
150
150
  .replace('(*)', '')
151
+
152
+ //work out Gradle resolved versioning e.g. org.slf4j:slf4j-api:1.7.25 -> 1.7.22
153
+ //take 1.7.22
154
+ const splitElements = initialStrippedElement.split(':')
155
+ if (
156
+ splitElements[2] !== undefined &&
157
+ splitElements[2] !== null &&
158
+ splitElements[2].includes('@')
159
+ ) {
160
+ const splitVersions = splitElements[2].split('@')
161
+ return initialStrippedElement
162
+ .replace(':' + splitVersions[0], '')
163
+ .replace('@', ':')
164
+ }
165
+
166
+ return initialStrippedElement
151
167
  }
152
168
 
153
169
  const checkVersion = element => {