@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.
Files changed (81) hide show
  1. package/.codeclimate.yml +25 -0
  2. package/.github/FUNDING.yml +3 -0
  3. package/.github/workflows/ci.yml +43 -0
  4. package/.github/workflows/codeql.yml +14 -0
  5. package/.github/workflows/publish.yml +16 -0
  6. package/.gitmodules +3 -0
  7. package/CHANGELOG.md +18 -0
  8. package/DEVELOP.md +9 -0
  9. package/README.md +6 -2
  10. package/eslint.config.mjs +41 -0
  11. package/index.js +6 -0
  12. package/package.json +12 -3
  13. package/rr/a.js +13 -3
  14. package/rr/aaaa.js +14 -4
  15. package/rr/caa.js +25 -13
  16. package/rr/cname.js +3 -3
  17. package/rr/dname.js +4 -4
  18. package/rr/dnskey.js +6 -11
  19. package/rr/ds.js +6 -8
  20. package/rr/hinfo.js +8 -6
  21. package/rr/https.js +62 -0
  22. package/rr/ipseckey.js +20 -9
  23. package/rr/key.js +2 -2
  24. package/rr/loc.js +4 -4
  25. package/rr/mx.js +15 -3
  26. package/rr/naptr.js +2 -2
  27. package/rr/ns.js +1 -1
  28. package/rr/nsec.js +2 -4
  29. package/rr/nsec3.js +6 -12
  30. package/rr/nsec3param.js +4 -9
  31. package/rr/nxt.js +2 -4
  32. package/rr/openpgpkey.js +7 -3
  33. package/rr/rrsig.js +3 -4
  34. package/rr/sig.js +1 -1
  35. package/rr/smimea.js +3 -5
  36. package/rr/soa.js +1 -2
  37. package/rr/spf.js +1 -1
  38. package/rr/srv.js +4 -4
  39. package/rr/sshfp.js +1 -1
  40. package/rr/svcb.js +64 -0
  41. package/rr/tlsa.js +10 -10
  42. package/rr/tsig.js +10 -2
  43. package/rr/txt.js +5 -5
  44. package/rr/uri.js +2 -2
  45. package/rr/wks.js +4 -3
  46. package/rr.js +32 -20
  47. package/test/a.js +75 -0
  48. package/test/aaaa.js +86 -0
  49. package/test/base.js +148 -0
  50. package/test/caa.js +111 -0
  51. package/test/cert.js +48 -0
  52. package/test/cname.js +40 -0
  53. package/test/dname.js +57 -0
  54. package/test/dnskey.js +45 -0
  55. package/test/ds.js +45 -0
  56. package/test/fake.js +34 -0
  57. package/test/hinfo.js +80 -0
  58. package/test/https.js +56 -0
  59. package/test/ipseckey.js +141 -0
  60. package/test/key.js +36 -0
  61. package/test/loc.js +75 -0
  62. package/test/mx.js +78 -0
  63. package/test/naptr.js +47 -0
  64. package/test/ns.js +56 -0
  65. package/test/nsec.js +37 -0
  66. package/test/nsec3.js +47 -0
  67. package/test/nsec3param.js +23 -0
  68. package/test/nxt.js +37 -0
  69. package/test/openpgpkey.js +85 -0
  70. package/test/ptr.js +56 -0
  71. package/test/rr.js +212 -0
  72. package/test/smimea.js +51 -0
  73. package/test/soa.js +99 -0
  74. package/test/spf.js +51 -0
  75. package/test/srv.js +101 -0
  76. package/test/sshfp.js +69 -0
  77. package/test/svcb.js +56 -0
  78. package/test/tinydns.js +163 -0
  79. package/test/tlsa.js +63 -0
  80. package/test/txt.js +82 -0
  81. package/test/uri.js +65 -0
package/test/cert.js ADDED
@@ -0,0 +1,48 @@
1
+ import * as base from './base.js'
2
+
3
+ import CERT from '../rr/cert.js'
4
+
5
+ const validRecords = [
6
+ {
7
+ owner: 'mail.example.com.',
8
+ ttl: 86400,
9
+ class: 'IN',
10
+ type: 'CERT',
11
+ 'cert type': 'PGP',
12
+ 'key tag': 0,
13
+ algorithm: 0,
14
+ certificate: 'hexidecimalkeystring1',
15
+ testB:
16
+ 'mail.example.com.\t86400\tIN\tCERT\tPGP\t0\t0\thexidecimalkeystring1\n',
17
+ },
18
+ {
19
+ owner: 'smith.example.com.',
20
+ ttl: 86400,
21
+ class: 'IN',
22
+ type: 'CERT',
23
+ 'cert type': 'PGP',
24
+ 'key tag': 0,
25
+ algorithm: 0,
26
+ certificate: 'hexidecimalkeystring2',
27
+ testB:
28
+ 'smith.example.com.\t86400\tIN\tCERT\tPGP\t0\t0\thexidecimalkeystring2\n',
29
+ },
30
+ ]
31
+
32
+ const invalidRecords = []
33
+
34
+ describe('CERT record', function () {
35
+ base.valid(CERT, validRecords)
36
+ base.invalid(CERT, invalidRecords)
37
+
38
+ base.getDescription(CERT)
39
+ base.getRFCs(CERT, validRecords[0])
40
+ base.getFields(CERT, ['cert type', 'key tag', 'algorithm', 'certificate'])
41
+ base.getTypeId(CERT, 37)
42
+
43
+ base.toBind(CERT, validRecords)
44
+ // base.toTinydns(CERT, validRecords)
45
+
46
+ base.fromBind(CERT, validRecords)
47
+ // base.fromTinydns(CERT, validRecords)
48
+ })
package/test/cname.js ADDED
@@ -0,0 +1,40 @@
1
+ import * as base from './base.js'
2
+
3
+ import CNAME from '../rr/cname.js'
4
+
5
+ const defaults = { class: 'IN', ttl: 3600, type: 'CNAME' }
6
+
7
+ const validRecords = [
8
+ {
9
+ ...defaults,
10
+ owner: 'ns1.example.com.',
11
+ cname: 'ns2.example.com.',
12
+ testB: 'ns1.example.com.\t3600\tIN\tCNAME\tns2.example.com.\n',
13
+ testT: 'Cns1.example.com:ns2.example.com.:3600::\n',
14
+ },
15
+ ]
16
+
17
+ const invalidRecords = [
18
+ {
19
+ ...defaults,
20
+ owner: 'example.com.',
21
+ cname: '192.0.2.4', // FQDN required
22
+ msg: /cname must be a FQDN/,
23
+ },
24
+ ]
25
+
26
+ describe('CNAME record', function () {
27
+ base.valid(CNAME, validRecords)
28
+ base.invalid(CNAME, invalidRecords)
29
+
30
+ base.getDescription(CNAME)
31
+ base.getRFCs(CNAME, validRecords[0])
32
+ base.getFields(CNAME, ['cname'])
33
+ base.getTypeId(CNAME, 5)
34
+
35
+ base.toBind(CNAME, validRecords)
36
+ base.toTinydns(CNAME, validRecords)
37
+
38
+ base.fromTinydns(CNAME, validRecords)
39
+ base.fromBind(CNAME, validRecords)
40
+ })
package/test/dname.js ADDED
@@ -0,0 +1,57 @@
1
+ import assert from 'assert'
2
+
3
+ import * as base from './base.js'
4
+
5
+ import DNAME from '../rr/dname.js'
6
+
7
+ const defaults = { class: 'IN', ttl: 86400, type: 'DNAME' }
8
+
9
+ const validRecords = [
10
+ {
11
+ ...defaults,
12
+ owner: '_tcp.example.com.',
13
+ target: '_tcp.example.net.',
14
+ testB: '_tcp.example.com.\t86400\tIN\tDNAME\t_tcp.example.net.\n',
15
+ testT:
16
+ ':_tcp.example.com:39:\\004\\137tcp\\007example\\003net\\000:86400::\n',
17
+ },
18
+ ]
19
+
20
+ const invalidRecords = [
21
+ {
22
+ ...defaults,
23
+ owner: 'spf.example.com.',
24
+ target: '1.2.3.4', // FQDN required
25
+ msg: /target must be a domain name/,
26
+ },
27
+ ]
28
+
29
+ describe('DNAME record', function () {
30
+ base.valid(DNAME, validRecords)
31
+ base.invalid(DNAME, invalidRecords)
32
+
33
+ base.getDescription(DNAME)
34
+ base.getRFCs(DNAME, validRecords[0])
35
+ base.getFields(DNAME, ['target'])
36
+ base.getTypeId(DNAME, 39)
37
+
38
+ base.toBind(DNAME, validRecords)
39
+ base.toTinydns(DNAME, validRecords)
40
+
41
+ base.fromBind(DNAME, validRecords)
42
+ base.fromTinydns(DNAME, validRecords)
43
+
44
+ for (const val of validRecords) {
45
+ it.skip(`imports tinydns DNAME (generic) record (${val.owner})`, async function () {
46
+ const r = new DNAME({ tinyline: val.testT })
47
+ if (process.env.DEBUG) console.dir(r)
48
+ for (const f of ['owner', 'target', 'ttl']) {
49
+ assert.deepStrictEqual(
50
+ r.get(f),
51
+ val[f],
52
+ `${f}: ${r.get(f)} !== ${val[f]}`,
53
+ )
54
+ }
55
+ })
56
+ }
57
+ })
package/test/dnskey.js ADDED
@@ -0,0 +1,45 @@
1
+ import * as base from './base.js'
2
+
3
+ import DNSKEY from '../rr/dnskey.js'
4
+
5
+ const defaults = { class: 'IN', ttl: 3600, type: 'DNSKEY' }
6
+
7
+ const validRecords = [
8
+ {
9
+ ...defaults,
10
+ owner: 'example.com.',
11
+ flags: 256,
12
+ protocol: 3,
13
+ algorithm: 5,
14
+ publickey: `( AQPSKmynfzW4kyBv015MUG2DeIQ3 Cbl+BBZH4b/0PY1kxkmvHjcZc8no kfzj31GajIQKY+5CptLr3buXA10h WqTkF7H6RfoRqXQeogmMHfpftf6z Mv1LyBUgia7za6ZEzOJBOztyvhjL 742iU/TpPSEDhm2SNKLijfUppn1U aNvv4w== )`,
15
+ testB:
16
+ 'example.com.\t3600\tIN\tDNSKEY\t256\t3\t5\t( AQPSKmynfzW4kyBv015MUG2DeIQ3 Cbl+BBZH4b/0PY1kxkmvHjcZc8no kfzj31GajIQKY+5CptLr3buXA10h WqTkF7H6RfoRqXQeogmMHfpftf6z Mv1LyBUgia7za6ZEzOJBOztyvhjL 742iU/TpPSEDhm2SNKLijfUppn1U aNvv4w== )\n',
17
+ testT:
18
+ ':example.com:48:\\001\\000\\003\\005( AQPSKmynfzW4kyBv015MUG2DeIQ3 Cbl+BBZH4b\\0570PY1kxkmvHjcZc8no kfzj31GajIQKY+5CptLr3buXA10h WqTkF7H6RfoRqXQeogmMHfpftf6z Mv1LyBUgia7za6ZEzOJBOztyvhjL 742iU\\057TpPSEDhm2SNKLijfUppn1U aNvv4w== ):3600::\n',
19
+ },
20
+ ]
21
+
22
+ const invalidRecords = [
23
+ {
24
+ ...defaults,
25
+ owner: 'test.example.com.',
26
+ algorithm: 257, // invalid
27
+ msg: /flags must be a 16-bit integer/,
28
+ },
29
+ ]
30
+
31
+ describe('DNSKEY record', function () {
32
+ base.valid(DNSKEY, validRecords)
33
+ base.invalid(DNSKEY, invalidRecords)
34
+
35
+ base.getDescription(DNSKEY)
36
+ base.getRFCs(DNSKEY, validRecords[0])
37
+ base.getFields(DNSKEY, ['flags', 'protocol', 'algorithm', 'publickey'])
38
+ base.getTypeId(DNSKEY, 48)
39
+
40
+ base.toBind(DNSKEY, validRecords)
41
+ base.toTinydns(DNSKEY, validRecords)
42
+
43
+ base.fromBind(DNSKEY, validRecords)
44
+ base.fromTinydns(DNSKEY, validRecords)
45
+ })
package/test/ds.js ADDED
@@ -0,0 +1,45 @@
1
+ import * as base from './base.js'
2
+
3
+ import DS from '../rr/ds.js'
4
+
5
+ const defaults = { class: 'IN', ttl: 3600, type: 'DS' }
6
+
7
+ const validRecords = [
8
+ {
9
+ ...defaults,
10
+ owner: 'dskey.example.com.',
11
+ 'key tag': 60485,
12
+ algorithm: 5,
13
+ 'digest type': 1,
14
+ digest: `( 2BB183AF5F22588179A53B0A 98631FAD1A292118 )`,
15
+ testB:
16
+ 'dskey.example.com.\t3600\tIN\tDS\t60485\t5\t1\t( 2BB183AF5F22588179A53B0A 98631FAD1A292118 )\n',
17
+ testT:
18
+ ':dskey.example.com:43:\\354\\105\\005\\001( 2BB183AF5F22588179A53B0A 98631FAD1A292118 ):3600::\n',
19
+ },
20
+ ]
21
+
22
+ const invalidRecords = [
23
+ {
24
+ ...defaults,
25
+ owner: 'test.example.com.',
26
+ algorithm: 6, // invalid
27
+ msg: /key tag is required/,
28
+ },
29
+ ]
30
+
31
+ describe('DS record', function () {
32
+ base.valid(DS, validRecords)
33
+ base.invalid(DS, invalidRecords)
34
+
35
+ base.getDescription(DS)
36
+ base.getRFCs(DS, validRecords[0])
37
+ base.getFields(DS, ['key tag', 'algorithm', 'digest type', 'digest'])
38
+ base.getTypeId(DS, 43)
39
+
40
+ base.toBind(DS, validRecords)
41
+ base.toTinydns(DS, validRecords)
42
+
43
+ base.fromBind(DS, validRecords)
44
+ base.fromTinydns(DS, validRecords)
45
+ })
package/test/fake.js ADDED
@@ -0,0 +1,34 @@
1
+ import assert from 'assert'
2
+
3
+ import * as RR from '../index.js'
4
+
5
+ const defaults = {
6
+ owner: 'fake.com.',
7
+ class: 'IN',
8
+ ttl: 3600,
9
+ address: '192.0.2.127',
10
+ }
11
+
12
+ describe('fake', function () {
13
+ it(`throws on invalid RR class`, async function () {
14
+ assert.throws(
15
+ () => {
16
+ new RR.fake({ ...defaults, type: 'A' })
17
+ },
18
+ {
19
+ message: /fake is not a constructor/,
20
+ },
21
+ )
22
+ })
23
+
24
+ it(`throws on invalid RR type`, async function () {
25
+ assert.throws(
26
+ () => {
27
+ new RR.A({ ...defaults, type: 'NONEXIST' })
28
+ },
29
+ {
30
+ message: /type NONEXIST doesn't match A/,
31
+ },
32
+ )
33
+ })
34
+ })
package/test/hinfo.js ADDED
@@ -0,0 +1,80 @@
1
+ import assert from 'assert'
2
+
3
+ import * as base from './base.js'
4
+
5
+ import HINFO from '../rr/hinfo.js'
6
+
7
+ const defaults = { class: 'IN', ttl: 86400, type: 'HINFO' }
8
+
9
+ const validRecords = [
10
+ {
11
+ ...defaults,
12
+ owner: 'server-under-my-desk.example.com.',
13
+ cpu: 'PDP-11/73',
14
+ os: 'UNIX',
15
+ testB:
16
+ 'server-under-my-desk.example.com.\t86400\tIN\tHINFO\t"PDP-11/73"\t"UNIX"\n',
17
+ testT:
18
+ ':server-under-my-desk.example.com:13:\\011PDP-11/73\\004UNIX:86400::\n',
19
+ },
20
+ {
21
+ ...defaults,
22
+ owner: 'sri-nic.arpa.',
23
+ cpu: 'DEC-2060',
24
+ os: 'TOPS20',
25
+ testB: 'sri-nic.arpa.\t86400\tIN\tHINFO\t"DEC-2060"\t"TOPS20"\n',
26
+ testT: ':sri-nic.arpa:13:\\010DEC-2060\\006TOPS20:86400::\n',
27
+ },
28
+ ]
29
+
30
+ const invalidRecords = [
31
+ {
32
+ ...defaults,
33
+ owner: 'www.example.com.',
34
+ address: '',
35
+ msg: /Cannot read proper/,
36
+ },
37
+ ]
38
+
39
+ describe('HINFO record', function () {
40
+ base.valid(HINFO, validRecords)
41
+ base.invalid(HINFO, invalidRecords)
42
+
43
+ base.getDescription(HINFO)
44
+ base.getRFCs(HINFO, validRecords[0])
45
+ base.getFields(HINFO, ['cpu', 'os'])
46
+ base.getTypeId(HINFO, 13)
47
+
48
+ base.toBind(HINFO, validRecords)
49
+ base.toTinydns(HINFO, validRecords)
50
+
51
+ base.fromBind(HINFO, validRecords)
52
+ base.fromTinydns(HINFO, validRecords)
53
+
54
+ for (const val of validRecords) {
55
+ it.skip(`imports tinydns HINFO (generic) record (${val.owner})`, async function () {
56
+ const r = new HINFO({ tinyline: val.testT })
57
+ if (process.env.DEBUG) console.dir(r)
58
+ for (const f of ['owner', 'address', 'ttl']) {
59
+ assert.deepStrictEqual(
60
+ r.get(f),
61
+ val[f],
62
+ `${f}: ${r.get(f)} !== ${val[f]}`,
63
+ )
64
+ }
65
+ })
66
+ }
67
+
68
+ for (const f of ['os', 'cpu']) {
69
+ it(`rejects ${f} value longer than 255 chars`, async () => {
70
+ const tooLong =
71
+ 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz'
72
+ const r = new HINFO(null)
73
+ try {
74
+ assert.fail(r[`set${r.ucfirst(f)}`](tooLong))
75
+ } catch (e) {
76
+ assert.ok(/cannot exceed 255 chars/.test(e.message))
77
+ }
78
+ })
79
+ }
80
+ })
package/test/https.js ADDED
@@ -0,0 +1,56 @@
1
+ import * as base from './base.js'
2
+
3
+ import HTTPS from '../rr/https.js'
4
+
5
+ const defaults = { class: 'IN', ttl: 3600, type: 'HTTPS' }
6
+
7
+ const validRecords = [
8
+ {
9
+ ...defaults,
10
+ owner: '_8443._foo.api.example.com.',
11
+ ttl: 7200,
12
+ priority: 0,
13
+ 'target name': 'svc4.example.net.',
14
+ params: 'alpn="bar" port="8004" ech="..."',
15
+ testB:
16
+ '_8443._foo.api.example.com.\t7200\tIN\tHTTPS\t0\tsvc4.example.net.\talpn="bar" port="8004" ech="..."\n',
17
+ },
18
+ {
19
+ ...defaults,
20
+ owner: '_8080._foo.example.com.',
21
+ priority: 0,
22
+ 'target name': 'foosvc.example.net.',
23
+ params: '',
24
+ testB:
25
+ '_8080._foo.example.com.\t3600\tIN\tHTTPS\t0\tfoosvc.example.net.\t\n',
26
+ },
27
+ /*
28
+ _1234._bar.example.com. 300 IN HTTPS 1 svc1.example.net. ( ech="111..." ipv6hint=2001:db8::1 port=1234 )
29
+ HTTPS 2 svc2.example.net. ( ech="222..." ipv6hint=2001:db8::2 port=1234 )
30
+ */
31
+ ]
32
+
33
+ const invalidRecords = [
34
+ // {
35
+ // ...defaults,
36
+ // owner : 'test.example.com.',
37
+ // 'target name': 'not-full-qualified.example.com',
38
+ // params : /must be a 16-bit integer/,
39
+ // },
40
+ ]
41
+
42
+ describe('HTTPS record', function () {
43
+ base.valid(HTTPS, validRecords)
44
+ base.invalid(HTTPS, invalidRecords)
45
+
46
+ base.getDescription(HTTPS)
47
+ base.getRFCs(HTTPS, validRecords[0])
48
+ base.getFields(HTTPS, ['priority', 'target name', 'params'])
49
+ base.getTypeId(HTTPS, 65)
50
+
51
+ base.toBind(HTTPS, validRecords)
52
+ // base.toTinydns(HTTPS, validRecords)
53
+
54
+ base.fromBind(HTTPS, validRecords)
55
+ // base.fromTinydns(HTTPS, validRecords)
56
+ })
@@ -0,0 +1,141 @@
1
+ import * as base from './base.js'
2
+
3
+ import IPSECKEY from '../rr/ipseckey.js'
4
+
5
+ const common = { ttl: 7200, class: 'IN', type: 'IPSECKEY' }
6
+
7
+ const validRecords = [
8
+ {
9
+ ...common,
10
+ owner: '38.2.0.192.in-addr.arpa.',
11
+ precedence: 10,
12
+ 'gateway type': 1,
13
+ algorithm: 2,
14
+ gateway: '192.0.2.38',
15
+ publickey: 'AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==',
16
+ testB:
17
+ '38.2.0.192.in-addr.arpa.\t7200\tIN\tIPSECKEY\t10\t1\t2\t192.0.2.38\tAQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==\n',
18
+ testT:
19
+ ':38.2.0.192.in-addr.arpa:45:\\012\\001\\002\\300\\000\\002\\046\\001\\003QSy\\206\\3555S\\073\\140dG\\216\\356\\262\\173\\133\\327M\\256\\024\\233n\\201\\272\\072\\005\\041\\257\\202\\253x\\001:7200::\n',
20
+ },
21
+ {
22
+ ...common,
23
+ owner: '38.2.0.192.in-addr.arpa.',
24
+ precedence: 10,
25
+ 'gateway type': 0,
26
+ algorithm: 2,
27
+ gateway: '.',
28
+ publickey: 'AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==',
29
+ testB:
30
+ '38.2.0.192.in-addr.arpa.\t7200\tIN\tIPSECKEY\t10\t0\t2\t.\tAQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==\n',
31
+ testT:
32
+ ':38.2.0.192.in-addr.arpa:45:\\012\\000\\002.\\001\\003QSy\\206\\3555S\\073\\140dG\\216\\356\\262\\173\\133\\327M\\256\\024\\233n\\201\\272\\072\\005\\041\\257\\202\\253x\\001:7200::\n',
33
+ },
34
+ {
35
+ ...common,
36
+ owner: '38.2.0.192.in-addr.arpa.',
37
+ precedence: 10,
38
+ 'gateway type': 1,
39
+ algorithm: 2,
40
+ gateway: '192.0.2.38',
41
+ publickey: 'AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==',
42
+ testB:
43
+ '38.2.0.192.in-addr.arpa.\t7200\tIN\tIPSECKEY\t10\t1\t2\t192.0.2.38\tAQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==\n',
44
+ testT:
45
+ ':38.2.0.192.in-addr.arpa:45:\\012\\001\\002\\300\\000\\002\\046\\001\\003QSy\\206\\3555S\\073\\140dG\\216\\356\\262\\173\\133\\327M\\256\\024\\233n\\201\\272\\072\\005\\041\\257\\202\\253x\\001:7200::\n',
46
+ },
47
+ {
48
+ ...common,
49
+ owner: '38.1.0.192.in-addr.arpa.',
50
+ precedence: 10,
51
+ 'gateway type': 3,
52
+ algorithm: 2,
53
+ gateway: 'mygateway.example.com.',
54
+ publickey: 'AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==',
55
+ testB:
56
+ '38.1.0.192.in-addr.arpa.\t7200\tIN\tIPSECKEY\t10\t3\t2\tmygateway.example.com.\tAQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==\n',
57
+ testT:
58
+ ':38.1.0.192.in-addr.arpa:45:\\012\\003\\002\\011mygateway\\007example\\003com\\000\\001\\003QSy\\206\\3555S\\073\\140dG\\216\\356\\262\\173\\133\\327M\\256\\024\\233n\\201\\272\\072\\005\\041\\257\\202\\253x\\001:7200::\n',
59
+ },
60
+ {
61
+ ...common,
62
+ owner:
63
+ '0.d.4.0.3.0.e.f.f.f.3.f.0.1.2.0.1.0.0.0.0.0.2.8.b.d.0.1.0.0.2.ip6.arpa.',
64
+ precedence: 10,
65
+ 'gateway type': 2,
66
+ algorithm: 2,
67
+ gateway: '2001:0db8:0:8002::2000:1',
68
+ publickey: 'AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==',
69
+ testB:
70
+ '0.d.4.0.3.0.e.f.f.f.3.f.0.1.2.0.1.0.0.0.0.0.2.8.b.d.0.1.0.0.2.ip6.arpa.\t7200\tIN\tIPSECKEY\t10\t2\t2\t2001:0db8:0:8002::2000:1\tAQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==\n',
71
+ },
72
+ {
73
+ ...common,
74
+ owner: 'ipsec.simerson.com.',
75
+ ttl: 86400,
76
+ precedence: 1,
77
+ 'gateway type': 3,
78
+ algorithm: 2,
79
+ gateway: 'matt.simerson.net.',
80
+ publickey:
81
+ '0sAQPeOwAGDPLrDebL1q5Lg8XW9B/d9MnxqlzIYKXhvZPWEHNYGP7AwART/tmkeDNn7HPMtgM6GIwQ4p0KGLfSRoUKbjtPlRVeWYLbsnNXeFU5bchyYef0efYiKlxZdo',
82
+ testB:
83
+ 'ipsec.simerson.com.\t86400\tIN\tIPSECKEY\t1\t3\t2\tmatt.simerson.net.\t0sAQPeOwAGDPLrDebL1q5Lg8XW9B/d9MnxqlzIYKXhvZPWEHNYGP7AwART/tmkeDNn7HPMtgM6GIwQ4p0KGLfSRoUKbjtPlRVeWYLbsnNXeFU5bchyYef0efYiKlxZdo\n',
84
+ testT:
85
+ ':ipsec.simerson.com:45:\\001\\003\\002\\004matt\\010simerson\\003net\\000\\322\\300\\020\\075\\343\\260\\000\\140\\317.\\260\\336l\\275j\\344\\270\\074\\135oA\\375\\337L\\237\\032\\245\\314\\206\\012\\136\\033\\331\\075a\\0075\\201\\217\\354\\014\\000E\\077\\355\\232G\\2036\\176\\307\\074\\313\\1403\\241\\210\\301\\016\\051\\320\\241\\213\\175\\044hP\\246\\343\\264\\371QU\\345\\230-\\273\\0475w\\205S\\226\\334\\207\\046\\036\\177G\\237b\\042\\245\\305\\227h:86400::\n',
86
+ },
87
+ ]
88
+
89
+ const invalidRecords = [
90
+ {
91
+ ...common,
92
+ owner:
93
+ '0.d.4.0.3.0.e.f.f.f.3.f.0.1.2.0.1.0.0.0.0.0.2.8.b.d.0.1.0.0.2.ip6.arpa.',
94
+ precedence: 10,
95
+ 'gateway type': 4,
96
+ algorithm: 2,
97
+ gateway: '2001:0db8:0:8002::2000:1',
98
+ publickey: 'AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==',
99
+ msg: /Gateway Type is invalid/,
100
+ },
101
+ {
102
+ ...common,
103
+ owner:
104
+ '0.d.4.0.3.0.e.f.f.f.3.f.0.1.2.0.1.0.0.0.0.0.2.8.b.d.0.1.0.0.2.ip6.arpa.',
105
+ precedence: 10,
106
+ 'gateway type': 3,
107
+ algorithm: 3,
108
+ gateway: '2001:0db8:0:8002::2000:1',
109
+ publickey: 'AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==',
110
+ msg: /Algorithm invalid/,
111
+ },
112
+ ]
113
+
114
+ describe('IPSECKEY record', function () {
115
+ base.valid(IPSECKEY, validRecords)
116
+ base.invalid(IPSECKEY, invalidRecords)
117
+
118
+ base.getDescription(IPSECKEY)
119
+ base.getRFCs(IPSECKEY, validRecords[0])
120
+ base.getRdataFields(IPSECKEY, [
121
+ 'precedence',
122
+ 'gateway type',
123
+ 'algorithm',
124
+ 'gateway',
125
+ 'publickey',
126
+ ])
127
+ base.getFields(IPSECKEY, [
128
+ 'precedence',
129
+ 'gateway type',
130
+ 'algorithm',
131
+ 'gateway',
132
+ 'publickey',
133
+ ])
134
+ base.getTypeId(IPSECKEY, 45)
135
+
136
+ base.toBind(IPSECKEY, validRecords)
137
+ base.toTinydns(IPSECKEY, validRecords)
138
+
139
+ base.fromBind(IPSECKEY, validRecords)
140
+ base.fromTinydns(IPSECKEY, validRecords)
141
+ })
package/test/key.js ADDED
@@ -0,0 +1,36 @@
1
+ import * as base from './base.js'
2
+
3
+ import KEY from '../rr/key.js'
4
+
5
+ const validRecords = [
6
+ {
7
+ owner: 'example.com.',
8
+ ttl: 3600,
9
+ class: 'IN',
10
+ type: 'KEY',
11
+ flags: 256,
12
+ protocol: 3,
13
+ algorithm: 5,
14
+ publickey: `( AQPSKmynfzW4kyBv015MUG2DeIQ3 Cbl+BBZH4b/0PY1kxkmvHjcZc8no kfzj31GajIQKY+5CptLr3buXA10h WqTkF7H6RfoRqXQeogmMHfpftf6z Mv1LyBUgia7za6ZEzOJBOztyvhjL 742iU/TpPSEDhm2SNKLijfUppn1U aNvv4w== )`,
15
+ testB:
16
+ 'example.com.\t3600\tIN\tKEY\t256\t3\t5\t( AQPSKmynfzW4kyBv015MUG2DeIQ3 Cbl+BBZH4b/0PY1kxkmvHjcZc8no kfzj31GajIQKY+5CptLr3buXA10h WqTkF7H6RfoRqXQeogmMHfpftf6z Mv1LyBUgia7za6ZEzOJBOztyvhjL 742iU/TpPSEDhm2SNKLijfUppn1U aNvv4w== )\n',
17
+ },
18
+ ]
19
+
20
+ const invalidRecords = []
21
+
22
+ describe('KEY record', function () {
23
+ base.valid(KEY, validRecords)
24
+ base.invalid(KEY, invalidRecords, { ttl: 3600 })
25
+
26
+ base.getDescription(KEY)
27
+ base.getRFCs(KEY, validRecords[0])
28
+ base.getFields(KEY, ['flags', 'protocol', 'algorithm', 'publickey'])
29
+ base.getTypeId(KEY, 25)
30
+
31
+ base.toBind(KEY, validRecords)
32
+ // base.toTinydns(KEY, validRecords)
33
+
34
+ base.fromBind(KEY, validRecords)
35
+ // base.fromTinydns(KEY, validRecords)
36
+ })
package/test/loc.js ADDED
@@ -0,0 +1,75 @@
1
+ import assert from 'assert'
2
+
3
+ import * as base from './base.js'
4
+
5
+ import LOC from '../rr/loc.js'
6
+
7
+ const defaults = { class: 'IN', ttl: 3600, type: 'LOC' }
8
+
9
+ const validRecords = [
10
+ {
11
+ ...defaults,
12
+ owner: 'loc.home.example.com.',
13
+ address: '47 43 47 N 122 21 35 W 132m 100m 100m 2m',
14
+ testB: `loc.home.example.com.\t3600\tIN\tLOC\t47 43 47 N 122 21 35 W 132m 100m 100m 2m\n`,
15
+ testT:
16
+ ':loc.home.example.com:29:\\000\\024\\024\\042\\212\\075\\337\\070\\145\\276\\224\\150\\000\\230\\312\\020:3600::\n',
17
+ },
18
+ {
19
+ ...defaults,
20
+ owner: 'cambridge-net.kei.com.',
21
+ address: '42 21 54 N 71 6 18 W -24m 30m',
22
+ testB:
23
+ 'cambridge-net.kei.com.\t3600\tIN\tLOC\t42 21 54 N 71 6 18 W -24m 30m\n',
24
+ testT:
25
+ ':cambridge-net.kei.com:29:\\000\\063\\000\\000\\211\\027\\055\\320\\160\\276\\025\\360\\000\\230\\215\\040:3600::\n',
26
+ },
27
+ {
28
+ ...defaults,
29
+ owner: 'rwy04l.logan-airport.boston.',
30
+ address: '42 21 28.764 N 71 0 51.617 W -44m 2000m',
31
+ testB:
32
+ 'rwy04l.logan-airport.boston.\t3600\tIN\tLOC\t42 21 28.764 N 71 0 51.617 W -44m 2000m\n',
33
+ testT:
34
+ ':rwy04l.logan-airport.boston:29:\\000\\045\\000\\000\\211\\026\\313\\074\\160\\303\\020\\337\\000\\230\\205\\120:3600::\n',
35
+ },
36
+ ]
37
+
38
+ const invalidRecords = [
39
+ {
40
+ ...defaults,
41
+ owner: 'server.example.com.',
42
+ address: '', // empty
43
+ msg: /address is required/,
44
+ },
45
+ ]
46
+
47
+ describe('LOC record', function () {
48
+ base.valid(LOC, validRecords)
49
+ base.invalid(LOC, invalidRecords)
50
+
51
+ base.getDescription(LOC)
52
+ base.getRFCs(LOC, validRecords[0])
53
+ base.getFields(LOC, ['address'])
54
+ base.getTypeId(LOC, 29)
55
+
56
+ base.toBind(LOC, validRecords)
57
+ base.toTinydns(LOC, validRecords)
58
+
59
+ describe('toExponent', function () {
60
+ const loc = new LOC(validRecords[0])
61
+ it('converts a SIZE/PREC to exponent format', function () {
62
+ assert.equal(loc.toExponent(100), 18)
63
+ })
64
+ })
65
+
66
+ describe('fromExponent', function () {
67
+ const loc = new LOC(validRecords[0])
68
+ it('decodes an exponent format to SIZE/PREC', function () {
69
+ assert.equal(loc.fromExponent(18), 100)
70
+ })
71
+ })
72
+
73
+ base.fromTinydns(LOC, validRecords)
74
+ base.fromBind(LOC, validRecords)
75
+ })