@nictool/dns-resource-record 1.2.3 → 1.3.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/rr/dnskey.js CHANGED
@@ -12,34 +12,63 @@ export default class DNSKEY extends RR {
12
12
  // a 2 octet Flags Field
13
13
  this.is16bitInt('DNSKEY', 'flags', val)
14
14
 
15
- // the possible values are: 0, 256, and 257; RFC 4034
16
- if (![0, 256, 257].includes(val)) this.throwHelp(`DNSKEY: flags invalid`)
15
+ if (!this.getFlagsOptions().has(val)) {
16
+ this.throwHelp(`DNSKEY: flags must be in the set: ${this.getFlagsOptions()}`)
17
+ }
17
18
 
18
19
  this.set('flags', val)
19
20
  }
20
21
 
22
+ // possible values are: 0, 256, and 257; RFC 4034
23
+ getFlagsOptions() {
24
+ return new Map([[0], [256], [257]])
25
+ }
26
+
21
27
  setProtocol(val) {
22
28
  // 1 octet
23
29
  this.is8bitInt('DNSKEY', 'protocol', val)
24
30
 
25
31
  // The Protocol Field MUST be represented as an unsigned decimal integer with a value of 3.
26
- if (![3].includes(val)) this.throwHelp(`DNSKEY: protocol invalid`)
32
+ if (!this.getProtocolOptions().has(val)) this.throwHelp(`DNSKEY: protocol invalid`)
27
33
 
28
34
  this.set('protocol', val)
29
35
  }
30
36
 
37
+ getProtocolOptions() {
38
+ return new Map([[3]])
39
+ }
40
+
31
41
  setAlgorithm(val) {
32
42
  // 1 octet
33
43
  this.is8bitInt('DNSKEY', 'algorithm', val)
34
44
 
35
45
  // https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml
36
- // 1=RSA/MD5, 2=DH, 3=DSA/SHA-1, 4=EC, 5=RSA/SHA-1
37
- if (![...Array(16).keys(), 253, 254].includes(val))
38
- console.error(`DNSKEY: algorithm (${val}) not recognized`)
46
+ if (!this.getAlgorithmOptions().has(val)) console.error(`DNSKEY: algorithm (${val}) not recognized`)
39
47
 
40
48
  this.set('algorithm', val)
41
49
  }
42
50
 
51
+ getAlgorithmOptions() {
52
+ return new Map([
53
+ [1, 'RSA/MD5 (DEPRECATED)'],
54
+ [2, 'DH'],
55
+ [3, 'DSA/SHA-1'],
56
+ [4, 'EC'],
57
+ [5, 'RSA/SHA-1'],
58
+ [6, 'DSA-NSEC3-SHA1'],
59
+ [7, 'RSASHA1-NSEC3-SHA1'],
60
+ [8, 'RSA/SHA-256'],
61
+ [9, ''],
62
+ [10, 'RSA/SHA-512'],
63
+ [13, 'ECDSA Curve P-256 with SHA-256'],
64
+ [14, 'ECDSA Curve P-384 with SHA-384'],
65
+ [15, 'Ed25519'],
66
+ [16, 'Ed448'],
67
+ [253],
68
+ [254],
69
+ ])
70
+ }
71
+
43
72
  setPublickey(val) {
44
73
  if (!val) this.throwHelp(`DNSKEY: publickey is required`)
45
74
 
@@ -66,12 +95,10 @@ export default class DNSKEY extends RR {
66
95
 
67
96
  fromBind(opts) {
68
97
  // test.example.com 3600 IN DNSKEY Flags Protocol Algorithm PublicKey
69
- const match = opts.bindline.match(
70
- /^([^\s]+)\s+([0-9]+)\s+(\w+)\s+(\w+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+\s*(.*?)\s*$/,
71
- )
98
+ const regex = /^([^\s]+)\s+([0-9]+)\s+(\w+)\s+(\w+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+\s*(.*?)\s*$/
99
+ const match = opts.bindline.match(regex)
72
100
  if (!match) this.throwHelp(`unable to parse DNSKEY: ${opts.bindline}`)
73
- const [owner, ttl, c, type, flags, protocol, algorithm, publickey] =
74
- match.slice(1)
101
+ const [owner, ttl, c, type, flags, protocol, algorithm, publickey] = match.slice(1)
75
102
 
76
103
  return new DNSKEY({
77
104
  owner,
package/rr/ds.js CHANGED
@@ -17,13 +17,23 @@ export default class DS extends RR {
17
17
  }
18
18
 
19
19
  setAlgorithm(val) {
20
- // 1=RSA/MD5, 2=DH, 3=DSA/SHA-1, 4=EC, 5=RSA/SHA-1
21
- if (![1, 2, 3, 4, 5, 253, 254].includes(val))
22
- this.throwHelp(`DS: algorithm invalid`)
20
+ if (!this.getAlgorithmOptions().has(val)) this.throwHelp(`DS: algorithm invalid`)
23
21
 
24
22
  this.set('algorithm', val)
25
23
  }
26
24
 
25
+ getAlgorithmOptions() {
26
+ return new Map([
27
+ [1, 'RSA/MD5'],
28
+ [2, 'DH'],
29
+ [3, 'DSA/SHA-1'],
30
+ [4, 'EC'],
31
+ [5, 'RSA/SHA-1'],
32
+ [253, ''],
33
+ [254, ''],
34
+ ])
35
+ }
36
+
27
37
  setDigestType(val) {
28
38
  if (![1, 2].includes(val)) this.throwHelp(`DS: digest type invalid`)
29
39
 
@@ -56,8 +66,7 @@ export default class DS extends RR {
56
66
 
57
67
  fromBind(opts) {
58
68
  // test.example.com 3600 IN DS Key Tag Algorithm, Digest Type, Digest
59
- const [owner, ttl, c, type, keytag, algorithm, digesttype] =
60
- opts.bindline.split(/\s+/)
69
+ const [owner, ttl, c, type, keytag, algorithm, digesttype] = opts.bindline.split(/\s+/)
61
70
  return new DS({
62
71
  owner,
63
72
  ttl: parseInt(ttl, 10),
package/rr/hinfo.js CHANGED
@@ -41,11 +41,8 @@ export default class HINFO extends RR {
41
41
  /****** IMPORTERS *******/
42
42
  fromBind(opts) {
43
43
  // test.example.com 3600 IN HINFO DEC-2060 TOPS20
44
- const match = opts.bindline
45
- .trim()
46
- .match(
47
- /^([\S]+)\s+([0-9]{1,10})\s+(IN)\s+(HINFO)\s+("[^"]+"|[\S]+)\s+("[^"]+"|[\S]+)/i,
48
- )
44
+ const regex = /^([\S]+)\s+([0-9]{1,10})\s+(IN)\s+(HINFO)\s+("[^"]+"|[\S]+)\s+("[^"]+"|[\S]+)/i
45
+ const match = opts.bindline.trim().match(regex)
49
46
  if (!match) this.throwHelp(`unable to parse HINFO: ${opts.bindline}`)
50
47
  const [owner, ttl, c, type, cpu, os] = match.slice(1)
51
48
 
@@ -78,10 +75,7 @@ export default class HINFO extends RR {
78
75
  /****** EXPORTERS *******/
79
76
  toTinydns() {
80
77
  return this.getTinydnsGeneric(
81
- [
82
- TINYDNS.packString(this.get('cpu')),
83
- TINYDNS.packString(this.get('os')),
84
- ].join(''),
78
+ [TINYDNS.packString(this.get('cpu')), TINYDNS.packString(this.get('os'))].join(''),
85
79
  )
86
80
  }
87
81
  }
package/rr/hip.js ADDED
@@ -0,0 +1,102 @@
1
+ import RR from '../rr.js'
2
+
3
+ import * as TINYDNS from '../lib/tinydns.js'
4
+
5
+ export default class HIP extends RR {
6
+ constructor(opts) {
7
+ super(opts)
8
+ }
9
+
10
+ /****** Resource record specific setters *******/
11
+ setPkAlgorithm(val) {
12
+ if (val === undefined) this.throwHelp('HIP: pk algorithm is required')
13
+ this.is8bitInt('HIP', 'pk algorithm', val)
14
+ this.set('pk algorithm', val)
15
+ }
16
+
17
+ setHit(val) {
18
+ if (!val) this.throwHelp('HIP: hit is required')
19
+ this.set('hit', val)
20
+ }
21
+
22
+ setPublicKey(val) {
23
+ if (!val) this.throwHelp('HIP: public key is required')
24
+ this.set('public key', val)
25
+ }
26
+
27
+ setRendezvousServers(val) {
28
+ this.set('rendezvous servers', val ?? '')
29
+ }
30
+
31
+ getDescription() {
32
+ return 'Host Identity Protocol'
33
+ }
34
+
35
+ getRdataFields(arg) {
36
+ return ['pk algorithm', 'hit', 'public key', 'rendezvous servers']
37
+ }
38
+
39
+ getRFCs() {
40
+ return [8005]
41
+ }
42
+
43
+ getTypeId() {
44
+ return 55
45
+ }
46
+
47
+ getCanonical() {
48
+ return {
49
+ owner: 'example.com.',
50
+ ttl: 3600,
51
+ class: 'IN',
52
+ type: 'HIP',
53
+ 'pk algorithm': 2,
54
+ hit: '200100107B1A74DF365639CC39F1D578',
55
+ 'public key':
56
+ 'AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwIXAqcOTiW7iHnQt5hwVAAAAA==',
57
+ 'rendezvous servers': '',
58
+ }
59
+ }
60
+
61
+ /****** IMPORTERS *******/
62
+ fromBind(opts) {
63
+ // owner ttl IN HIP pk-algorithm HIT public-key [rendezvous-server...]
64
+ const parts = opts.bindline.split(/\s+/)
65
+ const [owner, ttl, c, type, pkAlgorithm, hit, publicKey] = parts
66
+ return new HIP({
67
+ owner,
68
+ ttl: parseInt(ttl, 10),
69
+ class: c,
70
+ type,
71
+ 'pk algorithm': parseInt(pkAlgorithm, 10),
72
+ hit,
73
+ 'public key': publicKey,
74
+ 'rendezvous servers': parts.slice(7).join(' ').trim(),
75
+ })
76
+ }
77
+
78
+ /****** EXPORTERS *******/
79
+ toBind(zone_opts) {
80
+ const rs = this.get('rendezvous servers')
81
+ const rsPart = rs ? `\t${rs}` : ''
82
+ return `${this.getPrefix(zone_opts)}\t${this.get('pk algorithm')}\t${this.get('hit')}\t${this.get('public key')}${rsPart}\n`
83
+ }
84
+
85
+ toTinydns() {
86
+ const hitBytes = Buffer.from(this.get('hit'), 'hex')
87
+ const pkBytes = Buffer.from(this.get('public key'), 'base64')
88
+ const rs = this.get('rendezvous servers')
89
+
90
+ let rdata = ''
91
+ rdata += TINYDNS.UInt8toOctal(hitBytes.length)
92
+ rdata += TINYDNS.UInt8toOctal(this.get('pk algorithm'))
93
+ rdata += TINYDNS.UInt16toOctal(pkBytes.length)
94
+ for (const b of hitBytes) rdata += TINYDNS.UInt8toOctal(b)
95
+ for (const b of pkBytes) rdata += TINYDNS.UInt8toOctal(b)
96
+ if (rs) {
97
+ for (const name of rs.split(/\s+/)) rdata += TINYDNS.packDomainName(name)
98
+ }
99
+
100
+ return this.getTinydnsGeneric(rdata)
101
+ }
102
+ }
package/rr/https.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import RR from '../rr.js'
2
2
 
3
+ import * as TINYDNS from '../lib/tinydns.js'
4
+
3
5
  export default class HTTPS extends RR {
4
6
  constructor(opts) {
5
7
  super(opts)
@@ -59,4 +61,14 @@ export default class HTTPS extends RR {
59
61
  }
60
62
 
61
63
  /****** EXPORTERS *******/
64
+
65
+ toTinydns() {
66
+ const dataRe = new RegExp(/[\r\n\t:\\/]/, 'g')
67
+
68
+ return this.getTinydnsGeneric(
69
+ TINYDNS.UInt16toOctal(this.get('priority')) +
70
+ TINYDNS.packDomainName(this.get('target name')) +
71
+ TINYDNS.escapeOctal(dataRe, this.get('params')),
72
+ )
73
+ }
62
74
  }
package/rr/ipseckey.js CHANGED
@@ -16,23 +16,37 @@ export default class IPSECKEY extends RR {
16
16
  }
17
17
 
18
18
  setGatewayType(val) {
19
- // 0 (none), 1 (4-byte IPv4), 2 (16-byte IPv6), 3 (wire encoded domain name)
20
- if (![0, 1, 2, 3].includes(val))
21
- this.throwHelp(`IPSECKEY: Gateway Type is invalid`)
19
+ if (!this.getGatewayTypeOptions().has(val)) this.throwHelp(`IPSECKEY: Gateway Type is invalid`)
22
20
 
23
21
  this.set('gateway type', val)
24
22
  }
25
23
 
24
+ getGatewayTypeOptions() {
25
+ return new Map([
26
+ [0, 'none'],
27
+ [1, '4-byte IPv4'],
28
+ [2, '16-byte IPv6'],
29
+ [3, 'wire encoded domain name'],
30
+ ])
31
+ }
32
+
26
33
  setAlgorithm(val) {
27
- // unsigned int, 1 octet, values: 1=DSA, 2=RSA
28
- if (![1, 2].includes(val)) this.throwHelp(`IPSECKEY: Algorithm invalid`)
34
+ if (!this.getAlgorithmOptions().has(val)) this.throwHelp(`IPSECKEY: Algorithm invalid`)
29
35
 
30
36
  this.set('algorithm', val)
31
37
  }
32
38
 
39
+ getAlgorithmOptions() {
40
+ return new Map([
41
+ [1, 'DSA'],
42
+ [2, 'RSA'],
43
+ ])
44
+ }
45
+
33
46
  setGateway(val) {
34
- const gwErr = new Error(`IPSECKEY: gateway invalid (${val})`)
35
- switch (this.get('gateway type')) {
47
+ const type = this.get('gateway type')
48
+ const gwErr = new Error(`IPSECKEY: gateway invalid (${val}) for type ${type}`)
49
+ switch (type) {
36
50
  case 0:
37
51
  if (val !== '.') throw gwErr
38
52
  break
@@ -86,8 +100,7 @@ export default class IPSECKEY extends RR {
86
100
  /****** IMPORTERS *******/
87
101
  fromBind(opts) {
88
102
  // FQDN TTL CLASS IPSECKEY Precedence GatewayType Algorithm Gateway PublicKey
89
- const [owner, ttl, c, type, prec, gwt, algo, gateway, publickey] =
90
- opts.bindline.split(/\s+/)
103
+ const [owner, ttl, c, type, prec, gwt, algo, gateway, publickey] = opts.bindline.split(/\s+/)
91
104
  return new IPSECKEY({
92
105
  owner,
93
106
  ttl: parseInt(ttl, 10),
package/rr/key.js CHANGED
@@ -22,13 +22,24 @@ export default class KEY extends RR {
22
22
 
23
23
  setAlgorithm(val) {
24
24
  // 1 octet
25
- // 1=RSA/MD5, 2=DH, 3=DSA/SHA-1, 4=EC, 5=RSA/SHA-1
26
- if (![1, 2, 3, 4, 5, 253, 254].includes(val))
27
- this.throwHelp(`KEY: algorithm invalid`)
25
+
26
+ if (!this.getAlgorithmOptions().has(val)) this.throwHelp(`KEY: algorithm invalid`)
28
27
 
29
28
  this.set('algorithm', val)
30
29
  }
31
30
 
31
+ getAlgorithmOptions() {
32
+ return new Map([
33
+ [1, 'RSA/MD5'],
34
+ [2, 'DH'],
35
+ [3, 'DSA/SHA-1'],
36
+ [4, 'EC'],
37
+ [5, 'RSA/SHA-1'],
38
+ [253, ''],
39
+ [254, ''],
40
+ ])
41
+ }
42
+
32
43
  setPublickey(val) {
33
44
  if (!val) this.throwHelp(`KEY: publickey is required`)
34
45
 
@@ -55,8 +66,7 @@ export default class KEY extends RR {
55
66
 
56
67
  fromBind(opts) {
57
68
  // test.example.com 3600 IN KEY Flags Protocol Algorithm PublicKey
58
- const [owner, ttl, c, type, flags, protocol, algorithm] =
59
- opts.bindline.split(/\s+/)
69
+ const [owner, ttl, c, type, flags, protocol, algorithm] = opts.bindline.split(/\s+/)
60
70
  return new KEY({
61
71
  owner,
62
72
  ttl: parseInt(ttl, 10),
package/rr/kx.js ADDED
@@ -0,0 +1,77 @@
1
+ import RR from '../rr.js'
2
+
3
+ import * as TINYDNS from '../lib/tinydns.js'
4
+
5
+ export default class KX extends RR {
6
+ constructor(opts) {
7
+ super(opts)
8
+ }
9
+
10
+ /****** Resource record specific setters *******/
11
+ setPreference(val) {
12
+ if (val === undefined) this.throwHelp('KX: preference is required')
13
+ this.is16bitInt('KX', 'preference', val)
14
+ this.set('preference', val)
15
+ }
16
+
17
+ setExchanger(val) {
18
+ if (!val) this.throwHelp('KX: exchanger is required')
19
+
20
+ this.isFullyQualified('KX', 'exchanger', val)
21
+ this.isValidHostname('KX', 'exchanger', val)
22
+
23
+ this.set('exchanger', val.toLowerCase())
24
+ }
25
+
26
+ getDescription() {
27
+ return 'Key Exchanger'
28
+ }
29
+
30
+ getRdataFields(arg) {
31
+ return ['preference', 'exchanger']
32
+ }
33
+
34
+ getRFCs() {
35
+ return [2230]
36
+ }
37
+
38
+ getTypeId() {
39
+ return 36
40
+ }
41
+
42
+ getCanonical() {
43
+ return {
44
+ owner: 'example.com.',
45
+ ttl: 3600,
46
+ class: 'IN',
47
+ type: 'KX',
48
+ preference: 10,
49
+ exchanger: 'kx.example.com.',
50
+ }
51
+ }
52
+
53
+ /****** IMPORTERS *******/
54
+ fromBind(opts) {
55
+ // test.example.com 3600 IN KX preference exchanger
56
+ const [owner, ttl, c, type, preference, exchanger] = opts.bindline.split(/\s+/)
57
+ return new KX({
58
+ owner,
59
+ ttl: parseInt(ttl, 10),
60
+ class: c,
61
+ type,
62
+ preference: parseInt(preference, 10),
63
+ exchanger,
64
+ })
65
+ }
66
+
67
+ /****** EXPORTERS *******/
68
+ toBind(zone_opts) {
69
+ return `${this.getPrefix(zone_opts)}\t${this.get('preference')}\t${this.getFQDN('exchanger', zone_opts)}\n`
70
+ }
71
+
72
+ toTinydns() {
73
+ return this.getTinydnsGeneric(
74
+ TINYDNS.UInt16toOctal(this.get('preference')) + TINYDNS.packDomainName(this.get('exchanger')),
75
+ )
76
+ }
77
+ }
package/rr/loc.js CHANGED
@@ -53,8 +53,7 @@ export default class LOC extends RR {
53
53
  const dms = '(\\d+)\\s+(?:(\\d+)\\s+)?(?:([\\d.]+)\\s+)?'
54
54
 
55
55
  // alt["m"] [siz["m"] [hp["m"] [vp["m"]]]]
56
- const alt =
57
- '(-?[\\d.]+)m?(?:\\s+([\\d.]+)m?)?(?:\\s+([\\d.]+)m?)?(?:\\s+([\\d.]+)m?)?'
56
+ const alt = '(-?[\\d.]+)m?(?:\\s+([\\d.]+)m?)?(?:\\s+([\\d.]+)m?)?(?:\\s+([\\d.]+)m?)?'
58
57
 
59
58
  // put them all together
60
59
  const locRe = new RegExp(`^${dms}(N|S)\\s+${dms}(E|W)\\s+${alt}`, 'i')
@@ -96,21 +95,11 @@ export default class LOC extends RR {
96
95
  version: TINYDNS.octalToUInt8(rdata.substring(0, 4)),
97
96
  size: this.fromExponent(TINYDNS.octalToUInt8(rdata.substring(4, 8))),
98
97
  precision: {
99
- horizontal: this.fromExponent(
100
- TINYDNS.octalToUInt8(rdata.substring(8, 12)),
101
- ),
102
- vertical: this.fromExponent(
103
- TINYDNS.octalToUInt8(rdata.substring(12, 16)),
104
- ),
98
+ horizontal: this.fromExponent(TINYDNS.octalToUInt8(rdata.substring(8, 12))),
99
+ vertical: this.fromExponent(TINYDNS.octalToUInt8(rdata.substring(12, 16))),
105
100
  },
106
- latitude: this.arcSecToDMS(
107
- TINYDNS.octalToUInt32(rdata.substring(16, 32)),
108
- 'lat',
109
- ),
110
- longitude: this.arcSecToDMS(
111
- TINYDNS.octalToUInt32(rdata.substring(32, 48)),
112
- 'lon',
113
- ),
101
+ latitude: this.arcSecToDMS(TINYDNS.octalToUInt32(rdata.substring(16, 32)), 'lat'),
102
+ longitude: this.arcSecToDMS(TINYDNS.octalToUInt32(rdata.substring(32, 48)), 'lon'),
114
103
  altitude: TINYDNS.octalToUInt32(rdata.substring(48, 64)) - REF.ALTITUDE,
115
104
  }
116
105
 
@@ -137,10 +126,7 @@ export default class LOC extends RR {
137
126
  }
138
127
 
139
128
  dmsToArcSec(obj) {
140
- let retval =
141
- obj.degrees * CONV.deg +
142
- (obj.minutes || 0) * CONV.min +
143
- (obj.seconds || 0) * CONV.sec
129
+ let retval = obj.degrees * CONV.deg + (obj.minutes || 0) * CONV.min + (obj.seconds || 0) * CONV.sec
144
130
  switch (obj.hemisphere.toUpperCase()) {
145
131
  case 'W':
146
132
  case 'S':
package/rr/mx.js CHANGED
@@ -16,8 +16,7 @@ export default class MX extends RR {
16
16
  setExchange(val) {
17
17
  if (!val) this.throwHelp('MX: exchange is required')
18
18
 
19
- if (this.isIPv4(val) || this.isIPv6(val))
20
- this.throwHelp(`MX: exchange must be a FQDN`)
19
+ if (this.isIPv4(val) || this.isIPv6(val)) this.throwHelp(`MX: exchange must be a FQDN`)
21
20
 
22
21
  this.isFullyQualified('MX', 'exchange', val)
23
22
  this.isValidHostname('MX', 'exchange', val)
@@ -57,9 +56,7 @@ export default class MX extends RR {
57
56
  fromTinydns(opts) {
58
57
  // @fqdn:ip:x:dist:ttl:timestamp:lo
59
58
  // eslint-disable-next-line no-unused-vars
60
- const [owner, ip, x, preference, ttl, ts, loc] = opts.tinyline
61
- .substring(1)
62
- .split(':')
59
+ const [owner, ip, x, preference, ttl, ts, loc] = opts.tinyline.substring(1).split(':')
63
60
 
64
61
  return new MX({
65
62
  type: 'MX',
@@ -74,8 +71,7 @@ export default class MX extends RR {
74
71
 
75
72
  fromBind(opts) {
76
73
  // test.example.com 3600 IN MX preference exchange
77
- const [owner, ttl, c, type, preference, exchange] =
78
- opts.bindline.split(/\s+/)
74
+ const [owner, ttl, c, type, preference, exchange] = opts.bindline.split(/\s+/)
79
75
 
80
76
  return new MX({
81
77
  owner,
package/rr/naptr.js CHANGED
@@ -40,12 +40,15 @@ export default class NAPTR extends RR {
40
40
  }
41
41
 
42
42
  setFlags(val) {
43
- if (!['', 'S', 'A', 'U', 'P'].includes(val.toUpperCase()))
44
- this.throwHelp(`NAPTR flags are invalid`)
43
+ if (!this.getFlagsOptions().has(val.toUpperCase())) this.throwHelp(`NAPTR flags are invalid`)
45
44
 
46
45
  this.set('flags', val.toUpperCase())
47
46
  }
48
47
 
48
+ getFlagsOptions() {
49
+ return new Map([[''], ['S'], ['A'], ['U'], ['P']])
50
+ }
51
+
49
52
  setService(val) {
50
53
  this.set('service', val)
51
54
  }
package/rr/ns.js CHANGED
@@ -37,16 +37,12 @@ export default class NS extends RR {
37
37
  fromTinydns(opts) {
38
38
  // &fqdn:ip:x:ttl:timestamp:lo
39
39
  // eslint-disable-next-line no-unused-vars
40
- const [fqdn, ip, dname, ttl, ts, loc] = opts.tinyline
41
- .substring(1)
42
- .split(':')
40
+ const [fqdn, ip, dname, ttl, ts, loc] = opts.tinyline.substring(1).split(':')
43
41
 
44
42
  return new NS({
45
43
  type: 'NS',
46
44
  owner: this.fullyQualify(fqdn),
47
- dname: this.fullyQualify(
48
- /\./.test(dname) ? dname : `${dname}.ns.${fqdn}`,
49
- ),
45
+ dname: this.fullyQualify(/\./.test(dname) ? dname : `${dname}.ns.${fqdn}`),
50
46
  ttl: parseInt(ttl, 10),
51
47
  timestamp: ts,
52
48
  location: loc !== '' && loc !== '\n' ? loc : '',
package/rr/nsec.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import RR from '../rr.js'
2
2
 
3
+ import * as TINYDNS from '../lib/tinydns.js'
4
+
3
5
  export default class NSEC extends RR {
4
6
  constructor(opts) {
5
7
  super(opts)
@@ -50,16 +52,20 @@ export default class NSEC extends RR {
50
52
  class: c,
51
53
  type: type,
52
54
  'next domain': next,
53
- 'type bit maps': opts.bindline
54
- .split(/\s+/)
55
- .slice(5)
56
- .filter(removeParens)
57
- .join(' ')
58
- .trim(),
55
+ 'type bit maps': opts.bindline.split(/\s+/).slice(5).filter(removeParens).join(' ').trim(),
59
56
  })
60
57
  }
61
58
 
62
59
  /****** EXPORTERS *******/
60
+
61
+ toTinydns() {
62
+ const dataRe = new RegExp(/[\r\n\t:\\/]/, 'g')
63
+
64
+ return this.getTinydnsGeneric(
65
+ TINYDNS.packDomainName(this.get('next domain')) +
66
+ TINYDNS.escapeOctal(dataRe, this.get('type bit maps')),
67
+ )
68
+ }
63
69
  }
64
70
 
65
71
  const removeParens = (a) => !['(', ')'].includes(a)
package/rr/nsec3.js CHANGED
@@ -65,14 +65,7 @@ export default class NSEC3 extends RR {
65
65
  }
66
66
 
67
67
  getRdataFields(arg) {
68
- return [
69
- 'hash algorithm',
70
- 'flags',
71
- 'iterations',
72
- 'salt',
73
- 'next hashed owner name',
74
- 'type bit maps',
75
- ]
68
+ return ['hash algorithm', 'flags', 'iterations', 'salt', 'next hashed owner name', 'type bit maps']
76
69
  }
77
70
 
78
71
  getRFCs() {
@@ -87,8 +80,7 @@ export default class NSEC3 extends RR {
87
80
 
88
81
  fromBind(opts) {
89
82
  // test.example.com. 3600 IN NSEC3 1 1 12 aabbccdd (2vptu5timamqttgl4luu9kg21e0aor3s A RRSIG)
90
- const [owner, ttl, c, type, ha, flags, iterations, salt] =
91
- opts.bindline.split(/\s+/)
83
+ const [owner, ttl, c, type, ha, flags, iterations, salt] = opts.bindline.split(/\s+/)
92
84
  const rdata = opts.bindline.split(/\(|\)/)[1]
93
85
 
94
86
  return new NSEC3({
package/rr/nxt.js CHANGED
@@ -50,12 +50,7 @@ export default class NXT extends RR {
50
50
  class: c,
51
51
  type: type,
52
52
  'next domain': next,
53
- 'type bit map': opts.bindline
54
- .split(/\s+/)
55
- .slice(5)
56
- .filter(removeParens)
57
- .join(' ')
58
- .trim(),
53
+ 'type bit map': opts.bindline.split(/\s+/).slice(5).filter(removeParens).join(' ').trim(),
59
54
  })
60
55
  }
61
56
 
package/rr/openpgpkey.js CHANGED
@@ -29,10 +29,9 @@ export default class OPENPGPKEY extends RR {
29
29
  /****** IMPORTERS *******/
30
30
  fromBind(obj) {
31
31
  // test.example.com 3600 IN OPENPGPKEY <base64 public key>
32
+ const regex = /^([\S]+)\s+(\d{1,10})\s+(IN)\s+(OPENPGPKEY)\s+([\W\w]*)$/
32
33
  // eslint-disable-next-line no-unused-vars
33
- const [ignore, owner, ttl, c, type, publickey] = obj.bindline
34
- .trim()
35
- .match(/^([\S]+)\s+(\d{1,10})\s+(IN)\s+(OPENPGPKEY)\s+([\W\w]*)$/)
34
+ const [ignore, owner, ttl, c, type, publickey] = obj.bindline.trim().match(regex)
36
35
 
37
36
  return new OPENPGPKEY({
38
37
  owner,