@nictool/dns-resource-record 1.2.0 → 1.2.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.
- package/.codeclimate.yml +25 -0
- package/.github/FUNDING.yml +3 -0
- package/.github/workflows/ci.yml +43 -0
- package/.github/workflows/codeql.yml +14 -0
- package/.github/workflows/publish.yml +16 -0
- package/.gitmodules +3 -0
- package/CHANGELOG.md +18 -0
- package/DEVELOP.md +9 -0
- package/README.md +6 -2
- package/eslint.config.mjs +41 -0
- package/index.js +6 -0
- package/package.json +12 -3
- package/rr/a.js +13 -3
- package/rr/aaaa.js +14 -4
- package/rr/caa.js +25 -13
- package/rr/cname.js +3 -3
- package/rr/dname.js +4 -4
- package/rr/dnskey.js +6 -11
- package/rr/ds.js +6 -8
- package/rr/hinfo.js +8 -6
- package/rr/https.js +62 -0
- package/rr/ipseckey.js +20 -9
- package/rr/key.js +2 -2
- package/rr/loc.js +4 -4
- package/rr/mx.js +15 -3
- package/rr/naptr.js +2 -2
- package/rr/ns.js +1 -1
- package/rr/nsec.js +2 -4
- package/rr/nsec3.js +6 -12
- package/rr/nsec3param.js +4 -9
- package/rr/nxt.js +2 -4
- package/rr/openpgpkey.js +7 -3
- package/rr/rrsig.js +3 -4
- package/rr/sig.js +1 -1
- package/rr/smimea.js +3 -5
- package/rr/soa.js +1 -2
- package/rr/spf.js +1 -1
- package/rr/srv.js +4 -4
- package/rr/sshfp.js +1 -1
- package/rr/svcb.js +64 -0
- package/rr/tlsa.js +10 -10
- package/rr/tsig.js +10 -2
- package/rr/txt.js +5 -5
- package/rr/uri.js +2 -2
- package/rr/wks.js +4 -3
- package/rr.js +32 -20
- package/test/a.js +75 -0
- package/test/aaaa.js +86 -0
- package/test/base.js +148 -0
- package/test/caa.js +111 -0
- package/test/cert.js +48 -0
- package/test/cname.js +40 -0
- package/test/dname.js +57 -0
- package/test/dnskey.js +45 -0
- package/test/ds.js +45 -0
- package/test/fake.js +34 -0
- package/test/hinfo.js +80 -0
- package/test/https.js +56 -0
- package/test/ipseckey.js +141 -0
- package/test/key.js +36 -0
- package/test/loc.js +75 -0
- package/test/mx.js +78 -0
- package/test/naptr.js +47 -0
- package/test/ns.js +56 -0
- package/test/nsec.js +37 -0
- package/test/nsec3.js +47 -0
- package/test/nsec3param.js +23 -0
- package/test/nxt.js +37 -0
- package/test/openpgpkey.js +85 -0
- package/test/ptr.js +56 -0
- package/test/rr.js +212 -0
- package/test/smimea.js +51 -0
- package/test/soa.js +99 -0
- package/test/spf.js +51 -0
- package/test/srv.js +101 -0
- package/test/sshfp.js +69 -0
- package/test/svcb.js +56 -0
- package/test/tinydns.js +163 -0
- package/test/tlsa.js +63 -0
- package/test/txt.js +82 -0
- package/test/uri.js +65 -0
package/.codeclimate.yml
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
checks:
|
|
2
|
+
return-statements:
|
|
3
|
+
enabled: false
|
|
4
|
+
similar-code:
|
|
5
|
+
enabled: false
|
|
6
|
+
file-lines:
|
|
7
|
+
config:
|
|
8
|
+
threshold: 500
|
|
9
|
+
method-lines:
|
|
10
|
+
config:
|
|
11
|
+
threshold: 50
|
|
12
|
+
method-complexity:
|
|
13
|
+
config:
|
|
14
|
+
threshold: 10
|
|
15
|
+
|
|
16
|
+
plugins:
|
|
17
|
+
eslint:
|
|
18
|
+
enabled: true
|
|
19
|
+
channel: 'eslint-8'
|
|
20
|
+
config:
|
|
21
|
+
config: '.eslintrc.yaml'
|
|
22
|
+
|
|
23
|
+
ratings:
|
|
24
|
+
paths:
|
|
25
|
+
- '**.js'
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
env:
|
|
8
|
+
CI: true
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
lint:
|
|
12
|
+
uses: NicTool/.github/.github/workflows/lint.yml@main
|
|
13
|
+
|
|
14
|
+
coverage:
|
|
15
|
+
uses: NicTool/.github/.github/workflows/coverage.yml@main
|
|
16
|
+
secrets: inherit
|
|
17
|
+
|
|
18
|
+
test:
|
|
19
|
+
needs: get-lts
|
|
20
|
+
runs-on: ${{ matrix.os }}
|
|
21
|
+
strategy:
|
|
22
|
+
matrix:
|
|
23
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
24
|
+
node-version: ${{ fromJson(needs.get-lts.outputs.active) }}
|
|
25
|
+
fail-fast: false
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
- uses: actions/setup-node@v4
|
|
29
|
+
name: Node ${{ matrix.node-version }} on ${{ matrix.os }}
|
|
30
|
+
with:
|
|
31
|
+
node-version: ${{ matrix.node-version }}
|
|
32
|
+
- run: npm install
|
|
33
|
+
- run: npm test
|
|
34
|
+
|
|
35
|
+
get-lts:
|
|
36
|
+
needs: lint
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
steps:
|
|
39
|
+
- id: get
|
|
40
|
+
uses: msimerson/node-lts-versions@v1
|
|
41
|
+
outputs:
|
|
42
|
+
lts: ${{ steps.get.outputs.lts }}
|
|
43
|
+
active: ${{ steps.get.outputs.active }}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
name: CodeQL
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
# The branches below must be a subset of the branches above
|
|
8
|
+
branches: [main]
|
|
9
|
+
schedule:
|
|
10
|
+
- cron: '18 7 * * 4'
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
codeql:
|
|
14
|
+
uses: NicTool/.github/.github/workflows/codeql.yml@main
|
package/.gitmodules
ADDED
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.2] - 2024-11-17
|
|
8
|
+
|
|
9
|
+
- dep(eslint): update to v9 & config
|
|
10
|
+
- chore: tighten up fromBind regex
|
|
11
|
+
- packaging tweaks (#43)
|
|
12
|
+
|
|
13
|
+
### [1.2.1] - 2024-03-10
|
|
14
|
+
|
|
15
|
+
- fix(nsec3param): fixed setHash fname typo
|
|
16
|
+
- feat(SVCB,HTTPS): add record support (#29)
|
|
17
|
+
- feat(OPENGPGPKEY): improved bindline parser, added test
|
|
18
|
+
- feat(throwHelp): far more useful error messages (#41)
|
|
19
|
+
- feat(A,MX,AAAA,CAA,IPSECKEY): added getCanonical
|
|
20
|
+
|
|
7
21
|
### [1.2.0] - 2024-03-07
|
|
8
22
|
|
|
9
23
|
- feat(index): export typeMap (lookup table for type to id)
|
|
@@ -286,3 +300,7 @@ Notable changes to this project are documented in this file.
|
|
|
286
300
|
[1.1.5]: https://github.com/NicTool/dns-resource-record/releases/tag/1.1.5
|
|
287
301
|
[1.1.6]: https://github.com/NicTool/dns-resource-record/releases/tag/1.1.6
|
|
288
302
|
[1.1.8]: https://github.com/NicTool/dns-resource-record/releases/tag/1.1.8
|
|
303
|
+
[1.2.1]: https://github.com/NicTool/dns-resource-record/releases/tag/1.2.1
|
|
304
|
+
[1.2.2]: https://github.com/NicTool/dns-resource-record/releases/tag/v1.2.2
|
|
305
|
+
[1.1.7]: https://github.com/NicTool/dns-resource-record/releases/tag/1.1.7
|
|
306
|
+
[1.2.0]: https://github.com/NicTool/dns-resource-record/releases/tag/1.2.0
|
package/DEVELOP.md
ADDED
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ DNS resource record parser, validator, importer, and exporter.
|
|
|
10
10
|
This module is used to:
|
|
11
11
|
|
|
12
12
|
- validate well formedness and RFC compliance of DNS resource records
|
|
13
|
-
- import RRs
|
|
13
|
+
- import RRs to and from the following formats:
|
|
14
14
|
|
|
15
15
|
| **RR format** | **import** | **export** |
|
|
16
16
|
| :------------------------------------------------------: | :----------------: | :----------------: |
|
|
@@ -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
|
|
|
@@ -196,6 +196,7 @@ PRs are welcome, especially PRs with tests.
|
|
|
196
196
|
| **DNSKEY** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
197
197
|
| **DS** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
198
198
|
| **HINFO** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
199
|
+
| **HTTPS** | | | | |
|
|
199
200
|
| **IPSECKEY** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
200
201
|
| **KEY** | | | | |
|
|
201
202
|
| **LOC** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
@@ -215,6 +216,7 @@ PRs are welcome, especially PRs with tests.
|
|
|
215
216
|
| **SPF** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
216
217
|
| **SRV** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
217
218
|
| **SSHFP** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
219
|
+
| **SVCB** | | | | |
|
|
218
220
|
| **TLSA** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
219
221
|
| **TSIG** | | | | |
|
|
220
222
|
| **TXT** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
@@ -237,6 +239,8 @@ PRs are welcome, especially PRs with tests.
|
|
|
237
239
|
|
|
238
240
|
- [Dictionary of DNS terms](https://nictool.github.io/web/Dictionary)
|
|
239
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)
|
|
240
244
|
|
|
241
245
|
## TODO
|
|
242
246
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import globals from 'globals'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { fileURLToPath } from 'node:url'
|
|
4
|
+
import js from '@eslint/js'
|
|
5
|
+
import { FlatCompat } from '@eslint/eslintrc'
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
8
|
+
const __dirname = path.dirname(__filename)
|
|
9
|
+
const compat = new FlatCompat({
|
|
10
|
+
baseDirectory: __dirname,
|
|
11
|
+
recommendedConfig: js.configs.recommended,
|
|
12
|
+
allConfig: js.configs.all,
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
export default [
|
|
16
|
+
{
|
|
17
|
+
languageOptions: {
|
|
18
|
+
ecmaVersion: 'latest',
|
|
19
|
+
globals: {
|
|
20
|
+
...globals.node,
|
|
21
|
+
...globals.browser,
|
|
22
|
+
...globals.mocha,
|
|
23
|
+
},
|
|
24
|
+
sourceType: 'module',
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
rules: {
|
|
28
|
+
// 'no-undef': [ 'warn' ],
|
|
29
|
+
'no-unused-vars': [
|
|
30
|
+
'error',
|
|
31
|
+
{
|
|
32
|
+
args: 'none',
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
|
|
36
|
+
'dot-notation': 'error',
|
|
37
|
+
'prefer-const': 'warn',
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
js.configs.recommended,
|
|
41
|
+
]
|
package/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import DNAME from './rr/dname.js'
|
|
|
10
10
|
import DNSKEY from './rr/dnskey.js'
|
|
11
11
|
import DS from './rr/ds.js'
|
|
12
12
|
import HINFO from './rr/hinfo.js'
|
|
13
|
+
import HTTPS from './rr/https.js'
|
|
13
14
|
import IPSECKEY from './rr/ipseckey.js'
|
|
14
15
|
import KEY from './rr/key.js'
|
|
15
16
|
import LOC from './rr/loc.js'
|
|
@@ -29,6 +30,7 @@ import SOA from './rr/soa.js'
|
|
|
29
30
|
import SPF from './rr/spf.js'
|
|
30
31
|
import SRV from './rr/srv.js'
|
|
31
32
|
import SSHFP from './rr/sshfp.js'
|
|
33
|
+
import SVCB from './rr/svcb.js'
|
|
32
34
|
import TLSA from './rr/tlsa.js'
|
|
33
35
|
import TSIG from './rr/tsig.js'
|
|
34
36
|
import TXT from './rr/txt.js'
|
|
@@ -47,6 +49,7 @@ export {
|
|
|
47
49
|
DNSKEY,
|
|
48
50
|
DS,
|
|
49
51
|
HINFO,
|
|
52
|
+
HTTPS,
|
|
50
53
|
IPSECKEY,
|
|
51
54
|
KEY,
|
|
52
55
|
LOC,
|
|
@@ -66,6 +69,7 @@ export {
|
|
|
66
69
|
SOA,
|
|
67
70
|
SPF,
|
|
68
71
|
SRV,
|
|
72
|
+
SVCB,
|
|
69
73
|
TLSA,
|
|
70
74
|
TSIG,
|
|
71
75
|
TXT,
|
|
@@ -84,6 +88,7 @@ for (const c of [
|
|
|
84
88
|
DNSKEY,
|
|
85
89
|
DS,
|
|
86
90
|
HINFO,
|
|
91
|
+
HTTPS,
|
|
87
92
|
IPSECKEY,
|
|
88
93
|
KEY,
|
|
89
94
|
LOC,
|
|
@@ -103,6 +108,7 @@ for (const c of [
|
|
|
103
108
|
SOA,
|
|
104
109
|
SPF,
|
|
105
110
|
SRV,
|
|
111
|
+
SVCB,
|
|
106
112
|
TLSA,
|
|
107
113
|
TSIG,
|
|
108
114
|
TXT,
|
package/package.json
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nictool/dns-resource-record",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "DNS Resource Records",
|
|
5
5
|
"main": "index.js",
|
|
6
|
+
"file": [
|
|
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",
|
|
9
15
|
"format": "npm run prettier -- --write && npm run lint --fix",
|
|
10
|
-
"lint": "npx eslint **/*.js",
|
|
16
|
+
"lint": "npx eslint@9 **/*.js",
|
|
11
17
|
"lint:fix": "npm run lint -- --fix",
|
|
12
18
|
"prettier": "npx prettier --ignore-path .gitignore --check .",
|
|
13
19
|
"prettier:fix": "npx prettier --ignore-path .gitignore --write .",
|
|
@@ -39,6 +45,9 @@
|
|
|
39
45
|
},
|
|
40
46
|
"homepage": "https://github.com/NicTool/dns-resource-record#readme",
|
|
41
47
|
"devDependencies": {
|
|
42
|
-
"
|
|
48
|
+
"@eslint/js": "^9.15.0",
|
|
49
|
+
"eslint": "^9.15.0",
|
|
50
|
+
"globals": "^15.12.0",
|
|
51
|
+
"mocha": "^10.8.2"
|
|
43
52
|
}
|
|
44
53
|
}
|
package/rr/a.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import net from 'net'
|
|
1
|
+
import net from 'node:net'
|
|
2
2
|
|
|
3
3
|
import RR from '../rr.js'
|
|
4
4
|
|
|
@@ -9,8 +9,8 @@ export default class A extends RR {
|
|
|
9
9
|
|
|
10
10
|
/****** Resource record specific setters *******/
|
|
11
11
|
setAddress(val) {
|
|
12
|
-
if (!val)
|
|
13
|
-
if (!net.isIPv4(val))
|
|
12
|
+
if (!val) this.throwHelp('A: address is required')
|
|
13
|
+
if (!net.isIPv4(val)) this.throwHelp('A address must be IPv4')
|
|
14
14
|
this.set('address', val)
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -30,6 +30,16 @@ export default class A extends RR {
|
|
|
30
30
|
return 1
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
getCanonical() {
|
|
34
|
+
return {
|
|
35
|
+
owner: 'host.example.com.',
|
|
36
|
+
class: 'IN',
|
|
37
|
+
ttl: 3600,
|
|
38
|
+
type: 'A',
|
|
39
|
+
address: '192.0.2.127',
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
33
43
|
/****** IMPORTERS *******/
|
|
34
44
|
fromTinydns(opts) {
|
|
35
45
|
// +fqdn:ip:ttl:timestamp:lo
|
package/rr/aaaa.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import net from 'net'
|
|
1
|
+
import net from 'node:net'
|
|
2
2
|
|
|
3
3
|
import RR from '../rr.js'
|
|
4
4
|
import * as TINYDNS from '../lib/tinydns.js'
|
|
@@ -10,8 +10,8 @@ export default class AAAA extends RR {
|
|
|
10
10
|
|
|
11
11
|
/****** Resource record specific setters *******/
|
|
12
12
|
setAddress(val) {
|
|
13
|
-
if (!val)
|
|
14
|
-
if (!net.isIPv6(val))
|
|
13
|
+
if (!val) this.throwHelp('AAAA: address is required')
|
|
14
|
+
if (!net.isIPv6(val)) this.throwHelp(`AAAA: address must be IPv6 (${val})`)
|
|
15
15
|
|
|
16
16
|
this.set('address', this.expand(val.toLowerCase())) // lower case: RFC 5952
|
|
17
17
|
}
|
|
@@ -36,6 +36,16 @@ export default class AAAA extends RR {
|
|
|
36
36
|
return 28
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
getCanonical() {
|
|
40
|
+
return {
|
|
41
|
+
owner: 'host.example.com.',
|
|
42
|
+
address: '2001:0db8:0020:000a:0000:0000:0000:0004',
|
|
43
|
+
class: 'IN',
|
|
44
|
+
ttl: 3600,
|
|
45
|
+
type: 'A',
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
39
49
|
/****** IMPORTERS *******/
|
|
40
50
|
fromTinydns(opts) {
|
|
41
51
|
const str = opts.tinyline
|
|
@@ -45,7 +55,7 @@ export default class AAAA extends RR {
|
|
|
45
55
|
case ':':
|
|
46
56
|
// GENERIC => :fqdn:28:rdata:ttl:timestamp:lo
|
|
47
57
|
;[fqdn, n, rdata, ttl, ts, loc] = str.substring(1).split(':')
|
|
48
|
-
if (n != 28)
|
|
58
|
+
if (n != 28) this.throwHelp('AAAA fromTinydns, invalid n')
|
|
49
59
|
ip = TINYDNS.octalToHex(rdata)
|
|
50
60
|
.match(/([0-9a-fA-F]{4})/g)
|
|
51
61
|
.join(':')
|
package/rr/caa.js
CHANGED
|
@@ -11,7 +11,7 @@ export default class CAA extends RR {
|
|
|
11
11
|
this.is8bitInt('CAA', 'flags', val)
|
|
12
12
|
|
|
13
13
|
if (![0, 128].includes(val)) {
|
|
14
|
-
|
|
14
|
+
this.throwHelp(`CAA flags ${val} not recognized`)
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
this.set('flags', val)
|
|
@@ -19,12 +19,12 @@ export default class CAA extends RR {
|
|
|
19
19
|
|
|
20
20
|
setTag(val) {
|
|
21
21
|
if (typeof val !== 'string' || val.length < 1 || /[^a-z0-9]/.test(val))
|
|
22
|
-
|
|
23
|
-
`CAA tag must be a sequence of ASCII letters and numbers in lowercase
|
|
22
|
+
this.throwHelp(
|
|
23
|
+
`CAA tag must be a sequence of ASCII letters and numbers in lowercase`,
|
|
24
24
|
)
|
|
25
25
|
|
|
26
26
|
if (!['issue', 'issuewild', 'iodef'].includes(val)) {
|
|
27
|
-
|
|
27
|
+
this.throwHelp(`CAA tag ${val} not recognized`)
|
|
28
28
|
}
|
|
29
29
|
this.set('tag', val)
|
|
30
30
|
}
|
|
@@ -35,16 +35,14 @@ export default class CAA extends RR {
|
|
|
35
35
|
if (this.isQuoted(val)) {
|
|
36
36
|
val = val.replace(/^["']|["']$/g, '') // strip quotes
|
|
37
37
|
} else {
|
|
38
|
-
// if (/\s/.test(val))
|
|
38
|
+
// if (/\s/.test(val)) this.throwHelp(`CAA value may not have spaces unless quoted`)
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
// check if val starts with one of iodefSchemes
|
|
42
42
|
if (this.get('tag') === 'iodef') {
|
|
43
43
|
const iodefSchemes = ['mailto:', 'http:', 'https:']
|
|
44
44
|
if (!iodefSchemes.filter((s) => val.startsWith(s)).length) {
|
|
45
|
-
|
|
46
|
-
`CAA value must have valid iodefScheme prefix, ${this.citeRFC()}`,
|
|
47
|
-
)
|
|
45
|
+
this.throwHelp(`CAA value must have valid iodefScheme prefix`)
|
|
48
46
|
}
|
|
49
47
|
}
|
|
50
48
|
|
|
@@ -71,11 +69,23 @@ export default class CAA extends RR {
|
|
|
71
69
|
return 257
|
|
72
70
|
}
|
|
73
71
|
|
|
72
|
+
getCanonical() {
|
|
73
|
+
return {
|
|
74
|
+
owner: 'example.com.',
|
|
75
|
+
ttl: 3600,
|
|
76
|
+
class: 'IN',
|
|
77
|
+
type: 'CAA',
|
|
78
|
+
flags: 0,
|
|
79
|
+
tag: 'issue',
|
|
80
|
+
value: 'http://letsencrypt.org',
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
74
84
|
/****** IMPORTERS *******/
|
|
75
85
|
fromTinydns(opts) {
|
|
76
86
|
// CAA via generic, :fqdn:n:rdata:ttl:timestamp:lo
|
|
77
87
|
const [fqdn, n, rdata, ttl, ts, loc] = opts.tinyline.substring(1).split(':')
|
|
78
|
-
if (n != 257)
|
|
88
|
+
if (n != 257) this.throwHelp('CAA fromTinydns, invalid n')
|
|
79
89
|
|
|
80
90
|
const flags = TINYDNS.octalToUInt8(rdata.substring(0, 4))
|
|
81
91
|
const taglen = TINYDNS.octalToUInt8(rdata.substring(4, 8))
|
|
@@ -98,10 +108,12 @@ export default class CAA extends RR {
|
|
|
98
108
|
|
|
99
109
|
fromBind(opts) {
|
|
100
110
|
// test.example.com 3600 IN CAA flags, tags, value
|
|
101
|
-
const fields = opts.bindline
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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
|
+
)
|
|
116
|
+
if (!fields) this.throwHelp(`unable to parse: ${opts.bindline}`)
|
|
105
117
|
|
|
106
118
|
const [owner, ttl, c, type, flags, tag, value] = fields.slice(1)
|
|
107
119
|
return new CAA({
|
package/rr/cname.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import net from 'net'
|
|
1
|
+
import net from 'node:net'
|
|
2
2
|
|
|
3
3
|
import RR from '../rr.js'
|
|
4
4
|
|
|
@@ -12,10 +12,10 @@ export default class CNAME extends RR {
|
|
|
12
12
|
// A <domain-name> which specifies the canonical or primary
|
|
13
13
|
// name for the owner. The owner name is an alias.
|
|
14
14
|
|
|
15
|
-
if (!val)
|
|
15
|
+
if (!val) this.throwHelp('CNAME: cname is required')
|
|
16
16
|
|
|
17
17
|
if (net.isIPv4(val) || net.isIPv6(val))
|
|
18
|
-
|
|
18
|
+
this.throwHelp(`CNAME: cname must be a FQDN: RFC 2181`)
|
|
19
19
|
|
|
20
20
|
if (!this.isFullyQualified('CNAME', 'cname', val)) return
|
|
21
21
|
if (!this.isValidHostname('CNAME', 'cname', val)) return
|
package/rr/dname.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import net from 'net'
|
|
1
|
+
import net from 'node:net'
|
|
2
2
|
|
|
3
3
|
import RR from '../rr.js'
|
|
4
4
|
import * as TINYDNS from '../lib/tinydns.js'
|
|
@@ -10,10 +10,10 @@ export default class DNAME extends RR {
|
|
|
10
10
|
|
|
11
11
|
/****** Resource record specific setters *******/
|
|
12
12
|
setTarget(val) {
|
|
13
|
-
if (!val)
|
|
13
|
+
if (!val) this.throwHelp('DNAME: target is required')
|
|
14
14
|
|
|
15
15
|
if (net.isIPv4(val) || net.isIPv6(val))
|
|
16
|
-
|
|
16
|
+
this.throwHelp(`DNAME: target must be a domain name`)
|
|
17
17
|
|
|
18
18
|
this.isFullyQualified('DNAME', 'target', val)
|
|
19
19
|
this.isValidHostname('DNAME', 'target', val)
|
|
@@ -42,7 +42,7 @@ export default class DNAME extends RR {
|
|
|
42
42
|
fromTinydns(opts) {
|
|
43
43
|
// DNAME via generic, :fqdn:n:rdata:ttl:timestamp:lo
|
|
44
44
|
const [fqdn, n, rdata, ttl, ts, loc] = opts.tinyline.substring(1).split(':')
|
|
45
|
-
if (n != 39)
|
|
45
|
+
if (n != 39) this.throwHelp('DNAME fromTinydns, invalid n')
|
|
46
46
|
|
|
47
47
|
return new DNAME({
|
|
48
48
|
type: 'DNAME',
|
package/rr/dnskey.js
CHANGED
|
@@ -13,8 +13,7 @@ export default class DNSKEY extends RR {
|
|
|
13
13
|
this.is16bitInt('DNSKEY', 'flags', val)
|
|
14
14
|
|
|
15
15
|
// the possible values are: 0, 256, and 257; RFC 4034
|
|
16
|
-
if (![0, 256, 257].includes(val))
|
|
17
|
-
throw new Error(`DNSKEY: flags invalid, ${this.citeRFC()}`)
|
|
16
|
+
if (![0, 256, 257].includes(val)) this.throwHelp(`DNSKEY: flags invalid`)
|
|
18
17
|
|
|
19
18
|
this.set('flags', val)
|
|
20
19
|
}
|
|
@@ -24,8 +23,7 @@ export default class DNSKEY extends RR {
|
|
|
24
23
|
this.is8bitInt('DNSKEY', 'protocol', val)
|
|
25
24
|
|
|
26
25
|
// The Protocol Field MUST be represented as an unsigned decimal integer with a value of 3.
|
|
27
|
-
if (![3].includes(val))
|
|
28
|
-
throw new Error(`DNSKEY: protocol invalid, ${this.citeRFC()}`)
|
|
26
|
+
if (![3].includes(val)) this.throwHelp(`DNSKEY: protocol invalid`)
|
|
29
27
|
|
|
30
28
|
this.set('protocol', val)
|
|
31
29
|
}
|
|
@@ -37,16 +35,13 @@ export default class DNSKEY extends RR {
|
|
|
37
35
|
// https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml
|
|
38
36
|
// 1=RSA/MD5, 2=DH, 3=DSA/SHA-1, 4=EC, 5=RSA/SHA-1
|
|
39
37
|
if (![...Array(16).keys(), 253, 254].includes(val))
|
|
40
|
-
console.error(
|
|
41
|
-
`DNSKEY: algorithm (${val}) not recognized, ${this.citeRFC()}`,
|
|
42
|
-
)
|
|
38
|
+
console.error(`DNSKEY: algorithm (${val}) not recognized`)
|
|
43
39
|
|
|
44
40
|
this.set('algorithm', val)
|
|
45
41
|
}
|
|
46
42
|
|
|
47
43
|
setPublickey(val) {
|
|
48
|
-
if (!val)
|
|
49
|
-
throw new Error(`DNSKEY: publickey is required, ${this.citeRFC()}`)
|
|
44
|
+
if (!val) this.throwHelp(`DNSKEY: publickey is required`)
|
|
50
45
|
|
|
51
46
|
this.set('publickey', val)
|
|
52
47
|
}
|
|
@@ -74,7 +69,7 @@ export default class DNSKEY extends RR {
|
|
|
74
69
|
const match = opts.bindline.match(
|
|
75
70
|
/^([^\s]+)\s+([0-9]+)\s+(\w+)\s+(\w+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+\s*(.*?)\s*$/,
|
|
76
71
|
)
|
|
77
|
-
if (!match)
|
|
72
|
+
if (!match) this.throwHelp(`unable to parse DNSKEY: ${opts.bindline}`)
|
|
78
73
|
const [owner, ttl, c, type, flags, protocol, algorithm, publickey] =
|
|
79
74
|
match.slice(1)
|
|
80
75
|
|
|
@@ -92,7 +87,7 @@ export default class DNSKEY extends RR {
|
|
|
92
87
|
|
|
93
88
|
fromTinydns(opts) {
|
|
94
89
|
const [fqdn, n, rdata, ttl, ts, loc] = opts.tinyline.substring(1).split(':')
|
|
95
|
-
if (n != 48)
|
|
90
|
+
if (n != 48) this.throwHelp('DNSKEY fromTinydns, invalid n')
|
|
96
91
|
|
|
97
92
|
const bytes = Buffer.from(TINYDNS.octalToChar(rdata), 'binary')
|
|
98
93
|
|
package/rr/ds.js
CHANGED
|
@@ -10,9 +10,8 @@ export default class DS extends RR {
|
|
|
10
10
|
/****** Resource record specific setters *******/
|
|
11
11
|
setKeyTag(val) {
|
|
12
12
|
// a 2 octet Key Tag field...in network byte order
|
|
13
|
-
if (!val)
|
|
14
|
-
if (val.length > 2)
|
|
15
|
-
throw new Error(`DS: key tag is too long, ${this.citeRFC()}`)
|
|
13
|
+
if (!val) this.throwHelp(`DS: key tag is required`)
|
|
14
|
+
if (val.length > 2) this.throwHelp(`DS: key tag is too long`)
|
|
16
15
|
|
|
17
16
|
this.set('key tag', val)
|
|
18
17
|
}
|
|
@@ -20,20 +19,19 @@ export default class DS extends RR {
|
|
|
20
19
|
setAlgorithm(val) {
|
|
21
20
|
// 1=RSA/MD5, 2=DH, 3=DSA/SHA-1, 4=EC, 5=RSA/SHA-1
|
|
22
21
|
if (![1, 2, 3, 4, 5, 253, 254].includes(val))
|
|
23
|
-
|
|
22
|
+
this.throwHelp(`DS: algorithm invalid`)
|
|
24
23
|
|
|
25
24
|
this.set('algorithm', val)
|
|
26
25
|
}
|
|
27
26
|
|
|
28
27
|
setDigestType(val) {
|
|
29
|
-
if (![1, 2].includes(val))
|
|
30
|
-
throw new Error(`DS: digest type invalid, ${this.citeRFC()}`)
|
|
28
|
+
if (![1, 2].includes(val)) this.throwHelp(`DS: digest type invalid`)
|
|
31
29
|
|
|
32
30
|
this.set('digest type', val)
|
|
33
31
|
}
|
|
34
32
|
|
|
35
33
|
setDigest(val) {
|
|
36
|
-
if (!val)
|
|
34
|
+
if (!val) this.throwHelp(`DS: digest is required`)
|
|
37
35
|
|
|
38
36
|
this.set('digest', val)
|
|
39
37
|
}
|
|
@@ -74,7 +72,7 @@ export default class DS extends RR {
|
|
|
74
72
|
|
|
75
73
|
fromTinydns(opts) {
|
|
76
74
|
const [fqdn, n, rdata, ttl, ts, loc] = opts.tinyline.substring(1).split(':')
|
|
77
|
-
if (n != 43)
|
|
75
|
+
if (n != 43) this.throwHelp('DS fromTinydns, invalid n')
|
|
78
76
|
|
|
79
77
|
const binRdata = Buffer.from(TINYDNS.octalToChar(rdata), 'binary')
|
|
80
78
|
|
package/rr/hinfo.js
CHANGED
|
@@ -9,12 +9,12 @@ export default class HINFO extends RR {
|
|
|
9
9
|
|
|
10
10
|
/****** Resource record specific setters *******/
|
|
11
11
|
setCpu(val) {
|
|
12
|
-
if (val.length > 255)
|
|
12
|
+
if (val.length > 255) this.throwHelp('HINFO cpu cannot exceed 255 chars')
|
|
13
13
|
this.set('cpu', val.replace(/^["']|["']$/g, ''))
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
setOs(val) {
|
|
17
|
-
if (val.length > 255)
|
|
17
|
+
if (val.length > 255) this.throwHelp('HINFO os cannot exceed 255 chars')
|
|
18
18
|
this.set('os', val.replace(/^["']|["']$/g, ''))
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -41,10 +41,12 @@ 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
|
-
|
|
47
|
-
|
|
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
|
+
)
|
|
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
|
|
|
50
52
|
return new HINFO({
|