@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.
@@ -10,7 +10,7 @@ i18n.configure({
10
10
  },
11
11
  defaultLocale: 'en'
12
12
  });
13
- const sharedOptionDefinitions = [
13
+ const sharedCertOptionDefinitions = [
14
14
  {
15
15
  name: 'proxy',
16
16
  description: '{bold ' +
@@ -40,40 +40,48 @@ const sharedOptionDefinitions = [
40
40
  i18n.__('constantsProxyCert')
41
41
  },
42
42
  {
43
- name: 'ignore-cert-errors',
43
+ name: 'cert-self-signed',
44
44
  type: Boolean,
45
45
  description: '{bold ' +
46
46
  i18n.__('constantsOptional') +
47
47
  '}:' +
48
- i18n.__('constantsIgnoreCertErrors')
48
+ i18n.__('constantsCertSelfSigned')
49
49
  }
50
50
  ];
51
- const scanOptionDefinitions = [
52
- ...sharedOptionDefinitions,
51
+ const sharedConnectionOptionDefinitions = [
53
52
  {
54
- name: 'name',
55
- alias: 'n',
53
+ name: 'organization-id',
54
+ alias: 'o',
56
55
  description: '{bold ' +
57
- i18n.__('constantsOptional') +
56
+ i18n.__('constantsRequiredEnterprise') +
58
57
  '}: ' +
59
- i18n.__('constantsProjectName')
58
+ i18n.__('constantsOrganizationId')
60
59
  },
61
60
  {
62
- name: 'language',
63
- alias: 'l',
61
+ name: 'api-key',
64
62
  description: '{bold ' +
65
- i18n.__('constantsOptional') +
63
+ i18n.__('constantsRequiredEnterprise') +
66
64
  '}: ' +
67
- i18n.__('scanOptionsLanguageSummary')
65
+ i18n.__('constantsApiKey')
68
66
  },
69
67
  {
70
- name: 'file',
71
- alias: 'f',
68
+ name: 'authorization',
72
69
  description: '{bold ' +
73
- i18n.__('constantsOptional') +
70
+ i18n.__('constantsRequiredEnterprise') +
74
71
  '}: ' +
75
- i18n.__('scanOptionsFileNameSummary')
72
+ i18n.__('constantsAuthorization')
76
73
  },
74
+ {
75
+ name: 'host',
76
+ description: '{bold ' +
77
+ i18n.__('constantsRequiredEnterprise') +
78
+ '}: ' +
79
+ i18n.__('constantsHostId')
80
+ }
81
+ ];
82
+ const scanAdvancedOptionDefinitionsForHelp = [
83
+ ...sharedConnectionOptionDefinitions,
84
+ ...sharedCertOptionDefinitions,
77
85
  {
78
86
  name: 'project-id',
79
87
  alias: 'p',
@@ -83,49 +91,52 @@ const scanOptionDefinitions = [
83
91
  i18n.__('constantsProjectId')
84
92
  },
85
93
  {
86
- name: 'project-path',
94
+ name: 'language',
95
+ alias: 'l',
87
96
  description: '{bold ' +
88
97
  i18n.__('constantsOptional') +
89
98
  '}: ' +
90
- i18n.__('constantsProjectPath')
99
+ i18n.__('scanOptionsLanguageSummary')
91
100
  },
92
101
  {
93
- name: 'timeout',
94
- alias: 't',
95
- type: Number,
102
+ name: 'ff',
103
+ type: Boolean,
96
104
  description: '{bold ' +
97
105
  i18n.__('constantsOptional') +
98
106
  '}: ' +
99
- i18n.__('scanOptionsTimeoutSummary')
107
+ i18n.__('constantsDoNotWaitForScan')
100
108
  },
101
109
  {
102
- name: 'organization-id',
103
- alias: 'o',
104
- description: '{bold ' +
105
- i18n.__('constantsRequired') +
106
- '}: ' +
107
- i18n.__('constantsOrganizationId')
108
- },
110
+ name: 'label',
111
+ description: '{bold ' + i18n.__('constantsOptional') + '}:' + i18n.__('scanLabel')
112
+ }
113
+ ];
114
+ const scanOptionDefinitions = [
115
+ ...scanAdvancedOptionDefinitionsForHelp,
109
116
  {
110
- name: 'api-key',
117
+ name: 'name',
118
+ alias: 'n',
111
119
  description: '{bold ' +
112
- i18n.__('constantsRequired') +
120
+ i18n.__('constantsOptional') +
113
121
  '}: ' +
114
- i18n.__('constantsApiKey')
122
+ i18n.__('constantsProjectName')
115
123
  },
116
124
  {
117
- name: 'authorization',
125
+ name: 'file',
126
+ alias: 'f',
118
127
  description: '{bold ' +
119
- i18n.__('constantsRequired') +
128
+ i18n.__('constantsOptional') +
120
129
  '}: ' +
121
- i18n.__('constantsAuthorization')
130
+ i18n.__('scanOptionsFileNameSummary')
122
131
  },
123
132
  {
124
- name: 'host',
133
+ name: 'timeout',
134
+ alias: 't',
135
+ type: Number,
125
136
  description: '{bold ' +
126
- i18n.__('constantsRequired') +
137
+ i18n.__('constantsOptional') +
127
138
  '}: ' +
128
- i18n.__('constantsHostId')
139
+ i18n.__('scanOptionsTimeoutSummary')
129
140
  },
130
141
  {
131
142
  name: 'fail',
@@ -143,14 +154,6 @@ const scanOptionDefinitions = [
143
154
  '}: ' +
144
155
  i18n.__('constantsSeverity')
145
156
  },
146
- {
147
- name: 'ff',
148
- type: Boolean,
149
- description: '{bold ' +
150
- i18n.__('constantsOptional') +
151
- '}: ' +
152
- i18n.__('constantsDoNotWaitForScan')
153
- },
154
157
  {
155
158
  name: 'verbose',
156
159
  alias: 'v',
@@ -165,10 +168,6 @@ const scanOptionDefinitions = [
165
168
  alias: 's',
166
169
  description: '{bold ' + i18n.__('constantsOptional') + '}:' + i18n.__('constantsSave')
167
170
  },
168
- {
169
- name: 'label',
170
- description: '{bold ' + i18n.__('constantsOptional') + '}:' + i18n.__('scanLabel')
171
- },
172
171
  {
173
172
  name: 'help',
174
173
  alias: 'h',
@@ -183,16 +182,10 @@ const scanOptionDefinitions = [
183
182
  name: 'experimental',
184
183
  alias: 'e',
185
184
  type: Boolean
186
- },
187
- {
188
- name: 'application-name',
189
- description: '{bold ' +
190
- i18n.__('constantsOptional') +
191
- '}: ' +
192
- i18n.__('constantsApplicationName')
193
185
  }
194
186
  ];
195
187
  const authOptionDefinitions = [
188
+ ...sharedConnectionOptionDefinitions,
196
189
  {
197
190
  name: 'help',
198
191
  alias: 'h',
@@ -213,8 +206,9 @@ const configOptionDefinitions = [
213
206
  description: 'Clear the currently stored config'
214
207
  }
215
208
  ];
216
- const auditOptionDefinitions = [
217
- ...sharedOptionDefinitions,
209
+ const auditAdvancedOptionDefinitionsForHelp = [
210
+ ...sharedConnectionOptionDefinitions,
211
+ ...sharedCertOptionDefinitions,
218
212
  {
219
213
  name: 'application-id',
220
214
  description: '{bold ' +
@@ -229,35 +223,10 @@ const auditOptionDefinitions = [
229
223
  '}: ' +
230
224
  i18n.__('constantsApplicationName')
231
225
  },
232
- {
233
- name: 'file',
234
- alias: 'f',
235
- defaultValue: process.cwd().concat('/'),
236
- description: '{bold ' +
237
- i18n.__('constantsOptional') +
238
- '}: ' +
239
- i18n.__('constantsFilePath')
240
- },
241
- {
242
- name: 'fail',
243
- type: Boolean,
244
- description: '{bold ' +
245
- i18n.__('constantsOptional') +
246
- '}: ' +
247
- i18n.__('failOptionMessage')
248
- },
249
- {
250
- name: 'severity',
251
- type: severity => parseSeverity(severity),
252
- description: '{bold ' +
253
- i18n.__('constantsOptional') +
254
- '}: ' +
255
- i18n.__('constantsSeverity')
256
- },
257
226
  {
258
227
  name: 'app-groups',
259
228
  description: '{bold ' +
260
- i18n.__('constantsOptionalForCatalogue') +
229
+ i18n.__('constantsOptional') +
261
230
  '}: ' +
262
231
  i18n.__('constantsAppGroups')
263
232
  },
@@ -284,49 +253,52 @@ const auditOptionDefinitions = [
284
253
  description: '{bold ' + i18n.__('constantsOptional') + '}: ' + i18n.__('constantsCode')
285
254
  },
286
255
  {
287
- name: 'ignore-dev',
288
- type: Boolean,
289
- alias: 'i',
256
+ name: 'maven-settings-path',
290
257
  description: '{bold ' +
291
258
  i18n.__('constantsOptional') +
292
259
  '}: ' +
293
- i18n.__('constantsIgnoreDev')
294
- },
295
- {
296
- name: 'maven-settings-path'
297
- },
298
- {
299
- name: 'fingerprint',
300
- type: Boolean
301
- },
260
+ i18n.__('constantsMavenSettingsPath')
261
+ }
262
+ ];
263
+ const auditOptionDefinitions = [
264
+ ...auditAdvancedOptionDefinitionsForHelp,
302
265
  {
303
- name: 'organization-id',
304
- alias: 'o',
266
+ name: 'file',
267
+ alias: 'f',
268
+ defaultValue: process.cwd().concat('/'),
305
269
  description: '{bold ' +
306
- i18n.__('constantsRequired') +
270
+ i18n.__('constantsOptional') +
307
271
  '}: ' +
308
- i18n.__('constantsOrganizationId')
272
+ i18n.__('constantsFilePath')
309
273
  },
310
274
  {
311
- name: 'api-key',
275
+ name: 'fail',
276
+ type: Boolean,
312
277
  description: '{bold ' +
313
- i18n.__('constantsRequired') +
278
+ i18n.__('constantsOptional') +
314
279
  '}: ' +
315
- i18n.__('constantsApiKey')
280
+ i18n.__('failOptionMessage')
316
281
  },
317
282
  {
318
- name: 'authorization',
283
+ name: 'severity',
284
+ type: severity => parseSeverity(severity),
319
285
  description: '{bold ' +
320
- i18n.__('constantsRequired') +
286
+ i18n.__('constantsOptional') +
321
287
  '}: ' +
322
- i18n.__('constantsAuthorization')
288
+ i18n.__('constantsSeverity')
323
289
  },
324
290
  {
325
- name: 'host',
291
+ name: 'ignore-dev',
292
+ type: Boolean,
293
+ alias: 'i',
326
294
  description: '{bold ' +
327
- i18n.__('constantsRequired') +
295
+ i18n.__('constantsOptional') +
328
296
  '}: ' +
329
- i18n.__('constantsHostId')
297
+ i18n.__('constantsIgnoreDev')
298
+ },
299
+ {
300
+ name: 'fingerprint',
301
+ type: Boolean
330
302
  },
331
303
  {
332
304
  name: 'save',
@@ -410,6 +382,10 @@ const mainUsageGuide = commandLineUsage([
410
382
  { name: i18n.__('helpName'), summary: i18n.__('helpSummary') }
411
383
  ]
412
384
  },
385
+ {
386
+ header: i18n.__('constantsAdvancedOptions'),
387
+ optionList: sharedCertOptionDefinitions
388
+ },
413
389
  {
414
390
  header: i18n.__('configHeader2'),
415
391
  content: [
@@ -427,6 +403,8 @@ module.exports = {
427
403
  scanOptionDefinitions,
428
404
  auditOptionDefinitions,
429
405
  authOptionDefinitions,
430
- configOptionDefinitions
406
+ configOptionDefinitions,
407
+ scanAdvancedOptionDefinitionsForHelp,
408
+ auditAdvancedOptionDefinitionsForHelp
431
409
  }
432
410
  };
@@ -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,14 @@ 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: constants.commandLineDefinitions.auditAdvancedOptionDefinitionsForHelp
62
+ },
55
63
  commonHelpLinks()[0],
56
64
  commonHelpLinks()[1]
57
65
  ]);
@@ -1,21 +1,31 @@
1
1
  "use strict";
2
2
  const { v4: uuidv4 } = require('uuid');
3
- const { setConfigValues } = require('../../utils/getConfig');
4
- const open = require('open');
3
+ const configFunctions = require('../../utils/getConfig');
5
4
  const commonApi = require('../../utils/commonApi');
6
- const { sleep } = require('../../utils/requestUtils');
5
+ const requestUtils = require('../../utils/requestUtils');
7
6
  const i18n = require('i18n');
8
7
  const { returnOra, startSpinner, failSpinner, succeedSpinner } = require('../../utils/oraWrapper');
9
8
  const { TIMEOUT, AUTH_UI_URL } = require('../../constants/constants');
10
9
  const parsedCLIOptions = require('../../utils/parsedCLIOptions');
11
10
  const constants = require('../../cliConstants');
12
11
  const commandLineUsage = require('command-line-usage');
12
+ const { commonMessageFormatter } = require('../../common/errorHandling');
13
+ const open = require('open');
14
+ const messages = require('../../constants/locales').en_locales();
13
15
  const processAuth = async (argv, config) => {
14
16
  let authParams = await parsedCLIOptions.getCommandLineArgsCustom(config, 'auth', argv, constants.commandLineDefinitions.authOptionDefinitions);
15
17
  if (authParams.help) {
16
18
  console.log(authUsageGuide);
17
19
  process.exit(0);
18
20
  }
21
+ if (checkForCustomCredentials(authParams)) {
22
+ processCustomCredentials(authParams, config);
23
+ }
24
+ else {
25
+ await startAuthProcess(config);
26
+ }
27
+ };
28
+ const startAuthProcess = async (config) => {
19
29
  const token = uuidv4();
20
30
  const url = `${AUTH_UI_URL}/?token=${token}`;
21
31
  console.log(i18n.__('redirectAuth', url));
@@ -25,9 +35,8 @@ const processAuth = async (argv, config) => {
25
35
  }, 0);
26
36
  const result = await isAuthComplete(token, TIMEOUT, config);
27
37
  if (result) {
28
- setConfigValues(config, result);
38
+ configFunctions.setConfigValues(config, result);
29
39
  }
30
- return;
31
40
  }
32
41
  finally {
33
42
  }
@@ -54,7 +63,7 @@ const isAuthComplete = async (token, timeout, config) => {
54
63
  }
55
64
  };
56
65
  const pollAuthResult = async (token, client) => {
57
- await sleep(5000);
66
+ await requestUtils.sleep(5000);
58
67
  return client
59
68
  .pollForAuth(token)
60
69
  .then(res => {
@@ -74,6 +83,33 @@ const authUsageGuide = commandLineUsage([
74
83
  content: [i18n.__('constantsAuthUsageContents')]
75
84
  }
76
85
  ]);
86
+ const checkForCustomCredentials = authParams => {
87
+ const hasSomeKeys = authParams.apiKey ||
88
+ authParams.organizationId ||
89
+ authParams.host ||
90
+ authParams.authorization;
91
+ const hasAllKeys = authParams.apiKey &&
92
+ authParams.organizationId &&
93
+ authParams.host &&
94
+ authParams.authorization;
95
+ if (hasAllKeys) {
96
+ return true;
97
+ }
98
+ if (hasSomeKeys) {
99
+ commonMessageFormatter(messages.authCommand.credentialsMissing, true);
100
+ }
101
+ return false;
102
+ };
103
+ const processCustomCredentials = (authParams, config) => {
104
+ const valuesToSet = {
105
+ apiKey: authParams.apiKey,
106
+ orgId: authParams.organizationId,
107
+ authHeader: authParams.authorization,
108
+ host: authParams.host
109
+ };
110
+ configFunctions.setConfigValues(config, valuesToSet);
111
+ commonMessageFormatter(messages.authCommand.credentialsAccepted, false);
112
+ };
77
113
  module.exports = {
78
- processAuth: processAuth
114
+ processAuth
79
115
  };
@@ -46,6 +46,7 @@ const processSca = async (config) => {
46
46
  }
47
47
  else {
48
48
  filesFound = await autoDetection.autoDetectAuditFilesAndLanguages(config.file);
49
+ autoDetection.dealWithMultiJava(filesFound);
49
50
  if (filesFound.length > 1 && pathWithFile) {
50
51
  filesFound = filesFound.filter(i => Object.values(i)[0].includes(path.basename(config.fileName)));
51
52
  }
@@ -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
  const superApiKey = config.superApiKey;
11
11
  const superAuthToken = config.superAuthorization;
12
12
  this.requestOptions = {
@@ -332,18 +332,18 @@ function createSnapshotURL(config) {
332
332
  return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/snapshots`;
333
333
  }
334
334
  function createScaServiceReportURL(config, reportId) {
335
- let baseUrl = `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/applications/${config.applicationId}/reports/${reportId}`;
335
+ let baseUrl = `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/applications/${config.applicationId}/libraries/reports/${reportId}`;
336
336
  baseUrl = config.ignoreDev ? baseUrl.concat('?nodesToInclude=PROD') : baseUrl;
337
337
  return baseUrl;
338
338
  }
339
339
  function createScaServiceReportStatusURL(config, reportId) {
340
- return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/ingests/${reportId}/status`;
340
+ return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/applications/${config.applicationId}/libraries/ingests/${reportId}/status`;
341
341
  }
342
342
  function createScaServiceIngestsURL(config) {
343
- return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/ingests`;
343
+ return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/applications/${config.applicationId}/libraries/ingests`;
344
344
  }
345
345
  function createScaServiceIngestURL(config) {
346
- let baseUrl = `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/ingests/tree`;
346
+ let baseUrl = `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/applications/${config.applicationId}/libraries/ingests/tree`;
347
347
  baseUrl = config.track ? baseUrl.concat('?persist=true') : baseUrl;
348
348
  return baseUrl;
349
349
  }
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  const i18n = require('i18n');
3
+ const chalk = require('chalk');
3
4
  const libraryAnalysisError = () => {
4
5
  console.log(i18n.__('libraryAnalysisError'));
5
6
  };
@@ -35,6 +36,14 @@ const maxAppError = () => {
35
36
  generalError('No applications remaining', 'You have reached the maximum number of application you can create.');
36
37
  process.exit(1);
37
38
  };
39
+ const parametersError = () => {
40
+ generalError(`Values not recognised`, 'Check your command & keys again for hidden characters.\nFor more information use contrast help.');
41
+ process.exit(1);
42
+ };
43
+ const invalidHostNameError = () => {
44
+ generalError(`Invalid host`, 'Check that the host parameter does not include a trailing "/".');
45
+ process.exit(1);
46
+ };
38
47
  const failOptionError = () => {
39
48
  console.log('\n ******************************** ' +
40
49
  i18n.__('snapshotFailureHeader') +
@@ -71,6 +80,16 @@ const findCommandOnError = unknownOptions => {
71
80
  return foundCommands[0];
72
81
  }
73
82
  };
83
+ const commonMessageFormatter = (message, fail) => {
84
+ console.log(chalk.bold(i18n.__(message.title)));
85
+ console.log(i18n.__(message.body));
86
+ if (message.extra) {
87
+ console.log(i18n.__(message.extra));
88
+ }
89
+ if (fail) {
90
+ process.exit(1);
91
+ }
92
+ };
74
93
  module.exports = {
75
94
  genericError,
76
95
  unauthenticatedError,
@@ -85,5 +104,8 @@ module.exports = {
85
104
  snapshotFailureError,
86
105
  vulnerabilitiesFailureError,
87
106
  reportFailureError,
88
- maxAppError
107
+ maxAppError,
108
+ parametersError,
109
+ invalidHostNameError,
110
+ commonMessageFormatter
89
111
  };
@@ -12,7 +12,7 @@ const MEDIUM = 'MEDIUM';
12
12
  const HIGH = 'HIGH';
13
13
  const CRITICAL = 'CRITICAL';
14
14
  const APP_NAME = 'contrast';
15
- const APP_VERSION = '1.0.17';
15
+ const APP_VERSION = '1.0.19';
16
16
  const TIMEOUT = 120000;
17
17
  const HIGH_COLOUR = '#ff9900';
18
18
  const CRITICAL_COLOUR = '#e35858';