@contrast/contrast 1.0.18 → 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.
@@ -185,6 +185,7 @@ const scanOptionDefinitions = [
185
185
  }
186
186
  ];
187
187
  const authOptionDefinitions = [
188
+ ...sharedConnectionOptionDefinitions,
188
189
  {
189
190
  name: 'help',
190
191
  alias: 'h',
@@ -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
  };
@@ -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
  };
@@ -79,6 +80,16 @@ const findCommandOnError = unknownOptions => {
79
80
  return foundCommands[0];
80
81
  }
81
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
+ };
82
93
  module.exports = {
83
94
  genericError,
84
95
  unauthenticatedError,
@@ -95,5 +106,6 @@ module.exports = {
95
106
  reportFailureError,
96
107
  maxAppError,
97
108
  parametersError,
98
- invalidHostNameError
109
+ invalidHostNameError,
110
+ commonMessageFormatter
99
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.18';
15
+ const APP_VERSION = '1.0.19';
16
16
  const TIMEOUT = 120000;
17
17
  const HIGH_COLOUR = '#ff9900';
18
18
  const CRITICAL_COLOUR = '#e35858';
@@ -216,6 +216,18 @@ const en_locales = () => {
216
216
  commonHelpLearnMoreEnterpriseText: ' https://docs.contrastsecurity.com/en/run-contrast-cli.html ',
217
217
  commonHelpJoinDiscussionHeader: chalk.hex('#9DC184')('Join the discussion:'),
218
218
  commonHelpJoinDiscussionText: ' https://dev.to/codesec',
219
+ authCommand: {
220
+ credentialsAccepted: {
221
+ title: 'Credentials accepted',
222
+ body: 'Now run contrast audit, lambda or scan',
223
+ extra: 'Or contrast help for full list of commands'
224
+ },
225
+ credentialsMissing: {
226
+ title: 'Credentials missing',
227
+ body: 'You have not entered the right parameters or enough information',
228
+ extra: 'Please check and try again e.g. contrast auth --api-key yourApiKey--organization-id yourOrg --authorization yourAuth --host https://yourHost\nOr contrast help for full list of commands'
229
+ }
230
+ },
219
231
  ...lambda
220
232
  };
221
233
  };
@@ -21,6 +21,6 @@ const setConfigValues = (config, values) => {
21
21
  config.set('apiKey', values.apiKey);
22
22
  config.set('organizationId', values.orgId);
23
23
  config.set('authorization', values.authHeader);
24
- values.host ? config.set('host', values.host) : null;
24
+ values.host ? config.set('host', values.host) : config.set('host', constants_1.CE_URL);
25
25
  };
26
26
  exports.setConfigValues = setConfigValues;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/contrast",
3
- "version": "1.0.18",
3
+ "version": "1.0.19",
4
4
  "description": "Contrast Security's command line tool",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -211,6 +211,7 @@ const scanOptionDefinitions = [
211
211
  ]
212
212
 
213
213
  const authOptionDefinitions = [
214
+ ...sharedConnectionOptionDefinitions,
214
215
  {
215
216
  name: 'help',
216
217
  alias: 'h',
@@ -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
  }
@@ -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'))
@@ -124,6 +125,17 @@ const findCommandOnError = unknownOptions => {
124
125
  }
125
126
  }
126
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
+
127
139
  module.exports = {
128
140
  genericError,
129
141
  unauthenticatedError,
@@ -140,5 +152,6 @@ module.exports = {
140
152
  reportFailureError,
141
153
  maxAppError,
142
154
  parametersError,
143
- invalidHostNameError
155
+ invalidHostNameError,
156
+ commonMessageFormatter
144
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.18'
17
+ const APP_VERSION = '1.0.19'
18
18
  const TIMEOUT = 120000
19
19
  const HIGH_COLOUR = '#ff9900'
20
20
  const CRITICAL_COLOUR = '#e35858'
@@ -317,6 +317,19 @@ const en_locales = () => {
317
317
  'Join the discussion:'
318
318
  ),
319
319
  commonHelpJoinDiscussionText: ' https://dev.to/codesec',
320
+ authCommand: {
321
+ credentialsAccepted: {
322
+ title: 'Credentials accepted',
323
+ body: 'Now run contrast audit, lambda or scan',
324
+ extra: 'Or contrast help for full list of commands'
325
+ },
326
+ credentialsMissing: {
327
+ title: 'Credentials missing',
328
+ body: 'You have not entered the right parameters or enough information',
329
+ extra:
330
+ 'Please check and try again e.g. contrast auth --api-key yourApiKey--organization-id yourOrg --authorization yourAuth --host https://yourHost\nOr contrast help for full list of commands'
331
+ }
332
+ },
320
333
  ...lambda
321
334
  }
322
335
  }
@@ -29,7 +29,7 @@ const setConfigValues = (config: ContrastConf, values: ContrastConfOptions) => {
29
29
  config.set('apiKey', values.apiKey)
30
30
  config.set('organizationId', values.orgId)
31
31
  config.set('authorization', values.authHeader)
32
- values.host ? config.set('host', values.host) : null
32
+ values.host ? config.set('host', values.host) : config.set('host', CE_URL)
33
33
  }
34
34
 
35
35
  export { localConfig, setConfigValues, ContrastConf, ContrastConfOptions }