diff --git a/.github/workflows/validation.yml b/.github/workflows/validation.yml
index 6d9efe54d..0da107478 100644
--- a/.github/workflows/validation.yml
+++ b/.github/workflows/validation.yml
@@ -9,7 +9,7 @@ on:
- "domains/*"
- "tests/*"
- "utils/*"
- - ".github/workflows/validate.yml"
+ - ".github/workflows/validation.yml"
- "dnsconfig.js"
workflow_dispatch:
@@ -21,7 +21,6 @@ concurrency:
jobs:
dns:
name: DNS
- if: "!contains(github.event.head_commit.message, '[skip-ci]')"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@@ -33,7 +32,6 @@ jobs:
tests:
name: Tests
- if: "!contains(github.event.head_commit.message, '[skip-ci]')"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
diff --git a/README.md b/README.md
index 5f54b53fb..6629d8c78 100644
--- a/README.md
+++ b/README.md
@@ -18,30 +18,27 @@
Please join our [Discord server](https://discord.gg/is-a-dev-830872854677422150) for announcements, updates & upgrades, and downtimes regarding the service.
Not all of these will be posted on GitHub, however they will always be posted in our Discord server.
-
+
# Register
### NS Records
-When applying for NS records, please consider if you *actually* need them. Please provide a detailed reason (with evidence) of why you require NS records.
-
-9 times out of 10, you do not actually need NS records, and merely want them. We already support a wide range of records, so it is extremely unlikely you will actually require them.
+When applying for NS records, please consider if you *actually* need them.
+In your PR, please provide *extensive* reasoning, with evidence/examples, of why you need NS records.
+You can see a good example of this [here](https://github.com/is-a-dev/register/pull/17592).
***Pull requests adding NS records without valid reasoning will be closed.***
**Instant Denials**:
- I don't want to create a pull request everytime I want to update my DNS records.
- - Over 3,000 people have to, you can too.
-- I want to use Cloudflare's proxy for DDoS protection.
- - Simply add `"proxied": true` to your file, to enable Cloudflare's Enterprise-level DDoS protection for your subdomain.
- - Note: We *may* allow certain users to register NS records if it would expose their home IP.
-
-For any questions regarding NS records, feel free to email support@is-a.dev.
+ - Over 3,000 people have to create PRs for updating their records, you can too.
+- It is easier to manage DNS records on *(insert DNS provider name)*.
+ - It isn't too difficult to open a pull request to update your DNS records. We aim for PRs to be merged with-in 24 hours.
+- I want to use DDoS protection.
+ - You can simply add `"proxied": true` to your file, to enable Cloudflare's Enterprise-level DDoS protection for your subdomain.
> [!NOTE]
> You can skip these requirements by [supporting the service](https://wdh.gg/pvNCdvs) with a small amount of $2.
>
-> All donations go towards supporting the service's running costs.
->
> If you decide to donate, please email william@is-a.dev with your payment confirmation and your pull request link to receive your NS records.
## Manual Registration
diff --git a/domains/_discord.anirbaaaan.json b/domains/_discord.anirbaaaan.json
new file mode 100644
index 000000000..f7a613430
--- /dev/null
+++ b/domains/_discord.anirbaaaan.json
@@ -0,0 +1,9 @@
+{
+ "owner": {
+ "username": "anirbaaaan183",
+ "email": "anirbanrc@proton.me"
+ },
+ "record": {
+ "TXT": "dh=ef12f3d26e5f641e4a2f956c2a208b8da58b5c47"
+ }
+}
diff --git a/domains/_discord.sabbir.json b/domains/_discord.sabbir.json
new file mode 100644
index 000000000..1ae6b2940
--- /dev/null
+++ b/domains/_discord.sabbir.json
@@ -0,0 +1,8 @@
+{
+ "owner": {
+ "username": "s8rr"
+ },
+ "record": {
+ "TXT": ["dh=02cb947f7961bbd1816cb3aa4d2d47854665515c"]
+ }
+}
diff --git a/domains/_discord.wizardsword.json b/domains/_discord.wizardsword.json
new file mode 100644
index 000000000..e2b1afbb4
--- /dev/null
+++ b/domains/_discord.wizardsword.json
@@ -0,0 +1,9 @@
+{
+ "owner": {
+ "username": "MukuJhansi",
+ "email": "mukundagrawal800@gmail.com"
+ },
+ "record": {
+ "TXT": "dh=4df0e55d42947236385030525829593c2e5cbd62"
+ }
+}
diff --git a/domains/_github-pages-challenge-anirbaaaan183.anirbaaaan.json b/domains/_github-pages-challenge-anirbaaaan183.anirbaaaan.json
new file mode 100644
index 000000000..aef4a9302
--- /dev/null
+++ b/domains/_github-pages-challenge-anirbaaaan183.anirbaaaan.json
@@ -0,0 +1,9 @@
+{
+ "owner": {
+ "username": "anirbaaaan183",
+ "email": "anirbanrc@proton.me"
+ },
+ "record": {
+ "TXT": "5f8c296170c0f2cd8aa1089b065900"
+ }
+}
diff --git a/domains/_github-pages-challenge-wizcann.wizcann.json b/domains/_github-pages-challenge-wizcann.wizcann.json
new file mode 100644
index 000000000..f95b28284
--- /dev/null
+++ b/domains/_github-pages-challenge-wizcann.wizcann.json
@@ -0,0 +1,8 @@
+{
+ "owner": {
+ "username": "wizcann"
+ },
+ "record": {
+ "TXT": ["76bdb40edcf54ac449921a71e3e388"]
+ }
+}
diff --git a/domains/_vercel.kushdhingra.json b/domains/_vercel.kushdhingra.json
new file mode 100644
index 000000000..350a577a1
--- /dev/null
+++ b/domains/_vercel.kushdhingra.json
@@ -0,0 +1,8 @@
+{
+ "owner": {
+ "username": "kushdhingra"
+ },
+ "record": {
+ "TXT": ["vc-domain-verify=kushdhingra.is-a.dev,a0343a97ff791537efcd"]
+ }
+}
diff --git a/domains/_vercel.shubh.json b/domains/_vercel.shubh.json
new file mode 100644
index 000000000..79802a66f
--- /dev/null
+++ b/domains/_vercel.shubh.json
@@ -0,0 +1,8 @@
+{
+ "owner": {
+ "username": "R3tr0LastKnight"
+ },
+ "record": {
+ "TXT": ["vc-domain-verify=shubh.is-a.dev,ec236054bf6268762e7e"]
+ }
+}
diff --git a/domains/_vercel.wizardsword.json b/domains/_vercel.wizardsword.json
new file mode 100644
index 000000000..9d6d33c4a
--- /dev/null
+++ b/domains/_vercel.wizardsword.json
@@ -0,0 +1,11 @@
+{
+ "owner": {
+ "username": "MukuJhansi",
+ "discord": "1115658967012626542"
+ },
+ "record": {
+ "TXT": [
+ "vc-domain-verify=wizardsword.is-a.dev,bf203775c8ab97f0aa24"
+ ]
+ }
+}
diff --git a/domains/alan-huynh.json b/domains/alan-huynh.json
new file mode 100644
index 000000000..660323ea1
--- /dev/null
+++ b/domains/alan-huynh.json
@@ -0,0 +1,11 @@
+{
+ "owner": {
+ "username": "hdmquan",
+ "email": "hdmquan@gmail.com"
+ },
+ "record": {
+ "A": [
+ "75.2.60.5"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/domains/anhnguyen94.json b/domains/anhnguyen94.json
new file mode 100644
index 000000000..498cfa301
--- /dev/null
+++ b/domains/anhnguyen94.json
@@ -0,0 +1,10 @@
+{
+ "description": "Portfolio redirect for anhnguyen1907",
+ "owner": {
+ "username": "anhnguyen1907",
+ "email": "cau2tomy@gmail.com"
+ },
+ "record": {
+ "CNAME": "anhnguyen1907.github.io"
+ }
+}
diff --git a/domains/anirbaaaan.json b/domains/anirbaaaan.json
new file mode 100644
index 000000000..336288c99
--- /dev/null
+++ b/domains/anirbaaaan.json
@@ -0,0 +1,9 @@
+{
+ "owner": {
+ "username": "anirbaaaan183",
+ "email": "anirbanrc@proton.me"
+ },
+ "record": {
+ "CNAME": "anirbaaaan183.github.io"
+ }
+}
diff --git a/domains/api-peantastic.json b/domains/api-peantastic.json
new file mode 100644
index 000000000..97223312a
--- /dev/null
+++ b/domains/api-peantastic.json
@@ -0,0 +1,11 @@
+{
+ "owner": {
+ "username": "peantastic",
+ "email": "leostark.vndev@gmail.com"
+ },
+ "description": "Hello, my name is Peantastic, and I am a dedicated developer with a passion for creating innovative solutions and enhancing user experiences. It's a pleasure to connect with you!",
+ "repo": "https://github.com/peantastic/",
+ "record": {
+ "CNAME": "tantinh.onrender.com"
+ }
+}
\ No newline at end of file
diff --git a/domains/api.acronical.json b/domains/api.acronical.json
new file mode 100644
index 000000000..335fb70a7
--- /dev/null
+++ b/domains/api.acronical.json
@@ -0,0 +1,11 @@
+{
+ "owner": {
+ "username": "AcronicalYT",
+ "email": "acronicalbusiness@gmail.com"
+ },
+ "record": {
+ "A": [
+ "138.68.133.84"
+ ]
+ }
+}
diff --git a/domains/aynonyme.json b/domains/aynonyme.json
index 7801d201a..a7e2709de 100644
--- a/domains/aynonyme.json
+++ b/domains/aynonyme.json
@@ -6,6 +6,6 @@
"email": "aynonyme@proton.me"
},
"record": {
- "CNAME": "ayn0nyme.github.io"
+ "A": ["93.95.117.183"]
}
}
diff --git a/domains/blog.anirbaaaan.json b/domains/blog.anirbaaaan.json
new file mode 100644
index 000000000..4651dcda5
--- /dev/null
+++ b/domains/blog.anirbaaaan.json
@@ -0,0 +1,9 @@
+{
+ "owner": {
+ "username": "anirbaaaan183",
+ "email": "anirbanrc@proton.me"
+ },
+ "record": {
+ "URL": "https://anirbaaaan183.github.io/blog"
+ }
+}
diff --git a/domains/chez1s.json b/domains/chez1s.json
new file mode 100644
index 000000000..b60527bfe
--- /dev/null
+++ b/domains/chez1s.json
@@ -0,0 +1,11 @@
+{
+ "description": "chez1s's is-a-dev domain",
+ "repo": "https://github.com/TRIBUI106",
+ "owner": {
+ "username": "TRIBUI106",
+ "discord": "1250225950268850312"
+ },
+ "record": {
+ "URL": "https://yeume-enterprise.edu.vn"
+ }
+}
diff --git a/domains/chromesec.json b/domains/chromesec.json
new file mode 100644
index 000000000..5554d73f5
--- /dev/null
+++ b/domains/chromesec.json
@@ -0,0 +1,12 @@
+{
+ "description": "Website for ChromeSEC a guide for admins to secure their chromeOS devices",
+ "repo": "https://github.com/CaenJones/ChromeSEC",
+ "owner": {
+ "username": "CaenJones",
+ "email": "cj@caenjones.com",
+ "twitter": ""
+ },
+ "record": {
+ "URL": "https://caenjones.is-a.dev/ChromeSEC"
+ }
+}
diff --git a/domains/dash.bernardonogueira8.json b/domains/dash.bernardonogueira8.json
new file mode 100644
index 000000000..1b5d366c3
--- /dev/null
+++ b/domains/dash.bernardonogueira8.json
@@ -0,0 +1,11 @@
+{
+ "owner": {
+ "username": "Samuraiflamesf",
+ "email": "Samuraiflamesf@gmail.com"
+ },
+ "record": {
+ "A": [
+ "100.42.189.124"
+ ]
+ }
+}
diff --git a/domains/dyikes.json b/domains/dyikes.json
new file mode 100644
index 000000000..670fb7662
--- /dev/null
+++ b/domains/dyikes.json
@@ -0,0 +1,9 @@
+{
+ "owner": {
+ "username": "dyikes",
+ "email": "f@power.slmail.me"
+ },
+ "record": {
+ "CNAME": "dyikes.duckdns.org"
+ }
+}
diff --git a/domains/erdogan.json b/domains/erdogan.json
index 5120b3239..99c66a948 100644
--- a/domains/erdogan.json
+++ b/domains/erdogan.json
@@ -4,6 +4,6 @@
"email": "erdogan.sad@windowslive.com"
},
"record": {
- "A": ["194.87.246.134"]
+ "CNAME": "erdogans.space"
}
}
diff --git a/domains/haolamnm.json b/domains/haolamnm.json
new file mode 100644
index 000000000..3187a2d5e
--- /dev/null
+++ b/domains/haolamnm.json
@@ -0,0 +1,10 @@
+{
+ "description": "Portfolio redirect for haolamnm",
+ "owner": {
+ "username": "haolamnm",
+ "email": "haolamnm.work@gmail.com"
+ },
+ "record": {
+ "CNAME": "haolamnm.github.io"
+ }
+}
diff --git a/domains/kushdhingra.json b/domains/kushdhingra.json
index 755d91af3..94d0dfea3 100644
--- a/domains/kushdhingra.json
+++ b/domains/kushdhingra.json
@@ -1,6 +1,6 @@
{
"owner": {
- "username": "Kush-Dhingra",
+ "username": "kushdhingra",
"email": "kushdhingra3112@gmail.com",
"discord": "1035869217796403220",
"OWL": "eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiUlNBLU9BRVAiLCJraWQiOiJaa1VsRmRqVThiUEstLXVVM2JJR09PVHFYYVFFS1ZINFVXOW53MTR6WTJnIn0.gJTReSXxF-8BxDH8rn6i_DIx0XuVrc4yYnOEN1Awfp7mZcYPIgcPt4mvsScPbJYhZLN5XtDlxl0DcdU8Za12GCk-aIWegJ9-_32bdjw3agBzaJ-ltaslRoVpNJ3zfLaQ9V-BrhwVMEJhpz5-0eYeEiikL4tHAoPzzKMlYIf8f5l7IL6aMfhBZvIFf0B3upGg2FeOpFCXAsttU5QiKkjUt4BjetuYb29UJoNzDco1ZExLdudlKd_fz6IcaAsw2K1u6MMDDs2khsic9M42AE3pRFCP_hacdllY5Z66ATlmKhYAxFryJYWrgbfpGX2PxSrQalAao_IP1TIGgiq7ugiBDw.Lg-WIZSH_nzEfnLZct78Cg.soPtqjy32EA2Ew63dHQ8P8-dt4ZihvZpipBVkHyX_rlnv-y5YpS5v2-2d3O5hGHRfCKnfxQsvewDfcPSGa4_Oq8BN01Kzhbet8AXRCK6uOM.ouoa2YqHKAeX9lKWZoFaog"
diff --git a/domains/ldt.json b/domains/ldt.json
new file mode 100644
index 000000000..0a4eadf66
--- /dev/null
+++ b/domains/ldt.json
@@ -0,0 +1,9 @@
+{
+ "owner": {
+ "username": "luongductrong",
+ "email": "luongductrong2004@gmail.com"
+ },
+ "record": {
+ "CNAME": "luongductrong.github.io"
+ }
+}
diff --git a/domains/minitor.json b/domains/minitor.json
new file mode 100644
index 000000000..e10eeb8af
--- /dev/null
+++ b/domains/minitor.json
@@ -0,0 +1,11 @@
+{
+ "description": "Self hosted service",
+ "repo": "https://github.com/MinitorMHS/register",
+ "owner": {
+ "username": "minitormhs",
+ "email": "me@minitor.eu.org"
+ },
+ "record": {
+ "CNAME": "cf-repl.pages.dev"
+ }
+}
diff --git a/domains/mod.s4il.json b/domains/mod.s4il.json
new file mode 100644
index 000000000..6d450044b
--- /dev/null
+++ b/domains/mod.s4il.json
@@ -0,0 +1,9 @@
+{
+ "owner": {
+ "username": "S4IL21",
+ "email": "s4il.is.a.dev@gmail.com"
+ },
+ "record": {
+ "CNAME": "s4il21.github.io"
+ }
+}
diff --git a/domains/needrose.json b/domains/needrose.json
new file mode 100644
index 000000000..525238ca6
--- /dev/null
+++ b/domains/needrose.json
@@ -0,0 +1,9 @@
+{
+ "owner": {
+ "username": "Needrose",
+ "email": "neeedrose@gmail.com"
+ },
+ "record": {
+ "A": ["155.248.226.206"]
+ }
+}
diff --git a/domains/nh.json b/domains/nh.json
new file mode 100644
index 000000000..9a5666540
--- /dev/null
+++ b/domains/nh.json
@@ -0,0 +1,9 @@
+{
+ "owner": {
+ "username": "nonxistnt",
+ "email": "khtyiscooler@gmail.com"
+ },
+ "record": {
+ "CNAME": "nonxistnt.github.io"
+ }
+}
diff --git a/domains/phamthanhnghia.json b/domains/phamthanhnghia.json
new file mode 100644
index 000000000..2378ce50d
--- /dev/null
+++ b/domains/phamthanhnghia.json
@@ -0,0 +1,11 @@
+{
+ "description": "phamthanhnghia.is-a.dev",
+ "repo": "https://github.com/phamthanhnghia/phamthanhnghia.github.io",
+ "owner": {
+ "username": "phamthanhnghia",
+ "email": "phamthanhnghia.it@gmail.com"
+ },
+ "record": {
+ "CNAME": "phamthanhnghia.github.io"
+ }
+}
diff --git a/domains/proficode.json b/domains/proficode.json
new file mode 100644
index 000000000..ab1555bf5
--- /dev/null
+++ b/domains/proficode.json
@@ -0,0 +1,9 @@
+{
+ "owner": {
+ "username": "profic0de",
+ "email": "anonymou3489@gmail.com"
+ },
+ "record": {
+ "CNAME": "239581.site.bot-hosting.net"
+ }
+}
diff --git a/domains/redirect.akk1to.json b/domains/redirect.akk1to.json
new file mode 100644
index 000000000..2b819373c
--- /dev/null
+++ b/domains/redirect.akk1to.json
@@ -0,0 +1,12 @@
+{
+ "description": "This website is for redirect server",
+ "repo": "https://github.com/akk1to/redirect",
+ "owner": {
+ "username": "akk1to",
+ "email": "akk1to.dev@gmail.com",
+ "discord": "727497287777124414"
+ },
+ "record": {
+ "CNAME": "akk1to.github.io"
+ }
+}
diff --git a/domains/redolent.json b/domains/redolent.json
new file mode 100644
index 000000000..009222c74
--- /dev/null
+++ b/domains/redolent.json
@@ -0,0 +1,12 @@
+{
+ "owner": {
+ "username": "RedolentHalo",
+ "discord": "755718159641608202",
+ "OWL": "eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiUlNBLU9BRVAiLCJraWQiOiJaa1VsRmRqVThiUEstLXVVM2JJR09PVHFYYVFFS1ZINFVXOW53MTR6WTJnIn0.c0d7ul7E-LX1qEJeFPuXgcpGJvLDeqnotDBs20mJdeqQzpzoMFTGzEYQ3QExt5XVjdX9SzRFpdgGaY04gN_c_Nrx7WaG47ZJL1rNAapJYCUGmysp3W6g2Trwi45_cIaWUEwKGnjBIgp3BTLKO6yentnHJXKjMb5AUkDcZVj69Nly4sCpdUTSjj1Xw6hVtmapS-lGaIlm6iaftk1pEJm1q1uIuDSsrufH2oRF3lVwkmjJDIwD_tf7PXuHRUGgxvt0FK_bLZKnoqbFtpTh9nNg_RBf8H1YnzHhOc6dkjf6ikBBzcQDutiKxelMupFmatlU5eAGCBmKkEUwxtSKsp5jQQ.R8WtRKhJLz0P5qUPEEdXZg.oEOJF1FocJn0FqQ1P0RaKVK4G1RoQT6E3oyRUpMg_lv0UXDwn16BlIUcKowUWxiObofg1YKRgB1OM4uIZPjxbAYJwkS-Q4Hf0CTmeZCjCaVpaeNc20Z9dREuphe4He30.jP6ZbMY8WRHngmBV6kRBsg"
+ },
+
+ "record": {
+ "CNAME": "redolent.pages.dev"
+ }
+ }
+
\ No newline at end of file
diff --git a/domains/riskyprsty.json b/domains/riskyprsty.json
new file mode 100644
index 000000000..a79f3f3e4
--- /dev/null
+++ b/domains/riskyprsty.json
@@ -0,0 +1,8 @@
+{
+ "owner": {
+ "username": "riskyprsty"
+ },
+ "record": {
+ "CNAME": "riskyprsty.github.io"
+ }
+}
diff --git a/domains/sabbir.json b/domains/sabbir.json
index 9f02d817e..2c4dd5094 100644
--- a/domains/sabbir.json
+++ b/domains/sabbir.json
@@ -4,6 +4,6 @@
"email": "sabbir.apbn.edu@gmail.com"
},
"record": {
- "CNAME": "sabbir1.pages.dev"
+ "NS": ["clarissa.ns.cloudflare.com", "harley.ns.cloudflare.com"]
}
}
diff --git a/domains/saftec.json b/domains/saftec.json
new file mode 100644
index 000000000..1b5d366c3
--- /dev/null
+++ b/domains/saftec.json
@@ -0,0 +1,11 @@
+{
+ "owner": {
+ "username": "Samuraiflamesf",
+ "email": "Samuraiflamesf@gmail.com"
+ },
+ "record": {
+ "A": [
+ "100.42.189.124"
+ ]
+ }
+}
diff --git a/domains/shubh.json b/domains/shubh.json
index 2b950ba61..b4321f5ef 100644
--- a/domains/shubh.json
+++ b/domains/shubh.json
@@ -1,12 +1,8 @@
{
- "description": "personal portfolio website",
- "repo": "https://github.com/R3tr0LastKnight/Portfoio_v2.git",
"owner": {
- "username": "R3tr0LastKnight",
- "email": "r3tr0lastknight@gmail.com",
- "twitter": "R3tr0LastKnight"
+ "username": "R3tr0LastKnight"
},
"record": {
- "CNAME": "r3tr0lastknight.github.io"
+ "CNAME": "portfoio-v2.vercel.app"
}
}
diff --git a/domains/somaiyalbakhet.json b/domains/somaiyalbakhet.json
new file mode 100644
index 000000000..2e4f4b519
--- /dev/null
+++ b/domains/somaiyalbakhet.json
@@ -0,0 +1,10 @@
+{
+ "description": "my portfolio website on Netlify",
+ "owner": {
+ "username": "Somaiya-XI",
+ "discord": "Sen!#0577"
+ },
+ "record": {
+ "A": ["75.2.60.5"]
+ }
+}
diff --git a/domains/tan.json b/domains/tan.json
new file mode 100644
index 000000000..85ecae11e
--- /dev/null
+++ b/domains/tan.json
@@ -0,0 +1,10 @@
+{
+ "description": "tan.is-a.dev",
+ "owner": {
+ "username": "cuno92",
+ "email": "hoangvannhattan@gmail.com"
+ },
+ "record": {
+ "CNAME": "white-hill-030c00b00.4.azurestaticapps.net"
+ }
+}
diff --git a/domains/tortilla.json b/domains/tortilla.json
new file mode 100644
index 000000000..977c39694
--- /dev/null
+++ b/domains/tortilla.json
@@ -0,0 +1,11 @@
+{
+ "description": "tortilla.is-a.dev",
+ "owner": {
+ "username": "Colbster937",
+ "email": "colbster937@colbster937.dev"
+ },
+ "record": {
+ "CNAME": "dns.tortillagames.org"
+ },
+ "proxied": true
+}
diff --git a/domains/trungz.json b/domains/trungz.json
new file mode 100644
index 000000000..911383c15
--- /dev/null
+++ b/domains/trungz.json
@@ -0,0 +1,9 @@
+{
+ "owner": {
+ "username": "lehuutrung1412",
+ "email": "me@lehuutrung.dev"
+ },
+ "record": {
+ "URL": "https://lehuutrung.dev"
+ }
+}
diff --git a/domains/tsu.json b/domains/tsu.json
new file mode 100644
index 000000000..29c62defb
--- /dev/null
+++ b/domains/tsu.json
@@ -0,0 +1,9 @@
+{
+ "owner": {
+ "username": "dot-tsu",
+ "email": "lucanahtsu@gmail.com"
+ },
+ "record": {
+ "CNAME": "dot-tsu.github.io"
+ }
+}
diff --git a/domains/tweets.clyron.json b/domains/tweets.clyron.json
new file mode 100644
index 000000000..284409427
--- /dev/null
+++ b/domains/tweets.clyron.json
@@ -0,0 +1,11 @@
+{
+ "description": "Personal website of Clyron",
+ "repo": "https://github.com/theclyron/theclyron.github.io",
+ "owner": {
+ "username": "theclyron",
+ "email": "onenonlyclyron@gmail.com"
+ },
+ "record": {
+ "CNAME": "theclyron.github.io"
+ }
+}
diff --git a/domains/vasanth.json b/domains/vasanth.json
new file mode 100644
index 000000000..07f5aa342
--- /dev/null
+++ b/domains/vasanth.json
@@ -0,0 +1,13 @@
+{
+ "description": "Vasanth personal Blog",
+ "repo": "https://github.com/itsparser",
+ "owner": {
+ "username": "62d2",
+ "email": "itsparser@gmail.com",
+ "twitter": "itsparser",
+ "discord": "itsparser"
+ },
+ "record": {
+ "CNAME": "itsparser.github.io"
+ }
+}
diff --git a/domains/vdevanarayan.json b/domains/vdevanarayan.json
new file mode 100644
index 000000000..91adbc61a
--- /dev/null
+++ b/domains/vdevanarayan.json
@@ -0,0 +1,9 @@
+{
+ "owner": {
+ "username": "CodeTitan7",
+ "email": "octavius1983bc@gmail.com"
+ },
+ "record": {
+ "URL": "https://vdevanarayan.vercel.app"
+ }
+}
diff --git a/domains/vurihuang.json b/domains/vurihuang.json
new file mode 100644
index 000000000..fc7d3838f
--- /dev/null
+++ b/domains/vurihuang.json
@@ -0,0 +1,9 @@
+{
+ "owner": {
+ "username": "vurihuang",
+ "email": "vengeancehuang@gmail.com"
+ },
+ "record": {
+ "CNAME": "vurihuang.github.io"
+ }
+}
diff --git a/domains/wizardsword.json b/domains/wizardsword.json
index 2d669e7e2..a8bf76bee 100644
--- a/domains/wizardsword.json
+++ b/domains/wizardsword.json
@@ -4,6 +4,6 @@
"discord": "1115658967012626542"
},
"record": {
- "A": ["216.24.57.1"]
+ "A": ["76.76.21.21"]
}
}
diff --git a/domains/wizcann.json b/domains/wizcann.json
new file mode 100644
index 000000000..cc4df51b5
--- /dev/null
+++ b/domains/wizcann.json
@@ -0,0 +1,8 @@
+{
+ "owner": {
+ "username": "wizcann"
+ },
+ "record": {
+ "CNAME": "wizcann.github.io"
+ }
+}
diff --git a/domains/youssef-lmouden.json b/domains/youssef-lmouden.json
new file mode 100644
index 000000000..62c8bf2dc
--- /dev/null
+++ b/domains/youssef-lmouden.json
@@ -0,0 +1,8 @@
+{
+ "owner": {
+ "username": "YoussefDevPro"
+ },
+ "record": {
+ "CNAME": "youssefdevpro.github.io"
+ }
+}
diff --git a/domains/zalex.json b/domains/zalex.json
new file mode 100644
index 000000000..1fafd707a
--- /dev/null
+++ b/domains/zalex.json
@@ -0,0 +1,12 @@
+{
+ "owner": {
+ "username": "Orange-Figure",
+ "discord": "1212435420776890368",
+ "OWL": "eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiUlNBLU9BRVAiLCJraWQiOiJaa1VsRmRqVThiUEstLXVVM2JJR09PVHFYYVFFS1ZINFVXOW53MTR6WTJnIn0.N0_TVOrIKQHS-dgU5KDDcREwJDAtW1AfGLARAqAZyT-UjrmJz8IUFHg8zYxe6Spa4faQVR_emyVZKwqwlFvdIZZr4yQrWQSED-2WZJ5Z5DXpti6930sHO4CVgszWKjc5LqPW1764QP39iQrC7VtNSFxEmZTWJnmK0i8X_2AOSgu8BTH45vjMVKU4oBRzHjvoBZ-Z_17DCk0Awy2FxWSscZPDVF1-_1ETfQ60Ahcv8gYcMt3ZVs2vrUZR_sopt8LaPf6AQQ9zSgDtRiwBHogpiYWsAZVN_5EHTKosomGhUcxuHfUjhaHFauscXQjHZM6kDOEAEvY8MryV7jRy_gm7fQ.sZCseMTkxIHnGcrpk7SARA.SHzeybFf2FVb38kuLc62-X3zAK2SMpZiL2FlnaU77-UR5bsGoINyEnbJNdvCRd4nLItafWpWtCqu0NyvjBh8BWCNrCUhYMmmLRzg6sBgolI.kE2nsD9RtiZGMS-KFaXmZw"
+ },
+
+ "record": {
+ "CNAME": "zalex.betteruptime.com"
+ }
+ }
+
\ No newline at end of file
diff --git a/tests/domains.test.js b/tests/domains.test.js
index fa8988590..071f2c534 100644
--- a/tests/domains.test.js
+++ b/tests/domains.test.js
@@ -5,49 +5,73 @@ const path = require("path");
const domainsPath = path.resolve("domains");
const files = fs.readdirSync(domainsPath);
+function getParentSubdomain(subdomain) {
+ const parts = subdomain.split(".");
+
+ if (parts.length <= 1) return null; // No parent for top-level subdomains
+
+ // Attempt to find the parent subdomain by removing the last part
+ for (let i = parts.length - 1; i > 0; i--) {
+ const potentialParent = parts.slice(i - 1).join(".");
+ if (files.includes(`${potentialParent}.json`)) {
+ return potentialParent; // Return the parent subdomain if it exists
+ }
+ }
+
+ return null; // Return null if no valid parent is found
+}
+
+
+function getDomainData(subdomain) {
+ try {
+ return fs.readJsonSync(path.join(domainsPath, `${subdomain}.json`));
+ } catch (error) {
+ throw new Error(`Failed to read JSON for ${subdomain}: ${error.message}`);
+ }
+}
+
t("Nested subdomains should not exist without a parent subdomain", (t) => {
- files.forEach((file) => {
+ for (const file of files) {
const subdomain = file.replace(/\.json$/, "");
if (subdomain.split(".").length > 1) {
- const parentSubdomain = subdomain.split(".").pop();
-
+ const parentSubdomain = getParentSubdomain(subdomain);
t.true(files.includes(`${parentSubdomain}.json`), `${file}: Parent subdomain does not exist`);
}
- });
+ }
t.pass();
});
t("Nested subdomains should not exist if the parent subdomain has NS records", (t) => {
- files.forEach((file) => {
+ for (const file of files) {
const subdomain = file.replace(/\.json$/, "");
if (subdomain.split(".").length > 1) {
- const parentSubdomain = subdomain.split(".").pop();
- const parentDomain = fs.readJsonSync(path.join(domainsPath, `${parentSubdomain}.json`));
+ const parentSubdomain = getParentSubdomain(subdomain);
+ const parentDomain = getDomainData(parentSubdomain);
- t.is(parentDomain.record.NS, undefined, `${file}: Parent subdomain has NS records`);
+ t.true(!parentDomain.record.NS, `${file}: Parent subdomain has NS records`);
}
- });
+ }
t.pass();
});
t("Nested subdomains should be owned by the parent subdomain's owner", (t) => {
- files.forEach((file) => {
- const subdomain = file.replace(/\.json$/, "");
+ for (const file of files) {
+ const subdomain = file.replace(/\.json$/, "");
if (subdomain.split(".").length > 1) {
- const data = fs.readJsonSync(path.join(domainsPath, file));
+ const data = getDomainData(subdomain);
- const parentSubdomain = subdomain.split(".").pop();
- const parentDomain = fs.readJsonSync(path.join(domainsPath, `${parentSubdomain}.json`));
+ const parentSubdomain = getParentSubdomain(subdomain);
+ const parentDomain = getDomainData(parentSubdomain);
t.true(
data.owner.username.toLowerCase() === parentDomain.owner.username.toLowerCase(),
- `${file}: owner.username is not the same as the parent subdomain`
+ `${file}: Owner does not match the parent subdomain`
);
}
- });
+ }
});
diff --git a/tests/json.test.js b/tests/json.test.js
index 1a737900e..1bf3e3f3d 100644
--- a/tests/json.test.js
+++ b/tests/json.test.js
@@ -59,8 +59,9 @@ t("All files should have valid file names", (t) => {
// Ignore root domain
if (file !== "@.json") {
+ const subdomain = file.replace(/\.json$/, "");
t.regex(
- file.replace(/\.json$/, "") + ".is-a.dev",
+ subdomain + ".is-a.dev",
hostnameRegex,
`${file}: FQDN must be 1-253 characters, use letters, numbers, dots, or hyphens, and not start or end with a hyphen.`
);
@@ -72,9 +73,13 @@ t("All files should have the required fields", (t) => {
files.forEach((file) => {
const data = fs.readJsonSync(path.join(domainsPath, file));
+ // Validate top-level required fields
validateRequiredFields(t, data, requiredFields, file);
+
+ // Validate owner object fields
validateRequiredFields(t, data.owner, requiredOwnerFields, file);
+ // Ensure 'record' field is not empty unless reserved
if (!data.reserved) {
t.true(Object.keys(data.record).length > 0, `${file}: No record types found`);
}
@@ -85,11 +90,24 @@ t("All files should have valid optional fields", (t) => {
files.forEach((file) => {
const data = fs.readJsonSync(path.join(domainsPath, file));
+ // Validate optional fields at top level
validateOptionalFields(t, data, optionalFields, file);
+
+ // Validate optional fields for owner object
validateOptionalFields(t, data.owner, optionalOwnerFields, file);
+ // Email validation (if provided)
if (data.owner.email) {
t.regex(data.owner.email, emailRegex, `${file}: Owner email should be a valid email address`);
}
});
});
+
+const ignoredJSONFiles = ["package-lock.json", "package.json"];
+
+t("JSON files should not be in the root directory", (t) => {
+ const rootFiles = fs
+ .readdirSync(path.resolve())
+ .filter((file) => file.endsWith(".json") && !ignoredJSONFiles.includes(file));
+ t.is(rootFiles.length, 0, "JSON files should not be in the root directory");
+});
diff --git a/tests/proxy.test.js b/tests/proxy.test.js
index 7e8299c70..2bb64b48c 100644
--- a/tests/proxy.test.js
+++ b/tests/proxy.test.js
@@ -2,21 +2,27 @@ const t = require("ava");
const fs = require("fs-extra");
const path = require("path");
-const requiredRecordsToProxy = ["A", "AAAA", "CNAME"];
+const requiredRecordsToProxy = new Set(["A", "AAAA", "CNAME"]);
// URL records are not listed here because they are proxied by default, so they don't need the proxied flag
function validateProxiedRecords(t, data, file) {
- if (data.proxied) {
- const hasProxiedRecord = Object.keys(data.record).some((key) => requiredRecordsToProxy.includes(key));
+ // Convert the Set to an array for message display
+ const recordTypes = Array.from(requiredRecordsToProxy).join(", ");
- t.true(hasProxiedRecord, `${file}: Proxied is true but there are no records that can be proxied`);
+ if (data.proxied) {
+ const hasProxiedRecord = Object.keys(data.record).some((key) => requiredRecordsToProxy.has(key));
+
+ t.true(
+ hasProxiedRecord,
+ `${file}: Proxied is true but there are no records that can be proxied (${recordTypes} expected)`
+ );
}
}
const domainsPath = path.resolve("domains");
-const files = fs.readdirSync(domainsPath);
+const files = fs.readdirSync(domainsPath).filter((file) => file.endsWith(".json"));
-t("Domains with proxy enabled should have have at least one record that can be proxied", (t) => {
+t("Domains with proxy enabled should have at least one record that can be proxied", (t) => {
files.forEach((file) => {
const domain = fs.readJsonSync(path.join(domainsPath, file));
diff --git a/tests/records.test.js b/tests/records.test.js
index 2970b629e..d819fa9b9 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 = ["A", "AAAA", "CAA", "CNAME", "DS", "MX", "NS", "SRV", "TXT", "URL"];
+const validRecordTypes = new Set(["A", "AAAA", "CAA", "CNAME", "DS", "MX", "NS", "SRV", "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}$/;
@@ -13,17 +13,14 @@ const domainsPath = path.resolve("domains");
const files = fs.readdirSync(domainsPath);
function expandIPv6(ip) {
- // Split into segments by ":"
let segments = ip.split(":");
- // Count the number of segments that are empty due to "::" shorthand
const emptyIndex = segments.indexOf("");
+
if (emptyIndex !== -1) {
- // Calculate how many "0000" segments are missing
const nonEmptySegments = segments.filter((seg) => seg !== "");
const missingSegments = 8 - nonEmptySegments.length;
- // Insert the missing "0000" segments into the position of the empty segment
segments = [
...nonEmptySegments.slice(0, emptyIndex),
...Array(missingSegments).fill("0000"),
@@ -31,76 +28,66 @@ function expandIPv6(ip) {
];
}
- // Expand each segment to 4 characters, padding with leading zeros
- const expandedSegments = segments.map((segment) => segment.padStart(4, "0"));
-
- // Join the segments back together
- return expandedSegments.join(":");
+ return segments.map((segment) => segment.padStart(4, "0")).join(":");
}
-function isPublicIPv4(ip, proxied) {
+function validateIPv4(ip, proxied, file, index) {
const parts = ip.split(".").map(Number);
- // Validate IPv4 address format
- if (parts.length !== 4 || parts.some((part) => isNaN(part) || part < 0 || part > 255)) {
- return false;
- }
+ if (parts.length !== 4 || parts.some((part) => isNaN(part) || part < 0 || part > 255)) return false;
+ if (ip === "192.0.2.1" && proxied) return true;
- // Exception for 192.0.2.1, assuming the domain is proxied
- if (ip === "192.0.2.1" && proxied) {
- return true;
- }
-
- // Check for private and reserved IPv4 ranges
return !(
- // Private ranges
- (
- parts[0] === 10 ||
- (parts[0] === 172 && parts[1] >= 16 && parts[1] <= 31) ||
- (parts[0] === 192 && parts[1] === 168) ||
- // Reserved or special-use ranges
- (parts[0] === 100 && parts[1] >= 64 && parts[1] <= 127) || // Carrier-grade NAT
- (parts[0] === 169 && parts[1] === 254) || // Link-local
- (parts[0] === 192 && parts[1] === 0 && parts[2] === 0) || // IETF Protocol Assignments
- (parts[0] === 192 && parts[1] === 0 && parts[2] === 2) || // Documentation (TEST-NET-1)
- (parts[0] === 198 && parts[1] === 18) || // Network Interconnect Devices
- (parts[0] === 198 && parts[1] === 51 && parts[2] === 100) || // Documentation (TEST-NET-2)
- (parts[0] === 203 && parts[1] === 0 && parts[2] === 113) || // Documentation (TEST-NET-3)
- parts[0] >= 224
- ) // Multicast and reserved ranges
+ parts[0] === 10 ||
+ (parts[0] === 172 && parts[1] >= 16 && parts[1] <= 31) ||
+ (parts[0] === 192 && parts[1] === 168) ||
+ (parts[0] === 100 && parts[1] >= 64 && parts[1] <= 127) ||
+ (parts[0] === 169 && parts[1] === 254) ||
+ (parts[0] === 192 && parts[1] === 0 && parts[2] === 0) ||
+ (parts[0] === 192 && parts[1] === 0 && parts[2] === 2) ||
+ (parts[0] === 198 && parts[1] === 18) ||
+ (parts[0] === 198 && parts[1] === 51 && parts[2] === 100) ||
+ (parts[0] === 203 && parts[1] === 0 && parts[2] === 113) ||
+ parts[0] >= 224
);
}
-function isPublicIPv6(ip) {
- const normalizedIP = ip.toLowerCase();
-
- // Check for private or special-use IPv6 ranges
+function validateIPv6(ip) {
return !(
- (
- normalizedIP.startsWith("fc") || // Unique Local Address (ULA)
- normalizedIP.startsWith("fd") || // Unique Local Address (ULA)
- normalizedIP.startsWith("fe80") || // Link-local
- normalizedIP.startsWith("::1") || // Loopback address (::1)
- normalizedIP.startsWith("2001:db8")
- ) // Documentation range
+ ip.toLowerCase().startsWith("fc") ||
+ ip.toLowerCase().startsWith("fd") ||
+ ip.toLowerCase().startsWith("fe80") ||
+ ip.toLowerCase().startsWith("::1") ||
+ ip.toLowerCase().startsWith("2001:db8")
);
}
+function validateRecordType(recordType) {
+ return validRecordTypes.has(recordType);
+}
+
+function isValidHostname(hostname) {
+ return hostnameRegex.test(hostname);
+}
+
+function isValidHexadecimal(value) {
+ return /^[0-9a-fA-F]+$/.test(value);
+}
+
t("All files should have valid record types", (t) => {
files.forEach((file) => {
const data = fs.readJsonSync(path.join(domainsPath, file));
const recordKeys = Object.keys(data.record);
recordKeys.forEach((key) => {
- t.true(validRecordTypes.includes(key), `${file}: Invalid record type: ${key}`);
+ t.true(validateRecordType(key), `${file}: Invalid record type: ${key}`);
});
- // CNAME records cannot be combined with any other record type unless it is proxied
+ // Specific record rules for CNAME, NS, and DS
if (recordKeys.includes("CNAME") && !data.proxied) {
- t.is(recordKeys.length, Number(1), `${file}: CNAME records cannot be combined with other records`);
+ t.is(recordKeys.length, 1, `${file}: CNAME records cannot be combined with other records unless proxied`);
}
- // NS records cannot be combined with any other record type, except for DS records
if (recordKeys.includes("NS")) {
t.true(
recordKeys.length === 1 || (recordKeys.length === 2 && recordKeys.includes("DS")),
@@ -108,7 +95,6 @@ t("All files should have valid record types", (t) => {
);
}
- // DS records must be combined with NS records
if (recordKeys.includes("DS")) {
t.true(recordKeys.includes("NS"), `${file}: DS records must be combined with NS records`);
}
@@ -118,7 +104,6 @@ t("All files should have valid record types", (t) => {
t("All files should not have duplicate record keys", (t) => {
files.forEach((file) => {
const data = fs.readJsonSync(path.join(domainsPath, file));
-
const recordKeys = Object.keys(data.record);
const uniqueRecordKeys = new Set(recordKeys);
@@ -132,230 +117,95 @@ t("All files should have valid record values", (t) => {
Object.keys(data.record).forEach((key) => {
const value = data.record[key];
+ const subdomain = file.replace(/\.json$/, ""); // Get the subdomain from the filename
- // *: string[]
+ // Validate A, AAAA, MX, NS records: Array of strings
if (["A", "AAAA", "MX", "NS"].includes(key)) {
- t.true(Array.isArray(value), `${file}: Record value should be an array for ${key}`);
+ t.true(Array.isArray(value), `${file}: Record value for ${key} should be an array`);
- value.forEach((record) => {
+ value.forEach((record, idx) => {
t.true(
typeof record === "string",
- `${file}: Record value should be a string for ${key} at index ${value.indexOf(record)}`
+ `${file}: Record value for ${key} should be a string at index ${idx}`
);
- });
-
- // A: string[]
- if (key === "A") {
- value.forEach((record) => {
- t.regex(
- record,
- ipv4Regex,
- `${file}: Record value should be a valid IPv4 address for ${key} at index ${value.indexOf(
- record
- )}`
- );
+ if (key === "A") {
+ t.regex(record, ipv4Regex, `${file}: Invalid IPv4 address for ${key} at index ${idx}`);
t.true(
- isPublicIPv4(record, data.proxied),
- `${file}: Record value should be a public IPv4 address for ${key} at index ${value.indexOf(
- record
- )}`
+ validateIPv4(record, data.proxied, file, idx),
+ `${file}: Invalid IPv4 address for ${key} at index ${idx}`
);
- });
- }
+ }
- // AAAA: string[]
- if (key === "AAAA") {
- value.forEach((record) => {
+ if (key === "AAAA") {
t.regex(
expandIPv6(record),
ipv6Regex,
- `${file}: Record value should be a valid IPv6 address for ${key} at index ${value.indexOf(
- record
- )}`
+ `${file}: Invalid IPv6 address for ${key} at index ${idx}`
);
+ t.true(validateIPv6(record), `${file}: Invalid IPv6 address for ${key} at index ${idx}`);
+ }
- t.true(
- isPublicIPv6(record),
- `${file}: Record value should be a public IPv6 address for ${key} at index ${value.indexOf(
- record
- )}`
- );
- });
- }
-
- // *: string[]
- if (["MX", "NS"].includes(key)) {
- value.forEach((record) => {
- t.regex(
- record,
- hostnameRegex,
- `${file}: Record value should be a valid hostname for ${key} at index ${value.indexOf(
- record
- )}`
- );
- });
- }
+ if (["MX", "NS"].includes(key)) {
+ t.true(isValidHostname(record), `${file}: Invalid hostname for ${key} at index ${idx}`);
+ }
+ });
}
- // *: string
+ // Validate CNAME and URL records: Single string
if (["CNAME", "URL"].includes(key)) {
- t.true(typeof value === "string", `${file}: Record value should be a string for ${key}`);
+ t.true(typeof value === "string", `${file}: Record value for ${key} should be a string`);
if (key === "CNAME") {
- t.regex(value, hostnameRegex, `${file}: Record value should be a valid hostname for ${key}`);
-
- if(file === "@.json") {
- t.false(
- value === "is-a.dev",
- `${file}: Record value should not reference itself for ${key}`
- );
- } else {
- t.false(
- value === file.replace(/\.json$/, "") + ".is-a.dev",
- `${file}: Record value should not reference itself for ${key}`
- );
+ t.true(isValidHostname(value), `${file}: Invalid hostname for ${key}`);
+ t.true(value !== file, `${file}: CNAME cannot point to itself`);
+ if (file === "@.json") {
+ t.true(value !== "is-a.dev", `${file}: CNAME cannot point to itself`);
}
}
if (key === "URL") {
- t.notThrows(() => new URL(value), `${file}: Record value should be a valid URL for ${key}`);
-
- if(file === "@.json") {
- t.false(
- value === "http://is-a.dev",
- `${file}: Record value should not reference itself for ${key}`
- );
- t.false(
- value === "https://is-a.dev",
- `${file}: Record value should not reference itself for ${key}`
- );
- } else {
- t.false(
- value === "http://" + file.replace(/\.json$/, "") + ".is-a.dev",
- `${file}: Record value should not reference itself for ${key}`
- );
- t.false(
- value === "https://" + file.replace(/\.json$/, "") + ".is-a.dev",
- `${file}: Record value should not reference itself for ${key}`
- );
+ t.notThrows(() => new URL(value), `${file}: Invalid URL for ${key}`);
+ try {
+ const urlObj = new URL(value);
+ t.true(urlObj.hostname !== subdomain, `${file}: URL cannot point to itself`);
+ } catch {
+ t.fail(`${file}: Invalid URL for ${key}`);
}
}
}
- // *: {}[]
+ // Validate CAA, DS, SRV records: Array of objects
if (["CAA", "DS", "SRV"].includes(key)) {
- t.true(Array.isArray(value), `${file}: Record value should be an array for ${key}`);
+ t.true(Array.isArray(value), `${file}: Record value for ${key} should be an array`);
- value.forEach((record) => {
+ value.forEach((record, idx) => {
t.true(
typeof record === "object",
- `${file}: Record value should be an object for ${key} at index ${value.indexOf(record)}`
+ `${file}: Record value for ${key} should be an object at index ${idx}`
);
+
+ 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}`
+ );
+ t.true(isValidHexadecimal(record.digest), `${file}: Invalid digest for DS at index ${idx}`);
+ }
});
-
- // CAA: { flags: number, tag: string, value: string }[]
- if (key === "CAA") {
- value.forEach((record) => {
- t.true(
- typeof record.flags === "number",
- `${file}: CAA record value should have a number for flags at index ${value.indexOf(record)}`
- );
-
- t.true(
- typeof record.tag === "string",
- `${file}: CAA record value should have a string for tag at index ${value.indexOf(record)}`
- );
-
- t.true(
- typeof record.value === "string",
- `${file}: CAA record value should have a string for value at index ${value.indexOf(record)}`
- );
- });
- }
-
- // DS: { key_tag: number, algorithm: number, digest_type: number, digest: string }[]
- if (key === "DS") {
- value.forEach((record) => {
- t.true(
- typeof record.key_tag === "number",
- `${file}: DS record value should have a number for key_tag at index ${value.indexOf(
- record
- )}`
- );
-
- t.true(
- typeof record.algorithm === "number",
- `${file}: DS record value should have a number for algorithm at index ${value.indexOf(
- record
- )}`
- );
-
- t.true(
- typeof record.digest_type === "number",
- `${file}: DS record value should have a number for digest_type at index ${value.indexOf(
- record
- )}`
- );
-
- t.true(
- typeof record.digest === "string",
- `${file}: DS record value should have a string for digest at index ${value.indexOf(record)}`
- );
- });
- }
-
- // SRV: { priority: number, weight: number, port: number, target: string }[]
- if (key === "SRV") {
- value.forEach((record) => {
- t.true(
- typeof record.priority === "number",
- `${file}: SRV record value should have a number for priority at index ${value.indexOf(
- record
- )}`
- );
-
- t.true(
- typeof record.weight === "number",
- `${file}: SRV record value should have a number for weight at index ${value.indexOf(
- record
- )}`
- );
-
- t.true(
- typeof record.port === "number",
- `${file}: SRV record value should have a number for port at index ${value.indexOf(record)}`
- );
-
- t.true(
- typeof record.target === "string",
- `${file}: SRV record value should have a string for target at index ${value.indexOf(
- record
- )}`
- );
-
- t.regex(
- value.target,
- hostnameRegex,
- `${file}: SRV record value should be a valid hostname for target at index ${value.indexOf(
- record
- )}`
- );
- });
- }
}
- // TXT: string | string[]
+ // TXT: Single string or array of strings
if (key === "TXT") {
if (Array.isArray(value)) {
- value.forEach((record) => {
+ value.forEach((record, idx) => {
t.true(
typeof record === "string",
- `${file}: Record value should be a string for ${key} at index ${value.indexOf(record)}`
+ `${file}: TXT record value should be a string at index ${idx}`
);
});
} else {
- t.true(typeof value === "string", `${file}: Record value should be a string for ${key}`);
+ t.true(typeof value === "string", `${file}: TXT record value should be a string`);
}
}
});