@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
@@ -3,13 +3,10 @@ const analysis = require('./analysis');
3
3
  const { parseBuildDeps } = require('./javaBuildDepsParser');
4
4
  const { createJavaTSMessage } = require('../common/formatMessage');
5
5
  const { parseDependenciesForSCAServices } = require('../common/scaParserForGoAndJava');
6
- const chalk = require('chalk');
7
- const _ = require('lodash');
8
6
  const javaAnalysis = async (config, languageFiles) => {
9
7
  languageFiles.JAVA.forEach(file => {
10
8
  file.replace('build.gradle.kts', 'build.gradle');
11
9
  });
12
- await getAgreement(config);
13
10
  const javaDeps = buildJavaTree(config, languageFiles.JAVA);
14
11
  if (config.experimental) {
15
12
  return parseDependenciesForSCAServices(javaDeps);
@@ -18,19 +15,10 @@ const javaAnalysis = async (config, languageFiles) => {
18
15
  return createJavaTSMessage(javaDeps);
19
16
  }
20
17
  };
21
- const getAgreement = async (config) => {
22
- console.log(chalk.bold('Java project detected'));
23
- console.log('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.');
24
- if (!process.env.CI && !config?.javaAgreement) {
25
- return await analysis.agreementPrompt(config);
26
- }
27
- return config;
28
- };
29
18
  const buildJavaTree = (config, files) => {
30
19
  const javaBuildDeps = analysis.getJavaBuildDeps(config, files);
31
20
  return parseBuildDeps(config, javaBuildDeps);
32
21
  };
33
22
  module.exports = {
34
- javaAnalysis,
35
- getAgreement
23
+ javaAnalysis
36
24
  };
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.assignBySeverity = exports.stripTags = exports.getCodeFlowInfo = exports.getSourceLineNumber = exports.getLocationsSyncInfo = exports.editVulName = exports.getDefaultView = exports.formatLinks = exports.formatScanOutput = void 0;
6
+ exports.assignBySeverity = exports.stripTags = exports.getCodeFlowInfo = exports.getSourceLineNumber = exports.getLocationsSyncInfo = exports.editVulName = exports.doAddSourceLineNumber = exports.getDefaultView = exports.formatLinks = exports.formatScanOutput = void 0;
7
7
  const i18n_1 = __importDefault(require("i18n"));
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
9
  const groupedResultsModel_1 = require("./models/groupedResultsModel");
@@ -12,24 +12,25 @@ const cli_table3_1 = __importDefault(require("cli-table3"));
12
12
  const constants_1 = require("../constants/constants");
13
13
  const commonReportingFunctions_1 = require("../audit/report/commonReportingFunctions");
14
14
  function formatScanOutput(scanResults) {
15
- const { scanResultsInstances } = scanResults;
16
- const projectOverview = (0, commonReportingFunctions_1.getSeverityCounts)(scanResultsInstances.content);
17
- if (scanResultsInstances.content.length === 0) {
15
+ const { content } = scanResults.scanResultsInstances;
16
+ const { language } = scanResults.scanDetail;
17
+ const severityCounts = (0, commonReportingFunctions_1.getSeverityCounts)(content);
18
+ if (content.length === 0) {
18
19
  console.log(i18n_1.default.__('scanNoVulnerabilitiesFound'));
19
20
  console.log(i18n_1.default.__('scanNoVulnerabilitiesFoundSecureCode'));
20
21
  console.log(i18n_1.default.__('scanNoVulnerabilitiesFoundGoodWork'));
21
22
  }
22
23
  else {
23
- const message = projectOverview.critical || projectOverview.high
24
+ const message = severityCounts.critical || severityCounts.high
24
25
  ? 'Here are your top priorities to fix'
25
26
  : "No major issues, here's what we found";
26
27
  console.log(chalk_1.default.bold(message));
27
28
  console.log();
28
- let defaultView = getDefaultView(scanResultsInstances.content);
29
+ const defaultView = getDefaultView(content, language);
29
30
  let count = 0;
30
31
  defaultView.forEach(entry => {
31
32
  count++;
32
- let table = new cli_table3_1.default({
33
+ const table = new cli_table3_1.default({
33
34
  chars: {
34
35
  top: '',
35
36
  'top-mid': '',
@@ -90,8 +91,8 @@ function formatScanOutput(scanResults) {
90
91
  console.log();
91
92
  });
92
93
  }
93
- (0, commonReportingFunctions_1.printVulnInfo)(projectOverview);
94
- return projectOverview;
94
+ (0, commonReportingFunctions_1.printVulnInfo)(severityCounts);
95
+ return severityCounts;
95
96
  }
96
97
  exports.formatScanOutput = formatScanOutput;
97
98
  function formatLinks(objName, entry) {
@@ -107,7 +108,7 @@ function formatLinks(objName, entry) {
107
108
  }
108
109
  }
109
110
  exports.formatLinks = formatLinks;
110
- function getDefaultView(content) {
111
+ function getDefaultView(content, language) {
111
112
  const groupTypeResults = [];
112
113
  content.forEach(resultEntry => {
113
114
  const groupResultsObj = new groupedResultsModel_1.GroupedResultsModel(resultEntry.ruleId);
@@ -118,8 +119,7 @@ function getDefaultView(content) {
118
119
  groupResultsObj.learn = resultEntry.learn;
119
120
  groupResultsObj.message = resultEntry.message?.text
120
121
  ? editVulName(resultEntry.message.text) +
121
- ':' +
122
- getSourceLineNumber(resultEntry)
122
+ doAddSourceLineNumber(resultEntry, language)
123
123
  : '';
124
124
  groupResultsObj.codePath = getLocationsSyncInfo(resultEntry);
125
125
  groupTypeResults.push(groupResultsObj);
@@ -128,6 +128,12 @@ function getDefaultView(content) {
128
128
  return (0, lodash_1.sortBy)(groupTypeResults, ['priority']);
129
129
  }
130
130
  exports.getDefaultView = getDefaultView;
131
+ function doAddSourceLineNumber(resultEntry, language) {
132
+ return language !== constants_1.supportedLanguagesScan.JAVASCRIPT
133
+ ? ':' + getSourceLineNumber(resultEntry)
134
+ : '';
135
+ }
136
+ exports.doAddSourceLineNumber = doAddSourceLineNumber;
131
137
  function editVulName(message) {
132
138
  return message.substring(message.indexOf(' in '));
133
139
  }
@@ -143,7 +149,7 @@ function getLocationsSyncInfo(resultEntry) {
143
149
  exports.getLocationsSyncInfo = getLocationsSyncInfo;
144
150
  function getSourceLineNumber(resultEntry) {
145
151
  const locationsLineNumber = resultEntry.locations[0]?.physicalLocation?.region?.startLine || '';
146
- let codeFlowLineNumber = getCodeFlowInfo(resultEntry);
152
+ const codeFlowLineNumber = getCodeFlowInfo(resultEntry);
147
153
  return codeFlowLineNumber ? codeFlowLineNumber : locationsLineNumber;
148
154
  }
149
155
  exports.getSourceLineNumber = getSourceLineNumber;
@@ -15,15 +15,4 @@ const getAuth = () => {
15
15
  }
16
16
  return ContrastConfToUse;
17
17
  };
18
- const getAgreement = () => {
19
- const ContrastConf = config.localConfig(APP_NAME, APP_VERSION);
20
- let ContrastConfToUse = {};
21
- ContrastConfToUse.javaAgreement = ContrastConf.get('javaAgreement');
22
- return ContrastConfToUse;
23
- };
24
- const setAgreement = agreement => {
25
- const ContrastConf = config.localConfig(APP_NAME, APP_VERSION);
26
- ContrastConf.set('javaAgreement', agreement);
27
- return agreement;
28
- };
29
- module.exports = { getAuth, getAgreement, setAgreement };
18
+ module.exports = { getAuth };
@@ -22,10 +22,4 @@ const getAuth = params => {
22
22
  process.exit(1);
23
23
  }
24
24
  };
25
- const getAgreement = () => {
26
- return configStoreParams.getAgreement();
27
- };
28
- const setAgreement = answer => {
29
- return configStoreParams.setAgreement(answer);
30
- };
31
- module.exports = { getAuth, getAgreement, setAgreement };
25
+ module.exports = { getAuth };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/contrast",
3
- "version": "1.0.19",
3
+ "version": "1.0.20",
4
4
  "description": "Contrast Security's command line tool",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -15,6 +15,10 @@
15
15
  {
16
16
  "name": "Andrew Shanks",
17
17
  "email": "andrew.shanks@contrastsecurity.com"
18
+ },
19
+ {
20
+ "name": "Oisín Cassidy",
21
+ "email": "oisin.cassidy@contrastsecurity.com"
18
22
  }
19
23
  ],
20
24
  "license": "ISC",
@@ -108,7 +108,8 @@ const printFormattedOutput = (
108
108
  new SeverityCountModel()
109
109
  ).getTotal
110
110
  ),
111
- library.cveArray
111
+ library.cveArray,
112
+ null
112
113
  )
113
114
  report.reportOutputList.push(newOutputModel)
114
115
  }
@@ -131,6 +132,7 @@ const printFormattedOutput = (
131
132
  contrastHeaderNumCounter++
132
133
  const { libraryName, libraryVersion, highestSeverity } =
133
134
  reportModel.compositeKey
135
+
134
136
  const numOfCVEs = reportModel.cveArray.length
135
137
 
136
138
  const table = getReportTable()
@@ -236,9 +238,11 @@ function buildHeader(
236
238
  }
237
239
 
238
240
  function buildBody(cveArray, advice) {
239
- let assignPriorityToVulns = cveArray.map(result => findCVESeverity(result))
241
+ const orderedCvesWithSeverityAssigned = orderByHighestPriority(
242
+ cveArray.map(cve => findCVESeverity(cve))
243
+ )
240
244
 
241
- const issueMessage = getIssueRow(assignPriorityToVulns)
245
+ const issueMessage = getIssueRow(orderedCvesWithSeverityAssigned)
242
246
 
243
247
  //todo different advice based on remediationGuidance being available or now
244
248
  // console.log(advice)
@@ -254,7 +258,6 @@ function buildBody(cveArray, advice) {
254
258
  }
255
259
 
256
260
  function getIssueRow(cveArray) {
257
- orderByHighestPriority(cveArray)
258
261
  const cveMessagesList = getIssueCveMsgList(cveArray)
259
262
  return [chalk.bold('Issue'), ':', `${cveMessagesList.join(', ')}`]
260
263
  }
@@ -301,7 +304,6 @@ const getIssueCveMsgList = results => {
301
304
  const cveMessages = []
302
305
 
303
306
  results.forEach(reportSeverityModel => {
304
- // @ts-ignore
305
307
  const { colour, severity, name } = reportSeverityModel
306
308
 
307
309
  const severityShorthand = chalk
@@ -1,5 +1,9 @@
1
1
  import { ReportSeverityModel } from './reportSeverityModel'
2
2
  import { ReportCVEModel } from './reportLibraryModel'
3
+ import {
4
+ ScaReportRemediationAdviceModel,
5
+ ScaReportVulnerabilityModel
6
+ } from '../../../scaAnalysis/common/models/ScaReportModel'
3
7
 
4
8
  export class ReportList {
5
9
  reportOutputList: ReportModelStructure[]
@@ -11,11 +15,17 @@ export class ReportList {
11
15
 
12
16
  export class ReportModelStructure {
13
17
  compositeKey: ReportCompositeKey
14
- cveArray: ReportCVEModel[]
18
+ cveArray: ReportCVEModel[] | ScaReportVulnerabilityModel[]
19
+ remediationAdvice: ScaReportRemediationAdviceModel | null
15
20
 
16
- constructor(compositeKey: ReportCompositeKey, cveArray: ReportCVEModel[]) {
21
+ constructor(
22
+ compositeKey: ReportCompositeKey,
23
+ cveArray: ReportCVEModel[] | ScaReportVulnerabilityModel[],
24
+ remediationAdvice: ScaReportRemediationAdviceModel | null
25
+ ) {
17
26
  this.compositeKey = compositeKey
18
27
  this.cveArray = cveArray
28
+ this.remediationAdvice = remediationAdvice
19
29
  }
20
30
  }
21
31
 
@@ -87,7 +87,7 @@ export async function vulnerabilityReportV2(config: any, reportId: string) {
87
87
  const reportResponse = await getReport(config, reportId)
88
88
 
89
89
  if (reportResponse !== undefined) {
90
- let output = formatVulnerabilityOutput(
90
+ const output = formatVulnerabilityOutput(
91
91
  reportResponse.vulnerabilities,
92
92
  config.applicationId,
93
93
  config,
@@ -3,8 +3,7 @@ import {
3
3
  ReportLibraryModel
4
4
  } from '../models/reportLibraryModel'
5
5
  import { ReportSeverityModel } from '../models/reportSeverityModel'
6
- import languageAnalysisEngine from '../../../constants/constants'
7
- import {
6
+ import languageAnalysisEngine, {
8
7
  CRITICAL_COLOUR,
9
8
  CRITICAL_PRIORITY,
10
9
  HIGH_COLOUR,
@@ -19,6 +18,7 @@ import {
19
18
  import { orderBy } from 'lodash'
20
19
  import { SeverityCountModel } from '../models/severityCountModel'
21
20
  import { ReportModelStructure } from '../models/reportListModel'
21
+
22
22
  const {
23
23
  supportedLanguages: { GO }
24
24
  } = languageAnalysisEngine
@@ -30,8 +30,8 @@ export function findHighestSeverityCVE(cveArray: ReportCVEModel[]) {
30
30
  return orderBy(mappedToReportSeverityModels, cve => cve?.priority)[0]
31
31
  }
32
32
 
33
- export function orderByHighestPriority(cves: ReportCVEModel[]) {
34
- return orderBy(cves, ['priority'], ['asc'])
33
+ export function orderByHighestPriority(severityModels: ReportSeverityModel[]) {
34
+ return orderBy(severityModels, ['priority'], ['asc'])
35
35
  }
36
36
 
37
37
  export function findCVESeverity(cve: ReportCVEModel) {
@@ -10,8 +10,7 @@ const getAuditConfig = async (contrastConf, command, argv) => {
10
10
  constants.commandLineDefinitions.auditOptionDefinitions
11
11
  )
12
12
  const paramsAuth = paramHandler.getAuth(auditParameters)
13
- const javaAgreement = paramHandler.getAgreement()
14
- return { ...paramsAuth, ...auditParameters, ...javaAgreement }
13
+ return { ...paramsAuth, ...auditParameters }
15
14
  }
16
15
 
17
16
  module.exports = {
@@ -33,6 +33,9 @@ const scaUpload = require('../../../scaAnalysis/common/scaServicesUpload')
33
33
  const settingsHelper = require('../../../utils/settingsHelper')
34
34
  const chalk = require('chalk')
35
35
  const saveResults = require('../../../scan/saveResults')
36
+ const {
37
+ convertGenericToTypedReportModelSca
38
+ } = require('../../../scaAnalysis/common/utils/reportUtilsSca')
36
39
 
37
40
  const processSca = async config => {
38
41
  //checks to see whether to use old TS / new SCA path
@@ -133,12 +136,14 @@ const processSca = async config => {
133
136
  console.log('') //empty log for space before spinner
134
137
  const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
135
138
  startSpinner(reportSpinner)
136
- const [reports, reportId] = await scaUpload.scaTreeUpload(
139
+ const { reportArray, reportId } = await scaUpload.scaTreeUpload(
137
140
  messageToSend,
138
141
  config
139
142
  )
140
143
 
141
- auditReport.processAuditReport(config, reports[0])
144
+ const reportModelLibraryList =
145
+ convertGenericToTypedReportModelSca(reportArray)
146
+ auditReport.processAuditReport(config, reportModelLibraryList)
142
147
  succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
143
148
 
144
149
  if (config.save !== undefined) {
@@ -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 = '1.0.19'
17
+ const APP_VERSION = '1.0.20'
18
18
  const TIMEOUT = 120000
19
19
  const HIGH_COLOUR = '#ff9900'
20
20
  const CRITICAL_COLOUR = '#e35858'
@@ -194,7 +194,10 @@ const en_locales = () => {
194
194
  chalk.bold('\ncontrast scan') +
195
195
  " to run Contrast's industry leading SAST scanner. \nSupports Java, JavaScript and .Net \n" +
196
196
  chalk.bold('\ncontrast audit') +
197
- ' to find vulnerabilities in your open source dependencies.\nSupports Java, .NET, Node, Ruby, Python, Go and PHP \n' +
197
+ ' to find vulnerabilities in your open source dependencies.' +
198
+ '\nSupports Java, .NET, Node, Ruby, Python, Go and PHP.' +
199
+ '\nOur CLI runs native build tools to generate a complete dependency tree.' +
200
+ '\nIf you are running on untrusted code, consider running in a sandbox.\n' +
198
201
  chalk.bold('\ncontrast lambda') +
199
202
  ' to secure your AWS serverless functions. \nSupports Java and Python \n' +
200
203
  chalk.bold('\ncontrast help') +
@@ -259,7 +262,8 @@ const en_locales = () => {
259
262
  )} Maven build platform including the dependency plugin.
260
263
  ${chalk.bold('Or')} build.gradle ${chalk.bold(
261
264
  'and'
262
- )} gradle dependencies or ./gradlew dependencies must be supported`,
265
+ )} gradle dependencies or ./gradlew dependencies must be supported
266
+ If you are running on untrusted code, consider running in a sandbox.`,
263
267
  constantsAuditPrerequisitesContentDotNetMessage: `
264
268
  ${chalk.bold(
265
269
  '.NET framework and .NET core:'
@@ -1,105 +1,50 @@
1
1
  const {
2
2
  getSeverityCounts,
3
- createSummaryMessageTop,
4
- printVulnInfo,
5
- getReportTable,
6
- getIssueRow,
7
3
  printNoVulnFoundMsg
8
4
  } = require('../../audit/report/commonReportingFunctions')
9
- const { orderBy } = require('lodash')
10
- const { assignBySeverity } = require('../../scan/formatScanOutput')
11
- const chalk = require('chalk')
12
- const { CE_URL } = require('../../constants/constants')
13
5
  const common = require('../../common/fail')
14
- const i18n = require('i18n')
6
+ const { printFormattedOutputSca } = require('./commonReportingFunctionsSca')
15
7
 
16
- const processAuditReport = (config, results) => {
8
+ const processAuditReport = (config, reportModelList) => {
17
9
  let severityCounts = {}
18
- if (results !== undefined) {
19
- severityCounts = formatScaServicesReport(config, results)
10
+ if (reportModelList !== undefined) {
11
+ severityCounts = formatScaServicesReport(config, reportModelList)
20
12
  }
21
13
 
22
14
  if (config.fail) {
23
15
  common.processFail(config, severityCounts)
24
16
  }
25
17
  }
26
- const formatScaServicesReport = (config, results) => {
27
- const projectOverviewCount = getSeverityCounts(results)
18
+ const formatScaServicesReport = (config, reportModelList) => {
19
+ const projectOverviewCount = getSeverityCounts(reportModelList)
28
20
 
29
21
  if (projectOverviewCount.total === 0) {
30
22
  printNoVulnFoundMsg()
31
- return projectOverviewCount
32
23
  } else {
33
- let total = 0
34
- const numberOfCves = results.length
35
- const table = getReportTable()
36
- let contrastHeaderNumCounter = 0
37
- let assignPriorityToResults = results.map(result =>
38
- assignBySeverity(result, result)
39
- )
40
- const numberOfVulns = results
41
- .map(result => result.vulnerabilities)
42
- .reduce((a, b) => {
43
- return (total += b.length)
44
- }, 0)
45
- const outputOrderedByLowestSeverityAndLowestNumOfCvesFirst = orderBy(
46
- assignPriorityToResults,
47
- [
48
- reportListItem => {
49
- return reportListItem.priority
50
- },
51
- reportListItem => {
52
- return reportListItem.vulnerabilities.length
53
- }
54
- ],
55
- ['asc', 'desc']
56
- )
57
-
58
- for (const result of outputOrderedByLowestSeverityAndLowestNumOfCvesFirst) {
59
- contrastHeaderNumCounter++
60
- const cvesNum = result.vulnerabilities.length
61
- const grammaticallyCorrectVul =
62
- result.vulnerabilities.length > 1 ? 'vulnerabilities' : 'vulnerability'
63
-
64
- const headerColour = chalk.hex(result.colour)
65
- const headerRow = [
66
- headerColour(
67
- `CONTRAST-${contrastHeaderNumCounter.toString().padStart(3, '0')}`
68
- ),
69
- headerColour(`-`),
70
- headerColour(`[${result.severity}] `) +
71
- headerColour.bold(`${result.artifactName}`) +
72
- ` introduces ${cvesNum} ${grammaticallyCorrectVul}`
73
- ]
24
+ const numberOfVulnerableLibraries = reportModelList.map(library => {
25
+ let count = 0
74
26
 
75
- const adviceRow = [
76
- chalk.bold(`Advice`),
77
- chalk.bold(`:`),
78
- `Change to version ${result.remediationAdvice.latestStableVersion}`
79
- ]
27
+ if (library.vulnerabilities.length > 0) {
28
+ count++
29
+ }
80
30
 
81
- let assignPriorityToVulns = result.vulnerabilities.map(result =>
82
- assignBySeverity(result, result)
83
- )
84
- const issueRow = getIssueRow(assignPriorityToVulns)
31
+ return count
32
+ }).length
85
33
 
86
- table.push(headerRow, issueRow, adviceRow)
87
- console.log()
88
- }
89
-
90
- console.log()
91
- createSummaryMessageTop(numberOfCves, numberOfVulns)
92
- console.log(table.toString() + '\n')
93
- printVulnInfo(projectOverviewCount)
34
+ let numberOfCves = reportModelList.reduce(
35
+ (count, current) => count + current.vulnerabilities.length,
36
+ 0
37
+ )
94
38
 
95
- if (config.host !== CE_URL) {
96
- console.log('\n' + chalk.bold(i18n.__('auditServicesMessageForTS')))
97
- console.log(
98
- `${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/applications/${config.applicationId}/libs`
99
- )
100
- }
101
- return projectOverviewCount
39
+ printFormattedOutputSca(
40
+ config,
41
+ reportModelList,
42
+ numberOfVulnerableLibraries,
43
+ numberOfCves
44
+ )
102
45
  }
46
+
47
+ return projectOverviewCount
103
48
  }
104
49
  module.exports = {
105
50
  formatScaServicesReport,