From fc87c1ddbb0e8a3c45011b85f3b56fc622e0cefd Mon Sep 17 00:00:00 2001 From: Stefano Del Prete Date: Sun, 9 Mar 2025 14:55:19 +0100 Subject: [PATCH 1/7] add TLSA record and custom MX priority --- dnsconfig.js | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/dnsconfig.js b/dnsconfig.js index 3cd55b011..1d052d43c 100644 --- a/dnsconfig.js +++ b/dnsconfig.js @@ -67,7 +67,21 @@ for (var subdomain in domains) { // Handle MX records if (domainData.record.MX) { for (var mx in domainData.record.MX) { - records.push(MX(subdomainName, 10 + parseInt(mx), domainData.record.MX[mx] + ".")); + var mxRecord = domainData.record.MX[mx]; + +if (typeof mxRecord === "string") { + commit[domain].records.push( + MX(subdomainName, 10 + parseInt(mx), domainData.record.MX[mx] + ".") + ); +} else { + commit[domain].records.push( + MX( + subdomainName, + parseInt(mxRecord.priority) || 10 + parseInt(mx), + mxRecord.server + "." + ) + ); +} } } @@ -88,6 +102,23 @@ for (var subdomain in domains) { } } + // Handle TLSA records + if (domainData.record.TLSA) { + for (var tlsa in domainData.record.TLSA) { + var tlsaRecord = domainData.record.TLSA[tlsa]; + + commit[domain].records.push( + TLSA( + subdomainName, + tlsaRecord.usage, + tlsaRecord.selector, + tlsaRecord.matchingType, + tlsaRecord.certificate + ) + ); + } + } + // Handle TXT records if (domainData.record.TXT) { if (Array.isArray(domainData.record.TXT)) { From e5f02fa7ca81bbf78f3c89480f64969608a36e69 Mon Sep 17 00:00:00 2001 From: Stefano Del Prete Date: Sun, 9 Mar 2025 14:56:07 +0100 Subject: [PATCH 2/7] fix indentation --- dnsconfig.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/dnsconfig.js b/dnsconfig.js index 1d052d43c..acb714ecc 100644 --- a/dnsconfig.js +++ b/dnsconfig.js @@ -69,19 +69,19 @@ for (var subdomain in domains) { for (var mx in domainData.record.MX) { var mxRecord = domainData.record.MX[mx]; -if (typeof mxRecord === "string") { - commit[domain].records.push( - MX(subdomainName, 10 + parseInt(mx), domainData.record.MX[mx] + ".") - ); -} else { - commit[domain].records.push( - MX( - subdomainName, - parseInt(mxRecord.priority) || 10 + parseInt(mx), - mxRecord.server + "." - ) - ); -} + if (typeof mxRecord === "string") { + commit[domain].records.push( + MX(subdomainName, 10 + parseInt(mx), domainData.record.MX[mx] + ".") + ); + } else { + commit[domain].records.push( + MX( + subdomainName, + parseInt(mxRecord.priority) || 10 + parseInt(mx), + mxRecord.server + "." + ) + ); + } } } From f4e43a18e5c1eb1f26ab16312fdb6aabcca1fe17 Mon Sep 17 00:00:00 2001 From: Stefano Del Prete Date: Sun, 9 Mar 2025 14:56:55 +0100 Subject: [PATCH 3/7] add tests for TLSA and MX priority --- tests/records.test.js | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/tests/records.test.js b/tests/records.test.js index fbbeee156..c387c1721 100644 --- a/tests/records.test.js +++ b/tests/records.test.js @@ -2,7 +2,7 @@ const t = require("ava"); const fs = require("fs-extra"); const path = require("path"); -const validRecordTypes = new Set(["A", "AAAA", "CAA", "CNAME", "DS", "MX", "NS", "SRV", "TXT", "URL"]); +const validRecordTypes = new Set(["A", "AAAA", "CAA", "CNAME", "DS", "MX", "NS", "SRV", "TLSA", "TXT", "URL"]); const hostnameRegex = /^(?=.{1,253}$)(?:(?:[_a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)\.)+[a-zA-Z]{2,63}$/; const ipv4Regex = /^(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}$/; const ipv6Regex = @@ -98,8 +98,8 @@ function validateRecordValues(t, data, file) { value.forEach((record, idx) => { t.true( - typeof record === "string", - `${file}: Record value for ${key} should be a string at index ${idx}` + typeof record === "string" || typeof record === "object", + `${file}: Record value for ${key} should be a string or an object at index ${idx}` ); if (key === "A") { @@ -112,7 +112,22 @@ function validateRecordValues(t, data, file) { const expandedIPv6 = expandIPv6(record); t.true(ipv6Regex.test(expandedIPv6), `${file}: Invalid IPv6 address for ${key} at index ${idx}`); t.true(validateIPv6(expandedIPv6), `${file}: Invalid IPv6 address for ${key} at index ${idx}`); - } else if (["MX", "NS"].includes(key)) { + } else if (key === "MX") { + t.true( + typeof record === "object" || typeof record === "string", + `${file}: Record value for ${key} should be an object or a string at index ${idx}` + ); + + if (typeof record === "string") { + t.true(isValidHostname(record), `${file}: Invalid hostname for ${key} at index ${idx}`); + } else { + t.true(isValidHostname(record.server), `${file}: Invalid server for MX at index ${idx}`); + t.true( + Number.isInteger(record.priority) && record.priority >= 0 && record.priority <= 65535, + `${file}: Invalid priority for MX at index ${idx}` + ); + } + } else if (key === "NS") { t.true(isValidHostname(record), `${file}: Invalid hostname for ${key} at index ${idx}`); } }); @@ -140,8 +155,8 @@ function validateRecordValues(t, data, file) { } } - // CAA, DS, SRV validations - if (["CAA", "DS", "SRV"].includes(key)) { + // CAA, DS, SRV, TLSA validations + if (["CAA", "DS", "SRV", "TLSA"].includes(key)) { t.true(Array.isArray(value), `${file}: Record value for ${key} should be an array`); value.forEach((record, idx) => { @@ -188,6 +203,20 @@ function validateRecordValues(t, data, file) { `${file}: Invalid port for SRV at index ${idx}` ); t.true(isValidHostname(record.target), `${file}: Invalid target for SRV at index ${idx}`); + } else if (key === "TLSA") { + t.true( + Number.isInteger(record.usage) && record.usage >= 0 && record.usage <= 255, + `${file}: Invalid usage for TLSA at index ${idx}` + ); + t.true( + Number.isInteger(record.selector) && record.selector >= 0 && record.selector <= 255, + `${file}: Invalid selector for TLSA at index ${idx}` + ); + t.true( + Number.isInteger(record.matchingType) && record.matchingType >= 0 && record.matchingType <= 255, + `${file}: Invalid matchingType for TLSA at index ${idx}` + ); + t.true(isValidHexadecimal(record.certificate), `${file}: Invalid certificate for TLSA at index ${idx}`); } }); } From 714ff965ba5d83b2a2e9874740510d1d95f03709 Mon Sep 17 00:00:00 2001 From: Stefano Del Prete Date: Sun, 9 Mar 2025 14:58:33 +0100 Subject: [PATCH 4/7] forgot to remove a thing --- dnsconfig.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsconfig.js b/dnsconfig.js index acb714ecc..eb4204b25 100644 --- a/dnsconfig.js +++ b/dnsconfig.js @@ -70,11 +70,11 @@ for (var subdomain in domains) { var mxRecord = domainData.record.MX[mx]; if (typeof mxRecord === "string") { - commit[domain].records.push( + records.push( MX(subdomainName, 10 + parseInt(mx), domainData.record.MX[mx] + ".") ); } else { - commit[domain].records.push( + records.push( MX( subdomainName, parseInt(mxRecord.priority) || 10 + parseInt(mx), From d33315008f347d402919687ceae5ea9bd60ffa4b Mon Sep 17 00:00:00 2001 From: Stefano Del Prete Date: Sun, 9 Mar 2025 15:01:51 +0100 Subject: [PATCH 5/7] remove unused import --- tests/json.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/json.test.js b/tests/json.test.js index 3894f9567..ba51a9e75 100644 --- a/tests/json.test.js +++ b/tests/json.test.js @@ -1,7 +1,6 @@ const t = require("ava"); const fs = require("fs-extra"); const path = require("path"); -const { promisify } = require("util"); const ignoredRootJSONFiles = ["package-lock.json", "package.json"]; From b709c2b1a71326588dd48acba711246e30560623 Mon Sep 17 00:00:00 2001 From: William Harrison <87287585+wdhdev@users.noreply.github.com> Date: Thu, 13 Mar 2025 13:12:57 +0800 Subject: [PATCH 6/7] Update dnsconfig.js --- dnsconfig.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsconfig.js b/dnsconfig.js index eb4204b25..aa94cdc1d 100644 --- a/dnsconfig.js +++ b/dnsconfig.js @@ -77,8 +77,8 @@ for (var subdomain in domains) { records.push( MX( subdomainName, - parseInt(mxRecord.priority) || 10 + parseInt(mx), - mxRecord.server + "." + parseInt(mxRecord.priority), + mxRecord.target + "." ) ); } @@ -107,7 +107,7 @@ for (var subdomain in domains) { for (var tlsa in domainData.record.TLSA) { var tlsaRecord = domainData.record.TLSA[tlsa]; - commit[domain].records.push( + records.push( TLSA( subdomainName, tlsaRecord.usage, From 364847dcc212269658c245ac6a110232857808ee Mon Sep 17 00:00:00 2001 From: William Harrison <87287585+wdhdev@users.noreply.github.com> Date: Thu, 13 Mar 2025 13:16:47 +0800 Subject: [PATCH 7/7] Update records.test.js --- tests/records.test.js | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/records.test.js b/tests/records.test.js index c387c1721..52fb1f677 100644 --- a/tests/records.test.js +++ b/tests/records.test.js @@ -121,10 +121,10 @@ function validateRecordValues(t, data, file) { if (typeof record === "string") { t.true(isValidHostname(record), `${file}: Invalid hostname for ${key} at index ${idx}`); } else { - t.true(isValidHostname(record.server), `${file}: Invalid server for MX at index ${idx}`); + t.true(isValidHostname(record.target), `${file}: Invalid target for ${key} at index ${idx}`); t.true( Number.isInteger(record.priority) && record.priority >= 0 && record.priority <= 65535, - `${file}: Invalid priority for MX at index ${idx}` + `${file}: Invalid priority for ${key} at index ${idx}` ); } } else if (key === "NS") { @@ -168,55 +168,55 @@ function validateRecordValues(t, data, file) { if (key === "CAA") { t.true( ["issue", "issuewild", "iodef"].includes(record.tag), - `${file}: Invalid tag for CAA at index ${idx}` + `${file}: Invalid tag for ${key} at index ${idx}` ); - t.true(typeof record.value === "string", `${file}: Invalid value for CAA at index ${idx}`); + t.true(typeof record.value === "string", `${file}: Invalid value for ${key} at index ${idx}`); t.true( isValidHostname(record.value) || record.value === ";", - `${file}: Value must be a hostname or semicolon for CAA at index ${idx}` + `${file}: Value must be a hostname or semicolon for ${key} at index ${idx}` ); } else if (key === "DS") { t.true( Number.isInteger(record.key_tag) && record.key_tag >= 0 && record.key_tag <= 65535, - `${file}: Invalid key_tag for DS at index ${idx}` + `${file}: Invalid key_tag for ${key} at index ${idx}` ); t.true( Number.isInteger(record.algorithm) && record.algorithm >= 0 && record.algorithm <= 255, - `${file}: Invalid algorithm for DS at index ${idx}` + `${file}: Invalid algorithm for ${key} at index ${idx}` ); t.true( Number.isInteger(record.digest_type) && record.digest_type >= 0 && record.digest_type <= 255, - `${file}: Invalid digest_type for DS at index ${idx}` + `${file}: Invalid digest_type for ${key} at index ${idx}` ); - t.true(isValidHexadecimal(record.digest), `${file}: Invalid digest for DS at index ${idx}`); + t.true(isValidHexadecimal(record.digest), `${file}: Invalid digest for ${key} at index ${idx}`); } else if (key === "SRV") { t.true( Number.isInteger(record.priority) && record.priority >= 0 && record.priority <= 65535, - `${file}: Invalid priority for SRV at index ${idx}` + `${file}: Invalid priority for ${key} at index ${idx}` ); t.true( Number.isInteger(record.weight) && record.weight >= 0 && record.weight <= 65535, - `${file}: Invalid weight for SRV at index ${idx}` + `${file}: Invalid weight for ${key} at index ${idx}` ); t.true( Number.isInteger(record.port) && record.port >= 0 && record.port <= 65535, - `${file}: Invalid port for SRV at index ${idx}` + `${file}: Invalid port for ${key} at index ${idx}` ); - t.true(isValidHostname(record.target), `${file}: Invalid target for SRV at index ${idx}`); + t.true(isValidHostname(record.target), `${file}: Invalid target for ${key} at index ${idx}`); } else if (key === "TLSA") { t.true( Number.isInteger(record.usage) && record.usage >= 0 && record.usage <= 255, - `${file}: Invalid usage for TLSA at index ${idx}` + `${file}: Invalid usage for ${key} at index ${idx}` ); t.true( Number.isInteger(record.selector) && record.selector >= 0 && record.selector <= 255, - `${file}: Invalid selector for TLSA at index ${idx}` + `${file}: Invalid selector for ${key} at index ${idx}` ); t.true( Number.isInteger(record.matchingType) && record.matchingType >= 0 && record.matchingType <= 255, - `${file}: Invalid matchingType for TLSA at index ${idx}` + `${file}: Invalid matchingType for ${key} at index ${idx}` ); - t.true(isValidHexadecimal(record.certificate), `${file}: Invalid certificate for TLSA at index ${idx}`); + t.true(isValidHexadecimal(record.certificate), `${file}: Invalid certificate for ${key} at index ${idx}`); } }); }