@contrast/contrast 1.0.13 → 1.0.15

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 (45) hide show
  1. package/dist/audit/report/commonReportingFunctions.js +175 -116
  2. package/dist/audit/report/models/reportSeverityModel.js +3 -3
  3. package/dist/audit/report/reportingFeature.js +1 -10
  4. package/dist/audit/report/utils/reportUtils.js +4 -4
  5. package/dist/audit/save.js +7 -2
  6. package/dist/commands/audit/help.js +3 -1
  7. package/dist/commands/scan/processScan.js +0 -6
  8. package/dist/commands/scan/sca/scaAnalysis.js +32 -15
  9. package/dist/common/HTTPClient.js +22 -3
  10. package/dist/common/errorHandling.js +1 -2
  11. package/dist/constants/constants.js +10 -2
  12. package/dist/constants/locales.js +17 -7
  13. package/dist/constants.js +31 -2
  14. package/dist/index.js +4 -2
  15. package/dist/lambda/lambda.js +1 -1
  16. package/dist/sbom/generateSbom.js +18 -1
  17. package/dist/scaAnalysis/common/auditReport.js +78 -0
  18. package/dist/scaAnalysis/common/scaServicesUpload.js +21 -13
  19. package/dist/scan/formatScanOutput.js +4 -29
  20. package/dist/utils/commonApi.js +1 -0
  21. package/dist/utils/settingsHelper.js +24 -0
  22. package/package.json +4 -1
  23. package/src/audit/report/commonReportingFunctions.js +432 -0
  24. package/src/audit/report/models/reportSeverityModel.ts +6 -6
  25. package/src/audit/report/reportingFeature.ts +2 -16
  26. package/src/audit/report/utils/reportUtils.ts +2 -8
  27. package/src/audit/save.js +14 -6
  28. package/src/commands/audit/help.ts +3 -1
  29. package/src/commands/scan/processScan.js +0 -8
  30. package/src/commands/scan/sca/scaAnalysis.js +52 -32
  31. package/src/common/HTTPClient.js +26 -3
  32. package/src/common/errorHandling.ts +1 -2
  33. package/src/constants/constants.js +12 -2
  34. package/src/constants/locales.js +19 -7
  35. package/src/constants.js +34 -2
  36. package/src/index.ts +4 -6
  37. package/src/lambda/lambda.ts +1 -1
  38. package/src/lambda/lambdaUtils.ts +1 -1
  39. package/src/sbom/generateSbom.ts +20 -0
  40. package/src/scaAnalysis/common/auditReport.js +108 -0
  41. package/src/scaAnalysis/common/scaServicesUpload.js +24 -14
  42. package/src/scan/formatScanOutput.ts +5 -42
  43. package/src/utils/commonApi.js +1 -0
  44. package/src/utils/settingsHelper.js +26 -0
  45. package/src/audit/report/commonReportingFunctions.ts +0 -355
@@ -0,0 +1,432 @@
1
+ const commonApi = require('../../utils/commonApi')
2
+ const {
3
+ ReportCompositeKey,
4
+ ReportList,
5
+ ReportModelStructure
6
+ } = require('./models/reportListModel')
7
+ const { orderBy } = require('lodash')
8
+ const chalk = require('chalk')
9
+ const {
10
+ countVulnerableLibrariesBySeverity,
11
+ orderByHighestPriority,
12
+ findHighestSeverityCVE,
13
+ findNameAndVersion,
14
+ severityCountAllCVEs,
15
+ findCVESeverity
16
+ } = require('./utils/reportUtils')
17
+ const { SeverityCountModel } = require('./models/severityCountModel')
18
+ const {
19
+ ReportOutputBodyModel,
20
+ ReportOutputHeaderModel,
21
+ ReportOutputModel
22
+ } = require('./models/reportOutputModel')
23
+ const {
24
+ CE_URL,
25
+ CRITICAL_COLOUR,
26
+ HIGH_COLOUR,
27
+ LOW_COLOUR,
28
+ MEDIUM_COLOUR,
29
+ NOTE_COLOUR
30
+ } = require('../../constants/constants')
31
+ const Table = require('cli-table3')
32
+ const { ReportGuidanceModel } = require('./models/reportGuidanceModel')
33
+ const i18n = require('i18n')
34
+
35
+ const createSummaryMessageTop = (numberOfVulnerableLibraries, numberOfCves) => {
36
+ numberOfVulnerableLibraries === 1
37
+ ? console.log(`Found 1 vulnerable library containing ${numberOfCves} CVE`)
38
+ : console.log(
39
+ `Found ${numberOfVulnerableLibraries} vulnerable libraries containing ${numberOfCves} CVEs`
40
+ )
41
+ }
42
+
43
+ const createSummaryMessageBottom = numberOfVulnerableLibraries => {
44
+ numberOfVulnerableLibraries === 1
45
+ ? console.log(`Found 1 vulnerability`)
46
+ : console.log(`Found ${numberOfVulnerableLibraries} vulnerabilities`)
47
+ }
48
+
49
+ const getReport = async (config, reportId) => {
50
+ const client = commonApi.getHttpClient(config)
51
+ return client
52
+ .getReportById(config, reportId)
53
+ .then(res => {
54
+ if (res.statusCode === 200) {
55
+ return res.body
56
+ } else {
57
+ console.log(JSON.stringify(res.statusCode))
58
+ commonApi.handleResponseErrors(res, 'report')
59
+ }
60
+ })
61
+ .catch(err => {
62
+ console.log(err)
63
+ })
64
+ }
65
+
66
+ const printVulnerabilityResponse = (
67
+ config,
68
+ vulnerableLibraries,
69
+ numberOfVulnerableLibraries,
70
+ numberOfCves,
71
+ guidance
72
+ ) => {
73
+ let hasSomeVulnerabilitiesReported = false
74
+ printFormattedOutput(
75
+ config,
76
+ vulnerableLibraries,
77
+ numberOfVulnerableLibraries,
78
+ numberOfCves,
79
+ guidance
80
+ )
81
+ if (Object.keys(vulnerableLibraries).length > 0) {
82
+ hasSomeVulnerabilitiesReported = true
83
+ }
84
+ return hasSomeVulnerabilitiesReported
85
+ }
86
+
87
+ const printFormattedOutput = (
88
+ config,
89
+ libraries,
90
+ numberOfVulnerableLibraries,
91
+ numberOfCves,
92
+ guidance
93
+ ) => {
94
+ createSummaryMessageTop(numberOfVulnerableLibraries, numberOfCves)
95
+ console.log()
96
+ const report = new ReportList()
97
+
98
+ for (const library of libraries) {
99
+ const { name, version } = findNameAndVersion(library, config)
100
+
101
+ const newOutputModel = new ReportModelStructure(
102
+ new ReportCompositeKey(
103
+ name,
104
+ version,
105
+ findHighestSeverityCVE(library.cveArray),
106
+ severityCountAllCVEs(
107
+ library.cveArray,
108
+ new SeverityCountModel()
109
+ ).getTotal
110
+ ),
111
+ library.cveArray
112
+ )
113
+ report.reportOutputList.push(newOutputModel)
114
+ }
115
+
116
+ const outputOrderedByLowestSeverityAndLowestNumOfCvesFirst = orderBy(
117
+ report.reportOutputList,
118
+ [
119
+ reportListItem => {
120
+ return reportListItem.compositeKey.highestSeverity.priority
121
+ },
122
+ reportListItem => {
123
+ return reportListItem.compositeKey.numberOfSeverities
124
+ }
125
+ ],
126
+ ['asc', 'desc']
127
+ )
128
+
129
+ let contrastHeaderNumCounter = 0
130
+ for (const reportModel of outputOrderedByLowestSeverityAndLowestNumOfCvesFirst) {
131
+ contrastHeaderNumCounter++
132
+ const { libraryName, libraryVersion, highestSeverity } =
133
+ reportModel.compositeKey
134
+ const numOfCVEs = reportModel.cveArray.length
135
+
136
+ const table = getReportTable()
137
+
138
+ const header = buildHeader(
139
+ highestSeverity,
140
+ contrastHeaderNumCounter,
141
+ libraryName,
142
+ libraryVersion,
143
+ numOfCVEs
144
+ )
145
+
146
+ const advice = gatherRemediationAdvice(
147
+ guidance,
148
+ libraryName,
149
+ libraryVersion
150
+ )
151
+
152
+ const body = buildBody(reportModel.cveArray, advice)
153
+
154
+ const reportOutputModel = new ReportOutputModel(header, body)
155
+
156
+ table.push(
157
+ reportOutputModel.body.issueMessage,
158
+ reportOutputModel.body.adviceMessage
159
+ )
160
+
161
+ console.log(
162
+ reportOutputModel.header.vulnMessage,
163
+ reportOutputModel.header.introducesMessage
164
+ )
165
+ console.log(table.toString() + '\n')
166
+ }
167
+
168
+ createSummaryMessageBottom(numberOfVulnerableLibraries)
169
+ const {
170
+ criticalMessage,
171
+ highMessage,
172
+ mediumMessage,
173
+ lowMessage,
174
+ noteMessage
175
+ } = buildFooter(outputOrderedByLowestSeverityAndLowestNumOfCvesFirst)
176
+ console.log(
177
+ `${criticalMessage} | ${highMessage} | ${mediumMessage} | ${lowMessage} | ${noteMessage}`
178
+ )
179
+
180
+ if (config.host !== CE_URL) {
181
+ console.log(
182
+ '\n' + chalk.bold('View your full dependency tree in Contrast:')
183
+ )
184
+ console.log(
185
+ `${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/applications/${config.applicationId}/libs/dependency-tree`
186
+ )
187
+ }
188
+ }
189
+
190
+ function getReportTable() {
191
+ return new Table({
192
+ chars: {
193
+ top: '',
194
+ 'top-mid': '',
195
+ 'top-left': '',
196
+ 'top-right': '',
197
+ bottom: '',
198
+ 'bottom-mid': '',
199
+ 'bottom-left': '',
200
+ 'bottom-right': '',
201
+ left: '',
202
+ 'left-mid': '',
203
+ mid: '',
204
+ 'mid-mid': '',
205
+ right: '',
206
+ 'right-mid': '',
207
+ middle: ' '
208
+ },
209
+ style: { 'padding-left': 0, 'padding-right': 0 },
210
+ colAligns: ['right'],
211
+ wordWrap: true,
212
+ colWidths: [12, 1, 100]
213
+ })
214
+ }
215
+ function buildHeader(
216
+ highestSeverity,
217
+ contrastHeaderNum,
218
+ libraryName,
219
+ version,
220
+ numOfCVEs
221
+ ) {
222
+ const vulnerabilityPluralised =
223
+ numOfCVEs > 1 ? 'vulnerabilities' : 'vulnerability'
224
+ const formattedHeaderNum = buildFormattedHeaderNum(contrastHeaderNum)
225
+
226
+ const headerColour = chalk.hex(highestSeverity.colour)
227
+ const headerNumAndSeverity = headerColour(
228
+ `${formattedHeaderNum} - [${highestSeverity.severity}]`
229
+ )
230
+ const libraryNameAndVersion = headerColour.bold(`${libraryName}-${version}`)
231
+ const vulnMessage = `${headerNumAndSeverity} ${libraryNameAndVersion}`
232
+
233
+ const introducesMessage = `introduces ${numOfCVEs} ${vulnerabilityPluralised}`
234
+
235
+ return new ReportOutputHeaderModel(vulnMessage, introducesMessage)
236
+ }
237
+
238
+ function buildBody(cveArray, advice) {
239
+ let assignPriorityToVulns = cveArray.map(result => findCVESeverity(result))
240
+
241
+ const issueMessage = getIssueRow(assignPriorityToVulns)
242
+
243
+ //todo different advice based on remediationGuidance being available or now
244
+ // console.log(advice)
245
+
246
+ const minOrMax = advice.maximum ? advice.maximum : advice.minimum
247
+ const displayAdvice = minOrMax
248
+ ? `Change to version ${chalk.bold(minOrMax)}`
249
+ : 'No recommendation is available according to our data. Upgrade to the latest stable is the best advice we can give.'
250
+
251
+ const adviceMessage = [chalk.bold('Advice'), ':', displayAdvice]
252
+
253
+ return new ReportOutputBodyModel(issueMessage, adviceMessage)
254
+ }
255
+
256
+ function getIssueRow(cveArray) {
257
+ orderByHighestPriority(cveArray)
258
+ const cveMessagesList = getIssueCveMsgList(cveArray)
259
+ const cveNumbers = getSeverityCounts(cveArray)
260
+ const numAndSeverityTypeDesc = getNumOfAndSeverityType(cveNumbers)
261
+ return [
262
+ chalk.bold('Issue'),
263
+ ':',
264
+ `${numAndSeverityTypeDesc} ${cveMessagesList.join(', ')}`
265
+ ]
266
+ }
267
+
268
+ function gatherRemediationAdvice(guidance, libraryName, libraryVersion) {
269
+ const guidanceModel = new ReportGuidanceModel()
270
+
271
+ const data = guidance[libraryName + '@' + libraryVersion]
272
+
273
+ if (data) {
274
+ guidanceModel.minimum = data.minUpgradeVersion
275
+ guidanceModel.maximum = data.maxUpgradeVersion
276
+ }
277
+
278
+ return guidanceModel
279
+ }
280
+
281
+ function buildFormattedHeaderNum(contrastHeaderNum) {
282
+ return `CONTRAST-${contrastHeaderNum.toString().padStart(3, '0')}`
283
+ }
284
+
285
+ function getNumOfAndSeverityType(cveNumbers) {
286
+ const { critical, high, medium, low, note } = cveNumbers
287
+
288
+ const criticalMsg = critical > 0 ? `${critical} Critical | ` : ''
289
+ const highMsg = high > 0 ? `${high} High | ` : ''
290
+ const mediumMsg = medium > 0 ? `${medium} Medium | ` : ''
291
+ const lowMsg = low > 0 ? `${low} Low | ` : ''
292
+ const noteMsg = note > 0 ? `${note} Note` : ''
293
+
294
+ //removes/trims whitespace to single spaces
295
+ return `${criticalMsg} ${highMsg} ${mediumMsg} ${lowMsg} ${noteMsg}`
296
+ .replace(/\s+/g, ' ')
297
+ .trim()
298
+ }
299
+
300
+ const buildFooter = reportModelStructure => {
301
+ const { critical, high, medium, low, note } =
302
+ countVulnerableLibrariesBySeverity(reportModelStructure)
303
+
304
+ const criticalMessage = chalk
305
+ .hex(CRITICAL_COLOUR)
306
+ .bold(`${critical} Critical`)
307
+ const highMessage = chalk.hex(HIGH_COLOUR).bold(`${high} High`)
308
+ const mediumMessage = chalk.hex(MEDIUM_COLOUR).bold(`${medium} Medium`)
309
+ const lowMessage = chalk.hex(LOW_COLOUR).bold(`${low} Low`)
310
+ const noteMessage = chalk.hex(NOTE_COLOUR).bold(`${note} Note`)
311
+
312
+ return {
313
+ criticalMessage,
314
+ highMessage,
315
+ mediumMessage,
316
+ lowMessage,
317
+ noteMessage
318
+ }
319
+ }
320
+
321
+ const getIssueCveMsgList = results => {
322
+ const cveMessages = []
323
+
324
+ results.forEach(reportSeverityModel => {
325
+ // @ts-ignore
326
+ const { colour, severity, name } = reportSeverityModel
327
+
328
+ const severityShorthand = chalk
329
+ .hex(colour)
330
+ .bold(`[${severity.charAt(0).toUpperCase()}]`)
331
+
332
+ const builtMessage = severityShorthand + name
333
+ cveMessages.push(builtMessage)
334
+ })
335
+ return cveMessages
336
+ }
337
+
338
+ const getSeverityCounts = results => {
339
+ const acc = {
340
+ critical: 0,
341
+ high: 0,
342
+ medium: 0,
343
+ low: 0,
344
+ note: 0,
345
+ total: 0
346
+ }
347
+ if (results && results.length > 0) {
348
+ results.forEach(i => {
349
+ acc[i.severity.toLowerCase()] += 1
350
+ acc.total += 1
351
+ return acc
352
+ })
353
+ }
354
+
355
+ return acc
356
+ }
357
+
358
+ const printNoVulnFoundMsg = () => {
359
+ console.log(i18n.__('scanNoVulnerabilitiesFound'))
360
+ console.log(i18n.__('scanNoVulnerabilitiesFoundSecureCode'))
361
+ console.log(i18n.__('scanNoVulnerabilitiesFoundGoodWork'))
362
+ console.log(chalk.bold(`Found 0 vulnerabilities`))
363
+ console.log(
364
+ i18n.__(
365
+ 'foundDetailedVulnerabilities',
366
+ String(0),
367
+ String(0),
368
+ String(0),
369
+ String(0),
370
+ String(0)
371
+ )
372
+ )
373
+ }
374
+ const printVulnInfo = projectOverview => {
375
+ const totalVulnerabilities = projectOverview.total
376
+
377
+ createSummaryMessageBottom(totalVulnerabilities)
378
+ const formattedValues = severityFormatted(projectOverview)
379
+ console.log(
380
+ i18n.__(
381
+ 'foundDetailedVulnerabilities',
382
+ String(formattedValues.criticalFormatted),
383
+ String(formattedValues.highFormatted),
384
+ String(formattedValues.mediumFormatted),
385
+ String(formattedValues.lowFormatted),
386
+ String(formattedValues.noteFormatted)
387
+ )
388
+ )
389
+ }
390
+
391
+ const severityFormatted = projectOverview => {
392
+ const criticalFormatted = chalk
393
+ .hex(CRITICAL_COLOUR)
394
+ .bold(`${projectOverview.critical} Critical`)
395
+ const highFormatted = chalk
396
+ .hex(HIGH_COLOUR)
397
+ .bold(`${projectOverview.high} High`)
398
+ const mediumFormatted = chalk
399
+ .hex(MEDIUM_COLOUR)
400
+ .bold(`${projectOverview.medium} Medium`)
401
+ const lowFormatted = chalk.hex(LOW_COLOUR).bold(`${projectOverview.low} Low`)
402
+ const noteFormatted = chalk
403
+ .hex(NOTE_COLOUR)
404
+ .bold(`${projectOverview.note} Note`)
405
+
406
+ return {
407
+ criticalFormatted,
408
+ highFormatted,
409
+ mediumFormatted,
410
+ lowFormatted,
411
+ noteFormatted
412
+ }
413
+ }
414
+
415
+ module.exports = {
416
+ createSummaryMessageTop,
417
+ getReport,
418
+ createSummaryMessageBottom,
419
+ printVulnerabilityResponse,
420
+ printFormattedOutput,
421
+ getReportTable,
422
+ buildHeader,
423
+ buildBody,
424
+ getIssueRow,
425
+ gatherRemediationAdvice,
426
+ buildFormattedHeaderNum,
427
+ getNumOfAndSeverityType,
428
+ getIssueCveMsgList,
429
+ getSeverityCounts,
430
+ printNoVulnFoundMsg,
431
+ printVulnInfo
432
+ }
@@ -1,18 +1,18 @@
1
1
  export class ReportSeverityModel {
2
2
  severity: string
3
3
  priority: number
4
- outputColour: string
5
- cveName: string
4
+ colour: string
5
+ name: string
6
6
 
7
7
  constructor(
8
8
  severity: string,
9
9
  priority: number,
10
- outputColour: string,
11
- cveName: string
10
+ colour: string,
11
+ name: string
12
12
  ) {
13
13
  this.severity = severity
14
14
  this.priority = priority
15
- this.outputColour = outputColour
16
- this.cveName = cveName
15
+ this.colour = colour
16
+ this.name = name
17
17
  }
18
18
  }
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  getReport,
3
+ printNoVulnFoundMsg,
3
4
  printVulnerabilityResponse
4
5
  } from './commonReportingFunctions'
5
6
  import {
@@ -58,22 +59,7 @@ export function formatVulnerabilityOutput(
58
59
  const numberOfVulnerableLibraries = vulnerableLibraries.length
59
60
 
60
61
  if (numberOfVulnerableLibraries === 0) {
61
- console.log(i18n.__('scanNoVulnerabilitiesFound'))
62
- console.log(i18n.__('scanNoVulnerabilitiesFoundSecureCode'))
63
- console.log(i18n.__('scanNoVulnerabilitiesFoundGoodWork'))
64
- console.log(
65
- chalk.bold(`Found ${numberOfVulnerableLibraries} vulnerabilities`)
66
- )
67
- console.log(
68
- i18n.__(
69
- 'foundDetailedVulnerabilities',
70
- String(0),
71
- String(0),
72
- String(0),
73
- String(0),
74
- String(0)
75
- )
76
- )
62
+ printNoVulnFoundMsg()
77
63
  return [false, 0, [new SeverityCountModel()]]
78
64
  } else {
79
65
  let numberOfCves = 0
@@ -30,14 +30,8 @@ export function findHighestSeverityCVE(cveArray: ReportCVEModel[]) {
30
30
  return orderBy(mappedToReportSeverityModels, cve => cve?.priority)[0]
31
31
  }
32
32
 
33
- export function findCVESeveritiesAndOrderByHighestPriority(
34
- cves: ReportCVEModel[]
35
- ) {
36
- return orderBy(
37
- cves.map(cve => findCVESeverity(cve)),
38
- ['priority'],
39
- ['asc']
40
- )
33
+ export function orderByHighestPriority(cves: ReportCVEModel[]) {
34
+ return orderBy(cves, ['priority'], ['asc'])
41
35
  }
42
36
 
43
37
  export function findCVESeverity(cve: ReportCVEModel) {
package/src/audit/save.js CHANGED
@@ -8,7 +8,7 @@ const {
8
8
  SBOM_SPDX_FILE
9
9
  } = require('../constants/constants')
10
10
 
11
- async function auditSave(config) {
11
+ async function auditSave(config, reportId) {
12
12
  let fileFormat
13
13
  switch (config.save) {
14
14
  case null:
@@ -23,11 +23,19 @@ async function auditSave(config) {
23
23
  }
24
24
 
25
25
  if (fileFormat) {
26
- save.saveFile(
27
- config,
28
- fileFormat,
29
- await sbom.generateSbom(config, fileFormat)
30
- )
26
+ if (config.experimental) {
27
+ save.saveFile(
28
+ config,
29
+ fileFormat,
30
+ await sbom.generateSCASbom(config, fileFormat, reportId)
31
+ )
32
+ } else {
33
+ save.saveFile(
34
+ config,
35
+ fileFormat,
36
+ await sbom.generateSbom(config, fileFormat)
37
+ )
38
+ }
31
39
  const filename = `${config.applicationId}-sbom-${fileFormat}.json`
32
40
  if (fs.existsSync(filename)) {
33
41
  console.log(i18n.__('auditSBOMSaveSuccess') + ` - ${filename}`)
@@ -47,7 +47,9 @@ const auditUsageGuide = commandLineUsage([
47
47
  'language',
48
48
  'experimental',
49
49
  'app-groups',
50
- 'metadata'
50
+ 'metadata',
51
+ 'track',
52
+ 'branch'
51
53
  ]
52
54
  },
53
55
  commonHelpLinks()
@@ -3,21 +3,13 @@ const { startScan } = require('../../scan/scanController')
3
3
  const { saveScanFile } = require('../../utils/saveFile')
4
4
  const { ScanResultsModel } = require('../../scan/models/scanResultsModel')
5
5
  const { formatScanOutput } = require('../../scan/formatScanOutput')
6
- const { processSca } = require('./sca/scaAnalysis')
7
6
  const common = require('../../common/fail')
8
7
  const { sendTelemetryConfigAsObject } = require('../../telemetry/telemetry')
9
8
  const chalk = require('chalk')
10
- const generalAPI = require('../../utils/generalAPI')
11
9
 
12
10
  const processScan = async (contrastConf, argv) => {
13
11
  let config = await scanConfig.getScanConfig(contrastConf, 'scan', argv)
14
12
  let output = undefined
15
- config.mode = await generalAPI.getMode(config)
16
-
17
- //try SCA analysis first
18
- if (config.experimental) {
19
- await processSca(config, argv)
20
- }
21
13
 
22
14
  let scanResults = new ScanResultsModel(await startScan(config))
23
15
  await sendTelemetryConfigAsObject(
@@ -1,7 +1,6 @@
1
1
  const autoDetection = require('../../../scan/autoDetection')
2
2
  const javaAnalysis = require('../../../scaAnalysis/java')
3
3
  const treeUpload = require('../../../scaAnalysis/common/treeUpload')
4
- const scaUpload = require('../../../scaAnalysis/common/scaServicesUpload')
5
4
  const auditController = require('../../audit/auditController')
6
5
  const {
7
6
  supportedLanguages: { JAVA, GO, PYTHON, RUBY, JAVASCRIPT, NODE, PHP, DOTNET }
@@ -28,10 +27,13 @@ const { dotNetAnalysis } = require('../../../scaAnalysis/dotnet')
28
27
  const { auditUsageGuide } = require('../../audit/help')
29
28
  const rootFile = require('../../../audit/languageAnalysisEngine/getProjectRootFilenames')
30
29
  const path = require('path')
31
- const generalAPI = require('../../../utils/generalAPI')
30
+ const auditReport = require('../../../scaAnalysis/common/auditReport')
31
+ const scaUpload = require('../../../scaAnalysis/common/scaServicesUpload')
32
+ const settingsHelper = require('../../../utils/settingsHelper')
32
33
 
33
34
  const processSca = async config => {
34
- config.mode = await generalAPI.getMode(config)
35
+ //checks to see whether to use old TS / new SCA path
36
+ config = await settingsHelper.getSettings(config)
35
37
 
36
38
  const startTime = performance.now()
37
39
  let filesFound
@@ -104,38 +106,56 @@ const processSca = async config => {
104
106
  config.applicationId = await auditController.dealWithNoAppId(config)
105
107
  }
106
108
 
107
- // if (config.experimental) {
108
- // await scaUpload.scaTreeUpload(messageToSend, config)
109
- // } else
110
- // {
111
- console.log('') //empty log for space before spinner
112
- //send message to TS
113
- const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
114
- startSpinner(reportSpinner)
115
- const snapshotResponse = await treeUpload.commonSendSnapShot(
116
- messageToSend,
117
- config
118
- )
109
+ if (config.experimental) {
110
+ console.log('') //empty log for space before spinner
111
+ const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
112
+ startSpinner(reportSpinner)
113
+ const [reports, reportId] = await scaUpload.scaTreeUpload(
114
+ messageToSend,
115
+ config
116
+ )
119
117
 
120
- //poll for completion
121
- await pollForSnapshotCompletition(
122
- config,
123
- snapshotResponse.id,
124
- reportSpinner
125
- )
126
- succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
118
+ auditReport.processAuditReport(config, reports[0])
119
+ succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
127
120
 
128
- await vulnerabilityReportV2(config, snapshotResponse.id)
129
- if (config.save !== undefined) {
130
- await auditSave.auditSave(config)
131
- }
132
- const endTime = performance.now() - startTime
133
- const scanDurationMs = endTime - startTime
121
+ if (config.save !== undefined) {
122
+ await auditSave.auditSave(config, reportId)
123
+ }
134
124
 
135
- console.log(
136
- `----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
137
- )
138
- // }
125
+ const endTime = performance.now() - startTime
126
+ const scanDurationMs = endTime - startTime
127
+ console.log(
128
+ `----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
129
+ )
130
+ } else {
131
+ console.log('') //empty log for space before spinner
132
+ //send message to TS
133
+ const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
134
+ startSpinner(reportSpinner)
135
+ const snapshotResponse = await treeUpload.commonSendSnapShot(
136
+ messageToSend,
137
+ config
138
+ )
139
+
140
+ //poll for completion
141
+ await pollForSnapshotCompletition(
142
+ config,
143
+ snapshotResponse.id,
144
+ reportSpinner
145
+ )
146
+ succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
147
+
148
+ await vulnerabilityReportV2(config, snapshotResponse.id)
149
+ if (config.save !== undefined) {
150
+ await auditSave.auditSave(config)
151
+ }
152
+ const endTime = performance.now() - startTime
153
+ const scanDurationMs = endTime - startTime
154
+
155
+ console.log(
156
+ `----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
157
+ )
158
+ }
139
159
  } else {
140
160
  if (filesFound.length === 0) {
141
161
  console.log(i18n.__('languageAnalysisNoLanguage'))