@contrast/contrast 1.0.14 → 1.0.16

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 (59) hide show
  1. package/dist/audit/languageAnalysisEngine/sendSnapshot.js +2 -2
  2. package/dist/audit/report/commonReportingFunctions.js +1 -19
  3. package/dist/audit/save.js +7 -2
  4. package/dist/{constants.js → cliConstants.js} +70 -31
  5. package/dist/commands/audit/auditConfig.js +2 -2
  6. package/dist/commands/audit/help.js +5 -3
  7. package/dist/commands/auth/auth.js +1 -1
  8. package/dist/commands/config/config.js +1 -1
  9. package/dist/commands/scan/processScan.js +0 -6
  10. package/dist/commands/scan/sca/scaAnalysis.js +64 -33
  11. package/dist/common/HTTPClient.js +25 -4
  12. package/dist/constants/constants.js +10 -2
  13. package/dist/constants/locales.js +7 -30
  14. package/dist/index.js +5 -5
  15. package/dist/sbom/generateSbom.js +18 -1
  16. package/dist/scaAnalysis/common/auditReport.js +3 -2
  17. package/dist/scaAnalysis/common/scaParserForGoAndJava.js +1 -1
  18. package/dist/scaAnalysis/common/scaServicesUpload.js +14 -7
  19. package/dist/scaAnalysis/javascript/scaServiceParser.js +2 -2
  20. package/dist/scaAnalysis/php/phpNewServicesMapper.js +3 -3
  21. package/dist/scaAnalysis/python/analysis.js +1 -1
  22. package/dist/scaAnalysis/repoMode/gradleParser.js +75 -0
  23. package/dist/scaAnalysis/repoMode/index.js +21 -0
  24. package/dist/scaAnalysis/repoMode/mavenParser.js +76 -0
  25. package/dist/scaAnalysis/ruby/analysis.js +4 -4
  26. package/dist/scan/help.js +1 -1
  27. package/dist/scan/scanConfig.js +1 -1
  28. package/dist/utils/commonApi.js +1 -0
  29. package/dist/utils/settingsHelper.js +24 -0
  30. package/package.json +2 -1
  31. package/src/audit/languageAnalysisEngine/sendSnapshot.js +2 -6
  32. package/src/audit/report/commonReportingFunctions.js +1 -23
  33. package/src/audit/save.js +14 -6
  34. package/src/{constants.js → cliConstants.js} +79 -35
  35. package/src/commands/audit/auditConfig.ts +1 -1
  36. package/src/commands/audit/help.ts +4 -2
  37. package/src/commands/auth/auth.js +1 -1
  38. package/src/commands/config/config.js +1 -1
  39. package/src/commands/scan/processScan.js +0 -8
  40. package/src/commands/scan/sca/scaAnalysis.js +85 -54
  41. package/src/common/HTTPClient.js +29 -4
  42. package/src/constants/constants.js +12 -2
  43. package/src/constants/locales.js +9 -44
  44. package/src/index.ts +1 -1
  45. package/src/sbom/generateSbom.ts +20 -0
  46. package/src/scaAnalysis/common/auditReport.js +3 -4
  47. package/src/scaAnalysis/common/scaParserForGoAndJava.js +1 -1
  48. package/src/scaAnalysis/common/scaServicesUpload.js +15 -7
  49. package/src/scaAnalysis/javascript/scaServiceParser.js +8 -2
  50. package/src/scaAnalysis/php/phpNewServicesMapper.js +3 -3
  51. package/src/scaAnalysis/python/analysis.js +1 -1
  52. package/src/scaAnalysis/repoMode/gradleParser.js +88 -0
  53. package/src/scaAnalysis/repoMode/index.js +21 -0
  54. package/src/scaAnalysis/repoMode/mavenParser.js +89 -0
  55. package/src/scaAnalysis/ruby/analysis.js +4 -4
  56. package/src/scan/help.js +1 -1
  57. package/src/scan/scanConfig.js +1 -1
  58. package/src/utils/commonApi.js +1 -0
  59. package/src/utils/settingsHelper.js +26 -0
@@ -11,8 +11,53 @@ i18n.configure({
11
11
  defaultLocale: 'en'
12
12
  })
13
13
 
14
+ const sharedOptionDefinitions = [
15
+ {
16
+ name: 'proxy',
17
+ description:
18
+ '{bold ' +
19
+ i18n.__('constantsOptional') +
20
+ '}: ' +
21
+ i18n.__('constantsProxyServer')
22
+ },
23
+ {
24
+ name: 'key',
25
+ description:
26
+ '{bold ' +
27
+ i18n.__('constantsOptional') +
28
+ '}: ' +
29
+ i18n.__('constantsProxyKey')
30
+ },
31
+ {
32
+ name: 'cacert',
33
+ description:
34
+ '{bold ' +
35
+ i18n.__('constantsOptional') +
36
+ '}: ' +
37
+ i18n.__('constantsProxyCaCert')
38
+ },
39
+ {
40
+ name: 'cert',
41
+ description:
42
+ '{bold ' +
43
+ i18n.__('constantsOptional') +
44
+ '}: ' +
45
+ i18n.__('constantsProxyCert')
46
+ },
47
+ {
48
+ name: 'ignore-cert-errors',
49
+ type: Boolean,
50
+ description:
51
+ '{bold ' +
52
+ i18n.__('constantsOptional') +
53
+ '}:' +
54
+ i18n.__('constantsIgnoreCertErrors')
55
+ }
56
+ ]
57
+
14
58
  // CLI options that we will allow and handle
15
59
  const scanOptionDefinitions = [
60
+ ...sharedOptionDefinitions,
16
61
  {
17
62
  name: 'name',
18
63
  alias: 'n',
@@ -100,14 +145,6 @@ const scanOptionDefinitions = [
100
145
  '}: ' +
101
146
  i18n.__('constantsHostId')
102
147
  },
103
- {
104
- name: 'proxy',
105
- description:
106
- '{bold ' +
107
- i18n.__('constantsOptional') +
108
- '}: ' +
109
- i18n.__('constantsProxyServer')
110
- },
111
148
  {
112
149
  name: 'fail',
113
150
  type: Boolean,
@@ -133,16 +170,7 @@ const scanOptionDefinitions = [
133
170
  '{bold ' +
134
171
  i18n.__('constantsOptional') +
135
172
  '}: ' +
136
- i18n.__('constantsProxyServer')
137
- },
138
- {
139
- name: 'ignore-cert-errors',
140
- type: Boolean,
141
- description:
142
- '{bold ' +
143
- i18n.__('constantsOptional') +
144
- '}:' +
145
- i18n.__('constantsIgnoreCertErrors')
173
+ i18n.__('constantsDoNotWaitForScan')
146
174
  },
147
175
  {
148
176
  name: 'verbose',
@@ -214,6 +242,7 @@ const configOptionDefinitions = [
214
242
  ]
215
243
 
216
244
  const auditOptionDefinitions = [
245
+ ...sharedOptionDefinitions,
217
246
  {
218
247
  name: 'application-id',
219
248
  description:
@@ -338,23 +367,6 @@ const auditOptionDefinitions = [
338
367
  '}: ' +
339
368
  i18n.__('constantsHostId')
340
369
  },
341
- {
342
- name: 'proxy',
343
- description:
344
- '{bold ' +
345
- i18n.__('constantsOptional') +
346
- '}: ' +
347
- i18n.__('constantsProxyServer')
348
- },
349
- {
350
- name: 'ignore-cert-errors',
351
- type: Boolean,
352
- description:
353
- '{bold ' +
354
- i18n.__('constantsOptional') +
355
- '}:' +
356
- i18n.__('constantsIgnoreCertErrors')
357
- },
358
370
  {
359
371
  name: 'save',
360
372
  alias: 's',
@@ -384,6 +396,38 @@ const auditOptionDefinitions = [
384
396
  name: 'help',
385
397
  alias: 'h',
386
398
  type: Boolean
399
+ },
400
+ {
401
+ name: 'debug',
402
+ alias: 'd',
403
+ type: Boolean
404
+ },
405
+ {
406
+ name: 'verbose',
407
+ alias: 'v',
408
+ type: Boolean,
409
+ description:
410
+ '{bold ' +
411
+ i18n.__('constantsOptional') +
412
+ '}:' +
413
+ i18n.__('scanOptionsVerboseSummary')
414
+ },
415
+ {
416
+ name: 'track',
417
+ type: Boolean,
418
+ description:
419
+ '{bold ' +
420
+ i18n.__('constantsOptional') +
421
+ '}:' +
422
+ i18n.__('auditOptionsTrackSummary')
423
+ },
424
+ {
425
+ name: 'branch',
426
+ description:
427
+ '{bold ' +
428
+ i18n.__('constantsOptional') +
429
+ '}:' +
430
+ i18n.__('auditOptionsBranchSummary')
387
431
  }
388
432
  ]
389
433
 
@@ -1,5 +1,5 @@
1
1
  import paramHandler from '../../utils/paramsUtil/paramHandler'
2
- import constants from '../../constants'
2
+ import constants from '../../cliConstants'
3
3
  import { getCommandLineArgsCustom } from '../../utils/parsedCLIOptions'
4
4
  import { ContrastConf } from '../../utils/getConfig'
5
5
 
@@ -1,6 +1,6 @@
1
1
  import commandLineUsage from 'command-line-usage'
2
2
  import i18n from 'i18n'
3
- import constants from '../../constants'
3
+ import constants from '../../cliConstants'
4
4
  import { commonHelpLinks } from '../../common/commonHelp'
5
5
 
6
6
  const auditUsageGuide = commandLineUsage([
@@ -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()
@@ -12,7 +12,7 @@ const {
12
12
  } = require('../../utils/oraWrapper')
13
13
  const { TIMEOUT, AUTH_UI_URL } = require('../../constants/constants')
14
14
  const parsedCLIOptions = require('../../utils/parsedCLIOptions')
15
- const constants = require('../../constants')
15
+ const constants = require('../../cliConstants')
16
16
  const commandLineUsage = require('command-line-usage')
17
17
 
18
18
  const processAuth = async (argv, config) => {
@@ -1,5 +1,5 @@
1
1
  const parsedCLIOptions = require('../../utils/parsedCLIOptions')
2
- const constants = require('../../constants')
2
+ const constants = require('../../cliConstants')
3
3
  const commandLineUsage = require('command-line-usage')
4
4
  const i18n = require('i18n')
5
5
 
@@ -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,36 +1,41 @@
1
- const autoDetection = require('../../../scan/autoDetection')
2
- const javaAnalysis = require('../../../scaAnalysis/java')
3
- const treeUpload = require('../../../scaAnalysis/common/treeUpload')
4
- const auditController = require('../../audit/auditController')
5
1
  const {
6
2
  supportedLanguages: { JAVA, GO, PYTHON, RUBY, JAVASCRIPT, NODE, PHP, DOTNET }
7
3
  } = require('../../../constants/constants')
8
- const goAnalysis = require('../../../scaAnalysis/go/goAnalysis')
9
- const phpAnalysis = require('../../../scaAnalysis/php/index')
10
- const { rubyAnalysis } = require('../../../scaAnalysis/ruby')
11
- const { pythonAnalysis } = require('../../../scaAnalysis/python')
12
- const javascriptAnalysis = require('../../../scaAnalysis/javascript')
13
4
  const {
14
- pollForSnapshotCompletition
5
+ pollForSnapshotCompletion
15
6
  } = require('../../../audit/languageAnalysisEngine/sendSnapshot')
16
7
  const {
17
8
  returnOra,
18
9
  startSpinner,
19
10
  succeedSpinner
20
11
  } = require('../../../utils/oraWrapper')
21
- const i18n = require('i18n')
22
12
  const {
23
13
  vulnerabilityReportV2
24
14
  } = require('../../../audit/report/reportingFeature')
25
- const auditSave = require('../../../audit/save')
26
- const { dotNetAnalysis } = require('../../../scaAnalysis/dotnet')
27
- const { auditUsageGuide } = require('../../audit/help')
15
+ const autoDetection = require('../../../scan/autoDetection')
16
+ const treeUpload = require('../../../scaAnalysis/common/treeUpload')
17
+ const auditController = require('../../audit/auditController')
28
18
  const rootFile = require('../../../audit/languageAnalysisEngine/getProjectRootFilenames')
29
19
  const path = require('path')
30
- const generalAPI = require('../../../utils/generalAPI')
20
+ const i18n = require('i18n')
21
+ const auditSave = require('../../../audit/save')
22
+ const { auditUsageGuide } = require('../../audit/help')
23
+ const { buildRepo } = require('../../../scaAnalysis/repoMode/index')
24
+ const { dotNetAnalysis } = require('../../../scaAnalysis/dotnet')
25
+ const { goAnalysis } = require('../../../scaAnalysis/go/goAnalysis')
26
+ const { phpAnalysis } = require('../../../scaAnalysis/php/index')
27
+ const { rubyAnalysis } = require('../../../scaAnalysis/ruby')
28
+ const { pythonAnalysis } = require('../../../scaAnalysis/python')
29
+ const javaAnalysis = require('../../../scaAnalysis/java')
30
+ const jsAnalysis = require('../../../scaAnalysis/javascript')
31
+ const auditReport = require('../../../scaAnalysis/common/auditReport')
32
+ const scaUpload = require('../../../scaAnalysis/common/scaServicesUpload')
33
+ const settingsHelper = require('../../../utils/settingsHelper')
34
+ const chalk = require('chalk')
31
35
 
32
36
  const processSca = async config => {
33
- config.mode = await generalAPI.getMode(config)
37
+ //checks to see whether to use old TS / new SCA path
38
+ config = await settingsHelper.getSettings(config)
34
39
 
35
40
  const startTime = performance.now()
36
41
  let filesFound
@@ -59,6 +64,15 @@ const processSca = async config => {
59
64
  // files found looks like [ { javascript: [ Array ] } ]
60
65
  //check we have the language and call the right analyser
61
66
  //refactor new analyser and see if we can clean it up
67
+ if (config.mode === 'repo') {
68
+ try {
69
+ return buildRepo(config, filesFound[0])
70
+ } catch (e) {
71
+ console.log('Unable to build in repository mode. Check your project file')
72
+ process.exit(0)
73
+ }
74
+ }
75
+
62
76
  let messageToSend = undefined
63
77
  if (filesFound.length === 1) {
64
78
  switch (Object.keys(filesFound[0])[0]) {
@@ -67,10 +81,7 @@ const processSca = async config => {
67
81
  config.language = JAVA
68
82
  break
69
83
  case JAVASCRIPT:
70
- messageToSend = await javascriptAnalysis.jsAnalysis(
71
- config,
72
- filesFound[0]
73
- )
84
+ messageToSend = await jsAnalysis.jsAnalysis(config, filesFound[0])
74
85
  config.language = NODE
75
86
  break
76
87
  case PYTHON:
@@ -82,11 +93,11 @@ const processSca = async config => {
82
93
  config.language = RUBY
83
94
  break
84
95
  case PHP:
85
- messageToSend = phpAnalysis.phpAnalysis(config, filesFound[0])
96
+ messageToSend = phpAnalysis(config, filesFound[0])
86
97
  config.language = PHP
87
98
  break
88
99
  case GO:
89
- messageToSend = goAnalysis.goAnalysis(config, filesFound[0])
100
+ messageToSend = goAnalysis(config, filesFound[0])
90
101
  config.language = GO
91
102
  break
92
103
  case DOTNET:
@@ -103,48 +114,68 @@ const processSca = async config => {
103
114
  config.applicationId = await auditController.dealWithNoAppId(config)
104
115
  }
105
116
 
106
- // if (config.experimental) {
107
- // // const reports = await scaUpload.scaTreeUpload(messageToSend, config)
108
- // auditReport.processAuditReport(config, 'reports')
109
- // } else {
110
- console.log('') //empty log for space before spinner
111
- //send message to TS
112
- const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
113
- startSpinner(reportSpinner)
114
- const snapshotResponse = await treeUpload.commonSendSnapShot(
115
- messageToSend,
116
- config
117
- )
117
+ if (config.experimental) {
118
+ console.log('') //empty log for space before spinner
119
+ const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
120
+ startSpinner(reportSpinner)
121
+ const [reports, reportId] = await scaUpload.scaTreeUpload(
122
+ messageToSend,
123
+ config
124
+ )
118
125
 
119
- //poll for completion
120
- await pollForSnapshotCompletition(
121
- config,
122
- snapshotResponse.id,
123
- reportSpinner
124
- )
125
- succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
126
+ auditReport.processAuditReport(config, reports[0])
127
+ succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
126
128
 
127
- await vulnerabilityReportV2(config, snapshotResponse.id)
128
- if (config.save !== undefined) {
129
- await auditSave.auditSave(config)
130
- }
131
- const endTime = performance.now() - startTime
132
- const scanDurationMs = endTime - startTime
129
+ if (config.save !== undefined) {
130
+ await auditSave.auditSave(config, reportId)
131
+ }
133
132
 
134
- console.log(
135
- `----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
136
- )
137
- // }
133
+ const endTime = performance.now() - startTime
134
+ const scanDurationMs = endTime - startTime
135
+ console.log(
136
+ `----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
137
+ )
138
+ } else {
139
+ console.log('') //empty log for space before spinner
140
+ //send message to TS
141
+ const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
142
+ startSpinner(reportSpinner)
143
+ const snapshotResponse = await treeUpload.commonSendSnapShot(
144
+ messageToSend,
145
+ config
146
+ )
147
+
148
+ // poll for completion
149
+ await pollForSnapshotCompletion(
150
+ config,
151
+ snapshotResponse.id,
152
+ reportSpinner
153
+ )
154
+ succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
155
+
156
+ await vulnerabilityReportV2(config, snapshotResponse.id)
157
+ if (config.save !== undefined) {
158
+ await auditSave.auditSave(config)
159
+ }
160
+ const endTime = performance.now() - startTime
161
+ const scanDurationMs = endTime - startTime
162
+
163
+ console.log(
164
+ `----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
165
+ )
166
+ }
138
167
  } else {
139
168
  if (filesFound.length === 0) {
140
169
  console.log(i18n.__('languageAnalysisNoLanguage'))
141
170
  console.log(i18n.__('languageAnalysisNoLanguageHelpLine'))
142
171
  throw new Error()
143
172
  } else {
173
+ console.log(chalk.bold(`\nMultiple language files detected \n`))
174
+ filesFound.forEach(file => {
175
+ console.log(`${Object.keys(file)[0]} : `, Object.values(file)[0])
176
+ })
144
177
  throw new Error(
145
- `multiple language files detected \n` +
146
- JSON.stringify(filesFound) +
147
- `\nplease use --file to audit one language only. Example: contrast audit --file package-lock.json`
178
+ `Please use --file to audit one language only. \nExample: contrast audit --file package-lock.json`
148
179
  )
149
180
  }
150
181
  }
@@ -41,7 +41,7 @@ HTTPClient.prototype.maybeAddCertsToRequest = function (config) {
41
41
  const caFileContent = fs.readFileSync(caCertFilePath)
42
42
  if (caFileContent instanceof Error) {
43
43
  throw new Error(
44
- `Unable to read CA from config option contrast.api.certificate.ca_file='${caCertFilePath}', msg: ${caFileContent.message}`
44
+ `Unable to read CA from ${caCertFilePath}, msg: ${caFileContent.message}`
45
45
  )
46
46
  }
47
47
  this.requestOptions.ca = caFileContent
@@ -246,6 +246,13 @@ HTTPClient.prototype.scaServiceReportStatus = function scaServiceReport(
246
246
  return requestUtils.sendRequest({ method: 'get', options })
247
247
  }
248
248
 
249
+ HTTPClient.prototype.scaServiceIngests = function scaServiceIngests(config) {
250
+ const options = _.cloneDeep(this.requestOptions)
251
+ let url = createScaServiceIngestsURL(config)
252
+ options.url = url
253
+ return requestUtils.sendRequest({ method: 'get', options })
254
+ }
255
+
249
256
  HTTPClient.prototype.getReportById = function getReportById(config, reportId) {
250
257
  const options = _.cloneDeep(this.requestOptions)
251
258
  if (config.ignoreDev) {
@@ -370,6 +377,12 @@ HTTPClient.prototype.getSbom = function getSbom(config, type) {
370
377
  return requestUtils.sendRequest({ method: 'get', options })
371
378
  }
372
379
 
380
+ HTTPClient.prototype.getSCASbom = function getSbom(config, type, reportId) {
381
+ const options = _.cloneDeep(this.requestOptions)
382
+ options.url = createSCASbomUrl(config, type, reportId)
383
+ return requestUtils.sendRequest({ method: 'get', options })
384
+ }
385
+
373
386
  HTTPClient.prototype.getLatestVersion = function getLatestVersion() {
374
387
  const options = _.cloneDeep(this.requestOptions)
375
388
  options.url =
@@ -447,15 +460,23 @@ function createSnapshotURL(config) {
447
460
  }
448
461
 
449
462
  function createScaServiceReportURL(config, reportId) {
450
- return ``
463
+ let baseUrl = `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/applications/${config.applicationId}/reports/${reportId}`
464
+ baseUrl = config.ignoreDev ? baseUrl.concat('?nodesToInclude=PROD') : baseUrl
465
+ return baseUrl
451
466
  }
452
467
 
453
468
  function createScaServiceReportStatusURL(config, reportId) {
454
- return ``
469
+ return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/ingests/${reportId}/status`
470
+ }
471
+
472
+ function createScaServiceIngestsURL(config) {
473
+ return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/ingests`
455
474
  }
456
475
 
457
476
  function createScaServiceIngestURL(config) {
458
- return ``
477
+ let baseUrl = `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/ingests/tree`
478
+ baseUrl = config.track ? baseUrl.concat('?persist=true') : baseUrl
479
+ return baseUrl
459
480
  }
460
481
 
461
482
  const createAppCreateURL = config => {
@@ -492,6 +513,10 @@ function createSbomUrl(config, type) {
492
513
  return `${config.host}/Contrast/api/ng/${config.organizationId}/applications/${config.applicationId}/libraries/sbom/${type}`
493
514
  }
494
515
 
516
+ function createSCASbomUrl(config, type, reportId) {
517
+ return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/applications/${config.applicationId}/sbom/${reportId}?toolType=${type}`
518
+ }
519
+
495
520
  function createTelemetryEventUrl(config) {
496
521
  return `${config.host}/Contrast/api/sast/organizations/${config.organizationId}/cli`
497
522
  }
@@ -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.14'
17
+ const APP_VERSION = '1.0.16'
18
18
  const TIMEOUT = 120000
19
19
  const HIGH_COLOUR = '#ff9900'
20
20
  const CRITICAL_COLOUR = '#e35858'
@@ -34,6 +34,12 @@ const SBOM_CYCLONE_DX_FILE = 'cyclonedx'
34
34
  const SBOM_SPDX_FILE = 'spdx'
35
35
  const CE_URL = 'https://ce.contrastsecurity.com'
36
36
 
37
+ //configuration
38
+ const SAAS = 'SAAS'
39
+ const EOP = 'EOP'
40
+ const MODE_BUILD = 'BUILD'
41
+ const MODE_REPO = 'REPO'
42
+
37
43
  module.exports = {
38
44
  supportedLanguages: { NODE, DOTNET, JAVA, RUBY, PYTHON, GO, PHP, JAVASCRIPT },
39
45
  supportedLanguagesScan: { JAVASCRIPT, DOTNET, JAVA },
@@ -59,5 +65,9 @@ module.exports = {
59
65
  LOW_PRIORITY,
60
66
  NOTE_PRIORITY,
61
67
  SBOM_CYCLONE_DX_FILE,
62
- SBOM_SPDX_FILE
68
+ SBOM_SPDX_FILE,
69
+ SAAS,
70
+ EOP,
71
+ MODE_BUILD,
72
+ MODE_REPO
63
73
  }
@@ -137,7 +137,7 @@ const en_locales = () => {
137
137
  constantsGradleMultiProject:
138
138
  'Specify the sub project within your gradle application.',
139
139
  constantsScan: 'Upload java binaries to the static scan service',
140
- constantsWaitForScan: 'Waits for the result of the scan',
140
+ constantsDoNotWaitForScan: 'Do not wait for the result of the scan',
141
141
  constantsProjectName:
142
142
  'Contrast project name. If not specified, Contrast uses contrast.settings to identify the project or creates a project.',
143
143
  constantsProjectId:
@@ -201,56 +201,19 @@ const en_locales = () => {
201
201
  'After successful auth try the following command: contrast scan -f "<file>"',
202
202
  constantsHowToRunDev3:
203
203
  'Allowable languages are java (.jar and .war) and javascript (.js or .zip), if the language is not autodetected please use --language to specify',
204
- constantsHowToRunContent1:
205
- 'You can run the tool on the command line and manually add the parameters, or you can put the parameters in a YAML file.',
206
- constantsHowToRunContent2:
207
- 'If you are assessing an application that has not been instrumented by a Contrast agent you must first use the tool to register the application (Catalogue command). This will give you an application ID that you can then use in the Run Command.',
208
- constantsHowToRunContent3:
209
- 'Allowable language values are JAVA, NODE, PYTHON, RUBY and GO.',
210
- constantsManualInputHeader: 'Manual Input of Command:',
211
- constantsManualInputCatalogue: 'Catalogue Command:',
212
- constantsManualInputCatalogueInstruction:
213
- 'To analyse a new application not already instrumented by Contrast, run the following command:',
214
- constantsManualInputCatalogueRun:
215
- 'After you run this command, you are provided a new application ID in the console. Use this ID in the Run command:',
216
- constantsManualInputCatalogueRunTitle: 'Run Command:',
217
- constantsManualInputCatalogueRunInstruction:
218
- 'To analyse an application catalogued by Contrast, run the following command:',
219
- constantsYaml: 'Yaml:',
220
- constantsYamlRunCommand:
221
- 'After you catalogue your application go to Run Command above.',
222
204
  constantsOptions: 'Options',
223
- constantsCatalogueCommand:
224
- '%s YourApiKey %s YourAuthorizationKey %s YourOrganizationId %s YourHost %s YourApplicationName %s YourApplicationLanguage',
225
- constantsRunCommand:
226
- '%s YourApiKey %s YourAuthorizationKey %s YourOrganizationId %s YourHost %s YourApplicationId',
227
205
  constantsSpecialCharacterWarning:
228
206
  'Please Note: Parameters may need to be quoted to avoid issues with special characters.',
229
- yamlCatalogueCommand: '%s PathToYaml',
230
- yamlCommand: '%s PathToYaml',
231
- agentProxyAndTlsEnabledError:
232
- 'Please Note: We currently do not support having a proxy server and TLS enabled at the same time.',
233
- TlsHeader: 'TLS',
234
- TlsBody:
235
- 'To enable TLS please use the YAML file with the following parameters:',
236
- TlsKey: 'key: pathToKey',
237
- TlsCert: 'cert: pathToCert',
238
- TlsCaCert: 'cacert: pathToCaCert',
207
+ constantsProxyKey: 'Path to the Certificate Key',
208
+ constantsProxyCert: 'Path to the Cert file',
209
+ constantsProxyCaCert: 'Path to the CaCert file',
239
210
  goReadProjectFile: 'Failed to read the project file @ "%s" because: "%s"',
240
- goAnalysisError: 'GO analysis failed because: ',
241
- goParseProjectFile: 'Failed to parse go mod graph output because: ',
242
- mavenNotInstalledError:
243
- "'mvn' is not available. Please ensure you have Maven installed and available on your path.",
244
211
  mavenDependencyTreeNonZero:
245
212
  'Building maven dependancy tree failed with a non 0 exit code',
246
213
  gradleWrapperUnavailable:
247
214
  'Gradle wrapper not found in root of project. Please ensure gradlew or gradlew.bat is in root of the project.',
248
215
  gradleDependencyTreeNonZero:
249
216
  "Building gradle dependancy tree failed with a non 0 exit code. \n Please check you have the correct version of Java installed to compile your project? \n If running against a muti module project ensure you are using the '--sub-project' flag",
250
- yamlPathCamelCaseError:
251
- 'Warning: The "yamlPath" parameter will be deprecated in a future release. Please look at our documentation for further guidance.',
252
- constantsSbom:
253
- 'Generate the Software Bill of Materials (SBOM) for the given application',
254
217
  constantsMetadata:
255
218
  'Define a set of key=value pairs (which conforms to RFC 2253) for specifying user-defined metadata associated with the application.',
256
219
  constantsTags:
@@ -266,9 +229,7 @@ const en_locales = () => {
266
229
  'Excludes developer dependencies from the results. All dependencies are included by default.',
267
230
  constantsCommands: 'Commands',
268
231
  constantsScanOptions: 'Scan Options',
269
- sbomError: 'All required parameters are not present.',
270
232
  sbomRetrievalError: 'Unable to retrieve Software Bill of Materials (SBOM)',
271
- ignoreDevDep: 'No private libraries that are not scoped detected',
272
233
  foundExistingProjectScan: 'Found existing project...',
273
234
  projectCreatedScan: 'Project created',
274
235
  uploadingScan: 'Uploading file to scan.',
@@ -284,7 +245,6 @@ const en_locales = () => {
284
245
  specifyFileAuditNotFound: 'No files found for library analysis',
285
246
  populateProjectIdMessage: 'project ID is %s',
286
247
  genericServiceError: 'returned with status code %s',
287
- projectIdError: 'Your project ID is %s please check this is correct',
288
248
  permissionsError:
289
249
  'You do not have the correct permissions here. \n Contact support@contrastsecurity.com to get this fixed.',
290
250
  scanErrorFileMessage:
@@ -317,6 +277,9 @@ const en_locales = () => {
317
277
  scanOptionsFileNameSummary:
318
278
  'Path of the file you want to scan. If no file is specified, Contrast searches for a .jar, .war, .exe or .zip file in the working directory.',
319
279
  scanOptionsVerboseSummary: ' Returns extended information to the terminal.',
280
+ auditOptionsTrackSummary: ' Save the results to the UI.',
281
+ auditOptionsBranchSummary:
282
+ ' Set the branch name to associate the library results to.',
320
283
  authSuccessMessage: 'Authentication successful',
321
284
  runAuthSuccessMessage:
322
285
  chalk.bold('CodeSec by Contrast') +
@@ -443,6 +406,8 @@ const en_locales = () => {
443
406
  auditBadFiletypeSpecifiedForSave: `\n ${chalk.yellow.bold(
444
407
  'Bad file type specified for --save option. Use audit --help to see valid --save options.'
445
408
  )}`,
409
+ auditServicesMessageForTS:
410
+ 'View your vulnerable library list or full dependency tree in Contrast:',
446
411
  auditReportWaiting: 'Waiting for report...',
447
412
  auditReportFail: 'Report Retrieval Failed, please try again',
448
413
  auditReportSuccessMessage: 'Report successfully retrieved',
package/src/index.ts CHANGED
@@ -5,7 +5,7 @@ import { processAudit } from './commands/audit/processAudit'
5
5
  import { processAuth } from './commands/auth/auth'
6
6
  import { processConfig } from './commands/config/config'
7
7
  import { processScan } from './commands/scan/processScan'
8
- import constants from './constants'
8
+ import constants from './cliConstants'
9
9
  import { APP_NAME, APP_VERSION } from './constants/constants'
10
10
  import { processLambda } from './lambda/lambda'
11
11
  import { localConfig } from './utils/getConfig'
@@ -15,3 +15,23 @@ export const generateSbom = (config: any, type: string) => {
15
15
  console.log(err)
16
16
  })
17
17
  }
18
+
19
+ export const generateSCASbom = (
20
+ config: any,
21
+ type: string,
22
+ reportId: string
23
+ ) => {
24
+ const client = getHttpClient(config)
25
+ return client
26
+ .getSCASbom(config, type, reportId)
27
+ .then((res: { statusCode: number; body: any }) => {
28
+ if (res.statusCode === 200) {
29
+ return res.body
30
+ } else {
31
+ console.log('Unable to retrieve Software Bill of Materials (SBOM)')
32
+ }
33
+ })
34
+ .catch((err: any) => {
35
+ console.log(err)
36
+ })
37
+ }