pending-dns 1.1.1 → 1.2.0

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # PendingDNS
2
2
 
3
- Lightweight API driven Authoritative DNS server. Extracted from [Project Pending](https://projectpending.com/).
3
+ Lightweight API driven Authoritative DNS server.
4
4
 
5
5
  ## Features
6
6
 
package/lib/api-server.js CHANGED
@@ -18,28 +18,26 @@ const hostnameSchema = Joi.string().hostname({
18
18
  minDomainSegments: 1
19
19
  });
20
20
 
21
- const subdomainValidator = opts => {
22
- return (value, helpers) => {
23
- if (!value) {
24
- return value;
25
- }
21
+ const subdomainValidator = opts => (value, helpers) => {
22
+ if (!value) {
23
+ return value;
24
+ }
26
25
 
27
- let valueToCheck = value;
28
- if (opts.allowUnderscore) {
29
- valueToCheck = valueToCheck.replace(/\b_/g, 'x');
30
- }
26
+ let valueToCheck = value;
27
+ if (opts.allowUnderscore) {
28
+ valueToCheck = valueToCheck.replace(/\b_/g, 'x');
29
+ }
31
30
 
32
- if (opts.allowWildcard) {
33
- valueToCheck = valueToCheck.replace(/^\*\./, 'x.');
34
- }
31
+ if (opts.allowWildcard) {
32
+ valueToCheck = valueToCheck.replace(/^\*\./, 'x.');
33
+ }
35
34
 
36
- let result = hostnameSchema.validate(valueToCheck);
37
- if (result.error) {
38
- return helpers.error('any.invalid');
39
- }
35
+ let result = hostnameSchema.validate(valueToCheck);
36
+ if (result.error) {
37
+ return helpers.error('any.invalid');
38
+ }
40
39
 
41
- return value;
42
- };
40
+ return value;
43
41
  };
44
42
 
45
43
  const recordScheme = Joi.object({
@@ -2,7 +2,7 @@
2
2
 
3
3
  const config = require('wild-config');
4
4
  const db = require('./db');
5
- const punycode = require('punycode');
5
+ const punycode = require('punycode/');
6
6
  const { Resolver } = require('dns').promises;
7
7
  const resolver = new Resolver();
8
8
  const logger = require('./logger').child({ component: 'cached-resolver' });
package/lib/certs.js CHANGED
@@ -3,7 +3,7 @@
3
3
  const config = require('wild-config');
4
4
  const pkg = require('../package.json');
5
5
  const db = require('./db');
6
- const punycode = require('punycode');
6
+ const punycode = require('punycode/');
7
7
  const { zoneStore } = require('./zone-store');
8
8
  const crypto = require('crypto');
9
9
  const { checkNSStatus, normalizeDomain } = require('./tools');
@@ -34,11 +34,9 @@ const acme = ACME.create({
34
34
  },
35
35
  dns01(query) {
36
36
  return localResolver.resolveTxt(query.dnsHost).then(records => ({
37
- answer: records.map(rr => {
38
- return {
39
- data: rr
40
- };
41
- })
37
+ answer: records.map(rr => ({
38
+ data: rr
39
+ }))
42
40
  }));
43
41
  }
44
42
  });
@@ -2,12 +2,13 @@
2
2
 
3
3
  const config = require('wild-config');
4
4
  const dns2 = require('dns2');
5
- const punycode = require('punycode');
5
+ const punycode = require('punycode/');
6
6
  const { zoneStore } = require('./zone-store');
7
7
  const cachedResolver = require('./cached-resolver');
8
8
  const ipaddr = require('ipaddr.js');
9
9
  const logger = require('./logger').child({ component: 'dns-handler' });
10
10
  const { normalizeDomain } = require('./tools');
11
+ const { v4: uuidv4 } = require('uuid');
11
12
 
12
13
  // Split long string values into character chunks
13
14
  const formatTXTData = data => {
@@ -19,11 +20,7 @@ const formatTXTData = data => {
19
20
  };
20
21
 
21
22
  // Helps to convert DNS type integer into a string (0x01 -> 'A')
22
- const reversedTypes = new Map(
23
- Object.keys(dns2.Packet.TYPE).map(key => {
24
- return [dns2.Packet.TYPE[key], key];
25
- })
26
- );
23
+ const reversedTypes = new Map(Object.keys(dns2.Packet.TYPE).map(key => [dns2.Packet.TYPE[key], key]));
27
24
 
28
25
  const shuffle = array => {
29
26
  let currentIndex = array.length,
@@ -89,7 +86,7 @@ const processQuestion = async (response, question, domain, depth) => {
89
86
  let dnsEntries = (
90
87
  await Promise.all(
91
88
  Array.from(types).map(async type => {
92
- let records = await zoneStore.resolve(domain, type, true);
89
+ let records = await zoneStore.resolve(domain, type, false);
93
90
  if (records && records.length > 1) {
94
91
  switch (type) {
95
92
  case 'A':
@@ -187,7 +184,13 @@ const processQuestion = async (response, question, domain, depth) => {
187
184
  break;
188
185
  }
189
186
  } catch (err) {
190
- logger.error({ msg: 'Failed resolving ANAME', domain: dnsEntry.domain, type: questionTypeStr, err });
187
+ logger.error({
188
+ msg: 'Failed resolving ANAME',
189
+ id: response._id,
190
+ domain: dnsEntry.domain,
191
+ type: questionTypeStr,
192
+ err
193
+ });
191
194
  }
192
195
 
193
196
  [].concat(value || []).forEach(value => {
@@ -258,7 +261,12 @@ const processQuestion = async (response, question, domain, depth) => {
258
261
  try {
259
262
  entry.domain = punycode.toASCII(entry.domain);
260
263
  } catch (err) {
261
- logger.error({ msg: 'Failed to punycode', domain: entry.domain, err });
264
+ logger.error({
265
+ msg: 'Failed to punycode',
266
+ id: response._id,
267
+ domain: entry.domain,
268
+ err
269
+ });
262
270
  }
263
271
  break;
264
272
 
@@ -267,7 +275,12 @@ const processQuestion = async (response, question, domain, depth) => {
267
275
  try {
268
276
  entry.ns = punycode.toASCII(entry.ns);
269
277
  } catch (err) {
270
- logger.error({ msg: 'Failed to punycode', domain: entry.ns, err });
278
+ logger.error({
279
+ msg: 'Failed to punycode',
280
+ id: response._id,
281
+ domain: entry.ns,
282
+ err
283
+ });
271
284
  }
272
285
  break;
273
286
 
@@ -284,7 +297,12 @@ const processQuestion = async (response, question, domain, depth) => {
284
297
  try {
285
298
  entry.exchange = punycode.toASCII(entry.exchange);
286
299
  } catch (err) {
287
- logger.error({ msg: 'Failed to punycode', domain: entry.exchange, err });
300
+ logger.error({
301
+ msg: 'Failed to punycode',
302
+ id: response._id,
303
+ domain: entry.exchange,
304
+ err
305
+ });
288
306
  }
289
307
  break;
290
308
 
@@ -316,6 +334,7 @@ const processQuestion = async (response, question, domain, depth) => {
316
334
  const dnsHandler = async request => {
317
335
  let startTime = Date.now();
318
336
  const response = new dns2.Packet(request);
337
+ request._id = response._id = uuidv4();
319
338
 
320
339
  response.header.qr = 1;
321
340
  response.header.aa = 1;
@@ -323,18 +342,25 @@ const dnsHandler = async request => {
323
342
  await Promise.all(
324
343
  request.questions.map(question => {
325
344
  logger.info({
345
+ id: request._id,
326
346
  msg: 'DNS query',
327
347
  type: request.source.type,
328
348
  port: request.source.port,
329
349
  address: request.source.address,
330
- name: question.name,
350
+ question: question.name,
331
351
  rr: reversedTypes.get(question.type) || question.type
332
352
  });
333
353
  return processQuestion(response, question);
334
354
  })
335
355
  );
336
356
 
337
- logger.info({ msg: 'DNS response', dnsTime: Date.now() - startTime, questions: request.questions, answers: response.answers });
357
+ logger.info({
358
+ msg: 'DNS response',
359
+ id: request._id,
360
+ dnsTime: Date.now() - startTime,
361
+ questions: request.questions,
362
+ answers: response.answers
363
+ });
338
364
 
339
365
  // normalize answers for the DNS library
340
366
  response.answers.forEach(answer => {
package/lib/dns-server.js CHANGED
@@ -15,7 +15,7 @@ const SUPPORTED_TYPES = new Set(
15
15
 
16
16
  const init = async () => {
17
17
  // create UDP server
18
- createDNSUdpServer(function (request, send) {
18
+ createDNSUdpServer((request, send) => {
19
19
  // filter out unsupported requests (eg. EDNS)
20
20
  if (request.additionals && request.additionals.length) {
21
21
  request.additionals = request.additionals.filter(additional => SUPPORTED_TYPES.has(additional.type));
@@ -43,7 +43,7 @@ const init = async () => {
43
43
  });
44
44
 
45
45
  // create TCP server
46
- createDNSTcpServer(function (request, send) {
46
+ createDNSTcpServer((request, send) => {
47
47
  // filter out unsupported requests (eg. EDNS)
48
48
  if (request.additionals && request.additionals.length) {
49
49
  request.additionals = request.additionals.filter(additional => SUPPORTED_TYPES.has(additional.type));
@@ -52,9 +52,7 @@ class DNSTcpServer extends EventEmitter {
52
52
  port: socket.remotePort,
53
53
  address: socket.remoteAddress
54
54
  };
55
- this.emit('request', request, message => {
56
- return this.send(socket, message);
57
- });
55
+ this.emit('request', request, message => this.send(socket, message));
58
56
  };
59
57
 
60
58
  socket.on('readable', () => {
@@ -10,8 +10,8 @@ const tls = require('tls');
10
10
  const http = require('http');
11
11
  const https = require('https');
12
12
 
13
- const tcpHealthCheck = async url => {
14
- return new Promise((resolve, reject) => {
13
+ const tcpHealthCheck = async url =>
14
+ new Promise((resolve, reject) => {
15
15
  let connectTimeout;
16
16
 
17
17
  let conn;
@@ -57,10 +57,9 @@ const tcpHealthCheck = async url => {
57
57
  client.on('timeout', onTimeout);
58
58
  client.setTimeout(config.health.ttl);
59
59
  });
60
- };
61
60
 
62
- const httpHealthCheck = async url => {
63
- return new Promise((resolve, reject) => {
61
+ const httpHealthCheck = async url =>
62
+ new Promise((resolve, reject) => {
64
63
  let connectTimeout;
65
64
 
66
65
  let conn;
@@ -111,7 +110,6 @@ const httpHealthCheck = async url => {
111
110
  client.on('timeout', onTimeout);
112
111
  client.setTimeout(config.health.ttl);
113
112
  });
114
- };
115
113
 
116
114
  const healthCheck = async target => {
117
115
  try {
@@ -17,7 +17,7 @@ const httpProxy = require('http-proxy');
17
17
 
18
18
  const proxyServer = httpProxy.createProxyServer({});
19
19
 
20
- proxyServer.on('proxyReq', function (proxyReq, req /*, res, options*/) {
20
+ proxyServer.on('proxyReq', (proxyReq, req /*, res, options*/) => {
21
21
  proxyReq.setHeader('X-Forwarded-Proto', req.proto);
22
22
  proxyReq.setHeader('X-Connecting-IP', req.ip);
23
23
  proxyReq.setHeader('X-CDN-Loop', 'PendingDNS');
@@ -181,11 +181,7 @@ const handler = async (req, res) => {
181
181
  const url = new URL(req.url, `${req.proto}://${domain}/`);
182
182
  const route = url.pathname;
183
183
 
184
- const target =
185
- records &&
186
- records.find(rr => {
187
- return rr && rr.type === 'URL' && rr.value && rr.value.length;
188
- });
184
+ const target = records && records.find(rr => rr && rr.type === 'URL' && rr.value && rr.value.length);
189
185
 
190
186
  if (target) {
191
187
  // redirect to target URL
@@ -238,8 +234,8 @@ const handler = async (req, res) => {
238
234
  );
239
235
  };
240
236
 
241
- const setupHttps = () => {
242
- return new Promise((resolve, reject) => {
237
+ const setupHttps = () =>
238
+ new Promise((resolve, reject) => {
243
239
  const server = https.createServer(
244
240
  {
245
241
  key: defaultKey,
@@ -249,9 +245,7 @@ const setupHttps = () => {
249
245
  allowHTTP1: true,
250
246
  SNICallback(servername, cb) {
251
247
  getSNIContext(servername)
252
- .then(ctx => {
253
- return cb(null, ctx || defaultCtx);
254
- })
248
+ .then(ctx => cb(null, ctx || defaultCtx))
255
249
  .catch(err => {
256
250
  logger.error({ msg: 'SNI failed', servername, err });
257
251
  return cb(null, defaultCtx);
@@ -325,10 +319,9 @@ const setupHttps = () => {
325
319
  reject(err);
326
320
  });
327
321
  });
328
- };
329
322
 
330
- const setupHttp = () => {
331
- return new Promise((resolve, reject) => {
323
+ const setupHttp = () =>
324
+ new Promise((resolve, reject) => {
332
325
  const server = http.createServer((req, res) => {
333
326
  req.proto = 'http';
334
327
  middleware(req, res);
@@ -362,7 +355,6 @@ const setupHttp = () => {
362
355
  reject(err);
363
356
  });
364
357
  });
365
- };
366
358
 
367
359
  const init = async () => {
368
360
  await Promise.all([setupHttps(), setupHttp()]);
package/lib/tools.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const cachedResolver = require('./cached-resolver');
4
- const punycode = require('punycode');
4
+ const punycode = require('punycode/');
5
5
  const Joi = require('@hapi/joi');
6
6
 
7
7
  const emailSchema = Joi.string().email({}).required();
package/lib/zone-store.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const punycode = require('punycode');
3
+ const punycode = require('punycode/');
4
4
  const shortid = require('shortid');
5
5
  const db = require('./db');
6
6
  const logger = require('./logger').child({ component: 'zone-store' });
@@ -196,6 +196,7 @@ class ZoneStore {
196
196
  if (short) {
197
197
  return {
198
198
  id: this.getFullId(name, type, hid),
199
+ zone: zoneDomain,
199
200
  domain,
200
201
  type,
201
202
  value: JSON.parse(value)
@@ -225,9 +226,7 @@ class ZoneStore {
225
226
 
226
227
  return Object.keys(record)
227
228
  .map(key => [key, record[key]])
228
- .sort((a, b) => {
229
- return a[1].localeCompare(b[1]);
230
- })
229
+ .sort((a, b) => a[1].localeCompare(b[1]))
231
230
  .map(entry => {
232
231
  let hid = entry[0];
233
232
  let value = entry[1];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pending-dns",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "Lightweight API driven DNS server",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -25,34 +25,36 @@
25
25
  },
26
26
  "homepage": "https://github.com/postalsys/pending-dns#readme",
27
27
  "devDependencies": {
28
- "eslint": "7.1.0",
28
+ "eslint": "8.18.0",
29
29
  "eslint-config-nodemailer": "1.2.0",
30
- "eslint-config-prettier": "6.11.0",
31
- "grunt": "1.1.0",
32
- "grunt-cli": "1.3.2",
33
- "grunt-eslint": "23.0.0",
30
+ "eslint-config-prettier": "8.5.0",
31
+ "grunt": "1.5.3",
32
+ "grunt-cli": "1.4.3",
33
+ "grunt-eslint": "24.0.0",
34
34
  "npm-license-crawler": "0.2.1"
35
35
  },
36
36
  "dependencies": {
37
37
  "@fidm/x509": "1.2.1",
38
- "@hapi/boom": "9.1.0",
39
- "@hapi/hapi": "19.1.1",
40
- "@hapi/inert": "6.0.1",
38
+ "@hapi/boom": "10.0.0",
39
+ "@hapi/hapi": "20.2.2",
40
+ "@hapi/inert": "6.0.5",
41
41
  "@hapi/joi": "17.1.1",
42
- "@hapi/vision": "6.0.0",
43
- "@root/acme": "3.0.10",
42
+ "@hapi/vision": "6.1.0",
43
+ "@root/acme": "3.1.0",
44
44
  "@root/csr": "0.8.1",
45
- "dns2": "1.3.2",
46
- "hapi-pino": "8.0.1",
47
- "hapi-swagger": "13.0.2",
45
+ "dns2": "2.0.2",
46
+ "hapi-pino": "10.1.0",
47
+ "hapi-swagger": "14.5.5",
48
48
  "http-proxy": "1.18.1",
49
- "ioredfour": "1.0.2-ioredis-03",
50
- "ioredis": "4.17.3",
51
- "ipaddr.js": "1.9.1",
52
- "node-rsa": "1.0.8",
49
+ "ioredfour": "1.2.0-ioredis-06",
50
+ "ioredis": "5.0.6",
51
+ "ipaddr.js": "2.0.1",
52
+ "node-rsa": "1.1.1",
53
53
  "pem-jwk": "2.0.0",
54
- "pino": "6.3.2",
55
- "shortid": "2.2.15",
56
- "wild-config": "1.5.1"
54
+ "pino": "8.1.0",
55
+ "punycode": "^2.1.1",
56
+ "shortid": "2.2.16",
57
+ "uuid": "^8.3.2",
58
+ "wild-config": "1.6.1"
57
59
  }
58
60
  }