@nictool/dns-resource-record 1.2.1 → 1.2.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/CHANGELOG.md +19 -1
- package/README.md +3 -1
- package/package.json +16 -2
- package/rr/a.js +1 -3
- package/rr/aaaa.js +1 -3
- package/rr/caa.js +5 -3
- package/rr/cname.js +1 -3
- package/rr/dname.js +1 -3
- package/rr/hinfo.js +5 -3
- package/rr/ipseckey.js +2 -4
- package/rr/mx.js +1 -3
- package/rr/openpgpkey.js +3 -3
- package/rr/srv.js +1 -3
- package/rr/tlsa.js +5 -3
- package/rr/txt.js +3 -3
- package/rr.js +12 -3
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,20 @@ Notable changes to this project are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
#### Unreleased
|
|
6
6
|
|
|
7
|
+
### [1.2.3] - 2025-04-14
|
|
8
|
+
|
|
9
|
+
- test(\*): fully qualify node modules
|
|
10
|
+
- feat(rr.isIPv?): added regexes to validate format
|
|
11
|
+
- dep(node:{net|util): remove, for browser compatiblity
|
|
12
|
+
- doc(CONTRIBUTORS.md): added
|
|
13
|
+
- ci: disable codeql schedule (#45)
|
|
14
|
+
|
|
15
|
+
### [1.2.2] - 2024-11-17
|
|
16
|
+
|
|
17
|
+
- dep(eslint): update to v9 & config
|
|
18
|
+
- chore: tighten up fromBind regex
|
|
19
|
+
- packaging tweaks (#43)
|
|
20
|
+
|
|
7
21
|
### [1.2.1] - 2024-03-10
|
|
8
22
|
|
|
9
23
|
- fix(nsec3param): fixed setHash fname typo
|
|
@@ -294,4 +308,8 @@ Notable changes to this project are documented in this file.
|
|
|
294
308
|
[1.1.5]: https://github.com/NicTool/dns-resource-record/releases/tag/1.1.5
|
|
295
309
|
[1.1.6]: https://github.com/NicTool/dns-resource-record/releases/tag/1.1.6
|
|
296
310
|
[1.1.8]: https://github.com/NicTool/dns-resource-record/releases/tag/1.1.8
|
|
297
|
-
[1.
|
|
311
|
+
[1.1.7]: https://github.com/NicTool/dns-resource-record/releases/tag/1.1.7
|
|
312
|
+
[1.2.0]: https://github.com/NicTool/dns-resource-record/releases/tag/1.2.0
|
|
313
|
+
[1.2.1]: https://github.com/NicTool/dns-resource-record/releases/tag/v1.2.1
|
|
314
|
+
[1.2.2]: https://github.com/NicTool/dns-resource-record/releases/tag/1.2.2
|
|
315
|
+
[1.2.3]: https://github.com/NicTool/dns-resource-record/releases/tag/v1.2.3
|
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ This module is used to:
|
|
|
20
20
|
| **MaraDNS** | | :white_check_mark: |
|
|
21
21
|
| **JS** | :white_check_mark: | :white_check_mark: |
|
|
22
22
|
|
|
23
|
-
This package intends to import and export RFC compliant DNS resource records. Please [raise an issue](https://github.com/NicTool/dns-resource-record/issues) if
|
|
23
|
+
This package intends to import and export RFC compliant DNS resource records. Please [raise an issue](https://github.com/NicTool/dns-resource-record/issues) if a valid resource record fails to pass or an invalid resource record passes.
|
|
24
24
|
|
|
25
25
|
This package is for working with _individual_ Resource Records. For working with zones of RRs, use [dns-zone](https://github.com/NicTool/dns-zone).
|
|
26
26
|
|
|
@@ -239,6 +239,8 @@ PRs are welcome, especially PRs with tests.
|
|
|
239
239
|
|
|
240
240
|
- [Dictionary of DNS terms](https://nictool.github.io/web/Dictionary)
|
|
241
241
|
- [Wikipedia, List of DNS Record Types](https://en.wikipedia.org/wiki/List_of_DNS_record_types)
|
|
242
|
+
- @nictool/[dns-zone](https://www.npmjs.com/package/@nictool/dns-zone)
|
|
243
|
+
- @nictool/[dns-nameserver](https://www.npmjs.com/package/@nictool/dns-nameserver)
|
|
242
244
|
|
|
243
245
|
## TODO
|
|
244
246
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nictool/dns-resource-record",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.3",
|
|
4
4
|
"description": "DNS Resource Records",
|
|
5
5
|
"main": "index.js",
|
|
6
|
+
"files": [
|
|
7
|
+
"lib",
|
|
8
|
+
"rr",
|
|
9
|
+
"CHANGELOG.md",
|
|
10
|
+
"rr.js"
|
|
11
|
+
],
|
|
6
12
|
"type": "module",
|
|
7
13
|
"scripts": {
|
|
8
14
|
"format:check": "npm run prettier; npm run lint",
|
|
@@ -39,6 +45,14 @@
|
|
|
39
45
|
},
|
|
40
46
|
"homepage": "https://github.com/NicTool/dns-resource-record#readme",
|
|
41
47
|
"devDependencies": {
|
|
42
|
-
"
|
|
48
|
+
"@eslint/js": "^10.0.0",
|
|
49
|
+
"eslint": "^9.15.0",
|
|
50
|
+
"globals": "^16.0.0",
|
|
51
|
+
"mocha": "^11.2.2"
|
|
52
|
+
},
|
|
53
|
+
"prettier": {
|
|
54
|
+
"semi": false,
|
|
55
|
+
"singleQuote": true,
|
|
56
|
+
"trailingComma": "all"
|
|
43
57
|
}
|
|
44
58
|
}
|
package/rr/a.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import net from 'node:net'
|
|
2
|
-
|
|
3
1
|
import RR from '../rr.js'
|
|
4
2
|
|
|
5
3
|
export default class A extends RR {
|
|
@@ -10,7 +8,7 @@ export default class A extends RR {
|
|
|
10
8
|
/****** Resource record specific setters *******/
|
|
11
9
|
setAddress(val) {
|
|
12
10
|
if (!val) this.throwHelp('A: address is required')
|
|
13
|
-
if (!
|
|
11
|
+
if (!this.isIPv4(val)) this.throwHelp('A address must be IPv4')
|
|
14
12
|
this.set('address', val)
|
|
15
13
|
}
|
|
16
14
|
|
package/rr/aaaa.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import net from 'node:net'
|
|
2
|
-
|
|
3
1
|
import RR from '../rr.js'
|
|
4
2
|
import * as TINYDNS from '../lib/tinydns.js'
|
|
5
3
|
|
|
@@ -11,7 +9,7 @@ export default class AAAA extends RR {
|
|
|
11
9
|
/****** Resource record specific setters *******/
|
|
12
10
|
setAddress(val) {
|
|
13
11
|
if (!val) this.throwHelp('AAAA: address is required')
|
|
14
|
-
if (!
|
|
12
|
+
if (!this.isIPv6(val)) this.throwHelp(`AAAA: address must be IPv6 (${val})`)
|
|
15
13
|
|
|
16
14
|
this.set('address', this.expand(val.toLowerCase())) // lower case: RFC 5952
|
|
17
15
|
}
|
package/rr/caa.js
CHANGED
|
@@ -108,9 +108,11 @@ export default class CAA extends RR {
|
|
|
108
108
|
|
|
109
109
|
fromBind(opts) {
|
|
110
110
|
// test.example.com 3600 IN CAA flags, tags, value
|
|
111
|
-
const fields = opts.bindline
|
|
112
|
-
|
|
113
|
-
|
|
111
|
+
const fields = opts.bindline
|
|
112
|
+
.trim()
|
|
113
|
+
.match(
|
|
114
|
+
/^([\S]+)\s+([0-9]{1,10})\s+(IN)\s+(CAA)\s+([0-9]+)\s+(\w+)\s+("[^"]+"|[\S]+?)$/i,
|
|
115
|
+
)
|
|
114
116
|
if (!fields) this.throwHelp(`unable to parse: ${opts.bindline}`)
|
|
115
117
|
|
|
116
118
|
const [owner, ttl, c, type, flags, tag, value] = fields.slice(1)
|
package/rr/cname.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import net from 'node:net'
|
|
2
|
-
|
|
3
1
|
import RR from '../rr.js'
|
|
4
2
|
|
|
5
3
|
export default class CNAME extends RR {
|
|
@@ -14,7 +12,7 @@ export default class CNAME extends RR {
|
|
|
14
12
|
|
|
15
13
|
if (!val) this.throwHelp('CNAME: cname is required')
|
|
16
14
|
|
|
17
|
-
if (
|
|
15
|
+
if (this.isIPv4(val) || this.isIPv6(val))
|
|
18
16
|
this.throwHelp(`CNAME: cname must be a FQDN: RFC 2181`)
|
|
19
17
|
|
|
20
18
|
if (!this.isFullyQualified('CNAME', 'cname', val)) return
|
package/rr/dname.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import net from 'node:net'
|
|
2
|
-
|
|
3
1
|
import RR from '../rr.js'
|
|
4
2
|
import * as TINYDNS from '../lib/tinydns.js'
|
|
5
3
|
|
|
@@ -12,7 +10,7 @@ export default class DNAME extends RR {
|
|
|
12
10
|
setTarget(val) {
|
|
13
11
|
if (!val) this.throwHelp('DNAME: target is required')
|
|
14
12
|
|
|
15
|
-
if (
|
|
13
|
+
if (this.isIPv4(val) || this.isIPv6(val))
|
|
16
14
|
this.throwHelp(`DNAME: target must be a domain name`)
|
|
17
15
|
|
|
18
16
|
this.isFullyQualified('DNAME', 'target', val)
|
package/rr/hinfo.js
CHANGED
|
@@ -41,9 +41,11 @@ 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
|
-
|
|
46
|
-
|
|
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
|
+
)
|
|
47
49
|
if (!match) this.throwHelp(`unable to parse HINFO: ${opts.bindline}`)
|
|
48
50
|
const [owner, ttl, c, type, cpu, os] = match.slice(1)
|
|
49
51
|
|
package/rr/ipseckey.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import net from 'node:net'
|
|
2
|
-
|
|
3
1
|
import RR from '../rr.js'
|
|
4
2
|
|
|
5
3
|
import * as TINYDNS from '../lib/tinydns.js'
|
|
@@ -39,10 +37,10 @@ export default class IPSECKEY extends RR {
|
|
|
39
37
|
if (val !== '.') throw gwErr
|
|
40
38
|
break
|
|
41
39
|
case 1:
|
|
42
|
-
if (!
|
|
40
|
+
if (!this.isIPv4(val)) throw gwErr
|
|
43
41
|
break
|
|
44
42
|
case 2:
|
|
45
|
-
if (!
|
|
43
|
+
if (!this.isIPv6(val)) throw gwErr
|
|
46
44
|
break
|
|
47
45
|
}
|
|
48
46
|
|
package/rr/mx.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import net from 'node:net'
|
|
2
|
-
|
|
3
1
|
import RR from '../rr.js'
|
|
4
2
|
|
|
5
3
|
export default class MX extends RR {
|
|
@@ -18,7 +16,7 @@ export default class MX extends RR {
|
|
|
18
16
|
setExchange(val) {
|
|
19
17
|
if (!val) this.throwHelp('MX: exchange is required')
|
|
20
18
|
|
|
21
|
-
if (
|
|
19
|
+
if (this.isIPv4(val) || this.isIPv6(val))
|
|
22
20
|
this.throwHelp(`MX: exchange must be a FQDN`)
|
|
23
21
|
|
|
24
22
|
this.isFullyQualified('MX', 'exchange', val)
|
package/rr/openpgpkey.js
CHANGED
|
@@ -30,9 +30,9 @@ export default class OPENPGPKEY extends RR {
|
|
|
30
30
|
fromBind(obj) {
|
|
31
31
|
// test.example.com 3600 IN OPENPGPKEY <base64 public key>
|
|
32
32
|
// eslint-disable-next-line no-unused-vars
|
|
33
|
-
const [ignore, owner, ttl, c, type, publickey] = obj.bindline
|
|
34
|
-
|
|
35
|
-
|
|
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]*)$/)
|
|
36
36
|
|
|
37
37
|
return new OPENPGPKEY({
|
|
38
38
|
owner,
|
package/rr/srv.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import net from 'node:net'
|
|
2
|
-
|
|
3
1
|
import RR from '../rr.js'
|
|
4
2
|
import * as TINYDNS from '../lib/tinydns.js'
|
|
5
3
|
|
|
@@ -30,7 +28,7 @@ export default class SRV extends RR {
|
|
|
30
28
|
setTarget(val) {
|
|
31
29
|
if (!val) this.throwHelp(`SRV: target is required`)
|
|
32
30
|
|
|
33
|
-
if (
|
|
31
|
+
if (this.isIPv4(val) || this.isIPv6(val))
|
|
34
32
|
this.throwHelp(`SRV: target must be a FQDN`)
|
|
35
33
|
|
|
36
34
|
this.isFullyQualified('SRV', 'target', val)
|
package/rr/tlsa.js
CHANGED
|
@@ -60,9 +60,11 @@ export default class TLSA extends RR {
|
|
|
60
60
|
|
|
61
61
|
fromBind(opts) {
|
|
62
62
|
// test.example.com 3600 IN TLSA, usage, selector, match, data
|
|
63
|
-
const match = opts.bindline
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
const match = opts.bindline
|
|
64
|
+
.trim()
|
|
65
|
+
.split(
|
|
66
|
+
/^([^\s]+)\s+([0-9]{1,10})\s+(IN)\s+(TLSA)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+(.*?)$/,
|
|
67
|
+
)
|
|
66
68
|
if (!match) this.throwHelp(`unable to parse TLSA: ${opts.bindline}`)
|
|
67
69
|
const [owner, ttl, c, type, usage, selector, matchtype, cad] =
|
|
68
70
|
match.slice(1)
|
package/rr/txt.js
CHANGED
|
@@ -70,9 +70,9 @@ export default class TXT extends RR {
|
|
|
70
70
|
|
|
71
71
|
fromBind(opts) {
|
|
72
72
|
// test.example.com 3600 IN TXT "..."
|
|
73
|
-
const match = opts.bindline
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
const match = opts.bindline
|
|
74
|
+
.trim()
|
|
75
|
+
.split(/^([\S]{1,255})\s+([0-9]{1,10})\s+(IN)\s+(\w{3})\s+?\s*(.*?)$/i)
|
|
76
76
|
if (!match) this.throwHelp(`unable to parse TXT: ${opts.bindline}`)
|
|
77
77
|
const [owner, ttl, c, type, rdata] = match.slice(1)
|
|
78
78
|
|
package/rr.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import util from 'node:util'
|
|
2
|
-
|
|
3
1
|
export default class RR extends Map {
|
|
4
2
|
constructor(opts) {
|
|
5
3
|
super()
|
|
@@ -128,7 +126,7 @@ export default class RR extends Map {
|
|
|
128
126
|
if (this.constructor.name === 'RR') throw new Error(e)
|
|
129
127
|
|
|
130
128
|
const example = this.getCanonical
|
|
131
|
-
? `Example ${this.constructor.name}:\n${
|
|
129
|
+
? `Example ${this.constructor.name}:\n${this.getCanonical()}\n\n`
|
|
132
130
|
: `${this.constructor.name} records have the fields: ${this.getFields().join(', ')}\n\n`
|
|
133
131
|
|
|
134
132
|
throw new Error(`${e}\n\n${example}${this.citeRFC()}\n`)
|
|
@@ -313,6 +311,17 @@ export default class RR extends Map {
|
|
|
313
311
|
)
|
|
314
312
|
}
|
|
315
313
|
|
|
314
|
+
isIPv4(string) {
|
|
315
|
+
// https://stackoverflow.com/questions/5284147/validating-ipv4-addresses-with-regexp
|
|
316
|
+
return /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$/.test(string)
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
isIPv6(string) {
|
|
320
|
+
return /^(?:(?:[a-fA-F\d]{1,4}:){7}(?:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){6}(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){5}(?::(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,2}|:)|(?:[a-fA-F\d]{1,4}:){4}(?:(?::[a-fA-F\d]{1,4}){0,1}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,3}|:)|(?:[a-fA-F\d]{1,4}:){3}(?:(?::[a-fA-F\d]{1,4}){0,2}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,4}|:)|(?:[a-fA-F\d]{1,4}:){2}(?:(?::[a-fA-F\d]{1,4}){0,3}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,5}|:)|(?:[a-fA-F\d]{1,4}:){1}(?:(?::[a-fA-F\d]{1,4}){0,4}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,6}|:)|(?::(?:(?::[a-fA-F\d]{1,4}){0,5}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,7}|:)))(?:%[0-9a-zA-Z]{1,})?$/gm.test(
|
|
321
|
+
string,
|
|
322
|
+
)
|
|
323
|
+
}
|
|
324
|
+
|
|
316
325
|
toBind(zone_opts) {
|
|
317
326
|
return `${this.getPrefix(zone_opts)}\t${this.getRdataFields()
|
|
318
327
|
.map((f) => this.getQuoted(f))
|