tangerine 1.4.1 → 1.4.3
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/index.js +64 -9
- package/package.json +2 -1
package/index.js
CHANGED
|
@@ -7,7 +7,7 @@ const { debuglog } = require('node:util');
|
|
|
7
7
|
const { getEventListeners, setMaxListeners } = require('node:events');
|
|
8
8
|
const { isIP, isIPv4, isIPv6 } = require('node:net');
|
|
9
9
|
|
|
10
|
-
const
|
|
10
|
+
const autoBind = require('auto-bind');
|
|
11
11
|
const getStream = require('get-stream');
|
|
12
12
|
const ipaddr = require('ipaddr.js');
|
|
13
13
|
const mergeOptions = require('merge-options');
|
|
@@ -18,6 +18,8 @@ const packet = require('dns-packet');
|
|
|
18
18
|
const semver = require('semver');
|
|
19
19
|
const structuredClone = require('@ungap/structured-clone').default;
|
|
20
20
|
const { getService } = require('port-numbers');
|
|
21
|
+
// eslint-disable-next-line import/order
|
|
22
|
+
const { toASCII } = require('punycode/');
|
|
21
23
|
|
|
22
24
|
const pkg = require('./package.json');
|
|
23
25
|
|
|
@@ -363,6 +365,13 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
363
365
|
|
|
364
366
|
// manage set of abort controllers
|
|
365
367
|
this.abortControllers = new Set();
|
|
368
|
+
|
|
369
|
+
//
|
|
370
|
+
// NOTE: bind methods so we don't have to programmatically call `.bind`
|
|
371
|
+
// (e.g. `getDmarcRecord(name, resolver.resolve.bind(resolver))`)
|
|
372
|
+
// (alternative to `autoBind(this)` is `this[method] = this[method].bind(this)`)
|
|
373
|
+
//
|
|
374
|
+
autoBind(this);
|
|
366
375
|
}
|
|
367
376
|
|
|
368
377
|
setLocalAddress(ipv4, ipv6) {
|
|
@@ -1234,7 +1243,7 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
1234
1243
|
data = await this.options.cache.get(key);
|
|
1235
1244
|
// safeguard in case cache pollution
|
|
1236
1245
|
if (data && typeof data === 'object') {
|
|
1237
|
-
debug('cache retrieved',
|
|
1246
|
+
debug('cache retrieved', key);
|
|
1238
1247
|
const now = Date.now();
|
|
1239
1248
|
// safeguard in case cache pollution
|
|
1240
1249
|
if (
|
|
@@ -1243,6 +1252,7 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
1243
1252
|
!Number.isFinite(data.ttl) ||
|
|
1244
1253
|
data.ttl < 1
|
|
1245
1254
|
) {
|
|
1255
|
+
debug('cache expired', key);
|
|
1246
1256
|
data = undefined;
|
|
1247
1257
|
} else if (options?.ttl) {
|
|
1248
1258
|
// clone the data so that we don't mutate cache (e.g. if it's in-memory)
|
|
@@ -1262,6 +1272,7 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
1262
1272
|
|
|
1263
1273
|
// eslint-disable-next-line max-depth
|
|
1264
1274
|
if (data.answers[i].ttl <= 0) {
|
|
1275
|
+
debug('answer cache expired', key);
|
|
1265
1276
|
data = undefined;
|
|
1266
1277
|
break;
|
|
1267
1278
|
}
|
|
@@ -1508,13 +1519,57 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
1508
1519
|
|
|
1509
1520
|
case 'TXT': {
|
|
1510
1521
|
// text records `dnsPromises.resolveTxt()`
|
|
1511
|
-
return result.answers.flatMap((a) =>
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1522
|
+
return result.answers.flatMap((a) => {
|
|
1523
|
+
//
|
|
1524
|
+
// NOTE: we need to support buffer conversion
|
|
1525
|
+
// (e.g. JSON.stringify from most cache stores will convert this as such below)
|
|
1526
|
+
//
|
|
1527
|
+
// a {
|
|
1528
|
+
// name: 'forwardemail.net',
|
|
1529
|
+
// type: 'TXT',
|
|
1530
|
+
// ttl: 3600,
|
|
1531
|
+
// class: 'IN',
|
|
1532
|
+
// flush: false,
|
|
1533
|
+
// data: [ { type: 'Buffer', data: [Array] } ]
|
|
1534
|
+
// }
|
|
1535
|
+
//
|
|
1536
|
+
// (or)
|
|
1537
|
+
//
|
|
1538
|
+
// a {
|
|
1539
|
+
// name: 'forwardemail.net',
|
|
1540
|
+
// type: 'TXT',
|
|
1541
|
+
// ttl: 3600,
|
|
1542
|
+
// class: 'IN',
|
|
1543
|
+
// flush: false,
|
|
1544
|
+
// data: { type: 'Buffer', data: [Array] }
|
|
1545
|
+
// }
|
|
1546
|
+
//
|
|
1547
|
+
if (Array.isArray(a.data)) {
|
|
1548
|
+
a.data = a.data.map((d) => {
|
|
1549
|
+
if (
|
|
1550
|
+
typeof d === 'object' &&
|
|
1551
|
+
d.type === 'Buffer' &&
|
|
1552
|
+
Array.isArray(d.data)
|
|
1553
|
+
)
|
|
1554
|
+
return Buffer.from(d.data);
|
|
1555
|
+
return d;
|
|
1556
|
+
});
|
|
1557
|
+
} else if (
|
|
1558
|
+
typeof a.data === 'object' &&
|
|
1559
|
+
a.data.type === 'Buffer' &&
|
|
1560
|
+
Array.isArray(a.data.data)
|
|
1561
|
+
) {
|
|
1562
|
+
a.data = Buffer.from(a.data.data);
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
return [
|
|
1566
|
+
Buffer.isBuffer(a.data)
|
|
1567
|
+
? a.data.toString()
|
|
1568
|
+
: Array.isArray(a.data)
|
|
1569
|
+
? a.data.map((d) => (Buffer.isBuffer(d) ? d.toString() : d))
|
|
1570
|
+
: a.data
|
|
1571
|
+
];
|
|
1572
|
+
});
|
|
1518
1573
|
}
|
|
1519
1574
|
|
|
1520
1575
|
default: {
|
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.4.
|
|
4
|
+
"version": "1.4.3",
|
|
5
5
|
"author": "Forward Email (https://forwardemail.net)",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/forwardemail/tangerine/issues"
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
],
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@ungap/structured-clone": "^1.0.2",
|
|
14
|
+
"auto-bind": "4",
|
|
14
15
|
"dns-packet": "^5.4.0",
|
|
15
16
|
"dohdec": "^5.0.3",
|
|
16
17
|
"get-stream": "6",
|