@contrast/agent 4.13.0 → 4.13.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/bootstrap.js CHANGED
@@ -47,9 +47,8 @@ Module.runMain = async function (...args) {
47
47
  loader.logTime(appStartTime, 'application');
48
48
  loader.logTime(startTime, 'agent & application');
49
49
  } catch (err) {
50
- // eslint-disable-next-line no-console
51
50
  console.error(err);
52
- // eslint-disable-next-line no-process-exit
53
- process.exit(-1);
51
+ process.exit(-1); // eslint-disable-line no-process-exit
52
+
54
53
  }
55
54
  };
package/esm.mjs CHANGED
@@ -125,10 +125,15 @@ export async function load(url, context, defaultLoad) {
125
125
  const filename = fileURLToPath(url);
126
126
 
127
127
  try {
128
+ let result;
128
129
  const cached = helpers.find(agent, filename);
129
- const source = cached || await readFile(filename, 'utf8');
130
- const result = rewriter.rewriteFile(source, filename, { sourceType: type === 'commonjs' ? 'script' : 'module' });
131
- helpers.cacheWithSourceMap(agent, filename, result);
130
+ if (cached) {
131
+ result = { code: cached };
132
+ } else {
133
+ const source = await readFile(filename, 'utf8');
134
+ result = rewriter.rewriteFile(source, filename, { sourceType: type === 'commonjs' ? 'script' : 'module' });
135
+ helpers.cacheWithSourceMap(agent, filename, result);
136
+ }
132
137
  return { format: type, source: result.code };
133
138
  } catch (err) {
134
139
  logger.error(
@@ -14,8 +14,6 @@ Copyright: 2022 Contrast Security, Inc
14
14
  */
15
15
  'use strict';
16
16
 
17
- /* eslint-disable prettier/prettier */
18
-
19
17
  const { PROXY_TARGET } = require('../../constants');
20
18
 
21
19
  class Debraner {
@@ -152,12 +152,10 @@ class Membrane {
152
152
  }
153
153
 
154
154
  includes(object) {
155
- // eslint-disable-next-line prettier/prettier
156
155
  return this.members.has(object) || this.members.has(Membrane.unwrap(object));
157
156
  }
158
157
 
159
158
  getMapping(object) {
160
- // eslint-disable-next-line prettier/prettier
161
159
  return this.members.get(object) || this.members.get(Membrane.unwrap(object));
162
160
  }
163
161
 
@@ -422,7 +420,7 @@ function copyMetadata(tar, prop, metadata) {
422
420
  });
423
421
 
424
422
  if (!nm.path) {
425
- nm.path = prop || `''`;
423
+ nm.path = prop || "''";
426
424
  } else if (nm.isArray) {
427
425
  nm.path += `[${prop}]`;
428
426
  } else if (prop) {
@@ -158,7 +158,7 @@ function trim(list, start, stop) {
158
158
  return trimmedList;
159
159
  }
160
160
 
161
- /* eslint-disable complexity */
161
+ // eslint-disable-next-line complexity
162
162
  function trimInPlace(list, start, stop) {
163
163
  if (start < 0) {
164
164
  logger.debug(
@@ -205,7 +205,6 @@ function trimInPlace(list, start, stop) {
205
205
  }
206
206
  }
207
207
  }
208
- /* eslint-enable complexity */
209
208
 
210
209
  /**
211
210
  * Returns a filtered lists of TagRanges by type
@@ -12,6 +12,8 @@ Copyright: 2022 Contrast Security, Inc
12
12
  engineered, modified, repackaged, sold, redistributed or otherwise used in a
13
13
  way not consistent with the End User License Agreement.
14
14
  */
15
+ 'use strict';
16
+
15
17
  /**
16
18
  * Contains helper functions used to manage the policy
17
19
  * Management of hooked functions that are defined in assess policies(e.g. deadzone.json, propagators.json, rules.json)
@@ -184,7 +186,6 @@ utils.patch = function(obj, path, props, hookOptions) {
184
186
  // this triggers, it /should/ be patched anyways.
185
187
  const refs = new WeakSet();
186
188
 
187
- /* eslint-disable complexity */
188
189
  /**
189
190
  * Recursively patch all exports on objects and classes
190
191
  * note cyclomatic check disabled because there's no place to break
@@ -195,6 +196,7 @@ const refs = new WeakSet();
195
196
  * @param {number} depth current recursion depth
196
197
  * @returns {Object|function} returns original reference but patched
197
198
  */
199
+ // eslint-disable-next-line complexity
198
200
  utils.patchRecursive = function(obj, hookOptions, depth) {
199
201
  let protoNeedsPatch = false;
200
202
  let propertyNames; // scoped value so that this doesn't need to be called twice.
@@ -242,7 +244,6 @@ utils.patchRecursive = function(obj, hookOptions, depth) {
242
244
 
243
245
  return obj;
244
246
  };
245
- /* eslint-enable complexity */
246
247
 
247
248
  /**
248
249
  * Patches either global module or a resolved
@@ -44,14 +44,12 @@ const patcher = require('../../../hooks/patcher');
44
44
  const { PATCH_TYPES } = require('../../../constants');
45
45
 
46
46
  function makeCanary() {
47
- /* eslint-disable prettier/prettier */
48
47
  return crypto
49
- .randomBytes(12)
50
- .toString('base64')
51
- // map regex special chars to other chars
52
- .replace(/\+/g, '%')
53
- .replace(/\//g, '#');
54
- /* eslint-enable prettier/prettier */
48
+ .randomBytes(12)
49
+ .toString('base64')
50
+ // map regex special chars to other chars
51
+ .replace(/\+/g, '%')
52
+ .replace(/\//g, '#');
55
53
  }
56
54
 
57
55
  // read canary as if the word was "marker". it's just a string inserted into the values
@@ -233,8 +231,7 @@ module.exports.handle = function() {
233
231
  if (isString(value)) {
234
232
  // make skeletal version of valProperties with only the tagRanges prop.
235
233
  data.metadata[id] =
236
- // eslint-disable-next-line prettier/prettier
237
- { tagRanges: [new TagRange(0, value.length - 1, '')] };
234
+ { tagRanges: [new TagRange(0, value.length - 1, '')] };
238
235
  value = `${canary}${id}~${value}`;
239
236
  id++;
240
237
  }
@@ -333,7 +330,6 @@ module.exports.handle = function() {
333
330
  // this check is required only for tests, i believe. sourceEvents should
334
331
  // always exist, even if an empty array, for production code.
335
332
  if (metadata.sourceEvents && !metadata.sourceEvents.length) {
336
- // eslint-disable-next-line prettier/prettier
337
333
  const { sourceEvents, braned } = data.metadata;
338
334
  if (braned) {
339
335
  sourceEvents.push(
@@ -381,7 +377,6 @@ module.exports.handle = function() {
381
377
  // we only find our marker at the start of a string value.
382
378
  canaryReplacementDiff += m.length - 1;
383
379
  for (const tr of metadata[id].tagRanges) {
384
- // eslint-disable-next-line prettier/prettier
385
380
  tagRanges.push(new TagRange(tr.start + offset, tr.stop + offset, tr.tag));
386
381
  }
387
382
 
@@ -31,7 +31,6 @@ function executeConditionals(schema) {
31
31
  // if the conditional has a validator to check its schema, do it.
32
32
  if (conditional.validator) {
33
33
  if (!conditional.validator(schema[key])) {
34
- // eslint-disable-next-line prettier/prettier
35
34
  this.logger.trace(`conditional schema ${key} not valid`);
36
35
  continue;
37
36
  }
@@ -44,7 +43,6 @@ function executeConditionals(schema) {
44
43
  }
45
44
 
46
45
  if ('if' in schema) {
47
- // eslint-disable-next-line prettier/prettier
48
46
  valid = handleIfThenElse.call(this, schema.if, schema.then, schema.else) && valid;
49
47
  }
50
48
 
@@ -158,7 +156,6 @@ const conditionalDispatch = new Map([
158
156
  ['allOf', { method: handleAllOf, validator: nonEmptyArray }]
159
157
  ]);
160
158
 
161
- /* eslint-enable prettier/prettier */
162
159
  const conditionals = [...conditionalDispatch.keys()];
163
160
 
164
161
  module.exports = {
@@ -32,12 +32,11 @@ function t_boolean(schema, ctx) {
32
32
  return typeof ctx.data === 'boolean';
33
33
  }
34
34
 
35
- /* eslint-disable complexity */
36
35
  //
37
36
  // type: number, integer
38
37
  //
38
+ // eslint-disable-next-line complexity
39
39
  function t_number(schema, ctx) {
40
- /* eslint-disable prettier/prettier */
41
40
 
42
41
  // ajv's number evaluation order
43
42
  // integer (if type: integer)
@@ -83,7 +82,6 @@ function t_number(schema, ctx) {
83
82
  if ('multipleOf' in schema && (ctx.data / schema.multipleOf) % 1 !== 0) {
84
83
  valid = false;
85
84
  }
86
- /* eslint-enable prettier/prettier */
87
85
 
88
86
  return valid;
89
87
  }
@@ -91,6 +89,7 @@ function t_number(schema, ctx) {
91
89
  //
92
90
  // type: string
93
91
  //
92
+ // eslint-disable-next-line complexity
94
93
  function t_string(schema, ctx) {
95
94
  // ajv's string evaluation order
96
95
  // maxLength
@@ -134,6 +133,7 @@ function t_string(schema, ctx) {
134
133
  //
135
134
  // type: array
136
135
  //
136
+ // eslint-disable-next-line complexity
137
137
  function t_array(schema, ctx) {
138
138
  if (!Array.isArray(ctx.data)) {
139
139
  return false;
@@ -248,6 +248,7 @@ function elementsAreUnique(data) {
248
248
  //
249
249
  // type: object
250
250
  //
251
+ // eslint-disable-next-line complexity
251
252
  function t_object(schema, ctx) {
252
253
  if (typeof ctx.data !== 'object') {
253
254
  return false;
@@ -431,6 +432,7 @@ function* matching(patternProps, prop, ctx) {
431
432
  //
432
433
  // type: object helper
433
434
  //
435
+ // eslint-disable-next-line complexity
434
436
  function evaluateObjectDependencies(schema, ctx) {
435
437
  const deps = schema.dependencies;
436
438
  let valid = true;
@@ -455,7 +457,6 @@ function evaluateObjectDependencies(schema, ctx) {
455
457
  }
456
458
  // it's an array! if key is present in this.data then all the properties
457
459
  // enumerated in the array (they're strings) must be present in this.data.
458
- // eslint-disable-next-line prettier/prettier
459
460
  if (key in ctx.data && !dep.every((requiredProp) => requiredProp in ctx.data)) {
460
461
  // allErrors: true - check ajv's handling
461
462
  valid = false;
@@ -40,7 +40,7 @@ const { objectWalk, objectOnlyWalk } = require('./object-walk');
40
40
  // when userSchema sees '#/$defs/street' it tries to dereference it as a *local* reference
41
41
  // because it has lost the addressSchema context.
42
42
  //
43
- /* eslint-disable complexity */
43
+ // eslint-disable-next-line complexity
44
44
  function evalInRefSchema(ref) {
45
45
  const ctx = this;
46
46
  const ix = ref.indexOf('#');
@@ -194,7 +194,6 @@ function findNoHashRef(ref, ctx) {
194
194
  // yes, really.
195
195
 
196
196
  // try simple path replacement first.
197
- // eslint-disable-next-line node/no-deprecated-api
198
197
  const urlParts = url.parse(ref);
199
198
  if (schemaUrl && !urlParts.host && urlParts.path === ref) {
200
199
  const newRef = `${schemaUrl.origin}/${ref}`;
@@ -19,8 +19,6 @@ const { evalInRefSchema } = require('./refs');
19
19
  const fastDeepEqual = require('fast-deep-equal');
20
20
  const { objectWalk } = require('./object-walk');
21
21
 
22
- /* eslint-disable complexity */
23
-
24
22
  class SchemaContext {
25
23
  constructor(shadow, schema, object, key, options) {
26
24
  const schemaName = schema.$id || '';
@@ -107,6 +105,7 @@ class SchemaContext {
107
105
  * @param {object} ctx context for the evaluation, as defined above in evaluate().
108
106
  * @returns {boolean} validation result
109
107
  */
108
+ // eslint-disable-next-line complexity
110
109
  evaluate(schema) {
111
110
  this.inferredType = false;
112
111
  // don't do any validation of strings if the schema is boolean. while
@@ -165,6 +164,7 @@ class SchemaContext {
165
164
  return false;
166
165
  }
167
166
 
167
+ // eslint-disable-next-line complexity
168
168
  typeSpecificEval(schema) {
169
169
  const { type } = this;
170
170
 
@@ -374,7 +374,6 @@ class SchemaContext {
374
374
 
375
375
  const t = require('./json-schema-type-evaluators');
376
376
 
377
- /* eslint-disable prettier/prettier */
378
377
  // map each JSON Schema type to the method name for it
379
378
  SchemaContext.typeDispatch = new Map([
380
379
  ['null', { method: t.null, enumerator: 'scalarEnum' }],
@@ -59,23 +59,31 @@ function splitString(str, win32) {
59
59
  * @param {number} offset offset of full arg from result of path.resolve
60
60
  * @param {string} segment path segment from one of the args to path.resolve
61
61
  */
62
- function getSegmentOffset({ str, evaluator }, offset, segment, win32) {
62
+ // eslint-disable-next-line complexity
63
+ function getSegmentOffset({ meta: { str, evaluator }, offset, segment, win32, validateAgainstResult }) {
63
64
  // as the segments in each arg and in the result get traversed,
64
65
  // winnow away the string to ensure we are finding the proper
65
66
  // segment within the path
66
67
  const substr = str.substring(offset);
67
- let segmentOffset = substr.indexOf(segment);
68
+ const { sep } = path[win32 ? 'win32' : 'posix'];
69
+ let segmentOffset;
70
+ // Sometimes the segment starts with a separator, but the path method removes the initial separator if the path is not absolute
71
+ if (validateAgainstResult && segment.startsWith(sep) && offset == 0 && !['\\', '/', '.'].includes(substr[0]) && !['\\', '/'].includes(segment)) {
72
+ segment = segment.slice(1);
73
+ }
74
+ segmentOffset = substr.indexOf(segment);
75
+
68
76
  // If tracking separators, evaluator will fail on extensions
69
77
  if (substr === `.${segment}`) {
70
- return segmentOffset + offset;
78
+ return { offset: segmentOffset + offset, value: segment };
71
79
  }
80
+
72
81
  // Adjust offset if the segment does not start with a separator
73
- const { sep } = path[win32 ? 'win32' : 'posix'];
74
82
  if (substr.startsWith(sep) && !segment.startsWith(sep)) {
75
83
  segmentOffset--;
76
84
  }
77
85
 
78
- return evaluator(segmentOffset) ? segmentOffset + offset : -1;
86
+ return { offset: evaluator(segmentOffset) ? segmentOffset + offset : -1, value: segment };
79
87
  }
80
88
 
81
89
  /**
@@ -215,15 +223,19 @@ function filterSegmentsAndCalculateOffset(
215
223
  additionalOffset = hasChange ? (sepAdded ? 1 : -1) : 0;
216
224
  }
217
225
 
218
- const offset = getSegmentOffset(
219
- resultMeta,
220
- accumulator.offset + additionalOffset + accumulator.fileDotSeparator,
226
+
227
+ const validatedSegment = getSegmentOffset({
228
+ meta: resultMeta,
229
+ offset: accumulator.offset + additionalOffset + accumulator.fileDotSeparator,
221
230
  segment,
222
- win32
223
- );
231
+ win32,
232
+ validateAgainstResult: true
233
+ });
234
+
235
+ const { offset: segmentOffset, value: segmentValue } = validatedSegment;
224
236
 
225
237
  // no reason to proceed if segment is not in final result
226
- if (offset === -1) {
238
+ if (segmentOffset === -1) {
227
239
  if (hasChange) {
228
240
  additionalOffset = 0;
229
241
  accumulator.isModified = false;
@@ -233,12 +245,11 @@ function filterSegmentsAndCalculateOffset(
233
245
  }
234
246
 
235
247
  // in case we have a file we need to increment the offset
236
- if (resultMeta.str[offset + segment.length] === '.') {
248
+ if (resultMeta.str[segmentOffset + segmentValue.length] === '.') {
237
249
  accumulator.fileDotSeparator = 1;
238
250
  }
239
-
240
- validSegments.push(segment);
241
- accumulator.offset = calculateNewOffset(accumulator.offset, segment);
251
+ validSegments.push(validatedSegment);
252
+ accumulator.offset = calculateNewOffset(accumulator.offset, segmentValue);
242
253
  accumulator.isModified = true;
243
254
 
244
255
  return accumulator;
@@ -280,26 +291,20 @@ function adjustTagsToPart(resultMeta, argMeta, win32, data, index) {
280
291
  resultMeta.offset += additionalOffset;
281
292
 
282
293
  return segments.reduce((newTags, segment) => {
283
- const offset = getSegmentOffset(
284
- resultMeta,
285
- resultMeta.offset,
286
- segment,
287
- win32
288
- );
289
-
290
- const argOffset = getSegmentOffset(argMeta, argMeta.offset, segment, win32);
294
+ const { offset, value: segmentValue } = segment;
295
+ const { offset: argOffset } = getSegmentOffset({ meta: argMeta, offset: argMeta.offset, segment: segmentValue, win32, validateAgainstResult: false });
291
296
 
292
297
  // updating the offset
293
- resultMeta.offset = calculateNewOffset(resultMeta.offset, segment);
294
- argMeta.offset = calculateNewOffset(argMeta.offset, segment);
298
+ resultMeta.offset = calculateNewOffset(resultMeta.offset, segmentValue);
299
+ argMeta.offset = calculateNewOffset(argMeta.offset, segmentValue);
295
300
 
296
301
  // in case we have a file we need to increment the offset
297
- if (resultMeta.str[offset + segment.length] === '.') {
302
+ if (resultMeta.str[offset + segment.value.length] === '.') {
298
303
  resultMeta.offset += 1;
299
304
  }
300
305
 
301
306
  tagRanges.forEach((tag) => {
302
- if (!isWithinTag(segment, argOffset, tag)) return;
307
+ if (!isWithinTag(segmentValue, argOffset, tag)) return;
303
308
 
304
309
  const start = adjustStart({
305
310
  tag,
@@ -310,7 +315,7 @@ function adjustTagsToPart(resultMeta, argMeta, win32, data, index) {
310
315
  tag,
311
316
  argOffset,
312
317
  offset,
313
- segment
318
+ segment: segmentValue
314
319
  });
315
320
 
316
321
  newTags.push(new TagRange(start, stop, tag.tag));
@@ -327,6 +332,7 @@ function propagate({ resultMeta, data, win32 }) {
327
332
 
328
333
  data.args.forEach((arg, index) => {
329
334
  const argData = tracker.getData(arg);
335
+
330
336
  maybeUpdateResultMeta({ resultMeta, index, arg });
331
337
 
332
338
  const argMeta = {
@@ -354,7 +360,10 @@ function propagate({ resultMeta, data, win32 }) {
354
360
  }
355
361
 
356
362
  function getResultMeta(data, method) {
357
- const offset = path.win32.isAbsolute(data.args[0]) ? 0 : process.cwd().length;
363
+ let offset = 0;
364
+ if (method === 'resolve' && !path.win32.isAbsolute(data.args[0])) {
365
+ offset = process.cwd().length;
366
+ }
358
367
 
359
368
  return {
360
369
  method: `path.${method}`,
@@ -19,6 +19,7 @@ const patcher = require('../../../hooks/patcher');
19
19
  const { PATCH_TYPES } = require('../../../constants');
20
20
  const { propagate, absolutePath, getResultMeta } = require('./common');
21
21
 
22
+
22
23
  /**
23
24
  * Entry point to propagator provider
24
25
  * This instruments path.resolve on
@@ -30,8 +30,7 @@ module.exports.isTracked = function isTracked(value) {
30
30
  * Function to get sql-string export. Caches the export on first call.
31
31
  */
32
32
  module.exports.getSequelizeString = function() {
33
- // eslint-disable-next-line node/no-unpublished-require
34
- const data = require('sequelize/lib/sql-string');
33
+ const data = require('sequelize/lib/sql-string'); // eslint-disable-line node/no-unpublished-require
35
34
  module.exports.getSequelizeString = () => data;
36
35
  return data;
37
36
  };
@@ -14,7 +14,6 @@ Copyright: 2022 Contrast Security, Inc
14
14
  */
15
15
  'use strict';
16
16
 
17
- // eslint-disable-next-line no-unused-vars
18
17
  const logger = require('../../../core/logger')('contrast:v8:propagator');
19
18
  const tracker = require('../../../tracker');
20
19
  const patcher = require('../../../hooks/patcher');
@@ -22,7 +22,7 @@ const logger = require('../../core/logger')('contrast:rules:static');
22
22
  const _ = require('lodash');
23
23
  const generate = require('@babel/generator').default;
24
24
  const { createHash } = require('../../util/trace-util');
25
- const natives = process.binding('natives'); // eslint-disable-line node/no-deprecated-api
25
+ const natives = process.binding('natives');
26
26
 
27
27
  module.exports = ({ agent }) => {
28
28
  const rule = {};
@@ -62,8 +62,8 @@ module.exports = ({ agent }) => {
62
62
  hash: createHash([ruleId, filename, lineNum]),
63
63
  // some empty props required for backwards compatibility
64
64
  props: {
65
- value: "''", // eslint-disable-line
66
- signature: "''", // eslint-disable-line
65
+ value: "''",
66
+ signature: "''",
67
67
  access: 1,
68
68
  name,
69
69
  className: '""',
@@ -311,8 +311,8 @@ class DebugLogFactory {
311
311
  logger.console = this.mute
312
312
  ? noop
313
313
  : function() {
314
- return console.log(...arguments); // eslint-disable-line
315
- };
314
+ return console.log(...arguments); // eslint-disable-line prefer-rest-params
315
+ };
316
316
 
317
317
  [...levelNames, 'console'].forEach((level) => {
318
318
  if (level === 'console') {
@@ -65,7 +65,8 @@ class Factory {
65
65
  const eventFrames = [];
66
66
  const clsFrames = [];
67
67
  const callsites = Factory.generateCallsites(target);
68
- /* eslint-disable complexity */
68
+
69
+ // eslint-disable-next-line complexity
69
70
  ret = (callsites || []).reduce((acc, callsite) => {
70
71
  if (Factory.isCallsiteValid(callsite)) {
71
72
  const frame = Factory.makeFrame(callsite);
@@ -69,7 +69,7 @@ class AhoCorasick {
69
69
  this.state = 0;
70
70
  }
71
71
 
72
- /* eslint-disable complexity */
72
+ // eslint-disable-next-line complexity
73
73
  buildAutomata() {
74
74
  // only the root state (state 0) to start with
75
75
  let stateCount = 1;
@@ -13,7 +13,6 @@ Copyright: 2022 Contrast Security, Inc
13
13
  way not consistent with the End User License Agreement.
14
14
  */
15
15
  'use strict';
16
- /* eslint-disable complexity */
17
16
  const _ = require('lodash');
18
17
  const util = require('util');
19
18
 
@@ -77,6 +76,7 @@ class NoSqlInjectionRule extends require('../') {
77
76
  * @param {SinkEvent} event Emitted by database drivers/wrappers/ORMs
78
77
  * @param {Set} applicableSamples set of Samples applicable to rule.
79
78
  */
79
+ // eslint-disable-next-line complexity
80
80
  evaluateAtSink({ event, applicableSamples }) {
81
81
  if (applicableSamples.size == 0 || !event.data) {
82
82
  return;
@@ -45,7 +45,6 @@ const ctors = {
45
45
  [RULES.BOT_BLOCKER]: require('./bot-blocker/bot-blocker-rule'),
46
46
  [RULES.IP_DENYLIST]: require('./ip-denylist/ip-denylist-rule'),
47
47
  [RULES.VIRTUAL_PATCH]: require('./virtual-patch/virtual-patch-rule'),
48
- /* eslint-enable */
49
48
  };
50
49
 
51
50
  class ProtectRuleFactory {
@@ -46,28 +46,23 @@ class UnknownConnectionState extends BaseConnectionState {
46
46
  * @param {SpeedracerBaseMessage} message
47
47
  * @returns {Promise}
48
48
  */
49
- send(message) {
50
- const { speedracer } = this;
51
- return new Promise(async (resolve, reject) => {
49
+ async send(message) {
50
+ try {
51
+ const clientResponse = await super.send(message);
52
+ this.speedracer.transitionConnectionState(SUCCESS);
53
+ return clientResponse;
54
+ } catch (err) {
55
+ // See if we need to start or wait for service
52
56
  try {
53
- const clientResponse = await super.send(message);
54
- speedracer.transitionConnectionState(SUCCESS);
55
- resolve(clientResponse);
57
+ await this.handleSendFailure(err);
58
+ await this.retryInitialization();
59
+ const result = await this.speedracer.send(message);
60
+ return result;
56
61
  } catch (err) {
57
- // See if we need to start or wait for service
58
- try {
59
- await this.handleSendFailure(err);
60
- await this.retryInitialization();
61
- // eslint-disable-next-line prettier/prettier
62
- speedracer.send(message)
63
- .then((r) => resolve(r))
64
- .catch((e) => reject(e));
65
- } catch (err) {
66
- speedracer.transitionConnectionState(FAILURE);
67
- reject(err);
68
- }
62
+ this.speedracer.transitionConnectionState(FAILURE);
63
+ throw err;
69
64
  }
70
- });
65
+ }
71
66
  }
72
67
 
73
68
  /**
@@ -106,25 +101,18 @@ class UnknownConnectionState extends BaseConnectionState {
106
101
  * messages.
107
102
  * @returns {Promise}
108
103
  */
109
- retryInitialization() {
104
+ async retryInitialization() {
110
105
  const startup = this.speedracer.messageCache.get('startup');
111
106
  const appcreate = this.speedracer.messageCache.get('appcreate');
112
107
 
113
108
  if (!startup || !appcreate) return Promise.resolve();
114
109
 
115
- return new Promise(async (resolve, reject) => {
116
- this.speedracer.logger.debug(
117
- 'Sending initialization messages to service'
118
- );
110
+ this.speedracer.logger.debug(
111
+ 'Sending initialization messages to service'
112
+ );
119
113
 
120
- try {
121
- await this.speedracer.send(startup);
122
- await this.speedracer.send(appcreate);
123
- resolve();
124
- } catch (err) {
125
- reject(err);
126
- }
127
- });
114
+ await this.speedracer.send(startup);
115
+ await this.speedracer.send(appcreate);
128
116
  }
129
117
 
130
118
  /**
@@ -36,7 +36,6 @@ function AssessFeatures({
36
36
  validatorScopes,
37
37
  validators = []
38
38
  } = {}) {
39
- /* eslint-disable no-sparse-arrays, prettier/prettier */
40
39
  return new settings.AssessFeatures([
41
40
  enabled, // 1 enabled
42
41
  dynamicSources, // 2 dynamic_sources
@@ -52,13 +51,12 @@ function AssessFeatures({
52
51
  validators.map(CustomRuleFeature).map(v => v.array), // 12 validators
53
52
  disabledRules, // 13 disabled_rules (deprecated)
54
53
  Sampling(sampling).array, // 14 sampling
55
- , // 15 -
56
- , // 16 -
57
- , // 17 -
58
- , // 18 -
54
+ undefined, // 15 -
55
+ undefined, // 16 -
56
+ undefined, // 17 -
57
+ undefined, // 18 -
59
58
  [] // 19 dynamic_sources_map
60
59
  ]);
61
- /* eslint-enable */
62
60
  }
63
61
 
64
62
  function AssessStacktrace(stacktraces) {
@@ -19,27 +19,23 @@ const parent = require('parent-package-json');
19
19
 
20
20
  // eslint-disable-next-line complexity
21
21
  function getType(filename) {
22
- const url = filename.startsWith('file://') ? filename : `file://${filename}`;
23
-
24
- const { protocol, pathname } = new URL(url);
22
+ if (filename.startsWith('node:')) {
23
+ return 'builtin';
24
+ }
25
+ filename = filename.replace('file://', '');
25
26
 
26
27
  let parentType = 'commonjs';
27
28
  try {
28
- parentType = parent(pathname).parse().type;
29
+ parentType = parent(filename).parse().type;
29
30
  } catch (err) {
30
31
  // Node assumes `commonjs ` if there's no `type` set in package.json
31
32
  }
32
33
 
33
- if (protocol === 'node:') {
34
- return 'builtin';
35
- }
36
- if (protocol === 'file:') {
37
- const ext = path.extname(pathname);
38
- if (ext === '.mjs' || (ext === '.js' && parentType === 'module')) {
39
- return 'module';
40
- } else if (ext === '.cjs' || (ext === '.js' && parentType !== 'module')) {
41
- return 'commonjs';
42
- }
34
+ const ext = path.extname(filename);
35
+ if (ext === '.mjs' || (ext === '.js' && parentType === 'module')) {
36
+ return 'module';
37
+ } else if (ext === '.cjs' || (ext === '.js' && parentType !== 'module')) {
38
+ return 'commonjs';
43
39
  }
44
40
  return 'unknown';
45
41
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/agent",
3
- "version": "4.13.0",
3
+ "version": "4.13.1",
4
4
  "description": "Node.js security instrumentation by Contrast Security",
5
5
  "keywords": [
6
6
  "security",
@@ -29,8 +29,8 @@
29
29
  ],
30
30
  "scripts": {
31
31
  "docs": "jsdoc -c ../.jsdoc.json",
32
- "release": "scripts/make-release.js",
33
- "tag": "scripts/tag-release.js",
32
+ "release": "node scripts/make-release.js",
33
+ "tag": "node scripts/tag-release.js",
34
34
  "test:debug": "scripts/test.sh debug",
35
35
  "test": "scripts/test.sh",
36
36
  "test:screener": "mocha --parallel test/screener/**/*test.js",
@@ -117,14 +117,14 @@
117
117
  "devDependencies": {
118
118
  "@aws-sdk/client-dynamodb": "^3.39.0",
119
119
  "@bmacnaughton/string-generator": "^1.0.0",
120
- "@contrast/eslint-config": "^3.0.0-beta.4",
120
+ "@contrast/eslint-config": "^3.0.0",
121
121
  "@contrast/fake-module": "file:test/mock/contrast-fake",
122
122
  "@contrast/screener-service": "^1.12.9",
123
123
  "@hapi/boom": "file:test/mock/boom",
124
124
  "@hapi/hapi": "file:test/mock/hapi",
125
125
  "@ls-lint/ls-lint": "^1.8.1",
126
- "@typescript-eslint/eslint-plugin": "^5.12.0",
127
- "@typescript-eslint/parser": "^5.12.0",
126
+ "@typescript-eslint/eslint-plugin": "^5.12.1",
127
+ "@typescript-eslint/parser": "^5.12.1",
128
128
  "ajv": "^8.5.0",
129
129
  "ast-types": "^0.12.4",
130
130
  "aws-sdk": "file:test/mock/aws-sdk",
@@ -142,10 +142,8 @@
142
142
  "ejs": "^3.1.6",
143
143
  "escape-html": "^1.0.3",
144
144
  "eslint": "^8.9.0",
145
- "eslint-config-prettier": "^8.3.0",
146
145
  "eslint-plugin-mocha": "^10.0.3",
147
146
  "eslint-plugin-node": "^11.1.0",
148
- "eslint-plugin-prettier": "^4.0.0",
149
147
  "express": "file:test/mock/express",
150
148
  "fetch-cookie": "^0.11.0",
151
149
  "form-data": "^3.0.0",
@@ -175,7 +173,6 @@
175
173
  "nyc": "^15.1.0",
176
174
  "pg": "file:test/mock/pg",
177
175
  "pino": "^6.7.0",
178
- "prettier": "^2.5.1",
179
176
  "proxyquire": "^2.1.0",
180
177
  "qs": "^6.9.4",
181
178
  "rethinkdb": "file:test/mock/rethinkdb",
package/perf-logs.js CHANGED
@@ -104,7 +104,6 @@ async function processFile(filename, filter, group) {
104
104
  continue;
105
105
  }
106
106
  if (!group) {
107
- // eslint-disable-next-line no-console
108
107
  console.log(JSON.stringify(data, null, 4));
109
108
  } else {
110
109
  const key = filter
@@ -125,7 +124,6 @@ async function processFile(filename, filter, group) {
125
124
  }
126
125
 
127
126
  if (group) {
128
- // eslint-disable-next-line no-console
129
127
  console.log(JSON.stringify(Object.values(merged), null, 4));
130
128
  }
131
129
  }
@@ -148,10 +146,9 @@ if (program.filter) {
148
146
  try {
149
147
  filterRegex = new RegExp(program.filter);
150
148
  } catch (e) {
151
- // eslint-disable-next-line no-console
152
149
  console.error('invalid filter regex');
153
- // eslint-disable-next-line no-process-exit
154
- process.exit(-1);
150
+ process.exit(-1); // eslint-disable-line no-process-exit
151
+
155
152
  }
156
153
  }
157
154