@contrast/contrast 1.0.3 → 1.0.6

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 (107) hide show
  1. package/.prettierignore +4 -0
  2. package/README.md +20 -14
  3. package/dist/audit/autodetection/autoDetectLanguage.js +32 -0
  4. package/dist/audit/catalogueApplication/catalogueApplication.js +2 -11
  5. package/dist/audit/languageAnalysisEngine/{langugageAnalysisFactory.js → languageAnalysisFactory.js} +6 -14
  6. package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +29 -0
  7. package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +101 -234
  8. package/dist/audit/languageAnalysisEngine/report/models/reportLibraryModel.js +19 -0
  9. package/dist/audit/languageAnalysisEngine/report/models/reportListModel.js +24 -0
  10. package/dist/audit/languageAnalysisEngine/report/models/reportOutputModel.js +24 -0
  11. package/dist/audit/languageAnalysisEngine/report/models/reportSeverityModel.js +12 -0
  12. package/dist/audit/languageAnalysisEngine/report/models/severityCountModel.js +13 -0
  13. package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +24 -129
  14. package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +99 -0
  15. package/dist/audit/languageAnalysisEngine/sendSnapshot.js +2 -14
  16. package/dist/commands/audit/auditConfig.js +8 -2
  17. package/dist/commands/audit/auditController.js +14 -5
  18. package/dist/commands/scan/processScan.js +10 -6
  19. package/dist/commands/scan/sca/scaAnalysis.js +49 -0
  20. package/dist/common/HTTPClient.js +18 -26
  21. package/dist/common/errorHandling.js +7 -17
  22. package/dist/common/versionChecker.js +14 -12
  23. package/dist/constants/constants.js +24 -2
  24. package/dist/constants/lambda.js +3 -1
  25. package/dist/constants/locales.js +42 -42
  26. package/dist/constants.js +25 -1
  27. package/dist/index.js +2 -2
  28. package/dist/lambda/help.js +22 -14
  29. package/dist/lambda/lambda.js +6 -0
  30. package/dist/scaAnalysis/common/formatMessage.js +19 -0
  31. package/dist/scaAnalysis/common/treeUpload.js +29 -0
  32. package/dist/scaAnalysis/go/goAnalysis.js +17 -0
  33. package/dist/scaAnalysis/go/goParseDeps.js +158 -0
  34. package/dist/scaAnalysis/go/goReadDepFile.js +23 -0
  35. package/dist/scaAnalysis/java/analysis.js +108 -0
  36. package/dist/scaAnalysis/java/index.js +18 -0
  37. package/dist/scaAnalysis/java/javaBuildDepsParser.js +339 -0
  38. package/dist/scan/autoDetection.js +46 -1
  39. package/dist/scan/fileUtils.js +73 -1
  40. package/dist/scan/formatScanOutput.js +215 -0
  41. package/dist/scan/help.js +3 -1
  42. package/dist/scan/models/groupedResultsModel.js +11 -0
  43. package/dist/scan/models/resultContentModel.js +2 -0
  44. package/dist/scan/models/scanResultsModel.js +11 -0
  45. package/dist/scan/scan.js +27 -126
  46. package/dist/scan/scanConfig.js +1 -1
  47. package/dist/scan/scanController.js +11 -5
  48. package/dist/scan/scanResults.js +15 -19
  49. package/dist/utils/getConfig.js +3 -0
  50. package/dist/utils/oraWrapper.js +5 -1
  51. package/package.json +3 -2
  52. package/src/audit/autodetection/autoDetectLanguage.ts +40 -0
  53. package/src/audit/catalogueApplication/catalogueApplication.js +4 -16
  54. package/src/audit/languageAnalysisEngine/{langugageAnalysisFactory.js → languageAnalysisFactory.js} +11 -21
  55. package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +72 -0
  56. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +204 -0
  57. package/src/audit/languageAnalysisEngine/report/models/reportLibraryModel.ts +30 -0
  58. package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +32 -0
  59. package/src/audit/languageAnalysisEngine/report/models/reportOutputModel.ts +29 -0
  60. package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +13 -0
  61. package/src/audit/languageAnalysisEngine/report/models/severityCountModel.ts +16 -0
  62. package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +56 -0
  63. package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +116 -0
  64. package/src/audit/languageAnalysisEngine/sendSnapshot.js +2 -22
  65. package/src/commands/audit/auditConfig.ts +12 -3
  66. package/src/commands/audit/auditController.ts +20 -5
  67. package/src/commands/audit/processAudit.ts +3 -0
  68. package/src/commands/scan/processScan.js +13 -9
  69. package/src/commands/scan/sca/scaAnalysis.js +75 -0
  70. package/src/common/HTTPClient.js +31 -38
  71. package/src/common/errorHandling.ts +7 -25
  72. package/src/common/versionChecker.ts +24 -22
  73. package/src/constants/constants.js +24 -2
  74. package/src/constants/lambda.js +3 -1
  75. package/src/constants/locales.js +47 -56
  76. package/src/constants.js +29 -1
  77. package/src/index.ts +2 -3
  78. package/src/lambda/help.ts +22 -14
  79. package/src/lambda/lambda.ts +8 -0
  80. package/src/scaAnalysis/common/formatMessage.js +20 -0
  81. package/src/scaAnalysis/common/treeUpload.js +30 -0
  82. package/src/scaAnalysis/go/goAnalysis.js +20 -0
  83. package/src/scaAnalysis/go/goParseDeps.js +203 -0
  84. package/src/scaAnalysis/go/goReadDepFile.js +32 -0
  85. package/src/scaAnalysis/java/analysis.js +143 -0
  86. package/src/scaAnalysis/java/index.js +21 -0
  87. package/src/scaAnalysis/java/javaBuildDepsParser.js +404 -0
  88. package/src/scan/autoDetection.js +54 -1
  89. package/src/scan/fileUtils.js +91 -1
  90. package/src/scan/formatScanOutput.ts +250 -0
  91. package/src/scan/help.js +3 -1
  92. package/src/scan/models/groupedResultsModel.ts +20 -0
  93. package/src/scan/models/resultContentModel.ts +86 -0
  94. package/src/scan/models/scanResultsModel.ts +52 -0
  95. package/src/scan/scan.ts +63 -0
  96. package/src/scan/scanConfig.js +1 -1
  97. package/src/scan/scanController.js +15 -7
  98. package/src/scan/scanResults.js +21 -18
  99. package/src/utils/getConfig.ts +10 -0
  100. package/src/utils/oraWrapper.js +6 -1
  101. package/dist/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +0 -17
  102. package/dist/audit/languageAnalysisEngine/report/newReportingFeature.js +0 -81
  103. package/src/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +0 -27
  104. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.js +0 -303
  105. package/src/audit/languageAnalysisEngine/report/newReportingFeature.js +0 -124
  106. package/src/audit/languageAnalysisEngine/report/reportingFeature.js +0 -190
  107. package/src/scan/scan.js +0 -195
@@ -0,0 +1,250 @@
1
+ import {
2
+ ProjectOverview,
3
+ ScanResultsInstances,
4
+ ScanResultsModel
5
+ } from './models/scanResultsModel'
6
+ import i18n from 'i18n'
7
+ import chalk from 'chalk'
8
+ import { ResultContent } from './models/resultContentModel'
9
+ import { GroupedResultsModel } from './models/groupedResultsModel'
10
+ import { sortBy } from 'lodash'
11
+ import Table from 'cli-table3'
12
+ import {
13
+ CRITICAL_COLOUR,
14
+ HIGH_COLOUR,
15
+ LOW_COLOUR,
16
+ MEDIUM_COLOUR,
17
+ NOTE_COLOUR
18
+ } from '../constants/constants'
19
+
20
+ export function formatScanOutput(scanResults: ScanResultsModel) {
21
+ const { scanResultsInstances } = scanResults
22
+
23
+ let projectOverview = getProjectOverview(scanResultsInstances)
24
+ if (scanResultsInstances.content.length === 0) {
25
+ console.log(i18n.__('scanNoVulnerabilitiesFound'))
26
+ console.log(i18n.__('scanNoVulnerabilitiesFoundSecureCode'))
27
+ console.log(i18n.__('scanNoVulnerabilitiesFoundGoodWork'))
28
+ } else {
29
+ const message =
30
+ projectOverview.critical || projectOverview.high
31
+ ? 'Here are your top priorities to fix'
32
+ : "No major issues, here's what we found"
33
+ console.log(chalk.bold(message))
34
+ console.log()
35
+
36
+ let defaultView = getDefaultView(scanResultsInstances.content)
37
+
38
+ let count = defaultView.length
39
+ defaultView.forEach(entry => {
40
+ let table = new Table({
41
+ chars: {
42
+ top: '',
43
+ 'top-mid': '',
44
+ 'top-left': '',
45
+ 'top-right': '',
46
+ bottom: '',
47
+ 'bottom-mid': '',
48
+ 'bottom-left': '',
49
+ 'bottom-right': '',
50
+ left: '',
51
+ 'left-mid': '',
52
+ mid: '',
53
+ 'mid-mid': '',
54
+ right: '',
55
+ 'right-mid': '',
56
+ middle: ' '
57
+ },
58
+ style: { 'padding-left': 0, 'padding-right': 0 },
59
+ colAligns: ['right'],
60
+ wordWrap: true,
61
+ colWidths: [12, 1, 100]
62
+ })
63
+ let learnRow: string[] = []
64
+ let adviceRow = []
65
+ let headerRow = [
66
+ chalk
67
+ .hex(entry.colour)
68
+ .bold(`CONTRAST-${count.toString().padStart(3, '0')}`),
69
+ chalk.hex(entry.colour).bold('-'),
70
+ chalk.hex(entry.colour).bold(`[${entry.severity}] ${entry.ruleId}`) +
71
+ entry.message
72
+ ]
73
+ let codeRow = [
74
+ chalk.hex('#F6F5F5').bold(`Code`),
75
+ chalk.hex('#F6F5F5').bold(`:`),
76
+ chalk.hex('#F6F5F5').bold(`${entry.codePath}`)
77
+ ]
78
+ let issueRow = [chalk.bold(`Issue`), chalk.bold(`:`), `${entry.issue}`]
79
+
80
+ table.push(headerRow, codeRow, issueRow)
81
+
82
+ if (entry?.advice) {
83
+ adviceRow = [
84
+ chalk.bold('Advice'),
85
+ chalk.bold(`:`),
86
+ stripTags(entry.advice)
87
+ ]
88
+ table.push(adviceRow)
89
+ }
90
+
91
+ if (entry?.learn && entry?.learn.length > 0) {
92
+ learnRow = [
93
+ chalk.bold('Learn'),
94
+ chalk.bold(`:`),
95
+ chalk.hex('#97f7f7').bold.underline(entry.learn[0])
96
+ ]
97
+ table.push(learnRow)
98
+ }
99
+ count--
100
+ console.log(table.toString())
101
+ console.log()
102
+ })
103
+ }
104
+ printVulnInfo(projectOverview)
105
+ }
106
+
107
+ function printVulnInfo(projectOverview: any) {
108
+ const totalVulnerabilities = projectOverview.total
109
+
110
+ const vulMessage =
111
+ totalVulnerabilities === 1 ? `vulnerability` : `vulnerabilities`
112
+ console.log(chalk.bold(`Found ${totalVulnerabilities} ${vulMessage}`))
113
+ console.log(
114
+ i18n.__(
115
+ 'foundDetailedVulnerabilities',
116
+ String(projectOverview.critical),
117
+ String(projectOverview.high),
118
+ String(projectOverview.medium),
119
+ String(projectOverview.low),
120
+ String(projectOverview.note)
121
+ )
122
+ )
123
+ }
124
+
125
+ export function getProjectOverview(scanResultsInstances: ScanResultsInstances) {
126
+ let acc: any = {
127
+ critical: 0,
128
+ high: 0,
129
+ medium: 0,
130
+ low: 0,
131
+ note: 0,
132
+ total: 0
133
+ }
134
+ if (
135
+ scanResultsInstances?.content &&
136
+ scanResultsInstances.content.length > 0
137
+ ) {
138
+ scanResultsInstances.content.forEach((i: ResultContent) => {
139
+ acc[i.severity.toLowerCase()] += 1
140
+ acc.total += 1
141
+ return acc
142
+ })
143
+ }
144
+
145
+ return acc
146
+ }
147
+
148
+ export function formatLinks(objName: string, entry: any[]) {
149
+ let line = chalk.bold(objName + ' : ')
150
+ if (entry.length === 1) {
151
+ console.log(line + chalk.hex('#97DCF7').bold.underline(entry[0]))
152
+ } else {
153
+ console.log(line)
154
+ entry.forEach(link => {
155
+ console.log(chalk.hex('#97DCF7').bold.underline(link))
156
+ })
157
+ }
158
+ }
159
+
160
+ export function getDefaultView(content: ResultContent[]) {
161
+ const groupTypeResults = [] as GroupedResultsModel[]
162
+
163
+ content.forEach(resultEntry => {
164
+ const groupResultsObj = new GroupedResultsModel(resultEntry.ruleId)
165
+ groupResultsObj.severity = resultEntry.severity
166
+ groupResultsObj.ruleId = resultEntry.ruleId
167
+ groupResultsObj.issue = stripTags(resultEntry.issue)
168
+ groupResultsObj.advice = resultEntry.advice
169
+ groupResultsObj.learn = resultEntry.learn
170
+ groupResultsObj.message = resultEntry.message?.text
171
+ ? editVulName(resultEntry.message.text) +
172
+ ':' +
173
+ getSourceLineNumber(resultEntry)
174
+ : ''
175
+ groupResultsObj.codePath = getLocationsSyncInfo(resultEntry)
176
+ groupTypeResults.push(groupResultsObj)
177
+ assignBySeverity(resultEntry, groupResultsObj)
178
+ })
179
+
180
+ return sortBy(groupTypeResults, ['priority']).reverse()
181
+ }
182
+ export function editVulName(message: string) {
183
+ return message.substring(message.indexOf(' in '))
184
+ }
185
+ export function getLocationsSyncInfo(resultEntry: ResultContent) {
186
+ const locationsMessage =
187
+ resultEntry.locations[0]?.physicalLocation?.artifactLocation?.uri || ''
188
+ const locationsLineNumber =
189
+ resultEntry.locations[0]?.physicalLocation?.region?.startLine || ''
190
+
191
+ if (!locationsLineNumber) {
192
+ return '@' + locationsMessage
193
+ }
194
+
195
+ return '@' + locationsMessage + ':' + locationsLineNumber
196
+ }
197
+
198
+ export function getSourceLineNumber(resultEntry: ResultContent) {
199
+ const locationsLineNumber =
200
+ resultEntry.locations[0]?.physicalLocation?.region?.startLine || ''
201
+ let codeFlowLineNumber = getCodeFlowInfo(resultEntry)
202
+
203
+ return codeFlowLineNumber ? codeFlowLineNumber : locationsLineNumber
204
+ }
205
+
206
+ export function getCodeFlowInfo(resultEntry: ResultContent) {
207
+ let result: any
208
+ resultEntry.codeFlows[0]?.threadFlows.forEach((i: { locations: any[] }) => {
209
+ return (result = i.locations.find(
210
+ (locations: { importance: string }) =>
211
+ locations.importance === 'essential'
212
+ ))
213
+ })
214
+
215
+ return result?.location?.physicalLocation?.region?.startLine
216
+ }
217
+
218
+ export function stripTags(oldString: string) {
219
+ return oldString
220
+ .replace(/\n/g, ' ')
221
+ .replace(/\s+/g, ' ')
222
+ .trim()
223
+ }
224
+
225
+ export function assignBySeverity(
226
+ entry: ResultContent,
227
+ assignedObj: GroupedResultsModel
228
+ ) {
229
+ if (entry.severity.toUpperCase() === 'CRITICAL') {
230
+ assignedObj.priority = 1
231
+ assignedObj.colour = CRITICAL_COLOUR
232
+ return assignedObj
233
+ } else if (entry.severity.toUpperCase() === 'HIGH') {
234
+ assignedObj.priority = 2
235
+ assignedObj.colour = HIGH_COLOUR
236
+ return assignedObj
237
+ } else if (entry.severity.toUpperCase() === 'MEDIUM') {
238
+ assignedObj.priority = 3
239
+ assignedObj.colour = MEDIUM_COLOUR
240
+ return assignedObj
241
+ } else if (entry.severity.toUpperCase() === 'LOW') {
242
+ assignedObj.priority = 4
243
+ assignedObj.colour = LOW_COLOUR
244
+ return assignedObj
245
+ } else if (entry.severity.toUpperCase() === 'NOTE') {
246
+ assignedObj.priority = 5
247
+ assignedObj.colour = NOTE_COLOUR
248
+ return assignedObj
249
+ }
250
+ }
package/src/scan/help.js CHANGED
@@ -30,7 +30,9 @@ const scanUsageGuide = commandLineUsage([
30
30
  'ff',
31
31
  'ignore-cert-errors',
32
32
  'verbose',
33
- 'debug'
33
+ 'debug',
34
+ 'experimental',
35
+ 'application-name'
34
36
  ]
35
37
  },
36
38
  {
@@ -0,0 +1,20 @@
1
+ export class GroupedResultsModel {
2
+ ruleId: string
3
+ codePathSet: Set<string>
4
+ cwe?: string[]
5
+ reference?: string[]
6
+ severity?: string
7
+ advice?: string
8
+ learn?: string[]
9
+ issue?: string
10
+ priority?: number
11
+ message?: string | undefined
12
+ colour: string;
13
+ codePath?: string;
14
+
15
+ constructor(ruleId: string) {
16
+ this.ruleId = ruleId
17
+ this.colour = '#999999'
18
+ this.codePathSet = new Set<string>
19
+ }
20
+ }
@@ -0,0 +1,86 @@
1
+ type Importance = 'important' | 'essential'
2
+
3
+ interface ArtifactLocation {
4
+ uri: string
5
+ }
6
+
7
+ interface Region {
8
+ startLine: string
9
+ snippet: Snippet
10
+ }
11
+
12
+ interface Snippet {
13
+ text: string
14
+ rendered: Rendered
15
+ }
16
+
17
+ interface Rendered {
18
+ text: string
19
+ }
20
+
21
+ interface PhysicalLocation {
22
+ artifactLocation: ArtifactLocation
23
+ region: Region
24
+ }
25
+
26
+ interface LogicalLocation {
27
+ fullyQualifiedName: string
28
+ name: string
29
+ }
30
+
31
+ export interface Location {
32
+ physicalLocation: PhysicalLocation
33
+ logicalLocations?: LogicalLocation[]
34
+ }
35
+
36
+ export interface ThreadFlowLocation {
37
+ importance: Importance
38
+ location: Location
39
+ }
40
+
41
+ interface ThreadFlow {
42
+ locations: ThreadFlowLocation[]
43
+ }
44
+
45
+ interface Message {
46
+ text: string
47
+ }
48
+
49
+ export interface CodeFlow {
50
+ message: Message
51
+ threadFlows: ThreadFlow[]
52
+ }
53
+
54
+ export interface ResultContent {
55
+ message?: {text :string};
56
+ id: string
57
+ organizationId: string
58
+ projectId: string
59
+ firstCreatedTime: string
60
+ ruleId: string
61
+ codeFlows: CodeFlow[]
62
+ lastSeenTime: string
63
+ locations: Location[]
64
+ name: string
65
+ description: string
66
+ recommendation: string | null
67
+ risk: string | null
68
+ category: string
69
+ confidence: string
70
+ standards: { [key: string]: string[] }
71
+ cwe: string[]
72
+ owasp: string[]
73
+ reference: string[]
74
+ sink: string
75
+ detailsTrigger: string
76
+ type: RuleType
77
+ source: string
78
+ severity: Severity
79
+ advice: string
80
+ learn: string[]
81
+ issue: string
82
+ }
83
+
84
+ export type Severity = 'critical' | 'high' | 'medium' | 'low' | 'note'
85
+
86
+ export type RuleType = 'DATA_FLOW' | 'CRYPTO' | 'CONFIG' | 'DEFAULT'
@@ -0,0 +1,52 @@
1
+ import { ResultContent } from './resultContentModel'
2
+
3
+ export class ScanResultsModel {
4
+ projectOverview: ProjectOverview
5
+ scanDetail: ScanDetail
6
+ scanResultsInstances: ScanResultsInstances
7
+
8
+ constructor(scan: any) {
9
+ this.projectOverview = scan.projectOverview as ProjectOverview
10
+ this.scanDetail = scan.scanDetail as ScanDetail
11
+ this.scanResultsInstances = scan.scanResultsInstances as ScanResultsInstances
12
+ }
13
+ }
14
+
15
+ export interface ProjectOverview {
16
+ id: string
17
+ organizationId: string
18
+ name: string
19
+ archived: boolean
20
+ language: string
21
+ critical: number
22
+ high: number
23
+ medium: number
24
+ low: number
25
+ note: number
26
+ lastScanTime: string
27
+ completedScans: number
28
+ lastScanId: string
29
+ }
30
+
31
+ export interface ScanDetail {
32
+ critical: number
33
+ high: number
34
+ medium: number
35
+ low: number
36
+ note: number
37
+ id: string
38
+ organizationId: string
39
+ projectId: string
40
+ codeArtifactId: string
41
+ status: string
42
+ createdTime: string
43
+ startedTime: string
44
+ completedTime: string
45
+ language: string
46
+ label: string
47
+ errorMessage: string
48
+ }
49
+
50
+ export interface ScanResultsInstances {
51
+ content: ResultContent[]
52
+ }
@@ -0,0 +1,63 @@
1
+ import commonApi from '../utils/commonApi.js'
2
+ import fileUtils from '../scan/fileUtils'
3
+ import i18n from 'i18n'
4
+ import oraWrapper from '../utils/oraWrapper'
5
+
6
+ export const allowedFileTypes = ['.jar', '.war', '.js', '.zip', '.exe']
7
+
8
+ export const isFileAllowed = (scanOption: string) => {
9
+ let valid = false
10
+ allowedFileTypes.forEach(fileType => {
11
+ if (scanOption.endsWith(fileType)) {
12
+ valid = true
13
+ }
14
+ })
15
+ return valid
16
+ }
17
+
18
+ export const sendScan = async (config: any) => {
19
+ if (!isFileAllowed(config.file)) {
20
+ console.log(i18n.__('scanErrorFileMessage'))
21
+ process.exit(9)
22
+ } else {
23
+ fileUtils.checkFilePermissions(config.file)
24
+ const client = commonApi.getHttpClient(config)
25
+
26
+ const startUploadSpinner = oraWrapper.returnOra(i18n.__('uploadingScan'))
27
+ oraWrapper.startSpinner(startUploadSpinner)
28
+
29
+ return await client
30
+ .sendArtifact(config)
31
+ .then(res => {
32
+ if (res.statusCode === 201) {
33
+ oraWrapper.succeedSpinner(
34
+ startUploadSpinner,
35
+ i18n.__('uploadingScanSuccessful')
36
+ )
37
+ if (config.verbose) {
38
+ console.log(i18n.__('responseMessage', res.body))
39
+ }
40
+ return res.body.id
41
+ } else {
42
+ if (config.debug) {
43
+ console.log(config)
44
+ oraWrapper.failSpinner(
45
+ startUploadSpinner,
46
+ i18n.__('uploadingScanFail')
47
+ )
48
+ console.log(i18n.__('genericServiceError', res.statusCode))
49
+ }
50
+ if (res.statusCode === 403) {
51
+ console.log(i18n.__('permissionsError'))
52
+ process.exit(1)
53
+ }
54
+ oraWrapper.stopSpinner(startUploadSpinner)
55
+ console.log('Contrast Scan Finished')
56
+ process.exit(1)
57
+ }
58
+ })
59
+ .catch(err => {
60
+ console.log(err)
61
+ })
62
+ }
63
+ }
@@ -26,7 +26,7 @@ const getScanConfig = argv => {
26
26
  if (!Object.values(supportedLanguages).includes(scanParams.language)) {
27
27
  console.log(`Did not recognise --language ${scanParams.language}`)
28
28
  console.log(i18n.__('constantsHowToRunDev3'))
29
- process.exit(0)
29
+ process.exit(1)
30
30
  }
31
31
  }
32
32
 
@@ -2,7 +2,8 @@ const i18n = require('i18n')
2
2
  const {
3
3
  returnOra,
4
4
  startSpinner,
5
- succeedSpinner
5
+ succeedSpinner,
6
+ stopSpinner
6
7
  } = require('../utils/oraWrapper')
7
8
  const populateProjectIdAndProjectName = require('./populateProjectIdAndProjectName')
8
9
  const scan = require('./scan')
@@ -56,18 +57,25 @@ const startScan = async configToUse => {
56
57
  getTimeout(configToUse),
57
58
  startScanSpinner
58
59
  )
60
+
59
61
  const scanResultsInstances = await scanResults.returnScanResultsInstances(
60
62
  configToUse,
61
63
  scanDetail.id
62
64
  )
65
+
63
66
  const endTime = performance.now()
64
67
  const scanDurationMs = endTime - startTime
65
- succeedSpinner(startScanSpinner, 'Contrast Scan complete')
66
- console.log(
67
- `----- Scan completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
68
- )
69
- const projectOverview = await scanResults.returnScanProjectById(configToUse)
70
- return { projectOverview, scanDetail, scanResultsInstances }
68
+ if (scanResultsInstances.statusCode !== 200) {
69
+ stopSpinner(startScanSpinner)
70
+ console.log('Result Service is unavailable, please try again later')
71
+ process.exit(1)
72
+ } else {
73
+ succeedSpinner(startScanSpinner, 'Contrast Scan complete')
74
+ console.log(
75
+ `----- Scan completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
76
+ )
77
+ return { scanDetail, scanResultsInstances: scanResultsInstances.body }
78
+ }
71
79
  }
72
80
  }
73
81
 
@@ -3,6 +3,7 @@ const requestUtils = require('../../src/utils/requestUtils')
3
3
  const oraFunctions = require('../utils/oraWrapper')
4
4
  const _ = require('lodash')
5
5
  const i18n = require('i18n')
6
+ const oraWrapper = require('../utils/oraWrapper')
6
7
 
7
8
  const getScanId = async (config, codeArtifactId, client) => {
8
9
  return client
@@ -47,17 +48,27 @@ const returnScanResults = async (
47
48
  }
48
49
  if (result.body.status === 'FAILED') {
49
50
  complete = true
50
- oraFunctions.failSpinner(startScanSpinner, 'Contrast Scan Failed.')
51
- console.log(result.body.errorMessage)
51
+ if (config.debug) {
52
+ oraFunctions.failSpinner(
53
+ startScanSpinner,
54
+ i18n.__(
55
+ 'scanNotCompleted',
56
+ 'https://docs.contrastsecurity.com/en/binary-package-preparation.html'
57
+ )
58
+ )
59
+ }
52
60
  if (
53
- result.body.errorMessage ===
61
+ result?.body?.errorMessage ===
54
62
  'Unable to determine language for code artifact'
55
63
  ) {
64
+ console.log(result.body.errorMessage)
56
65
  console.log(
57
66
  'Try scanning again using --language param. ',
58
67
  i18n.__('scanOptionsLanguageSummary')
59
68
  )
60
69
  }
70
+ oraWrapper.stopSpinner(startScanSpinner)
71
+ console.log('Contrast Scan Finished')
61
72
  process.exit(1)
62
73
  }
63
74
  }
@@ -80,23 +91,16 @@ const returnScanResultsInstances = async (config, scanId) => {
80
91
  try {
81
92
  result = await client.getScanResultsInstances(config, scanId)
82
93
  if (JSON.stringify(result.statusCode) == 200) {
83
- return result.body
94
+ return { body: result.body, statusCode: result.statusCode }
84
95
  }
85
- } catch (e) {
86
- console.log(e.message.toString())
87
- }
88
- }
89
96
 
90
- const returnScanProjectById = async config => {
91
- const client = commonApi.getHttpClient(config)
92
- let result
93
- try {
94
- result = await client.getScanProjectById(config)
95
- if (JSON.stringify(result.statusCode) == 200) {
96
- return result.body
97
+ if (JSON.stringify(result.statusCode) == 503) {
98
+ return { statusCode: result.statusCode }
97
99
  }
98
100
  } catch (e) {
99
- console.log(e.message.toString())
101
+ if (config.debug) {
102
+ console.log(e.message.toString())
103
+ }
100
104
  }
101
105
  }
102
106
 
@@ -104,6 +108,5 @@ module.exports = {
104
108
  getScanId: getScanId,
105
109
  returnScanResults: returnScanResults,
106
110
  pollScanResults: pollScanResults,
107
- returnScanResultsInstances: returnScanResultsInstances,
108
- returnScanProjectById: returnScanProjectById
111
+ returnScanResultsInstances: returnScanResultsInstances
109
112
  }
@@ -7,6 +7,7 @@ type ContrastConfOptions = Partial<{
7
7
  orgId: string
8
8
  authHeader: string
9
9
  numOfRuns: number
10
+ updateMessageHidden: boolean
10
11
  }>
11
12
 
12
13
  type ContrastConf = Conf<ContrastConfOptions>
@@ -17,6 +18,15 @@ const localConfig = (name: string, version: string) => {
17
18
  })
18
19
  config.set('version', version)
19
20
 
21
+ if (process.env.CONTRAST_CODSEC_DISABLE_UPDATE_MESSAGE) {
22
+ config.set(
23
+ 'updateMessageHidden',
24
+ JSON.parse(
25
+ process.env.CONTRAST_CODSEC_DISABLE_UPDATE_MESSAGE.toLowerCase()
26
+ )
27
+ )
28
+ }
29
+
20
30
  if (!config.has('host')) {
21
31
  config.set('host', 'https://ce.contrastsecurity.com/')
22
32
  }
@@ -8,6 +8,10 @@ const startSpinner = spinner => {
8
8
  spinner.start()
9
9
  }
10
10
 
11
+ const stopSpinner = spinner => {
12
+ spinner.stop()
13
+ }
14
+
11
15
  const succeedSpinner = (spinner, text) => {
12
16
  spinner.succeed(text)
13
17
  }
@@ -20,5 +24,6 @@ module.exports = {
20
24
  returnOra,
21
25
  startSpinner,
22
26
  succeedSpinner,
23
- failSpinner
27
+ failSpinner,
28
+ stopSpinner
24
29
  }
@@ -1,17 +0,0 @@
1
- "use strict";
2
- const { getGlobalProperties, getFeatures, isFeatureEnabled } = require('../util/generalAPI');
3
- const { CLI_IGNORE_DEV_DEPS } = require('../util/capabilities');
4
- const checkDevDeps = async (config) => {
5
- const shouldIgnoreDev = config.ignoreDev;
6
- const globalProperties = await getGlobalProperties();
7
- const features = getFeatures(globalProperties.internal_version);
8
- const isfeatureEnabled = isFeatureEnabled(features, CLI_IGNORE_DEV_DEPS);
9
- let ignoreDevUrl = false;
10
- if (shouldIgnoreDev) {
11
- ignoreDevUrl = isfeatureEnabled;
12
- }
13
- return ignoreDevUrl;
14
- };
15
- module.exports = {
16
- checkDevDeps
17
- };