@contrast/contrast 1.0.17 → 1.0.19

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.
@@ -11,7 +11,7 @@ i18n.configure({
11
11
  defaultLocale: 'en'
12
12
  })
13
13
 
14
- const sharedOptionDefinitions = [
14
+ const sharedCertOptionDefinitions = [
15
15
  {
16
16
  name: 'proxy',
17
17
  description:
@@ -45,46 +45,55 @@ const sharedOptionDefinitions = [
45
45
  i18n.__('constantsProxyCert')
46
46
  },
47
47
  {
48
- name: 'ignore-cert-errors',
48
+ name: 'cert-self-signed',
49
49
  type: Boolean,
50
50
  description:
51
51
  '{bold ' +
52
52
  i18n.__('constantsOptional') +
53
53
  '}:' +
54
- i18n.__('constantsIgnoreCertErrors')
54
+ i18n.__('constantsCertSelfSigned')
55
55
  }
56
56
  ]
57
57
 
58
- // CLI options that we will allow and handle
59
- const scanOptionDefinitions = [
60
- ...sharedOptionDefinitions,
58
+ const sharedConnectionOptionDefinitions = [
61
59
  {
62
- name: 'name',
63
- alias: 'n',
60
+ name: 'organization-id',
61
+ alias: 'o',
64
62
  description:
65
63
  '{bold ' +
66
- i18n.__('constantsOptional') +
64
+ i18n.__('constantsRequiredEnterprise') +
67
65
  '}: ' +
68
- i18n.__('constantsProjectName')
66
+ i18n.__('constantsOrganizationId')
69
67
  },
70
68
  {
71
- name: 'language',
72
- alias: 'l',
69
+ name: 'api-key',
73
70
  description:
74
71
  '{bold ' +
75
- i18n.__('constantsOptional') +
72
+ i18n.__('constantsRequiredEnterprise') +
76
73
  '}: ' +
77
- i18n.__('scanOptionsLanguageSummary')
74
+ i18n.__('constantsApiKey')
78
75
  },
79
76
  {
80
- name: 'file',
81
- alias: 'f',
77
+ name: 'authorization',
82
78
  description:
83
79
  '{bold ' +
84
- i18n.__('constantsOptional') +
80
+ i18n.__('constantsRequiredEnterprise') +
85
81
  '}: ' +
86
- i18n.__('scanOptionsFileNameSummary')
82
+ i18n.__('constantsAuthorization')
87
83
  },
84
+ {
85
+ name: 'host',
86
+ description:
87
+ '{bold ' +
88
+ i18n.__('constantsRequiredEnterprise') +
89
+ '}: ' +
90
+ i18n.__('constantsHostId')
91
+ }
92
+ ]
93
+
94
+ const scanAdvancedOptionDefinitionsForHelp = [
95
+ ...sharedConnectionOptionDefinitions,
96
+ ...sharedCertOptionDefinitions,
88
97
  {
89
98
  name: 'project-id',
90
99
  alias: 'p',
@@ -95,55 +104,60 @@ const scanOptionDefinitions = [
95
104
  i18n.__('constantsProjectId')
96
105
  },
97
106
  {
98
- name: 'project-path',
107
+ name: 'language',
108
+ alias: 'l',
99
109
  description:
100
110
  '{bold ' +
101
111
  i18n.__('constantsOptional') +
102
112
  '}: ' +
103
- i18n.__('constantsProjectPath')
113
+ i18n.__('scanOptionsLanguageSummary')
104
114
  },
105
115
  {
106
- name: 'timeout',
107
- alias: 't',
108
- type: Number,
116
+ name: 'ff',
117
+ type: Boolean,
109
118
  description:
110
119
  '{bold ' +
111
120
  i18n.__('constantsOptional') +
112
121
  '}: ' +
113
- i18n.__('scanOptionsTimeoutSummary')
122
+ i18n.__('constantsDoNotWaitForScan')
114
123
  },
115
124
  {
116
- name: 'organization-id',
117
- alias: 'o',
125
+ name: 'label',
118
126
  description:
119
- '{bold ' +
120
- i18n.__('constantsRequired') +
121
- '}: ' +
122
- i18n.__('constantsOrganizationId')
123
- },
127
+ '{bold ' + i18n.__('constantsOptional') + '}:' + i18n.__('scanLabel')
128
+ }
129
+ ]
130
+
131
+ // CLI options that we will allow and handle
132
+ const scanOptionDefinitions = [
133
+ ...scanAdvancedOptionDefinitionsForHelp,
124
134
  {
125
- name: 'api-key',
135
+ name: 'name',
136
+ alias: 'n',
126
137
  description:
127
138
  '{bold ' +
128
- i18n.__('constantsRequired') +
139
+ i18n.__('constantsOptional') +
129
140
  '}: ' +
130
- i18n.__('constantsApiKey')
141
+ i18n.__('constantsProjectName')
131
142
  },
132
143
  {
133
- name: 'authorization',
144
+ name: 'file',
145
+ alias: 'f',
134
146
  description:
135
147
  '{bold ' +
136
- i18n.__('constantsRequired') +
148
+ i18n.__('constantsOptional') +
137
149
  '}: ' +
138
- i18n.__('constantsAuthorization')
150
+ i18n.__('scanOptionsFileNameSummary')
139
151
  },
140
152
  {
141
- name: 'host',
153
+ name: 'timeout',
154
+ alias: 't',
155
+ type: Number,
142
156
  description:
143
157
  '{bold ' +
144
- i18n.__('constantsRequired') +
158
+ i18n.__('constantsOptional') +
145
159
  '}: ' +
146
- i18n.__('constantsHostId')
160
+ i18n.__('scanOptionsTimeoutSummary')
147
161
  },
148
162
  {
149
163
  name: 'fail',
@@ -163,15 +177,6 @@ const scanOptionDefinitions = [
163
177
  '}: ' +
164
178
  i18n.__('constantsSeverity')
165
179
  },
166
- {
167
- name: 'ff',
168
- type: Boolean,
169
- description:
170
- '{bold ' +
171
- i18n.__('constantsOptional') +
172
- '}: ' +
173
- i18n.__('constantsDoNotWaitForScan')
174
- },
175
180
  {
176
181
  name: 'verbose',
177
182
  alias: 'v',
@@ -188,11 +193,6 @@ const scanOptionDefinitions = [
188
193
  description:
189
194
  '{bold ' + i18n.__('constantsOptional') + '}:' + i18n.__('constantsSave')
190
195
  },
191
- {
192
- name: 'label',
193
- description:
194
- '{bold ' + i18n.__('constantsOptional') + '}:' + i18n.__('scanLabel')
195
- },
196
196
  {
197
197
  name: 'help',
198
198
  alias: 'h',
@@ -207,18 +207,11 @@ const scanOptionDefinitions = [
207
207
  name: 'experimental',
208
208
  alias: 'e',
209
209
  type: Boolean
210
- },
211
- {
212
- name: 'application-name',
213
- description:
214
- '{bold ' +
215
- i18n.__('constantsOptional') +
216
- '}: ' +
217
- i18n.__('constantsApplicationName')
218
210
  }
219
211
  ]
220
212
 
221
213
  const authOptionDefinitions = [
214
+ ...sharedConnectionOptionDefinitions,
222
215
  {
223
216
  name: 'help',
224
217
  alias: 'h',
@@ -241,8 +234,9 @@ const configOptionDefinitions = [
241
234
  }
242
235
  ]
243
236
 
244
- const auditOptionDefinitions = [
245
- ...sharedOptionDefinitions,
237
+ const auditAdvancedOptionDefinitionsForHelp = [
238
+ ...sharedConnectionOptionDefinitions,
239
+ ...sharedCertOptionDefinitions,
246
240
  {
247
241
  name: 'application-id',
248
242
  description:
@@ -259,39 +253,11 @@ const auditOptionDefinitions = [
259
253
  '}: ' +
260
254
  i18n.__('constantsApplicationName')
261
255
  },
262
- {
263
- name: 'file',
264
- alias: 'f',
265
- defaultValue: process.cwd().concat('/'),
266
- description:
267
- '{bold ' +
268
- i18n.__('constantsOptional') +
269
- '}: ' +
270
- i18n.__('constantsFilePath')
271
- },
272
- {
273
- name: 'fail',
274
- type: Boolean,
275
- description:
276
- '{bold ' +
277
- i18n.__('constantsOptional') +
278
- '}: ' +
279
- i18n.__('failOptionMessage')
280
- },
281
- {
282
- name: 'severity',
283
- type: severity => parseSeverity(severity),
284
- description:
285
- '{bold ' +
286
- i18n.__('constantsOptional') +
287
- '}: ' +
288
- i18n.__('constantsSeverity')
289
- },
290
256
  {
291
257
  name: 'app-groups',
292
258
  description:
293
259
  '{bold ' +
294
- i18n.__('constantsOptionalForCatalogue') +
260
+ i18n.__('constantsOptional') +
295
261
  '}: ' +
296
262
  i18n.__('constantsAppGroups')
297
263
  },
@@ -322,54 +288,58 @@ const auditOptionDefinitions = [
322
288
  '{bold ' + i18n.__('constantsOptional') + '}: ' + i18n.__('constantsCode')
323
289
  },
324
290
  {
325
- name: 'ignore-dev',
326
- type: Boolean,
327
- alias: 'i',
291
+ name: 'maven-settings-path',
328
292
  description:
329
293
  '{bold ' +
330
294
  i18n.__('constantsOptional') +
331
295
  '}: ' +
332
- i18n.__('constantsIgnoreDev')
333
- },
334
- {
335
- name: 'maven-settings-path'
336
- },
337
- {
338
- name: 'fingerprint',
339
- type: Boolean
340
- },
296
+ i18n.__('constantsMavenSettingsPath')
297
+ }
298
+ ]
299
+
300
+ const auditOptionDefinitions = [
301
+ ...auditAdvancedOptionDefinitionsForHelp,
341
302
  {
342
- name: 'organization-id',
343
- alias: 'o',
303
+ name: 'file',
304
+ alias: 'f',
305
+ defaultValue: process.cwd().concat('/'),
344
306
  description:
345
307
  '{bold ' +
346
- i18n.__('constantsRequired') +
308
+ i18n.__('constantsOptional') +
347
309
  '}: ' +
348
- i18n.__('constantsOrganizationId')
310
+ i18n.__('constantsFilePath')
349
311
  },
350
312
  {
351
- name: 'api-key',
313
+ name: 'fail',
314
+ type: Boolean,
352
315
  description:
353
316
  '{bold ' +
354
- i18n.__('constantsRequired') +
317
+ i18n.__('constantsOptional') +
355
318
  '}: ' +
356
- i18n.__('constantsApiKey')
319
+ i18n.__('failOptionMessage')
357
320
  },
358
321
  {
359
- name: 'authorization',
322
+ name: 'severity',
323
+ type: severity => parseSeverity(severity),
360
324
  description:
361
325
  '{bold ' +
362
- i18n.__('constantsRequired') +
326
+ i18n.__('constantsOptional') +
363
327
  '}: ' +
364
- i18n.__('constantsAuthorization')
328
+ i18n.__('constantsSeverity')
365
329
  },
366
330
  {
367
- name: 'host',
331
+ name: 'ignore-dev',
332
+ type: Boolean,
333
+ alias: 'i',
368
334
  description:
369
335
  '{bold ' +
370
- i18n.__('constantsRequired') +
336
+ i18n.__('constantsOptional') +
371
337
  '}: ' +
372
- i18n.__('constantsHostId')
338
+ i18n.__('constantsIgnoreDev')
339
+ },
340
+ {
341
+ name: 'fingerprint',
342
+ type: Boolean
373
343
  },
374
344
  {
375
345
  name: 'save',
@@ -459,6 +429,10 @@ const mainUsageGuide = commandLineUsage([
459
429
  { name: i18n.__('helpName'), summary: i18n.__('helpSummary') }
460
430
  ]
461
431
  },
432
+ {
433
+ header: i18n.__('constantsAdvancedOptions'),
434
+ optionList: sharedCertOptionDefinitions
435
+ },
462
436
  {
463
437
  header: i18n.__('configHeader2'),
464
438
  content: [
@@ -478,6 +452,8 @@ module.exports = {
478
452
  scanOptionDefinitions,
479
453
  auditOptionDefinitions,
480
454
  authOptionDefinitions,
481
- configOptionDefinitions
455
+ configOptionDefinitions,
456
+ scanAdvancedOptionDefinitionsForHelp,
457
+ auditAdvancedOptionDefinitionsForHelp
482
458
  }
483
459
  }
@@ -34,9 +34,12 @@ const auditUsageGuide = commandLineUsage([
34
34
  'authorization',
35
35
  'host',
36
36
  'proxy',
37
+ 'cert',
38
+ 'cacert',
39
+ 'key',
37
40
  'help',
38
41
  'ff',
39
- 'ignore-cert-errors',
42
+ 'cert-self-signed',
40
43
  'verbose',
41
44
  'debug',
42
45
  'experimental',
@@ -49,9 +52,15 @@ const auditUsageGuide = commandLineUsage([
49
52
  'app-groups',
50
53
  'metadata',
51
54
  'track',
52
- 'fingerprint'
55
+ 'fingerprint',
56
+ 'branch'
53
57
  ]
54
58
  },
59
+ {
60
+ header: i18n.__('constantsAdvancedOptions'),
61
+ optionList:
62
+ constants.commandLineDefinitions.auditAdvancedOptionDefinitionsForHelp
63
+ },
55
64
  commonHelpLinks()[0],
56
65
  commonHelpLinks()[1]
57
66
  ])
@@ -1,8 +1,7 @@
1
1
  const { v4: uuidv4 } = require('uuid')
2
- const { setConfigValues } = require('../../utils/getConfig')
3
- const open = require('open')
2
+ const configFunctions = require('../../utils/getConfig')
4
3
  const commonApi = require('../../utils/commonApi')
5
- const { sleep } = require('../../utils/requestUtils')
4
+ const requestUtils = require('../../utils/requestUtils')
6
5
  const i18n = require('i18n')
7
6
  const {
8
7
  returnOra,
@@ -14,6 +13,9 @@ const { TIMEOUT, AUTH_UI_URL } = require('../../constants/constants')
14
13
  const parsedCLIOptions = require('../../utils/parsedCLIOptions')
15
14
  const constants = require('../../cliConstants')
16
15
  const commandLineUsage = require('command-line-usage')
16
+ const { commonMessageFormatter } = require('../../common/errorHandling')
17
+ const open = require('open')
18
+ const messages = require('../../constants/locales').en_locales()
17
19
 
18
20
  const processAuth = async (argv, config) => {
19
21
  let authParams = await parsedCLIOptions.getCommandLineArgsCustom(
@@ -28,6 +30,15 @@ const processAuth = async (argv, config) => {
28
30
  process.exit(0)
29
31
  }
30
32
 
33
+ //check if user has entered enterprise credentials
34
+ if (checkForCustomCredentials(authParams)) {
35
+ processCustomCredentials(authParams, config)
36
+ } else {
37
+ await startAuthProcess(config)
38
+ }
39
+ }
40
+
41
+ const startAuthProcess = async config => {
31
42
  const token = uuidv4()
32
43
  const url = `${AUTH_UI_URL}/?token=${token}`
33
44
 
@@ -41,9 +52,8 @@ const processAuth = async (argv, config) => {
41
52
 
42
53
  const result = await isAuthComplete(token, TIMEOUT, config)
43
54
  if (result) {
44
- setConfigValues(config, result)
55
+ configFunctions.setConfigValues(config, result)
45
56
  }
46
- return
47
57
  } finally {
48
58
  //spinner stop
49
59
  }
@@ -72,7 +82,7 @@ const isAuthComplete = async (token, timeout, config) => {
72
82
  }
73
83
 
74
84
  const pollAuthResult = async (token, client) => {
75
- await sleep(5000)
85
+ await requestUtils.sleep(5000)
76
86
  return client
77
87
  .pollForAuth(token)
78
88
  .then(res => {
@@ -94,6 +104,38 @@ const authUsageGuide = commandLineUsage([
94
104
  }
95
105
  ])
96
106
 
107
+ const checkForCustomCredentials = authParams => {
108
+ const hasSomeKeys =
109
+ authParams.apiKey ||
110
+ authParams.organizationId ||
111
+ authParams.host ||
112
+ authParams.authorization
113
+ const hasAllKeys =
114
+ authParams.apiKey &&
115
+ authParams.organizationId &&
116
+ authParams.host &&
117
+ authParams.authorization
118
+
119
+ if (hasAllKeys) {
120
+ return true
121
+ }
122
+ if (hasSomeKeys) {
123
+ commonMessageFormatter(messages.authCommand.credentialsMissing, true)
124
+ }
125
+ return false
126
+ }
127
+
128
+ const processCustomCredentials = (authParams, config) => {
129
+ const valuesToSet = {
130
+ apiKey: authParams.apiKey,
131
+ orgId: authParams.organizationId,
132
+ authHeader: authParams.authorization,
133
+ host: authParams.host
134
+ }
135
+ configFunctions.setConfigValues(config, valuesToSet)
136
+ commonMessageFormatter(messages.authCommand.credentialsAccepted, false)
137
+ }
138
+
97
139
  module.exports = {
98
- processAuth: processAuth
140
+ processAuth
99
141
  }
@@ -64,6 +64,8 @@ const processSca = async config => {
64
64
  config.file
65
65
  )
66
66
 
67
+ autoDetection.dealWithMultiJava(filesFound)
68
+
67
69
  if (filesFound.length > 1 && pathWithFile) {
68
70
  filesFound = filesFound.filter(i =>
69
71
  Object.values(i)[0].includes(path.basename(config.fileName))
@@ -6,7 +6,7 @@ const { AUTH_CALLBACK_URL } = require('../constants/constants')
6
6
  function HTTPClient(config) {
7
7
  const apiKey = config.apiKey
8
8
  const authToken = config.authorization
9
- this.rejectUnauthorized = !config.ignoreCertErrors
9
+ this.rejectUnauthorized = !config.certSelfSigned
10
10
 
11
11
  const superApiKey = config.superApiKey
12
12
  const superAuthToken = config.superAuthorization
@@ -226,6 +226,7 @@ HTTPClient.prototype.scaServiceIngest = function scaServiceIngest(
226
226
  options.body = requestBody
227
227
  return requestUtils.sendRequest({ method: 'post', options })
228
228
  }
229
+
229
230
  HTTPClient.prototype.scaServiceReport = function scaServiceReport(
230
231
  config,
231
232
  reportId
@@ -460,21 +461,21 @@ function createSnapshotURL(config) {
460
461
  }
461
462
 
462
463
  function createScaServiceReportURL(config, reportId) {
463
- let baseUrl = `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/applications/${config.applicationId}/reports/${reportId}`
464
+ let baseUrl = `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/applications/${config.applicationId}/libraries/reports/${reportId}`
464
465
  baseUrl = config.ignoreDev ? baseUrl.concat('?nodesToInclude=PROD') : baseUrl
465
466
  return baseUrl
466
467
  }
467
468
 
468
469
  function createScaServiceReportStatusURL(config, reportId) {
469
- return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/ingests/${reportId}/status`
470
+ return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/applications/${config.applicationId}/libraries/ingests/${reportId}/status`
470
471
  }
471
472
 
472
473
  function createScaServiceIngestsURL(config) {
473
- return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/ingests`
474
+ return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/applications/${config.applicationId}/libraries/ingests`
474
475
  }
475
476
 
476
477
  function createScaServiceIngestURL(config) {
477
- let baseUrl = `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/ingests/tree`
478
+ let baseUrl = `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/applications/${config.applicationId}/libraries/ingests/tree`
478
479
  baseUrl = config.track ? baseUrl.concat('?persist=true') : baseUrl
479
480
  return baseUrl
480
481
  }
@@ -1,4 +1,5 @@
1
1
  const i18n = require('i18n')
2
+ const chalk = require('chalk')
2
3
 
3
4
  const libraryAnalysisError = () => {
4
5
  console.log(i18n.__('libraryAnalysisError'))
@@ -48,6 +49,22 @@ const maxAppError = () => {
48
49
  process.exit(1)
49
50
  }
50
51
 
52
+ const parametersError = () => {
53
+ generalError(
54
+ `Values not recognised`,
55
+ 'Check your command & keys again for hidden characters.\nFor more information use contrast help.'
56
+ )
57
+ process.exit(1)
58
+ }
59
+
60
+ const invalidHostNameError = () => {
61
+ generalError(
62
+ `Invalid host`,
63
+ 'Check that the host parameter does not include a trailing "/".'
64
+ )
65
+ process.exit(1)
66
+ }
67
+
51
68
  const failOptionError = () => {
52
69
  console.log(
53
70
  '\n ******************************** ' +
@@ -108,6 +125,17 @@ const findCommandOnError = unknownOptions => {
108
125
  }
109
126
  }
110
127
 
128
+ const commonMessageFormatter = (message, fail) => {
129
+ console.log(chalk.bold(i18n.__(message.title)))
130
+ console.log(i18n.__(message.body))
131
+ if (message.extra) {
132
+ console.log(i18n.__(message.extra))
133
+ }
134
+ if (fail) {
135
+ process.exit(1)
136
+ }
137
+ }
138
+
111
139
  module.exports = {
112
140
  genericError,
113
141
  unauthenticatedError,
@@ -122,5 +150,8 @@ module.exports = {
122
150
  snapshotFailureError,
123
151
  vulnerabilitiesFailureError,
124
152
  reportFailureError,
125
- maxAppError
153
+ maxAppError,
154
+ parametersError,
155
+ invalidHostNameError,
156
+ commonMessageFormatter
126
157
  }
@@ -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.17'
17
+ const APP_VERSION = '1.0.19'
18
18
  const TIMEOUT = 120000
19
19
  const HIGH_COLOUR = '#ff9900'
20
20
  const CRITICAL_COLOUR = '#e35858'