@contrast/agentify 1.24.2 → 1.25.1

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.
package/lib/index.js CHANGED
@@ -16,11 +16,12 @@
16
16
  'use strict';
17
17
 
18
18
  const Module = require('module');
19
- const { IntentionalError } = require('@contrast/common');
20
19
  const {
21
20
  assertValidOpts,
22
- preStartupValidation
21
+ preStartupValidation,
22
+ postConfigValidation,
23
23
  } = require('./utils');
24
+ const { IntentionalError } = require('@contrast/common');
24
25
 
25
26
  const ERROR_MESSAGE = 'An error prevented the Contrast agent from installing. The application will be run without instrumentation.';
26
27
  /**
@@ -136,16 +137,12 @@ module.exports = function init(core = {}) {
136
137
 
137
138
  require('@contrast/core/lib/messages')(core);
138
139
  require('@contrast/config')(core);
139
- if (core.config._errors?.length) {
140
- throw core.config._errors[0];
141
- }
142
- if (!core.config.enable) {
143
- const errorMessage = 'Contrast agent disabled by configuration (enable: false)';
144
- console.info(errorMessage);
145
- throw new IntentionalError(errorMessage);
146
- }
147
140
 
148
141
  require('@contrast/logger').default(core);
142
+
143
+ // validate the config now that the logger has been installed
144
+ postConfigValidation(core);
145
+
149
146
  require('@contrast/core/lib/agent-info')(core);
150
147
  require('@contrast/core/lib/system-info')(core);
151
148
  require('@contrast/core/lib/app-info')(core);
@@ -177,7 +174,6 @@ module.exports = function init(core = {}) {
177
174
  return core;
178
175
  };
179
176
 
180
- // ignore intentional errors
181
177
  if (!(err instanceof IntentionalError)) {
182
178
  if (core.logger) {
183
179
  core.logger.error({ err }, ERROR_MESSAGE);
@@ -26,26 +26,38 @@ const DEADZONED_PATHS = [
26
26
  'bcrypt',
27
27
  'bcrypt-nodejs',
28
28
  'bcryptjs', // node_modules/bcryptjs/index.js, node_modules/bcryptjs/dist/bcrypt.js
29
+ '@babel', // this should handle all namespaced packages
29
30
  'babel',
30
31
  'babel-cli',
31
32
  'babel-core',
33
+ 'babel-traverse',
34
+ 'babel-generator',
35
+ 'babylon',
36
+ 'bn.js',
32
37
  'browserify',
38
+ 'bson',
33
39
  'bunyan',
34
- 'coffee-script',
40
+ '@cyclonedx/cyclonedx-library',
41
+ 'coffeescript',
35
42
  'compression',
36
- // 'cookie', // todo: verify this doesn't break sources/propagation
37
- // 'cookie-signature', // ditto
38
- 'gzippo',
39
- // 'handlebars', // ditto
43
+ 'etag',
44
+ // 'cookie', // todo: verify this doesn't break sources/propagation (*)
45
+ // 'cookie-signature', // (*)
46
+ 'gzippo', // 149 weekly downloads
47
+ // 'handlebars', // (*)
40
48
  'handlebars-precompiler',
41
49
  // 'hbs', // ditto
42
50
  'html-webpack-plugin',
51
+ 'iconv-lite',
43
52
  'jquery',
44
53
  'jsrsasign',
45
- 'iconv-lite',
46
54
  'less',
47
- 'logger-console',
55
+ // 'dustjs-linkedin', // todo
56
+ 'logger-console', // 2 weekly downloads
48
57
  'loopback-datasource-juggler',
58
+ 'moment',
59
+ 'moment-timezone',
60
+ 'node-forge',
49
61
  'node-webpack',
50
62
  'react',
51
63
  'react-dom',
@@ -53,11 +65,8 @@ const DEADZONED_PATHS = [
53
65
  'requirejs',
54
66
  'semver',
55
67
  'strong-remoting',
68
+ 'type-is',
56
69
  'uglify-js',
57
- 'bn.js',
58
- 'node-forge',
59
- 'moment',
60
- 'moment-timezone'
61
70
  ].map((pkgName) => ['node_modules', pkgName, ''].join(sep));
62
71
 
63
72
  module.exports = function rewriteIsDeadzoned(filename) {
package/lib/utils.js CHANGED
@@ -18,6 +18,7 @@
18
18
  const path = require('path');
19
19
  const process = require('process');
20
20
  const semver = require('semver');
21
+ const { IntentionalError } = require('@contrast/common');
21
22
  const { findPackageJsonSync } = require('@contrast/find-package-json');
22
23
  const {
23
24
  engines: {
@@ -128,6 +129,79 @@ function isLoader(arg) {
128
129
  return arg == '--import' || arg == '--loader' || arg == '--experimental-loader';
129
130
  }
130
131
 
132
+ /**
133
+ * Check that the config contains the minimum required settings. Issue appropriate
134
+ * error messages.
135
+ * @throws IntentionalError
136
+ */
137
+ function postConfigValidation(core) {
138
+ // find out if any required settings are missing.
139
+ const missingRequiredSettings = [];
140
+ // these are only required if the API is enabled. if api.enable is false, it
141
+ // had to be set by the user because it defaults to true.
142
+ if (core.config.getEffectiveValue('api.enable')) {
143
+ for (const setting of ['api.api_key', 'api.service_key', 'api.user_name']) {
144
+ if (!core.config.getEffectiveValue(setting)) {
145
+ missingRequiredSettings.push(setting);
146
+ }
147
+ }
148
+ }
149
+
150
+ // v4 accepted `-c` or `--configFile` option in argv, but v5 does not. so if
151
+ // something that looks like a config flag is present on the command line, we
152
+ // log it. the worst case is that it's a false positive; if that's a problem
153
+ // we can make it an info level, but the goal here is for the user to see it
154
+ // without having to contact customer support and rerun their test at a more
155
+ // verbose log level.
156
+ const configFlag = getConfigFlag(process.argv);
157
+ if (configFlag) {
158
+ const msg = `Command line config flag present: ${configFlag[0]} ${configFlag[1]}`;
159
+
160
+ if (core.logger) {
161
+ core.logger.warn(msg);
162
+ } else {
163
+ console.warn(msg);
164
+ }
165
+ }
166
+
167
+ if (missingRequiredSettings.length) {
168
+ const reason = `Missing required settings: ${missingRequiredSettings.join(', ')}`;
169
+ const finalMsg = 'A configuration error prevents the Contrast agent from starting.';
170
+ if (core.logger) {
171
+ core.logger.error({ reason }, finalMsg);
172
+ } else {
173
+ console.error(reason, finalMsg);
174
+ }
175
+ throw new IntentionalError(finalMsg);
176
+ }
177
+
178
+ // now check for serious errors, like file not readable, file format is wrong, etc.
179
+ // that were captured when building the config.
180
+ if (core.config._errors?.length) {
181
+ throw core.config._errors[0];
182
+ }
183
+ // finally, was it disabled?
184
+ if (!core.config.enable) {
185
+ const errorMessage = 'Contrast agent disabled by configuration (enable: false)';
186
+ throw new IntentionalError(errorMessage);
187
+ }
188
+ }
189
+
190
+ function getConfigFlag(argv) {
191
+ for (let i = 0; i < argv.length - 1; i++) {
192
+ if (argv[i] === '-c' || argv[i] === '--configFile') {
193
+ // should this check to see if the name looks like a contrast config file?
194
+ // let's not because that seems false-negative prone.
195
+
196
+ // if the next arg is another flag, then this isn't a contrast config flag
197
+ if (!argv[i + 1].startsWith('-') && argv[i + 1].toLowerCase().includes('contrast')) {
198
+ return argv.slice(i, i + 2);
199
+ }
200
+ }
201
+ }
202
+ return undefined;
203
+ }
204
+
131
205
  /**
132
206
  * Validates custom `installOrder` options. We currently need the reporter component
133
207
  * to install first in order to onboard and get effective settings and mode values.
@@ -150,4 +224,6 @@ module.exports = {
150
224
  assertSupportedNodeVersion,
151
225
  assertSupportedPreloadUsage,
152
226
  preStartupValidation,
227
+ postConfigValidation,
228
+ getConfigFlag,
153
229
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/agentify",
3
- "version": "1.24.2",
3
+ "version": "1.25.1",
4
4
  "description": "Configures Contrast agent services and instrumentation within an application",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "Contrast Security <nodejs@contrastsecurity.com> (https://www.contrastsecurity.com)",
@@ -17,19 +17,19 @@
17
17
  "test": "../scripts/test.sh"
18
18
  },
19
19
  "dependencies": {
20
- "@contrast/common": "1.20.1",
21
- "@contrast/config": "1.27.1",
22
- "@contrast/core": "1.31.2",
23
- "@contrast/deadzones": "1.1.3",
20
+ "@contrast/common": "1.21.0",
21
+ "@contrast/config": "1.28.0",
22
+ "@contrast/core": "1.32.0",
23
+ "@contrast/deadzones": "1.2.0",
24
24
  "@contrast/dep-hooks": "1.3.2",
25
- "@contrast/esm-hooks": "2.5.2",
25
+ "@contrast/esm-hooks": "2.6.0",
26
26
  "@contrast/find-package-json": "^1.1.0",
27
- "@contrast/instrumentation": "1.7.1",
28
- "@contrast/logger": "1.8.1",
29
- "@contrast/metrics": "1.7.1",
27
+ "@contrast/instrumentation": "1.8.0",
28
+ "@contrast/logger": "1.8.2",
29
+ "@contrast/metrics": "1.8.0",
30
30
  "@contrast/patcher": "1.7.2",
31
- "@contrast/reporter": "1.26.1",
32
- "@contrast/rewriter": "1.7.2",
31
+ "@contrast/reporter": "1.27.0",
32
+ "@contrast/rewriter": "1.8.0",
33
33
  "@contrast/scopes": "1.4.1",
34
34
  "semver": "^7.6.0"
35
35
  }