tangerine 1.5.0 → 1.5.2

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.
Files changed (3) hide show
  1. package/README.md +10 -6
  2. package/index.js +16 -16
  3. package/package.json +14 -14
package/README.md CHANGED
@@ -51,12 +51,12 @@
51
51
  * [`tangerine.resolveSoa(hostname[, options, abortController]))`](#tangerineresolvesoahostname-options-abortcontroller)
52
52
  * [`tangerine.resolveSrv(hostname[, options, abortController]))`](#tangerineresolvesrvhostname-options-abortcontroller)
53
53
  * [`tangerine.resolveTxt(hostname[, options, abortController]))`](#tangerineresolvetxthostname-options-abortcontroller)
54
- * [`tangerine.resolveCert(hostname, [, options, abortController]))`](#tangerineresolvecerthostname--options-abortcontroller)
55
- * [`tangerine.resolveTlsa(hostname, [, options, abortController]))`](#tangerineresolvetlsahostname--options-abortcontroller)
54
+ * [`tangerine.resolveCert(hostname[, options, abortController]))`](#tangerineresolvecerthostname-options-abortcontroller)
55
+ * [`tangerine.resolveTlsa(hostname[, options, abortController]))`](#tangerineresolvetlsahostname-options-abortcontroller)
56
56
  * [`tangerine.reverse(ip[, abortController, purgeCache])`](#tangerinereverseip-abortcontroller-purgecache)
57
57
  * [`tangerine.setDefaultResultOrder(order)`](#tangerinesetdefaultresultorderorder)
58
58
  * [`tangerine.setServers(servers)`](#tangerinesetserversservers)
59
- * [`tangerine.spoofPacket(hostname, rrtype, answers)`](#tangerinespoofpackethostname-rrtype-answers)
59
+ * [`tangerine.spoofPacket(hostname, rrtype, answers[, json, expires = 30000])`](#tangerinespoofpackethostname-rrtype-answers-json-expires--30000)
60
60
  * [Options](#options)
61
61
  * [Cache](#cache)
62
62
  * [Compatibility](#compatibility)
@@ -274,7 +274,7 @@ Tangerine supports a new `ecsSubnet` property in the `options` Object argument.
274
274
 
275
275
  ### `tangerine.resolveTxt(hostname[, options, abortController]))`
276
276
 
277
- ### `tangerine.resolveCert(hostname, [, options, abortController]))`
277
+ ### `tangerine.resolveCert(hostname[, options, abortController]))`
278
278
 
279
279
  This function returns a Promise that resolves with an Array with parsed values from results:
280
280
 
@@ -293,7 +293,7 @@ This function returns a Promise that resolves with an Array with parsed values f
293
293
 
294
294
  This mirrors output from <https://github.com/rthalley/dnspython>.
295
295
 
296
- ### `tangerine.resolveTlsa(hostname, [, options, abortController]))`
296
+ ### `tangerine.resolveTlsa(hostname[, options, abortController]))`
297
297
 
298
298
  This method was added for DANE and TLSA support. See this [excellent article](https://www.mailhardener.com/kb/dane), [index.js](https://github.com/forwardemail/tangerine/blob/main/index.js), and <https://github.com/nodejs/node/issues/39569> for more insight.
299
299
 
@@ -332,12 +332,16 @@ This mirrors output from <https://github.com/rthalley/dnspython>.
332
332
 
333
333
  ### `tangerine.setServers(servers)`
334
334
 
335
- ### `tangerine.spoofPacket(hostname, rrtype, answers)`
335
+ ### `tangerine.spoofPacket(hostname, rrtype, answers[, json, expires = 30000])`
336
336
 
337
337
  This method is useful for writing tests to spoof DNS packets in-memory.
338
338
 
339
339
  The `rrtype` must be either `"TXT"` or `"MX"`, and `answers` must be an Array of DNS resource record answers.
340
340
 
341
+ If you pass `json` as `true`, then value returned will be converted to JSON via `JSON.stringify`.
342
+
343
+ The last argument `expires` can either be a `Date` or `Number`. This is the value used for calculating the DNS packet expiration. If it is a `Number`, then the `expires` value will be `Date.now() + expires`. The default value is `30000`, which means it will expire in 30 seconds.
344
+
341
345
  For example, if you want to spoof TXT and MX records:
342
346
 
343
347
  ```js
package/index.js CHANGED
@@ -6,9 +6,7 @@ const { Buffer } = require('node:buffer');
6
6
  const { debuglog } = require('node:util');
7
7
  const { getEventListeners, setMaxListeners } = require('node:events');
8
8
  const { isIP, isIPv4, isIPv6 } = require('node:net');
9
-
10
9
  const { toASCII } = require('punycode/');
11
-
12
10
  const autoBind = require('auto-bind');
13
11
  const getStream = require('get-stream');
14
12
  const hostile = require('hostile');
@@ -21,7 +19,6 @@ const packet = require('dns-packet');
21
19
  const semver = require('semver');
22
20
  const structuredClone = require('@ungap/structured-clone').default;
23
21
  const { getService } = require('port-numbers');
24
-
25
22
  const pkg = require('./package.json');
26
23
 
27
24
  const debug = debuglog('tangerine');
@@ -123,21 +120,21 @@ class Tangerine extends dns.promises.Resolver {
123
120
 
124
121
  // if all errors had `name` and they were all the same then preserve it
125
122
  if (
126
- typeof errors[0].name !== 'undefined' &&
123
+ errors[0].name !== undefined &&
127
124
  errors.every((e) => e.name === errors[0].name)
128
125
  )
129
126
  err.name = errors[0].name;
130
127
 
131
128
  // if all errors had `code` and they were all the same then preserve it
132
129
  if (
133
- typeof errors[0].code !== 'undefined' &&
130
+ errors[0].code !== undefined &&
134
131
  errors.every((e) => e.code === errors[0].code)
135
132
  )
136
133
  err.code = errors[0].code;
137
134
 
138
135
  // if all errors had `errno` and they were all the same then preserve it
139
136
  if (
140
- typeof errors[0].errno !== 'undefined' &&
137
+ errors[0].errno !== undefined &&
141
138
  errors.every((e) => e.errno === errors[0].errno)
142
139
  )
143
140
  err.errno = errors[0].errno;
@@ -607,7 +604,7 @@ class Tangerine extends dns.promises.Resolver {
607
604
 
608
605
  options = { family: options };
609
606
  } else if (
610
- typeof options?.family !== 'undefined' &&
607
+ options?.family !== undefined &&
611
608
  ![0, 4, 6, 'IPv4', 'IPv6'].includes(options.family)
612
609
  ) {
613
610
  // validate family
@@ -761,7 +758,7 @@ class Tangerine extends dns.promises.Resolver {
761
758
  if (answers.length > 0)
762
759
  answers =
763
760
  answers[0].length > 0 &&
764
- (typeof options.family === 'undefined' || options.family === 0)
761
+ (options.family === undefined || options.family === 0)
765
762
  ? answers[0]
766
763
  : answers.flat();
767
764
 
@@ -1428,7 +1425,8 @@ class Tangerine extends dns.promises.Resolver {
1428
1425
  this.options.servers = new Set(servers);
1429
1426
  }
1430
1427
 
1431
- spoofPacket(name, rrtype, answers = []) {
1428
+ // eslint-disable-next-line max-params
1429
+ spoofPacket(name, rrtype, answers = [], json = false, expires = 30000) {
1432
1430
  if (typeof name !== 'string') {
1433
1431
  const err = new TypeError('The "name" argument must be of type string.');
1434
1432
  err.code = 'ERR_INVALID_ARG_TYPE';
@@ -1455,7 +1453,7 @@ class Tangerine extends dns.promises.Resolver {
1455
1453
  throw err;
1456
1454
  }
1457
1455
 
1458
- return {
1456
+ const obj = {
1459
1457
  id: 0,
1460
1458
  type: 'response',
1461
1459
  flags: 384,
@@ -1492,8 +1490,11 @@ class Tangerine extends dns.promises.Resolver {
1492
1490
  }
1493
1491
  ],
1494
1492
  ttl: 300,
1495
- expires: Date.now() + 10000
1493
+ expires:
1494
+ expires instanceof Date ? expires.getTime() : Date.now() + expires
1496
1495
  };
1496
+
1497
+ return json ? JSON.stringify(obj) : obj;
1497
1498
  }
1498
1499
 
1499
1500
  // eslint-disable-next-line complexity
@@ -1909,11 +1910,10 @@ class Tangerine extends dns.promises.Resolver {
1909
1910
  algorithm: answer.data.subarray(4, 5).readUInt8(),
1910
1911
  certificate: answer.data.subarray(5).toString('base64')
1911
1912
  };
1912
- obj.certificate_type = this.constructor.CTYPE_BY_VALUE[
1913
- obj.certificate_type
1914
- ]
1915
- ? this.constructor.CTYPE_BY_VALUE[obj.certificate_type]
1916
- : obj.certificate_type.toString();
1913
+ if (this.constructor.CTYPE_BY_VALUE[obj.certificate_type])
1914
+ obj.certificate_type =
1915
+ this.constructor.CTYPE_BY_VALUE[obj.certificate_type];
1916
+ else obj.certificate_type = obj.certificate_type.toString();
1917
1917
  return obj;
1918
1918
  } catch (err) {
1919
1919
  this.options.logger.error(err, { name, rrtype, options, answer });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tangerine",
3
3
  "description": "Tangerine is the best Node.js drop-in replacement for dns.promises.Resolver using DNS over HTTPS (\"DoH\") via undici with built-in retries, timeouts, smart server rotation, AbortControllers, and caching support for multiple backends (with TTL and purge support).",
4
- "version": "1.5.0",
4
+ "version": "1.5.2",
5
5
  "author": "Forward Email (https://forwardemail.net)",
6
6
  "bugs": {
7
7
  "url": "https://github.com/forwardemail/tangerine/issues"
@@ -10,9 +10,9 @@
10
10
  "Forward Email (https://forwardemail.net)"
11
11
  ],
12
12
  "dependencies": {
13
- "@ungap/structured-clone": "^1.0.2",
13
+ "@ungap/structured-clone": "^1.2.0",
14
14
  "auto-bind": "4",
15
- "dns-packet": "^5.4.0",
15
+ "dns-packet": "^5.6.0",
16
16
  "dohdec": "^5.0.3",
17
17
  "get-stream": "6",
18
18
  "hostile": "^1.3.3",
@@ -21,16 +21,16 @@
21
21
  "p-map": "4",
22
22
  "p-timeout": "4",
23
23
  "p-wait-for": "3",
24
- "port-numbers": "^6.0.1",
24
+ "port-numbers": "6.0.1",
25
25
  "private-ip": "^3.0.0",
26
26
  "punycode": "^2.3.0",
27
- "semver": "^7.3.8"
27
+ "semver": "^7.5.1"
28
28
  },
29
29
  "devDependencies": {
30
- "@commitlint/cli": "^17.4.4",
31
- "@commitlint/config-conventional": "^17.4.4",
30
+ "@commitlint/cli": "^17.6.3",
31
+ "@commitlint/config-conventional": "^17.6.3",
32
32
  "ava": "^5.2.0",
33
- "axios": "^1.3.4",
33
+ "axios": "^1.4.0",
34
34
  "benchmark": "^2.1.4",
35
35
  "cross-env": "^7.0.3",
36
36
  "eslint": "^8.34.0",
@@ -39,12 +39,12 @@
39
39
  "fixpack": "^4.0.0",
40
40
  "got": "11",
41
41
  "husky": "^8.0.3",
42
- "ioredis": "^5.3.1",
43
- "ioredis-mock": "^8.2.6",
42
+ "ioredis": "^5.3.2",
43
+ "ioredis-mock": "^8.7.0",
44
44
  "is-ci": "^3.0.1",
45
- "lint-staged": "^13.1.2",
45
+ "lint-staged": "^13.2.2",
46
46
  "lodash": "^4.17.21",
47
- "nock": "^13.3.0",
47
+ "nock": "^13.3.1",
48
48
  "node-fetch": "2",
49
49
  "nyc": "^15.1.0",
50
50
  "phin": "^3.7.0",
@@ -53,8 +53,8 @@
53
53
  "request": "^2.88.2",
54
54
  "sort-keys": "4.2.0",
55
55
  "superagent": "^8.0.9",
56
- "undici": "^5.20.0",
57
- "xo": "^0.53.1"
56
+ "undici": "^5.22.1",
57
+ "xo": "^0.54.2"
58
58
  },
59
59
  "engines": {
60
60
  "node": ">=16"