@contrast/agentify 1.3.1 → 1.4.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.
@@ -15,7 +15,7 @@
15
15
 
16
16
  'use strict';
17
17
 
18
- module.exports = function(core) {
18
+ module.exports = function (core) {
19
19
  const { logger, patcher } = core;
20
20
 
21
21
  const getOrig = (v) => patcher.unwrap(v);
@@ -28,70 +28,123 @@ module.exports = function(core) {
28
28
  * 2) patch those functions on `contrastMethods.api` in order to add instrumentation
29
29
  */
30
30
  const contrastMethods = {
31
- // TODO: Assess will require add'l methods
32
- // TODO: ESM will require add'l methods
33
31
  api: {
34
32
  eval(v) {
35
33
  return v;
36
34
  },
37
- plus(left, right) {
35
+
36
+ // Binary Operators
37
+ add(left, right) {
38
38
  const ret = getOrig(left) + getOrig(right);
39
39
  return ret;
40
40
  },
41
- doubleEqual(left, right) {
41
+ eqEq(left, right) {
42
42
  left = getOrig(left);
43
43
  right = getOrig(right);
44
44
 
45
45
  return left == right;
46
46
  },
47
- notTripleEqual(left, right) {
47
+ eqEqEq(left, right) {
48
48
  left = getOrig(left);
49
49
  right = getOrig(right);
50
50
 
51
- return left !== right;
51
+ return left === right;
52
52
  },
53
- tripleEqual(left, right) {
53
+ notEqEq(left, right) {
54
54
  left = getOrig(left);
55
55
  right = getOrig(right);
56
56
 
57
- return left === right;
57
+ return left !== right;
58
58
  },
59
- notDoubleEqual(left, right) {
59
+ notEq(left, right) {
60
60
  left = getOrig(left);
61
61
  right = getOrig(right);
62
62
 
63
63
  return left != right;
64
64
  },
65
+
66
+ // Computed Properties
67
+ // Used to force a copy of handle:
68
+ // https://stackoverflow.com/a/31733628
69
+ // This is a workaround for CONTRAST-30333, in which something we
70
+ // suspect is a v8 bug means that handle will otherwise be clobbered
71
+ // and if it was externalized, we will lose the data associated with it
65
72
  forceCopy(handle) {
66
- // Used to force a copy of handle:
67
- // https://stackoverflow.com/a/31733628
68
- // This is a workaround for CONTRAST-30333, in which something we
69
- // suspect is a v8 bug means that handle will otherwise be clobbered
70
- // and if it was externalized, we will lose the data associated with it
71
73
  if (typeof handle === 'string') {
72
74
  handle = toUntrackedString(handle);
73
75
  }
74
76
  return handle;
75
77
  },
76
- cast: function __cast(val) {
78
+
79
+ // Switch Case
80
+ cast(val) {
77
81
  return getOrig(val);
78
82
  },
79
- tag: function __contrastTag(strings) {
80
- // XXX implemented in lib/assess/propagators/templates.js
83
+
84
+ /**
85
+ * Tagged Templates
86
+ * The first argument received by the tag function is an array of strings.
87
+ * For any template literal, its length is equal to the number of
88
+ * substitutions (occurrences of ${...}) plus one, and is therefore always
89
+ * non-empty.
90
+ * see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates
91
+ * @param {string[]} strings length n+1
92
+ * @param {string[]} args length n
93
+ * @returns {string}
94
+ */
95
+ tag(strings, ...args) {
96
+ const [first, ...rest] = strings;
97
+
98
+ return rest.reduce(
99
+ (result, str, i) => result.concat(args[i], str),
100
+ first,
101
+ );
102
+ },
103
+
104
+ // Import Statements
105
+ importDefault(...args) {
106
+ // noop
81
107
  },
82
108
 
109
+ importStarAs(...args) {
110
+ // noop
111
+ },
112
+
113
+ importNamed(...args) {
114
+ // noop
115
+ },
116
+
117
+ // Injections
83
118
  Function: core.patcher.patch(global.Function, {
84
119
  name: 'global.Function',
85
- patchType: 'rewrite-injection'
120
+ patchType: 'rewrite-injection',
121
+ }),
122
+ JSON: core.patcher.patch(global.JSON, {
123
+ name: 'global.JSON',
124
+ patchType: 'rewrite-injection',
125
+ }),
126
+ Number: core.patcher.patch(global.Number, {
127
+ name: 'global.Number',
128
+ patchType: 'rewrite-injection',
129
+ }),
130
+ Object: core.patcher.patch(global.Object, {
131
+ name: 'global.Object',
132
+ patchType: 'rewrite-injection',
133
+ }),
134
+ String: core.patcher.patch(global.String, {
135
+ name: 'global.String',
136
+ patchType: 'rewrite-injection',
86
137
  }),
87
138
  },
139
+
88
140
  installed: false,
141
+
89
142
  getGlobal() {
90
143
  return global;
91
- }
144
+ },
92
145
  };
93
146
 
94
- contrastMethods.install = function() {
147
+ contrastMethods.install = function () {
95
148
  if (contrastMethods.installed) {
96
149
  return;
97
150
  }
@@ -102,15 +155,15 @@ module.exports = function(core) {
102
155
  Object.defineProperty(global, 'ContrastMethods', {
103
156
  enumerable: true,
104
157
  configurable: false,
105
- value: contrastMethods.api
158
+ value: contrastMethods.api,
106
159
  });
107
160
  contrastMethods.installed = true;
108
161
  } catch (err) {
109
162
  // We should never expect this since the installation process is well
110
163
  // controlled, but still we should have the defensive code.
111
- logger.error({ err }, 'Unable to install global.ContrastMethods');
164
+ logger.error({ err }, 'Unable to inject global.ContrastMethods');
112
165
  }
113
166
  };
114
167
 
115
- return core.contrastMethods = contrastMethods;
168
+ return (core.contrastMethods = contrastMethods);
116
169
  };
@@ -81,7 +81,7 @@ module.exports = function (deps) {
81
81
  unwritten = rewriter.unwrite(unwritten);
82
82
  unwritten = unwritten.replace(METHOD_CONTEXT, '');
83
83
  unwritten = unwritten.replace(FUNCTION_CONTEXT, '');
84
- unwritten = unwritten.replace(/;$/, ''); // removes trailing semicolon
84
+ unwritten = unwritten.replace(/;\s*$/, ''); // removes trailing semicolon/whitespace
85
85
  return unwritten;
86
86
  } catch (err) {
87
87
  logger.warn({ err, code }, 'Failed to unwrite function code');
package/lib/index.js CHANGED
@@ -31,7 +31,8 @@ const defaultOpts = {
31
31
  'assess',
32
32
  'protect',
33
33
  'depHooks',
34
- 'enhancedLibraryUsage',
34
+ 'routeCoverage',
35
+ 'libraryAnalysis',
35
36
  'rewriteHooks',
36
37
  'functionHooks'
37
38
  ]
@@ -106,7 +107,7 @@ class Agent {
106
107
  await self.handleInstallFailure(err);
107
108
  }
108
109
 
109
- self.logEffectiveConfig();
110
+ self.logDiagnosticFiles();
110
111
  return self.runMain.apply(this, args);
111
112
  };
112
113
  }
@@ -135,29 +136,39 @@ class Agent {
135
136
  }
136
137
  }
137
138
 
138
- logEffectiveConfig() {
139
- const { config, getEffectiveConfig } = this.core;
139
+ logDiagnosticFiles() {
140
+ const { agentName, agentVersion, config, getEffectiveConfig, getSystemInfo } = this.core;
140
141
 
141
- if (config._flat['agent.diagnostics.enable'] !== false) {
142
- const content = JSON.stringify(getEffectiveConfig(), null, 2).concat('\n\n');
142
+ if (config.agent.diagnostics.enable !== false) {
143
+ const effectiveConfig = JSON.stringify(getEffectiveConfig(), null, 2).concat('\n\n');
143
144
 
144
- if (config._flat['agent.diagnostics.quiet'] !== true) {
145
- fs.writeFileSync(1, content, 'utf8');
145
+ let systemInfo = getSystemInfo();
146
+ systemInfo.Contrast.Agent = {
147
+ Name: agentName,
148
+ Version: agentVersion,
149
+ };
150
+
151
+ systemInfo = JSON.stringify(systemInfo, null, 2).concat('\n\n');
152
+ if (!config.agent.diagnostics.quiet) {
153
+ fs.writeFileSync(1, effectiveConfig, 'utf8');
154
+ fs.writeFileSync(1, systemInfo, 'utf8');
146
155
  }
147
156
 
148
- let outputDir = config._flat['agent.diagnostics.report_path'];
157
+ let outputDir = config.agent.diagnostics.report_path;
149
158
  if (!outputDir && config.agent.logger.path) {
150
- outputDir = path.join(config.agent.logger.path, '../contrast_effective_config.json');
159
+ outputDir = path.join(config.agent.logger.path, '..');
151
160
  }
152
161
 
153
162
  try {
154
- fs.writeFileSync(outputDir, content, 'utf-8');
163
+ fs.writeFileSync(path.join(outputDir, 'contrast_effective_config.json'), effectiveConfig, 'utf-8');
164
+ fs.writeFileSync(path.join(outputDir, 'contrast_system_info.json'), systemInfo, 'utf-8');
155
165
  } catch (err) {
156
- outputDir = path.join(process.cwd(), 'contrast_effective_config.json');
166
+ outputDir = path.join(process.cwd());
157
167
  try {
158
- fs.writeFileSync(outputDir, content, 'utf-8');
168
+ fs.writeFileSync(path.join(outputDir, 'contrast_effective_config.json'), effectiveConfig, 'utf-8');
169
+ fs.writeFileSync(path.join(outputDir, 'contrast_system_info.json'), systemInfo, 'utf-8');
159
170
  } catch (err) {
160
- fs.writeFileSync(1, `Couldn't create effective config file: ${err}`, 'utf-8');
171
+ fs.writeFileSync(1, `Couldn't create the diagnostic files: ${err}`, 'utf-8');
161
172
  }
162
173
  }
163
174
  }
@@ -27,7 +27,12 @@ module.exports = function(deps) {
27
27
 
28
28
  Module.prototype._compile = function(content, filename) {
29
29
  let compiled;
30
- const { code } = deps.rewriter.rewrite(content, { filename, inject: true, wrap: true });
30
+ const { code } = deps.rewriter.rewrite(content, {
31
+ filename,
32
+ isModule: false,
33
+ inject: true,
34
+ wrap: true,
35
+ });
31
36
 
32
37
  try {
33
38
  compiled = origCompile.call(this, code, filename);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/agentify",
3
- "version": "1.3.1",
3
+ "version": "1.4.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)",
@@ -16,4 +16,4 @@
16
16
  "scripts": {
17
17
  "test": "../scripts/test.sh"
18
18
  }
19
- }
19
+ }