@contrast/contrast 1.0.19 → 1.0.20

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 (38) hide show
  1. package/dist/audit/report/commonReportingFunctions.js +3 -4
  2. package/dist/audit/report/models/reportListModel.js +2 -1
  3. package/dist/audit/report/reportingFeature.js +1 -1
  4. package/dist/audit/report/utils/reportUtils.js +30 -11
  5. package/dist/commands/audit/auditConfig.js +1 -2
  6. package/dist/commands/scan/sca/scaAnalysis.js +4 -2
  7. package/dist/constants/constants.js +1 -1
  8. package/dist/constants/locales.js +6 -2
  9. package/dist/scaAnalysis/common/auditReport.js +16 -60
  10. package/dist/scaAnalysis/common/commonReportingFunctionsSca.js +154 -0
  11. package/dist/scaAnalysis/common/models/ScaReportModel.js +45 -0
  12. package/dist/scaAnalysis/common/scaServicesUpload.js +4 -3
  13. package/dist/scaAnalysis/common/utils/reportUtilsSca.js +76 -0
  14. package/dist/scaAnalysis/java/analysis.js +1 -28
  15. package/dist/scaAnalysis/java/index.js +1 -13
  16. package/dist/scan/formatScanOutput.js +19 -13
  17. package/dist/utils/paramsUtil/configStoreParams.js +1 -12
  18. package/dist/utils/paramsUtil/paramHandler.js +1 -7
  19. package/package.json +5 -1
  20. package/src/audit/report/commonReportingFunctions.js +7 -5
  21. package/src/audit/report/models/reportListModel.ts +12 -2
  22. package/src/audit/report/reportingFeature.ts +1 -1
  23. package/src/audit/report/utils/reportUtils.ts +4 -4
  24. package/src/commands/audit/auditConfig.js +1 -2
  25. package/src/commands/scan/sca/scaAnalysis.js +7 -2
  26. package/src/constants/constants.js +1 -1
  27. package/src/constants/locales.js +6 -2
  28. package/src/scaAnalysis/common/auditReport.js +25 -80
  29. package/src/scaAnalysis/common/commonReportingFunctionsSca.js +276 -0
  30. package/src/scaAnalysis/common/models/ScaReportModel.ts +81 -0
  31. package/src/scaAnalysis/common/scaServicesUpload.js +5 -3
  32. package/src/scaAnalysis/common/utils/reportUtilsSca.ts +123 -0
  33. package/src/scaAnalysis/java/analysis.js +1 -28
  34. package/src/scaAnalysis/java/index.js +1 -18
  35. package/src/scan/formatScanOutput.ts +28 -17
  36. package/src/utils/getConfig.ts +0 -1
  37. package/src/utils/paramsUtil/configStoreParams.js +1 -14
  38. package/src/utils/paramsUtil/paramHandler.js +1 -9
@@ -0,0 +1,276 @@
1
+ const {
2
+ ReportList,
3
+ ReportModelStructure,
4
+ ReportCompositeKey
5
+ } = require('../../audit/report/models/reportListModel')
6
+ const {
7
+ countVulnerableLibrariesBySeverity
8
+ } = require('../../audit/report/utils/reportUtils')
9
+ const {
10
+ SeverityCountModel
11
+ } = require('../../audit/report/models/severityCountModel')
12
+ const { orderBy } = require('lodash')
13
+ const {
14
+ ReportOutputModel,
15
+ ReportOutputHeaderModel,
16
+ ReportOutputBodyModel
17
+ } = require('../../audit/report/models/reportOutputModel')
18
+ const {
19
+ CE_URL,
20
+ CRITICAL_COLOUR,
21
+ HIGH_COLOUR,
22
+ MEDIUM_COLOUR,
23
+ LOW_COLOUR,
24
+ NOTE_COLOUR
25
+ } = require('../../constants/constants')
26
+ const chalk = require('chalk')
27
+ const Table = require('cli-table3')
28
+ const {
29
+ findHighestSeverityCVESca,
30
+ severityCountAllCVEsSca,
31
+ findCVESeveritySca,
32
+ orderByHighestPrioritySca
33
+ } = require('./utils/reportUtilsSca')
34
+ const {
35
+ buildFormattedHeaderNum
36
+ } = require('../../audit/report/commonReportingFunctions')
37
+
38
+ const createSummaryMessageTop = (numberOfVulnerableLibraries, numberOfCves) => {
39
+ numberOfVulnerableLibraries === 1
40
+ ? console.log(
41
+ `\n\nFound 1 vulnerable library containing ${numberOfCves} CVE`
42
+ )
43
+ : console.log(
44
+ `\n\nFound ${numberOfVulnerableLibraries} vulnerable libraries containing ${numberOfCves} CVEs`
45
+ )
46
+ }
47
+
48
+ const createSummaryMessageBottom = numberOfVulnerableLibraries => {
49
+ numberOfVulnerableLibraries === 1
50
+ ? console.log(`Found 1 vulnerability`)
51
+ : console.log(`Found ${numberOfVulnerableLibraries} vulnerabilities`)
52
+ }
53
+
54
+ const printFormattedOutputSca = (
55
+ config,
56
+ reportModelList,
57
+ numberOfVulnerableLibraries,
58
+ numberOfCves
59
+ ) => {
60
+ createSummaryMessageTop(numberOfVulnerableLibraries, numberOfCves)
61
+ console.log()
62
+ const report = new ReportList()
63
+
64
+ for (const library of reportModelList) {
65
+ const { artifactName, version, vulnerabilities, remediationAdvice } =
66
+ library
67
+
68
+ const newOutputModel = new ReportModelStructure(
69
+ new ReportCompositeKey(
70
+ artifactName,
71
+ version,
72
+ findHighestSeverityCVESca(vulnerabilities),
73
+ severityCountAllCVEsSca(
74
+ vulnerabilities,
75
+ new SeverityCountModel()
76
+ ).getTotal
77
+ ),
78
+ vulnerabilities,
79
+ remediationAdvice
80
+ )
81
+ report.reportOutputList.push(newOutputModel)
82
+ }
83
+
84
+ const outputOrderedByLowestSeverityAndLowestNumOfCvesFirst = orderBy(
85
+ report.reportOutputList,
86
+ [
87
+ reportListItem => {
88
+ return reportListItem.compositeKey.highestSeverity.priority
89
+ },
90
+ reportListItem => {
91
+ return reportListItem.compositeKey.numberOfSeverities
92
+ }
93
+ ],
94
+ ['asc', 'desc']
95
+ )
96
+
97
+ let contrastHeaderNumCounter = 0
98
+ for (const reportModel of outputOrderedByLowestSeverityAndLowestNumOfCvesFirst) {
99
+ contrastHeaderNumCounter++
100
+ const { libraryName, libraryVersion, highestSeverity } =
101
+ reportModel.compositeKey
102
+
103
+ const { cveArray, remediationAdvice } = reportModel
104
+
105
+ const numOfCVEs = reportModel.cveArray.length
106
+
107
+ const table = getReportTable()
108
+
109
+ const header = buildHeader(
110
+ highestSeverity,
111
+ contrastHeaderNumCounter,
112
+ libraryName,
113
+ libraryVersion,
114
+ numOfCVEs
115
+ )
116
+
117
+ const body = buildBody(cveArray, remediationAdvice)
118
+
119
+ const reportOutputModel = new ReportOutputModel(header, body)
120
+
121
+ table.push(
122
+ reportOutputModel.body.issueMessage,
123
+ reportOutputModel.body.adviceMessage
124
+ )
125
+
126
+ console.log(
127
+ reportOutputModel.header.vulnMessage,
128
+ reportOutputModel.header.introducesMessage
129
+ )
130
+ console.log(table.toString() + '\n')
131
+ }
132
+
133
+ createSummaryMessageBottom(numberOfVulnerableLibraries)
134
+ const {
135
+ criticalMessage,
136
+ highMessage,
137
+ mediumMessage,
138
+ lowMessage,
139
+ noteMessage
140
+ } = buildFooter(outputOrderedByLowestSeverityAndLowestNumOfCvesFirst)
141
+ console.log(
142
+ `${criticalMessage} | ${highMessage} | ${mediumMessage} | ${lowMessage} | ${noteMessage}`
143
+ )
144
+
145
+ if (config.host !== CE_URL) {
146
+ console.log(
147
+ '\n' + chalk.bold('View your full dependency tree in Contrast:')
148
+ )
149
+ console.log(
150
+ `${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/applications/${config.applicationId}/libs/dependency-tree`
151
+ )
152
+ }
153
+ }
154
+
155
+ function getReportTable() {
156
+ return new Table({
157
+ chars: {
158
+ top: '',
159
+ 'top-mid': '',
160
+ 'top-left': '',
161
+ 'top-right': '',
162
+ bottom: '',
163
+ 'bottom-mid': '',
164
+ 'bottom-left': '',
165
+ 'bottom-right': '',
166
+ left: '',
167
+ 'left-mid': '',
168
+ mid: '',
169
+ 'mid-mid': '',
170
+ right: '',
171
+ 'right-mid': '',
172
+ middle: ' '
173
+ },
174
+ style: { 'padding-left': 0, 'padding-right': 0 },
175
+ colAligns: ['right'],
176
+ wordWrap: true,
177
+ colWidths: [12, 1, 100]
178
+ })
179
+ }
180
+
181
+ function buildHeader(
182
+ highestSeverity,
183
+ contrastHeaderNum,
184
+ libraryName,
185
+ version,
186
+ numOfCVEs
187
+ ) {
188
+ const vulnerabilityPluralised =
189
+ numOfCVEs > 1 ? 'vulnerabilities' : 'vulnerability'
190
+ const formattedHeaderNum = buildFormattedHeaderNum(contrastHeaderNum)
191
+
192
+ const headerColour = chalk.hex(highestSeverity.colour)
193
+ const headerNumAndSeverity = headerColour(
194
+ `${formattedHeaderNum} - [${highestSeverity.severity}]`
195
+ )
196
+ const libraryNameAndVersion = headerColour.bold(`${libraryName}-${version}`)
197
+ const vulnMessage = `${headerNumAndSeverity} ${libraryNameAndVersion}`
198
+
199
+ const introducesMessage = `introduces ${numOfCVEs} ${vulnerabilityPluralised}`
200
+
201
+ return new ReportOutputHeaderModel(vulnMessage, introducesMessage)
202
+ }
203
+
204
+ function buildBody(cveArray, advice) {
205
+ const orderedCvesWithSeverityAssigned = orderByHighestPrioritySca(
206
+ cveArray.map(cve => findCVESeveritySca(cve))
207
+ )
208
+ const issueMessage = getIssueRow(orderedCvesWithSeverityAssigned)
209
+ const adviceMessage = getAdviceRow(advice)
210
+
211
+ return new ReportOutputBodyModel(issueMessage, adviceMessage)
212
+ }
213
+
214
+ function getIssueRow(cveArray) {
215
+ const cveMessagesList = getIssueCveMsgList(cveArray)
216
+ return [chalk.bold('Issue'), ':', `${cveMessagesList.join(', ')}`]
217
+ }
218
+
219
+ function getAdviceRow(advice) {
220
+ const latestOrClosest = advice.latestStableVersion
221
+ ? advice.latestStableVersion
222
+ : advice.closestStableVersion
223
+ const displayAdvice = latestOrClosest
224
+ ? `Change to version ${chalk.bold(latestOrClosest)}`
225
+ : 'No recommendation is available according to our data. Upgrade to the latest stable is the best advice we can give.'
226
+
227
+ return [chalk.bold(`Advice`), chalk.bold(`:`), `${displayAdvice}`]
228
+ }
229
+
230
+ const buildFooter = reportModelStructure => {
231
+ const { critical, high, medium, low, note } =
232
+ countVulnerableLibrariesBySeverity(reportModelStructure)
233
+
234
+ const criticalMessage = chalk
235
+ .hex(CRITICAL_COLOUR)
236
+ .bold(`${critical} Critical`)
237
+ const highMessage = chalk.hex(HIGH_COLOUR).bold(`${high} High`)
238
+ const mediumMessage = chalk.hex(MEDIUM_COLOUR).bold(`${medium} Medium`)
239
+ const lowMessage = chalk.hex(LOW_COLOUR).bold(`${low} Low`)
240
+ const noteMessage = chalk.hex(NOTE_COLOUR).bold(`${note} Note`)
241
+
242
+ return {
243
+ criticalMessage,
244
+ highMessage,
245
+ mediumMessage,
246
+ lowMessage,
247
+ noteMessage
248
+ }
249
+ }
250
+
251
+ const getIssueCveMsgList = reportSeverityModels => {
252
+ const cveMessages = []
253
+ reportSeverityModels.forEach(reportSeverityModel => {
254
+ const { colour, severity, name } = reportSeverityModel
255
+
256
+ const severityShorthand = chalk
257
+ .hex(colour)
258
+ .bold(`[${severity.charAt(0).toUpperCase()}]`)
259
+
260
+ const builtMessage = severityShorthand + name
261
+ cveMessages.push(builtMessage)
262
+ })
263
+ return cveMessages
264
+ }
265
+
266
+ module.exports = {
267
+ createSummaryMessageTop,
268
+ createSummaryMessageBottom,
269
+ printFormattedOutputSca,
270
+ getReportTable,
271
+ buildHeader,
272
+ buildBody,
273
+ getIssueRow,
274
+ buildFormattedHeaderNum,
275
+ getIssueCveMsgList
276
+ }
@@ -0,0 +1,81 @@
1
+ export class ScaReportModel {
2
+ uuid: string
3
+ groupName: string
4
+ artifactName: string
5
+ version: string
6
+ hash: string
7
+ fileName: string
8
+ libraryLanguage: string
9
+ vulnerable: boolean
10
+ privateLibrary: boolean
11
+ severity: string
12
+ releaseDate: string
13
+ latestVersionReleaseDate: string
14
+ latestVersion: string
15
+ versionsBehind: number
16
+ vulnerabilities: ScaReportVulnerabilityModel[]
17
+ remediationAdvice: ScaReportRemediationAdviceModel
18
+
19
+ constructor(library: any) {
20
+ this.uuid = library.uuid
21
+ this.groupName = library.groupName
22
+ this.artifactName = library.artifactName
23
+ this.version = library.version
24
+ this.hash = library.hash
25
+ this.fileName = library.fileName
26
+ this.libraryLanguage = library.libraryLanguage
27
+ this.vulnerable = library.vulnerable
28
+ this.privateLibrary = library.privateLibrary
29
+ this.severity = library.severity
30
+ this.releaseDate = library.releaseDate
31
+ this.latestVersionReleaseDate = library.latestVersionReleaseDate
32
+ this.latestVersion = library.latestVersion
33
+ this.versionsBehind = library.versionsBehind
34
+ this.vulnerabilities = library.vulnerabilities
35
+ this.remediationAdvice = library.remediationAdvice
36
+ }
37
+ }
38
+
39
+ export class ScaReportVulnerabilityModel {
40
+ name: string
41
+ description: string
42
+ cvss2Vector: string
43
+ severityValue: number
44
+ severity: string
45
+ cvss3Vector: string
46
+ cvss3SeverityValue: number
47
+ cvss3Severity: string
48
+ hasCvss3: boolean
49
+
50
+ constructor(
51
+ name: string,
52
+ description: string,
53
+ cvss2Vector: string,
54
+ severityValue: number,
55
+ severity: string,
56
+ cvss3Vector: string,
57
+ cvss3SeverityValue: number,
58
+ cvss3Severity: string,
59
+ hasCvss3: boolean
60
+ ) {
61
+ this.name = name
62
+ this.description = description
63
+ this.cvss2Vector = cvss2Vector
64
+ this.severityValue = severityValue
65
+ this.severity = severity
66
+ this.cvss3Vector = cvss3Vector
67
+ this.cvss3SeverityValue = cvss3SeverityValue
68
+ this.cvss3Severity = cvss3Severity
69
+ this.hasCvss3 = hasCvss3
70
+ }
71
+ }
72
+
73
+ export class ScaReportRemediationAdviceModel {
74
+ closestStableVersion: string
75
+ latestStableVersion: string
76
+
77
+ constructor(closestStableVersion: string, latestStableVersion: string) {
78
+ this.closestStableVersion = closestStableVersion
79
+ this.latestStableVersion = latestStableVersion
80
+ }
81
+ }
@@ -46,17 +46,19 @@ const scaTreeUpload = async (analysis, config) => {
46
46
  if (res.body.status === 'COMPLETED') {
47
47
  keepChecking = false
48
48
  return client.scaServiceReport(config, reportID).then(res => {
49
- return [res.body, reportID]
49
+ const reportBody = res.body
50
+ return { reportBody, reportID }
50
51
  })
51
52
  }
52
53
  })
53
54
 
54
55
  if (!keepChecking) {
55
- return [res, reportID]
56
+ return { reportArray: res.reportBody, reportID }
56
57
  }
57
58
  await requestUtils.sleep(5000)
58
59
  }
59
- return [res, reportID]
60
+
61
+ return { reportArray: res, reportID }
60
62
  }
61
63
 
62
64
  module.exports = {
@@ -0,0 +1,123 @@
1
+ import { orderBy } from 'lodash'
2
+ import {
3
+ CRITICAL_COLOUR,
4
+ CRITICAL_PRIORITY,
5
+ HIGH_COLOUR,
6
+ HIGH_PRIORITY,
7
+ LOW_COLOUR,
8
+ LOW_PRIORITY,
9
+ MEDIUM_COLOUR,
10
+ MEDIUM_PRIORITY,
11
+ NOTE_COLOUR,
12
+ NOTE_PRIORITY
13
+ } from '../../../constants/constants'
14
+ import { ReportSeverityModel } from '../../../audit/report/models/reportSeverityModel'
15
+ import { SeverityCountModel } from '../../../audit/report/models/severityCountModel'
16
+ import {
17
+ ScaReportModel,
18
+ ScaReportVulnerabilityModel
19
+ } from '../models/ScaReportModel'
20
+
21
+ export function findHighestSeverityCVESca(
22
+ cveArray: ScaReportVulnerabilityModel[]
23
+ ) {
24
+ const mappedToReportSeverityModels = cveArray.map(cve =>
25
+ findCVESeveritySca(cve)
26
+ )
27
+
28
+ //order and get first
29
+ return orderBy(mappedToReportSeverityModels, cve => cve?.priority)[0]
30
+ }
31
+
32
+ export function orderByHighestPrioritySca(
33
+ reportSeverityModel: ReportSeverityModel[]
34
+ ) {
35
+ return orderBy(reportSeverityModel, ['priority'], ['asc'])
36
+ }
37
+
38
+ export function findCVESeveritySca(
39
+ vulnerabilityModel: ScaReportVulnerabilityModel
40
+ ) {
41
+ const { name } = vulnerabilityModel
42
+
43
+ if (
44
+ vulnerabilityModel.cvss3Severity === 'CRITICAL' ||
45
+ vulnerabilityModel.severity === 'CRITICAL'
46
+ ) {
47
+ return new ReportSeverityModel(
48
+ 'CRITICAL',
49
+ CRITICAL_PRIORITY,
50
+ CRITICAL_COLOUR,
51
+ name
52
+ )
53
+ } else if (
54
+ vulnerabilityModel.cvss3Severity === 'HIGH' ||
55
+ vulnerabilityModel.severity === 'HIGH'
56
+ ) {
57
+ return new ReportSeverityModel('HIGH', HIGH_PRIORITY, HIGH_COLOUR, name)
58
+ } else if (
59
+ vulnerabilityModel.cvss3Severity === 'MEDIUM' ||
60
+ vulnerabilityModel.severity === 'MEDIUM'
61
+ ) {
62
+ return new ReportSeverityModel(
63
+ 'MEDIUM',
64
+ MEDIUM_PRIORITY,
65
+ MEDIUM_COLOUR,
66
+ name
67
+ )
68
+ } else if (
69
+ vulnerabilityModel.cvss3Severity === 'LOW' ||
70
+ vulnerabilityModel.severity === 'LOW'
71
+ ) {
72
+ return new ReportSeverityModel('LOW', LOW_PRIORITY, LOW_COLOUR, name)
73
+ } else if (
74
+ vulnerabilityModel.cvss3Severity === 'NOTE' ||
75
+ vulnerabilityModel.severity === 'NOTE'
76
+ ) {
77
+ return new ReportSeverityModel('NOTE', NOTE_PRIORITY, NOTE_COLOUR, name)
78
+ }
79
+ }
80
+
81
+ export function convertGenericToTypedReportModelSca(reportArray: any) {
82
+ return reportArray.map((library: any) => {
83
+ return new ScaReportModel(library)
84
+ })
85
+ }
86
+
87
+ export function severityCountAllLibrariesSca(
88
+ vulnerableLibraries: ScaReportModel[],
89
+ severityCount: SeverityCountModel
90
+ ) {
91
+ vulnerableLibraries.forEach(lib =>
92
+ severityCountAllCVEsSca(lib.vulnerabilities, severityCount)
93
+ )
94
+ return severityCount
95
+ }
96
+
97
+ export function severityCountAllCVEsSca(
98
+ cveArray: ScaReportVulnerabilityModel[],
99
+ severityCount: SeverityCountModel
100
+ ) {
101
+ const severityCountInner = severityCount
102
+ cveArray.forEach(cve => severityCountSingleCVESca(cve, severityCountInner))
103
+ return severityCountInner
104
+ }
105
+
106
+ export function severityCountSingleCVESca(
107
+ cve: ScaReportVulnerabilityModel,
108
+ severityCount: SeverityCountModel
109
+ ) {
110
+ if (cve.cvss3Severity === 'CRITICAL' || cve.severity === 'CRITICAL') {
111
+ severityCount.critical += 1
112
+ } else if (cve.cvss3Severity === 'HIGH' || cve.severity === 'HIGH') {
113
+ severityCount.high += 1
114
+ } else if (cve.cvss3Severity === 'MEDIUM' || cve.severity === 'MEDIUM') {
115
+ severityCount.medium += 1
116
+ } else if (cve.cvss3Severity === 'LOW' || cve.severity === 'LOW') {
117
+ severityCount.low += 1
118
+ } else if (cve.cvss3Severity === 'NOTE' || cve.severity === 'NOTE') {
119
+ severityCount.note += 1
120
+ }
121
+
122
+ return severityCount
123
+ }
@@ -147,34 +147,7 @@ const getJavaBuildDeps = (config, files) => {
147
147
  }
148
148
  }
149
149
 
150
- const agreementPrompt = async config => {
151
- const rl = readLine.createInterface({
152
- input: process.stdin,
153
- output: process.stdout
154
- })
155
-
156
- return new Promise((resolve, reject) => {
157
- rl.question('❔ Do you want to continue? Type Y or N', async input => {
158
- if (input.toLowerCase() === 'yes' || input.toLowerCase() === 'y') {
159
- config.javaAgreement = paramHandler.setAgreement(true)
160
- rl.close()
161
- resolve(config)
162
- } else if (input.toLowerCase() === 'no' || input.toLowerCase() === 'n') {
163
- rl.close()
164
- resolve(process.exit(1))
165
- } else {
166
- rl.close()
167
- console.log('Invalid Input: Exiting')
168
- resolve(process.exit(1))
169
- }
170
- })
171
- }).catch(e => {
172
- throw e
173
- })
174
- }
175
-
176
150
  module.exports = {
177
151
  getJavaBuildDeps,
178
- determineProjectTypeAndCwd,
179
- agreementPrompt
152
+ determineProjectTypeAndCwd
180
153
  }
@@ -4,16 +4,12 @@ const { createJavaTSMessage } = require('../common/formatMessage')
4
4
  const {
5
5
  parseDependenciesForSCAServices
6
6
  } = require('../common/scaParserForGoAndJava')
7
- const chalk = require('chalk')
8
- const _ = require('lodash')
9
7
 
10
8
  const javaAnalysis = async (config, languageFiles) => {
11
9
  languageFiles.JAVA.forEach(file => {
12
10
  file.replace('build.gradle.kts', 'build.gradle')
13
11
  })
14
12
 
15
- await getAgreement(config)
16
-
17
13
  const javaDeps = buildJavaTree(config, languageFiles.JAVA)
18
14
 
19
15
  if (config.experimental) {
@@ -23,24 +19,11 @@ const javaAnalysis = async (config, languageFiles) => {
23
19
  }
24
20
  }
25
21
 
26
- const getAgreement = async config => {
27
- console.log(chalk.bold('Java project detected'))
28
- console.log(
29
- 'Java analysis uses maven / gradle which are potentially susceptible to command injection. Be sure that the code you are running Contrast CLI on is trusted before continuing.'
30
- )
31
-
32
- if (!process.env.CI && !config?.javaAgreement) {
33
- return await analysis.agreementPrompt(config)
34
- }
35
- return config
36
- }
37
-
38
22
  const buildJavaTree = (config, files) => {
39
23
  const javaBuildDeps = analysis.getJavaBuildDeps(config, files)
40
24
  return parseBuildDeps(config, javaBuildDeps)
41
25
  }
42
26
 
43
27
  module.exports = {
44
- javaAnalysis,
45
- getAgreement
28
+ javaAnalysis
46
29
  }
@@ -1,7 +1,4 @@
1
- import {
2
- ScanResultsInstances,
3
- ScanResultsModel
4
- } from './models/scanResultsModel'
1
+ import { ScanResultsModel } from './models/scanResultsModel'
5
2
  import i18n from 'i18n'
6
3
  import chalk from 'chalk'
7
4
  import { ResultContent } from './models/resultContentModel'
@@ -13,7 +10,8 @@ import {
13
10
  HIGH_COLOUR,
14
11
  LOW_COLOUR,
15
12
  MEDIUM_COLOUR,
16
- NOTE_COLOUR
13
+ NOTE_COLOUR,
14
+ supportedLanguagesScan
17
15
  } from '../constants/constants'
18
16
  import {
19
17
  getSeverityCounts,
@@ -21,27 +19,28 @@ import {
21
19
  } from '../audit/report/commonReportingFunctions'
22
20
 
23
21
  export function formatScanOutput(scanResults: ScanResultsModel) {
24
- const { scanResultsInstances } = scanResults
22
+ const { content } = scanResults.scanResultsInstances
23
+ const { language } = scanResults.scanDetail
25
24
 
26
- const projectOverview = getSeverityCounts(scanResultsInstances.content)
27
- if (scanResultsInstances.content.length === 0) {
25
+ const severityCounts = getSeverityCounts(content)
26
+ if (content.length === 0) {
28
27
  console.log(i18n.__('scanNoVulnerabilitiesFound'))
29
28
  console.log(i18n.__('scanNoVulnerabilitiesFoundSecureCode'))
30
29
  console.log(i18n.__('scanNoVulnerabilitiesFoundGoodWork'))
31
30
  } else {
32
31
  const message =
33
- projectOverview.critical || projectOverview.high
32
+ severityCounts.critical || severityCounts.high
34
33
  ? 'Here are your top priorities to fix'
35
34
  : "No major issues, here's what we found"
36
35
  console.log(chalk.bold(message))
37
36
  console.log()
38
37
 
39
- let defaultView = getDefaultView(scanResultsInstances.content)
38
+ const defaultView = getDefaultView(content, language)
40
39
 
41
40
  let count = 0
42
41
  defaultView.forEach(entry => {
43
42
  count++
44
- let table = new Table({
43
+ const table = new Table({
45
44
  chars: {
46
45
  top: '',
47
46
  'top-mid': '',
@@ -64,6 +63,7 @@ export function formatScanOutput(scanResults: ScanResultsModel) {
64
63
  wordWrap: true,
65
64
  colWidths: [12, 1, 100]
66
65
  })
66
+
67
67
  let learnRow: string[] = []
68
68
  let adviceRow = []
69
69
  const headerColour = chalk.hex(entry.colour)
@@ -107,9 +107,9 @@ export function formatScanOutput(scanResults: ScanResultsModel) {
107
107
  console.log()
108
108
  })
109
109
  }
110
- printVulnInfo(projectOverview)
110
+ printVulnInfo(severityCounts)
111
111
 
112
- return projectOverview
112
+ return severityCounts
113
113
  }
114
114
 
115
115
  export function formatLinks(objName: string, entry: any[]) {
@@ -124,7 +124,7 @@ export function formatLinks(objName: string, entry: any[]) {
124
124
  }
125
125
  }
126
126
 
127
- export function getDefaultView(content: ResultContent[]) {
127
+ export function getDefaultView(content: ResultContent[], language: string) {
128
128
  const groupTypeResults = [] as GroupedResultsModel[]
129
129
 
130
130
  content.forEach(resultEntry => {
@@ -136,8 +136,7 @@ export function getDefaultView(content: ResultContent[]) {
136
136
  groupResultsObj.learn = resultEntry.learn
137
137
  groupResultsObj.message = resultEntry.message?.text
138
138
  ? editVulName(resultEntry.message.text) +
139
- ':' +
140
- getSourceLineNumber(resultEntry)
139
+ doAddSourceLineNumber(resultEntry, language)
141
140
  : ''
142
141
  groupResultsObj.codePath = getLocationsSyncInfo(resultEntry)
143
142
  groupTypeResults.push(groupResultsObj)
@@ -146,9 +145,21 @@ export function getDefaultView(content: ResultContent[]) {
146
145
 
147
146
  return sortBy(groupTypeResults, ['priority'])
148
147
  }
148
+
149
+ export function doAddSourceLineNumber(
150
+ resultEntry: ResultContent,
151
+ language: string
152
+ ) {
153
+ //only add source line num if not JS
154
+ return language !== supportedLanguagesScan.JAVASCRIPT
155
+ ? ':' + getSourceLineNumber(resultEntry)
156
+ : ''
157
+ }
158
+
149
159
  export function editVulName(message: string) {
150
160
  return message.substring(message.indexOf(' in '))
151
161
  }
162
+
152
163
  export function getLocationsSyncInfo(resultEntry: ResultContent) {
153
164
  const locationsMessage =
154
165
  resultEntry.locations[0]?.physicalLocation?.artifactLocation?.uri || ''
@@ -165,7 +176,7 @@ export function getLocationsSyncInfo(resultEntry: ResultContent) {
165
176
  export function getSourceLineNumber(resultEntry: ResultContent) {
166
177
  const locationsLineNumber =
167
178
  resultEntry.locations[0]?.physicalLocation?.region?.startLine || ''
168
- let codeFlowLineNumber = getCodeFlowInfo(resultEntry)
179
+ const codeFlowLineNumber = getCodeFlowInfo(resultEntry)
169
180
 
170
181
  return codeFlowLineNumber ? codeFlowLineNumber : locationsLineNumber
171
182
  }