diff --git a/.env b/.env index f87d42da0..26270e769 100644 --- a/.env +++ b/.env @@ -1,4 +1,5 @@ -NC_USER=xxx -NC_API_KEY=xxxxxxxxxxxxxxx -NC_DOMAIN=domain.com -IP_ADDRESS=100.100.100.100 +DOMAIN_USER=username +DOMAIN_API_KEY=apikey +DOMAIN_API_HOST=api-example.com +DOMAIN_API_PORT=2087 +DOMAIN_DOMAIN=example.com diff --git a/.github/workflows/publish-records.yml b/.github/workflows/publish-records.yml index 17bb7bdc0..e4b02e011 100644 --- a/.github/workflows/publish-records.yml +++ b/.github/workflows/publish-records.yml @@ -8,12 +8,13 @@ jobs: publish: runs-on: ubuntu-latest env: - CI: '1' + CI: 1 ENV: production - NC_USER: ${{ secrets.NC_USER }} - NC_API_KEY: ${{ secrets.NC_API_KEY }} - NC_DOMAIN: ${{ secrets.NC_DOMAIN }} - IP_ADDRESS: ${{ secrets.IP_ADDRESS }} + DOMAIN_USER: ${{ secrets.DOMAIN_USER }} + DOMAIN_API_KEY: ${{ secrets.DOMAIN_API_KEY }} + DOMAIN_API_HOST: ${{ secrets.DOMAIN_API_HOST }} + DOMAIN_API_PORT: ${{ secrets.DOMAIN_API_PORT }} + DOMAIN_DOMAIN: ${{ secrets.DOMAIN_DOMAIN }} steps: - uses: actions/checkout@v2 - uses: borales/actions-yarn@v2.0.0 diff --git a/API.md b/API.md index 47d125c53..43bc51d64 100644 --- a/API.md +++ b/API.md @@ -17,13 +17,12 @@ "email": "any@email" }, "record": { - "CNAME": "github-username.github.io", - "URL": "https://your-domain.is-a.dev" + "CNAME": "github-username.github.io" } } ``` * After the pull request is merged, you will see a 404 error on `your-domain.is-a.dev`. To fix this go to your github page repo's `Settings > Github pages > Custom domain` and add `your-domain.is-a.dev` in the given field -* If you have added the `URL` record for forced https, check the `Enforce HTTPS` checkbox too +* Check the `Enforce HTTPS` checkbox below the custom domain input @@ -63,12 +62,11 @@ This is a link to your website repository or your github account. This is purely ### record (required) This is where you specify how you want to link to your server/webpage. -Currently, only `CNAME`, `ALIAS`, `A`, `URL` record types are supported. +Currently, only `CNAME`, `A`, `URL` record types are supported. Here's a few different use cases for the given record types - -* **CNAME/ALIAS** -Replace CNAME with ALIAS for alias record type +* **CNAME** ```json { "record": { @@ -100,13 +98,3 @@ Replace CNAME with ALIAS for alias record type } ``` -* **Force HTTPS on your CNAME (or ALIAS or A) record** -```json -{ - "record": { - "CNAME": "username.github.io", - "URL": "https://your-domain.is-a.dev" - } -} -``` - diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..b382809f4 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,6 @@ +# Security Policy + +## Reporting a Vulnerability + +You can report low severity bugs as [issues](https://github.com/is-a-dev/register/issues/new/choose) on this repo. +For higher severity vulnerabilities and bugs, kindly email them to me at [akshay-n0@protonmail.com](mailto:akshay-n0@protonmail.com). diff --git a/domains/aaraam.json b/domains/aaraam.json new file mode 100644 index 000000000..f75b6b11d --- /dev/null +++ b/domains/aaraam.json @@ -0,0 +1,12 @@ +{ + "description": "This website is a link to my personal developer portfolio.", + "repo": "https://github.com/aaraam/aaraam.github.io", + "owner": { + "username": "aaraam", + "email": "aaraam.goblin@gmail.com" + }, + "record": { + "CNAME": "aaraam.github.io", + "URL": "https://aaraam.is-a.dev" + } +} diff --git a/domains/abdulrshaikh.json b/domains/abdulrshaikh.json new file mode 100644 index 000000000..94621368c --- /dev/null +++ b/domains/abdulrshaikh.json @@ -0,0 +1,12 @@ +{ + "description": "Abdul's personal developer website", + "repo": "https://github.com/ariskycode/ariskycode.github.io", + "owner": { + "username": "ariskycode", + "email": "arirfanshaikh23@gmail.com" + }, + "record": { + "CNAME": "ariskycode.github.io", + "URL": "https://abdulrshaikh.is-a.dev" + } +} diff --git a/domains/adarsh.json b/domains/adarsh.json new file mode 100644 index 000000000..4abb316bd --- /dev/null +++ b/domains/adarsh.json @@ -0,0 +1,12 @@ +{ + "description": "Adarsh's personal developer website", + "repo": "https://github.com/Adarsh1999/adarsh-portfolio.github.io", + "owner": { + "username": "Adarsh1999", + "email": "adarshguptamaurya@gmail.com" + }, + "record": { + "CNAME": "adarsh-portfolio.github.io", + "URL": "https://adarsh.is-a.dev" + } +} diff --git a/domains/adrian.json b/domains/adrian.json new file mode 100644 index 000000000..d2873ec12 --- /dev/null +++ b/domains/adrian.json @@ -0,0 +1,12 @@ +{ + "description": "The awesome portfolio site for Adrian Grimm", + "repo": "https://github.com/usmcamgrimm/usmcamgrimm.github.io", + "owner": { + "username": "usmcamgrimm", + "email": "usmcamgrimm@gmail.com" + }, + "record": { + "CNAME": "usmcamgrimm.github.io", + "URL": "https://adrian.is-a.dev" + } + } diff --git a/domains/ahmadeyamin.json b/domains/ahmadeyamin.json new file mode 100644 index 000000000..1e8007a2c --- /dev/null +++ b/domains/ahmadeyamin.json @@ -0,0 +1,12 @@ +{ + "description": "Eyamin Personal Website", + "repo": "https://github.com/ahmadeyamin/ahmadeyamin.github.io", + "owner": { + "username": "ahmadeyamin", + "email": "ahmadeyamin@gmail.com" + }, + "record": { + "CNAME": "ahmadeyamin.github.io", + "URL": "https://ahmadeyamin.is-a.dev" + } +} diff --git a/domains/akas.json b/domains/akas.json new file mode 100644 index 000000000..a0ddc0f4e --- /dev/null +++ b/domains/akas.json @@ -0,0 +1,12 @@ +{ + "description": "Akas Portfolio", + "repo":"https://github.com/akasrai/akasrai.github.io", + "owner": { + "username": "akasrai", + "email": "akasky70@gmail.com" + }, + "record": { + "CNAME":"akasrai.github.io", + "URL": "https://akas.is-a.dev" + } +} \ No newline at end of file diff --git a/domains/alestor123.json b/domains/alestor123.json new file mode 100644 index 000000000..b9ae0804e --- /dev/null +++ b/domains/alestor123.json @@ -0,0 +1,12 @@ +{ + "description": "A Mortal Web Developer With Immortal Dreams", + "repo": "https://github.com/alestor123/alestor123.github.io", + "owner": { + "username": "alestor123", + "email": "alestoraldous@gmail.com" + }, + "record": { + "CNAME": "alestor123.github.io", + "URL": "https://alestor123.is-a.dev" + } +} diff --git a/domains/alexander.json b/domains/alexander.json new file mode 100644 index 000000000..43758f6d1 --- /dev/null +++ b/domains/alexander.json @@ -0,0 +1,12 @@ +{ + "description": "Alexander's personal website", + "repo": "https://github.com/amatzen", + "owner": { + "username": "amatzen", + "email": "alexander@alexander.dk" + }, + "record": { + "CNAME": "alexander.dk", + "URL": "https://alexander.is-a.dev" + } +} diff --git a/domains/alexjoseph.json b/domains/alexjoseph.json new file mode 100644 index 000000000..01c7cc49e --- /dev/null +++ b/domains/alexjoseph.json @@ -0,0 +1,12 @@ +{ + "description": "This is my first githib page", + "repo": "https://github.com/alexkjoseph/alexkjoseph.github.io", + "owner": { + "username": "alexkjoseph", + "email": "aj71563@gmail.com" + }, + "record": { + "CNAME": "alexkjoseph.github.io", + "URL": "https://alexjoseph.is-a.dev" + } +} diff --git a/domains/allan.json b/domains/allan.json new file mode 100644 index 000000000..6ca03fa35 --- /dev/null +++ b/domains/allan.json @@ -0,0 +1,12 @@ +{ + "description": "Allan's personal website", + "repo": "https://github.com/abarriel", + "owner": { + "username": "abarriel", + "email": "abarriel@student.42.fr" + }, + "record": { + "CNAME": "abarriel.github.io", + "URL": "https://allan.is-a.dev" + } +} diff --git a/domains/allsyed.json b/domains/allsyed.json new file mode 100644 index 000000000..f12be2194 --- /dev/null +++ b/domains/allsyed.json @@ -0,0 +1,11 @@ +{ + "description": "Allsyed's personal website", + "repo": "https://github.com/allsyed", + "owner": { + "username": "allsyed", + "email": "allsyed@pm.me" + }, + "record": { + "CNAME": "allsyed.com" + } +} diff --git a/domains/amal.json b/domains/amal.json new file mode 100644 index 000000000..bbf4685c6 --- /dev/null +++ b/domains/amal.json @@ -0,0 +1,12 @@ +{ + "description": "Amal's personal developer website", + "repo": "https://github.com/amalsebs/amalsebs.github.io", + "owner": { + "username": "amalsebs", + "email": "amalsebastian48@gmail.com" + }, + "record": { + "CNAME": "amalsebs.github.io", + "URL": "https://amal.is-a.dev" + } +} diff --git a/domains/amalsr.json b/domains/amalsr.json new file mode 100644 index 000000000..1729c3da8 --- /dev/null +++ b/domains/amalsr.json @@ -0,0 +1,11 @@ +{ + "description": "A very simple but stupid website", + "repo": "https://github.com/asr1191/asr1191.github.io", + "owner": { + "username": "asr1191", + "email": "amalsraj95@gmail.com" + }, + "record": { + "CNAME": "asr1191.github.io" + } +} diff --git a/domains/andy.json b/domains/andy.json new file mode 100644 index 000000000..3b626ef57 --- /dev/null +++ b/domains/andy.json @@ -0,0 +1,12 @@ +{ + "description": "Andy's portfolio website", + "repo": "https://github.com/andyfaizan/andyfaizan.github.io", + "owner": { + "username": "andyfaizan", + "email": "andyfaizan@gmail.com" + }, + "record": { + "CNAME": "andyfaizan.github.io", + "URL": "https://andy.is-a.dev" + } +} diff --git a/domains/anlshn.json b/domains/anlshn.json new file mode 100644 index 000000000..58b12cac2 --- /dev/null +++ b/domains/anlshn.json @@ -0,0 +1,12 @@ +{ + "description": "Anil's personal developer website", + "repo": "https://github.com/anilsahindev", + "owner": { + "username": "anilsahindev", + "email": "anilsahindev@gmail.com" + }, + "record": { + "CNAME": "anlshn.com", + "URL": "https://anlshn.is-a.dev" + } +} diff --git a/domains/anupam.json b/domains/anupam.json new file mode 100644 index 000000000..20d42352f --- /dev/null +++ b/domains/anupam.json @@ -0,0 +1,12 @@ +{ + "description": "Anupam's portfolio website", + "repo": "https://github.com/anupamroy8/portfolio", + "owner": { + "username": "anupamroy8", + "email": "anupamroy8@gmail.com" + }, + "record": { + "CNAME": "anupamroy8.github.io", + "URL": "https://anupam.is-a.dev" + } +} diff --git a/domains/anwar.json b/domains/anwar.json new file mode 100644 index 000000000..5451e6598 --- /dev/null +++ b/domains/anwar.json @@ -0,0 +1,11 @@ +{ + "description": "Anwar's personal website", + "repo": "https://github.com/getanwar", + "owner": { + "username": "getanwar", + "email": "say@anwar.im" + }, + "record": { + "URL": "https://anwar.im" + } +} diff --git a/domains/art.json b/domains/art.json new file mode 100644 index 000000000..fbfcc4a11 --- /dev/null +++ b/domains/art.json @@ -0,0 +1,11 @@ +{ + "description": "Art's personal developer website", + "repo": "https://github.com/dotiful", + "owner": { + "username": "dotiful", + "email": "dots.util@gmail.com" + }, + "record": { + "CNAME": "dotiful.github.io" + } +} diff --git a/domains/asad-khan.json b/domains/asad-khan.json new file mode 100644 index 000000000..fc9c93aa0 --- /dev/null +++ b/domains/asad-khan.json @@ -0,0 +1,12 @@ +{ + "description": "👋 Hello there! I'm Asad, nice to meet you. Building things that bring delight to users is what I enjoy, always learning new stuff everyday.", + "repo": "https://github.com/asadkhan777", + "owner": { + "username": "asadkhan777", + "email": "asadkhan1776@gmail.com" + }, + "record": { + "CNAME": "asadkhan777.github.io", + "URL": "https://asad-khan.is-a.dev" + } +} diff --git a/domains/ashleymavericks.json b/domains/ashleymavericks.json new file mode 100644 index 000000000..2aa81aab6 --- /dev/null +++ b/domains/ashleymavericks.json @@ -0,0 +1,11 @@ +{ + "description": "Portfolio Website", + "repo": "https://github.com/ashleymavericks/Portfolio-Site", + "owner": { + "username": "ashlyemavericks", + "email": "singhanurag024@gmail.com" + }, + "record": { + "URL": "https://anuragsingh.dev" + } +} diff --git a/domains/aswin.json b/domains/aswin.json new file mode 100644 index 000000000..9ce17190d --- /dev/null +++ b/domains/aswin.json @@ -0,0 +1,12 @@ +{ + "description": "Aswin's personal portfolio", + "repo": "https://github.com/aswinskumar67/iamaswin.github.io", + "owner": { + "username": "aswinskumar67", + "email": "aswin.skumaro2bme@gmail.com" + }, + "record": { + "CNAME": "aswinskumar67.github.io", + "URL": "https://aswin.is-a.dev" + } +} \ No newline at end of file diff --git a/domains/athira-li.json b/domains/athira-li.json new file mode 100644 index 000000000..62a1ec2c1 --- /dev/null +++ b/domains/athira-li.json @@ -0,0 +1,11 @@ +{ + "description": "Athira's Web-Dev Home", + "repo": "https://github.com/Athira-L-I/Athira-L-I.github.io", + "owner": { + "username": "Athira-L-I", + "email": "athirali4582@gmail.com" + }, + "record": { + "CNAME": "Athira-L-I.github.io" + } +} diff --git a/domains/atlas.json b/domains/atlas.json new file mode 100644 index 000000000..b02d23321 --- /dev/null +++ b/domains/atlas.json @@ -0,0 +1,12 @@ +{ + "description": "Portfolio website", + "repo": "https://github.com/robertdrakedennis/portfolio", + "owner": { + "username": "robertdrakedennis", + "email": "robertdennispersonal@gmail.com" + }, + "record": { + "CNAME": "robertdennis.netlify.app", + "URL": "https://atlas.is-a.dev" + } +} diff --git a/domains/augustin.json b/domains/augustin.json new file mode 100644 index 000000000..6920bcdef --- /dev/null +++ b/domains/augustin.json @@ -0,0 +1,12 @@ +{ + "description": "Augustin's personal developer website", + "repo": "https://github.com/AugustinJose1221", + "owner": { + "username": "AugustinJose1221", + "email": "augustinjose1221@gmail.com" + }, + "record": { + "CNAME": "www.augustinjose.com", + "URL": "https://augustin.is-a.dev" + } +} diff --git a/domains/augustine.json b/domains/augustine.json new file mode 100644 index 000000000..83610f675 --- /dev/null +++ b/domains/augustine.json @@ -0,0 +1,12 @@ +{ + "description": "Augustine's personal developer website", + "repo": "https://github.com/augustineaykara", + "owner": { + "username": "augustineaykara", + "email": "augustineaykara@gmail.com" + }, + "record": { + "CNAME": "augustine.aykara4.com", + "URL": "https://augustine.is-a.dev" + } +} diff --git a/domains/austin.json b/domains/austin.json new file mode 100644 index 000000000..8b4f10207 --- /dev/null +++ b/domains/austin.json @@ -0,0 +1,13 @@ +{ + "description": "Austin's personal developer website", + "repo": "https://github.com/austindyoung", + "owner": { + "username": "austindyoung", + "email": "austin@doesweb.dev", + "twitter": "" + }, + "record": { + "URL": "austindyoung.github.io" + } + } + diff --git a/domains/b45i.json b/domains/b45i.json new file mode 100644 index 000000000..6e3ef7d7d --- /dev/null +++ b/domains/b45i.json @@ -0,0 +1,12 @@ +{ + "description": "B45i - Home Page", + "repo": "https://github.com/B45i/b45i.github.io", + "owner": { + "username": "B45i", + "email": "amalshajan2011@gmail.com" + }, + "record": { + "CNAME": "b45i.github.io", + "URL": "https://b45i.is-a.dev" + } +} \ No newline at end of file diff --git a/domains/bae.json b/domains/bae.json new file mode 100644 index 000000000..bdde25c56 --- /dev/null +++ b/domains/bae.json @@ -0,0 +1,13 @@ +{ + "description": "Bae's personal website", + + "owner": { + "username": "ba-e", + "email": "bae.nyom@gmail.com" + }, + + "record": { + "CNAME": "bae.codes", + "URL": "https://bae.is-a.dev" + } +} \ No newline at end of file diff --git a/domains/bhargav-gohil.json b/domains/bhargav-gohil.json new file mode 100644 index 000000000..32ab130f4 --- /dev/null +++ b/domains/bhargav-gohil.json @@ -0,0 +1,12 @@ +{ + "description": "Bhargav Gohil's personal developer website", + "repo": "https://github.com/bhargav252000/bhargav252000.github.io", + "owner": { + "username": "bhargav252000", + "email": "bhargavgohil25@gmail.com" + }, + "record": { + "CNAME": "bhargav252000.github.io", + "URL": "https://bhargav-gohil.is-a.dev" + } +} diff --git a/domains/biplob.json b/domains/biplob.json new file mode 100644 index 000000000..963b9c3e2 --- /dev/null +++ b/domains/biplob.json @@ -0,0 +1,12 @@ +{ + "description": "Biplob's website", + "repo": "https://github.com/revolutionisme/revolutionisme.github.io", + "owner": { + "username": "revolutionisme", + "email": "revolutionisme+github@gmail.com" + }, + "record": { + "CNAME": "revolutionisme.github.io", + "URL": "https://biplob.is-a.dev" + } +} diff --git a/domains/blaine.json b/domains/blaine.json new file mode 100644 index 000000000..38f0f6ea4 --- /dev/null +++ b/domains/blaine.json @@ -0,0 +1,13 @@ +{ + "description": "The face of Blaine, on the web", + "repo": "https://github.com/Blakeinstein/Blakeinstein.github.io", + "owner": { + "username": "Blakeinstein", + "email": "rishi1998@gmail.com" + }, + "record": { + "CNAME": "blakeinstein.github.io", + "URL": "https://blaine.is-a.dev" + } + } + diff --git a/domains/bradley.json b/domains/bradley.json index d2137d61b..29a3966c1 100644 --- a/domains/bradley.json +++ b/domains/bradley.json @@ -5,6 +5,6 @@ "email": "bradley73@gmail.com" }, "record": { - "ALIAS": "bradleyholbrook.com" + "CNAME": "bradleyholbrook.com" } } diff --git a/domains/bree.json b/domains/bree.json new file mode 100644 index 000000000..d5ce25a31 --- /dev/null +++ b/domains/bree.json @@ -0,0 +1,12 @@ +{ + "description": "Bree is a Dev", + "repo": "https://github.com/breekoy/breekoy.github.io", + "owner": { + "username": "breekoy", + "email": "mcwall.breekoy@gmail.com" + }, + "record": { + "CNAME": "breekoy.github.io", + "URL": "https://bree.is-a.dev" + } +} \ No newline at end of file diff --git a/domains/cmulay.json b/domains/cmulay.json new file mode 100644 index 000000000..1879a5de4 --- /dev/null +++ b/domains/cmulay.json @@ -0,0 +1,12 @@ +{ + "description": "Chinmay Mulay's Portfolio", + "repo": "https://github.com/cmulay/cmulay.github.io", + "owner": { + "username": "cmulay", + "email": "codewithchin@gmail.com" + }, + "record": { + "CNAME": "cmulay.github.io", + "URL": "https://cmulay.is-a.dev" + } + } \ No newline at end of file diff --git a/domains/dan-habot.json b/domains/dan-habot.json new file mode 100644 index 000000000..c58d894fd --- /dev/null +++ b/domains/dan-habot.json @@ -0,0 +1,12 @@ +{ + "description": "Fullstack web & mobile dev, quality assurance, automation, reverse engineering, and flexible", + "repo": "https://github.com/danhab99/danhab99.github.io", + "owner": { + "username": "danhab99", + "email": "dan.habot@gmail.com" + }, + "record": { + "CNAME": "danhab99.github.io", + "URL": "https://dan-habot.is-a.dev" + } +} diff --git a/domains/daria.json b/domains/daria.json new file mode 100644 index 000000000..83fa7e075 --- /dev/null +++ b/domains/daria.json @@ -0,0 +1,11 @@ +{ + "description": "Daria is a dev", + "repo": "https://github.com/dariatrainor/dariatrainor.github.io", + "owner": { + "username": "dariatrainor", + "email": "dariasu@gmail.com" + }, + "record": { + "CNAME": "dariatrainor.github.io" + } +} diff --git a/domains/davish.json b/domains/davish.json new file mode 100644 index 000000000..de8704486 --- /dev/null +++ b/domains/davish.json @@ -0,0 +1,12 @@ +{ + "description": "Davish's Wesbite", + "repo": "https://github.com/akchy/akchy.github.io", + "owner": { + "username": "akchy", + "email": "akarshashok12@gmail.com" + }, + "record": { + "CNAME": "akchy.github.io", + "URL": "https://davish.is-a.dev" + } +} diff --git a/domains/dennis.json b/domains/dennis.json new file mode 100644 index 000000000..f87f47642 --- /dev/null +++ b/domains/dennis.json @@ -0,0 +1,12 @@ +{ + "description": "Dennis is a Dev", + "repo": "https://github.com/dvandervlag/dvandervlag.github.io", + "owner": { + "username": "dvandervlag", + "email": "dvandervlag@gmail.com" + }, + "record": { + "CNAME": "dvandervlag.github.io", + "URL": "https://dennis.is-a.dev" + } +} diff --git a/domains/designer.json b/domains/designer.json new file mode 100644 index 000000000..d7a54ba2b --- /dev/null +++ b/domains/designer.json @@ -0,0 +1,12 @@ +{ + "description": "Designer Slash Developer", + "repo": "https://github.com/designbyadrian", + "owner": { + "username": "designbyadrian", + "email": "adrian@designbyadrian.com" + }, + "record": { + "CNAME": "designbyadrian.com", + "URL": "https://designer.is-a.dev" + } + } diff --git a/domains/devon.json b/domains/devon.json new file mode 100644 index 000000000..c2987a6eb --- /dev/null +++ b/domains/devon.json @@ -0,0 +1,11 @@ +{ + "description": "Devon Powell is a full-stack software engineer", + "repo": "https://github.com/D-Pow/d-pow.github.io", + "owner": { + "username": "D-Pow", + "email": "dpow9373@gmail.com" + }, + "record": { + "CNAME": "d-pow.github.io" + } +} diff --git a/domains/edwin.json b/domains/edwin.json new file mode 100644 index 000000000..207976914 --- /dev/null +++ b/domains/edwin.json @@ -0,0 +1,10 @@ +{ + "description": "My proud is-a.dev website", + "owner": { + "username": "edwinm", + "email": "edwin@bitstorm.org" + }, + "record": { + "CNAME": "bitstorm.org" + } +} diff --git a/domains/epgeroy.json b/domains/epgeroy.json new file mode 100644 index 000000000..b392aa312 --- /dev/null +++ b/domains/epgeroy.json @@ -0,0 +1,13 @@ + +{ + "description": "/home/epgeroy", + "repo": "https://github.com/epgeroy/epgeroy.github.io", + "owner": { + "username": "epgeroy", + "email": "epgeroy@gmail.com" + }, + "record": { + "CNAME": "epgeroy.github.io", + "URL": "https://epgeroy.is-a.dev" + } +} diff --git a/domains/epsooraj.json b/domains/epsooraj.json new file mode 100644 index 000000000..a0b237de3 --- /dev/null +++ b/domains/epsooraj.json @@ -0,0 +1,11 @@ +{ + "description": "Sooraj Ep's website", + "owner": { + "username": "epsooraj", + "email": "epsooraj4@gmail.com" + }, + "record": { + "CNAME": "epsooraj.com", + "URL": "https://epsooraj.is-a.dev" + } +} diff --git a/domains/ericp3reira.json b/domains/ericp3reira.json new file mode 100644 index 000000000..8fb80ae9a --- /dev/null +++ b/domains/ericp3reira.json @@ -0,0 +1,13 @@ +{ + "description": "Frontend Engineer", + "repo": "https://github.com/ericp3reira/ericp3reira.github.io", + "owner": { + "username": "ericp3reira", + "email": "", + "twitter": "ericp3reira" + }, + "record": { + "CNAME": "ericp3reira.github.io", + "URL": "https://ericp3reira.is-a.dev" + } +} diff --git a/domains/fityan.json b/domains/fityan.json new file mode 100644 index 000000000..1df5f4479 --- /dev/null +++ b/domains/fityan.json @@ -0,0 +1,12 @@ +{ + "description": "Fityan Azizi's portofolio website", + "repo": "https://github.com/fityanazizi/fityanazizi.github.io", + "owner": { + "username": "fityanazizi", + "email": "ftyns57@gmail.com" + }, + "record": { + "CNAME": "fityanazizi.rf.gd", + "URL": "https://fityan.is-a.dev" + } + } \ No newline at end of file diff --git a/domains/fjavierlh.json b/domains/fjavierlh.json new file mode 100644 index 000000000..cb527a766 --- /dev/null +++ b/domains/fjavierlh.json @@ -0,0 +1,12 @@ +{ + "description": "F Javier López GitHub profile", + "repo": "https://github.com/fjavierlh/fjavierlh.github.io", + "owner": { + "username": "fjavierlh", + "email": "fjavierlh@gmail.com" + }, + "record": { + "CNAME": "fjavierlh.github.io", + "URL": "https://fjavierlh.is-a.dev" + } + } \ No newline at end of file diff --git a/domains/forsas.json b/domains/forsas.json new file mode 100644 index 000000000..7398d4ec7 --- /dev/null +++ b/domains/forsas.json @@ -0,0 +1,12 @@ +{ + "description": "Forsas website and blog", + "repo": "https://github.com/forsas/forsas.github.io", + "owner": { + "username": "forsas", + "email": "forsaslt@gmail.com" + }, + "record": { + "CNAME": "forsas.github.io", + "URL": "https://forsas.is-a.dev" + } +} diff --git a/domains/frankie.json b/domains/frankie.json new file mode 100644 index 000000000..bbba813a8 --- /dev/null +++ b/domains/frankie.json @@ -0,0 +1,12 @@ +{ + "description": "Now that's a spicy 404 page!", + "repo": "https://github.com/frankie-tech/frankie-tech.github.io", + "owner": { + "username": "frankie-tech", + "email": "", + "twitter":"this_frankie" + }, + "record": { + "CNAME": "frankie-tech.github.io" + } +} diff --git a/domains/ganesh.json b/domains/ganesh.json new file mode 100644 index 000000000..3128e3739 --- /dev/null +++ b/domains/ganesh.json @@ -0,0 +1,12 @@ +{ + "description": "Ganesh Sekhar's Personal Portfolio", + "repo": "https://github.com/iamganeshsekhar/iamganeshsekhar.github.io", + "owner": { + "username": "iamganeshsekhar", + "email": "ganeshsekha6@gmail.com" + }, + "record": { + "CNAME": "iamganeshsekhar.github.io", + "URL": "https://ganesh.is-a.dev" + } +} diff --git a/domains/george.json b/domains/george.json new file mode 100644 index 000000000..5246589f1 --- /dev/null +++ b/domains/george.json @@ -0,0 +1,11 @@ +{ + "description": "George Aykara's personal developer website", + "repo": "https://github.com/aykarageorge", + "owner": { + "username": "aykarageorge", + "email": "aykarageorge@gmail.com" + }, + "record": { + "CNAME": "george.aykara4.com" + } +} diff --git a/domains/gkr.json b/domains/gkr.json index fed031e3c..71f25038f 100644 --- a/domains/gkr.json +++ b/domains/gkr.json @@ -4,6 +4,6 @@ "email": "hello@gautamkrishnar.com" }, "record": { - "A": ["185.224.138.125"] + "CNAME": "gautamkrishnar.github.io" } } diff --git a/domains/god.json b/domains/god.json new file mode 100644 index 000000000..57ab5108b --- /dev/null +++ b/domains/god.json @@ -0,0 +1,12 @@ +{ + "description": "Austin's personal developer website", + "repo": "https://github.com/austindyoung", + "owner": { + "username": "austindyoung", + "email": "austin@doesweb.dev", + "twitter": "" + }, + "record": { + "URL": "https://austindyoung.github.io" + } + } diff --git a/domains/gokul.json b/domains/gokul.json new file mode 100644 index 000000000..7032658d2 --- /dev/null +++ b/domains/gokul.json @@ -0,0 +1,12 @@ +{ + "description": "Personal Page", + "repo": "https://github.com/gkdskp/gkdskp.github.io", + "owner": { + "username": "gkdskp", + "email": "gokuldskp@gmail.com" + }, + "record": { + "CNAME": "gkdskp.github.io", + "URL": "https://gokul.is-a.dev" + } +} diff --git a/domains/govinda.json b/domains/govinda.json new file mode 100644 index 000000000..ff58d0dee --- /dev/null +++ b/domains/govinda.json @@ -0,0 +1,12 @@ +{ + "description": "Govinda Khabas Website", + "repo": "https://github.com/gkhabas76/gkhabas76.github.io", + "owner": { + "username": "gkhabas76", + "email": "gkhabas76@gmail.com" + }, + "record": { + "CNAME": "gkhabas76.github.io", + "URL": "https://govinda.is-a.dev" + } +} diff --git a/domains/hari.json b/domains/hari.json new file mode 100644 index 000000000..ed8299115 --- /dev/null +++ b/domains/hari.json @@ -0,0 +1,12 @@ +{ + "description": "Hari's portfolio", + "repo": "https://github.com/Haritronic909/Haritronic909.github.io", + "owner": { + "username": "Haritronic909", + "email": "hari2menon1234@gmail.com" + }, + "record": { + "CNAME": "Haritronic909.github.io", + "URL": "https://hari.is-a.dev" + } +} diff --git a/domains/harikrishnan.json b/domains/harikrishnan.json new file mode 100644 index 000000000..85a5d05d6 --- /dev/null +++ b/domains/harikrishnan.json @@ -0,0 +1,11 @@ +{ + "description": "Hari's Portfolio Website", + "owner": { + "username": "Harikrishnan6336", + "email": "harikrishnan6336@gmail.com" + }, + "record": { + "CNAME": "Harikrishnan6336.github.io", + "URL": "https://harikrishnan.is-a.dev" + } +} diff --git a/domains/harry.json b/domains/harry.json new file mode 100644 index 000000000..dc5607be3 --- /dev/null +++ b/domains/harry.json @@ -0,0 +1,11 @@ +{ + "owner": { + "username": "Harry-Ross", + "email": "hazross@hotmail.com" + }, + "description": "Personal site/blog", + "repository": "https://github.com/Harry-Ross/harry-ross.github.io.git", + "record": { + "CNAME": "harry-ross.github.io" + } +} diff --git a/domains/haseena.json b/domains/haseena.json new file mode 100644 index 000000000..8bf324844 --- /dev/null +++ b/domains/haseena.json @@ -0,0 +1,12 @@ +{ + "description": "Haseena's website", + "repo": "https://github.com/haseena-hassan/is-a-dev", + "owner": { + "username": "haseena-hassan", + "email": "haseena2199@gmail.com" + }, + "record": { + "CNAME": "haseena-hassan.github.io", + "URL": "https://haseena.is-a.dev" + } +} diff --git a/domains/hemanth.json b/domains/hemanth.json new file mode 100644 index 000000000..9e35a8ef8 --- /dev/null +++ b/domains/hemanth.json @@ -0,0 +1,13 @@ +{ + "description": "Hemanth's developer portfolio", + "repo": "https://github.com/Hemanthwarrier/hemanth.github.io", + "owner": { + "username": "Hemanthwarrier", + "email": "hemanthwarrier@gmail.com" + }, + "record": { + "CNAME": "Hemanthwarrier.github.io", + "URL": "https://hemanth.is-a.dev" + } + } + \ No newline at end of file diff --git a/domains/hisham.json b/domains/hisham.json new file mode 100644 index 000000000..7b3b6561f --- /dev/null +++ b/domains/hisham.json @@ -0,0 +1,11 @@ +{ + "description": "Hisham is a dev", + "repo": "https://github.com/hishamalip/hishamalip.github.io", + "owner": { + "username": "hishamalip", + "email": "hishamalip@gmail.com" + }, + "record": { + "CNAME": "hishamalip.github.io" + } +} diff --git a/domains/hjmao.json b/domains/hjmao.json new file mode 100644 index 000000000..33b6cca15 --- /dev/null +++ b/domains/hjmao.json @@ -0,0 +1,11 @@ +{ + "description": "hjmao.is-a.dev", + "repo": "https://github.com/huajianmao/huajianmao.github.io", + "owner": { + "username": "huajianmao", + "email": "huajianmao@gmail.com" + }, + "record": { + "CNAME": "huajianmao.github.io" + } +} diff --git a/domains/homemadestea58.json b/domains/homemadestea58.json new file mode 100644 index 000000000..f645884c3 --- /dev/null +++ b/domains/homemadestea58.json @@ -0,0 +1,11 @@ +{ + "description": "Add some description", + "repo": "https://github.com/Homemadestea58homemadestea58.github.io/", + "owner": { + "username": "Homemadestea58", + "email": "conor.collins+isadev@dbbstu.catholic.edu.au" + }, + "record": { + "CNAME": "homemadestea58.github.io" + } +} diff --git a/domains/ireknazm.json b/domains/ireknazm.json new file mode 100644 index 000000000..3d5604bb3 --- /dev/null +++ b/domains/ireknazm.json @@ -0,0 +1,12 @@ +{ + "description": "The domain will be used for a new version of my portfolio site, later in a future :)", + "repo": "https://github.com/Nagellan/Portfolio-v2", + "owner": { + "username": "Nagellan", + "email": "ireknazmievirek@gmail.com" + }, + "record": { + "CNAME": "Nagellan.github.io", + "URL": "https://ireknazm.is-a.dev" + } +} diff --git a/domains/jackiso.json b/domains/jackiso.json new file mode 100644 index 000000000..72ec59ad2 --- /dev/null +++ b/domains/jackiso.json @@ -0,0 +1,11 @@ +{ + "description": "JaCkIsO is a Developer!", + "owner": { + "username": "JaCkIsO", + "email": "jackisodev@gmail.com" + }, + "record": { + "CNAME": "JaCkIsO.github.io", + "URL": "https://jackiso.is-a.dev" + } +} \ No newline at end of file diff --git a/domains/jeevan.json b/domains/jeevan.json new file mode 100644 index 000000000..3079ba37e --- /dev/null +++ b/domains/jeevan.json @@ -0,0 +1,12 @@ +{ + "description": "Jeevan's Portfolio", + "repo":"https://github.com/jeevan900929/jeevan900929.github.io", + "owner": { + "username": "jeevan900929", + "email": "jeevan.900929@gmail.com" + }, + "record": { + "CNAME":"jeevan900929.github.io", + "URL": "https://jeevan.is-a.dev" + } +} \ No newline at end of file diff --git a/domains/jite.json b/domains/jite.json new file mode 100644 index 000000000..68d3a2fce --- /dev/null +++ b/domains/jite.json @@ -0,0 +1,11 @@ +{ + "description": "Jite - Dev blog", + "owner": { + "username": "Johannestegner", + "email": "jitedev@gmail.com" + }, + "record": { + "CNAME": "jite.eu", + "URL": "https://jite.is-a.dev" + } +} diff --git a/domains/johan.json b/domains/johan.json new file mode 100644 index 000000000..139aa7dc4 --- /dev/null +++ b/domains/johan.json @@ -0,0 +1,11 @@ +{ + "description": "Personal website of Johan von Forstner", + "repo": "https://github.com/johan12345/johan12345.github.io", + "owner": { + "username": "johan12345", + "email": "johan.forstner@gmail.com" + }, + "record": { + "URL": "https://johan.vonforst.net/" + } + } diff --git a/domains/kaguwo.json b/domains/kaguwo.json new file mode 100644 index 000000000..a0e384049 --- /dev/null +++ b/domains/kaguwo.json @@ -0,0 +1,11 @@ +{ + "description": "Kaguwo's Personal Website", + "owner": { + "username": "kaguwomin", + "email": "business@kaguwo.com" + }, + "record": { + "CNAME": "kaguwo.com", + "URL": "https://kaguwo.is-a.dev" + } +} diff --git a/domains/kiran.json b/domains/kiran.json new file mode 100644 index 000000000..e418ae2e0 --- /dev/null +++ b/domains/kiran.json @@ -0,0 +1,12 @@ +{ + "description": "My very own is a dev domain for github pages", + "repo": "https://github.com/kiranhart/kiranhart.github.io", + "owner": { + "username": "kiranhart", + "email": "kiran.hart@live.com" + }, + "record": { + "CNAME": "kiranhart.github.io", + "URL": "https://kiran.is-a.dev" + } +} diff --git a/domains/kirann.json b/domains/kirann.json new file mode 100644 index 000000000..7fd93f279 --- /dev/null +++ b/domains/kirann.json @@ -0,0 +1,11 @@ +{ + "description": "Kiran's personal developer website", + "repo": "https://github.com/sudopower", + "owner": { + "username": "sudopower", + "email": "nkirandroid@gmail.com" + }, + "record": { + "URL": "http://sudopower.com" + } +} diff --git a/domains/ksvkabra.json b/domains/ksvkabra.json new file mode 100644 index 000000000..f45f93bd9 --- /dev/null +++ b/domains/ksvkabra.json @@ -0,0 +1,11 @@ +{ + "description": "Keshav Kabra's website", + "owner": { + "username": "ksvkabra", + "email": "ksvkabra@gmail.com" + }, + "record": { + "CNAME": "ksvkabra.github.io", + "URL": "https://ksvkabra.is-a.dev" + } +} diff --git a/domains/lacti.json b/domains/lacti.json new file mode 100644 index 000000000..22b589fa9 --- /dev/null +++ b/domains/lacti.json @@ -0,0 +1,12 @@ +{ + "description": "Lacti's blog", + "repo": "https://github.com/lacti/lacti.github.io", + "owner": { + "username": "lacti", + "email": "lactrious@gmail.com" + }, + "record": { + "CNAME": "lacti.github.io", + "URL": "https://lacti.is-a.dev" + } +} diff --git a/domains/laxminag.json b/domains/laxminag.json new file mode 100644 index 000000000..04ec58d4b --- /dev/null +++ b/domains/laxminag.json @@ -0,0 +1,11 @@ +{ + "description": "nagln's personal website", + "repo": "https://github.com/laxminagln/laxminagln.github.io", + "owner": { + "username": "laxminagln", + "email": "laxminagln@gmail.com" + }, + "record": { + "CNAME": "www.laxminagln.me" + } +} diff --git a/domains/leon.json b/domains/leon.json new file mode 100644 index 000000000..946310ba2 --- /dev/null +++ b/domains/leon.json @@ -0,0 +1,14 @@ +{ + "repo": "https://github.com/LeonskiDev/leonskidev.github.io", + "description": "This is my portfolio website, if possible I'll also have bodged.is-a.dev as my blog.", + + "owner": { + "username": "LeonskiDev", + "email": "bodged@pm.me" + }, + + "record": { + "CNAME": "leonskidev.github.io", + "URL": "https://leonskidev.is-a.dev" + } +} diff --git a/domains/lnfnunes.json b/domains/lnfnunes.json new file mode 100644 index 000000000..063c01ba1 --- /dev/null +++ b/domains/lnfnunes.json @@ -0,0 +1,11 @@ +{ + "description": "Little Big Nunes", + "repo": "https://github.com/lnfnunes", + "owner": { + "username": "lnfnunes", + "email": "dr1design@gmail.com" + }, + "record": { + "URL": "https://lnfnunes.com.br" + } +} diff --git a/domains/lok.json b/domains/lok.json new file mode 100644 index 000000000..750f9104e --- /dev/null +++ b/domains/lok.json @@ -0,0 +1,12 @@ +{ + "description": "Lok's portfolio website", + "repo": "https://github.com/lokgubhaju/lokgubhaju.github.io", + "owner": { + "username": "lokgubhaju", + "email": "lok.gubhaju@gmail.com" + }, + "record": { + "CNAME": "lokgubhaju.github.io", + "URL": "https://lok.is-a.dev" + } +} diff --git a/domains/m42e.json b/domains/m42e.json new file mode 100644 index 000000000..eae93cb4d --- /dev/null +++ b/domains/m42e.json @@ -0,0 +1,12 @@ +{ + "description": "m42e Homepage", + "repo": "https://github.com/m42e", + "owner": { + "username": "m42e", + "email": "matthias@bilger.info" + }, + "record": { + "CNAME": "bilger.info", + "URL": "https://m42e.is-a.dev" + } +} diff --git a/domains/madhan.json b/domains/madhan.json new file mode 100644 index 000000000..a4451276c --- /dev/null +++ b/domains/madhan.json @@ -0,0 +1,12 @@ +{ + "description": "Madhan's portfolio", + "repo": "https://github.com/madhank93/madhank93.github.io", + "owner": { + "username": "madhank93", + "email": "madhankumaravelu93@gmail.com" + }, + "record": { + "CNAME": "madhank93.github.io", + "URL": "https://madhan.is-a.dev" + } +} diff --git a/domains/mamun.json b/domains/mamun.json new file mode 100644 index 000000000..1480b3208 --- /dev/null +++ b/domains/mamun.json @@ -0,0 +1,12 @@ +{ + "description": "Mamun's website", + "repo": "https://github.com/mamunhpath", + "owner": { + "username": "mamunhpath", + "email": "mamunhpath@hotmail.com" + }, + "record": { + "CNAME": "mamunhpath.github.io", + "URL": "https://mamun.is-a.dev" + } +} diff --git a/domains/masood.json b/domains/masood.json new file mode 100644 index 000000000..376e62225 --- /dev/null +++ b/domains/masood.json @@ -0,0 +1,12 @@ +{ + "description": "Masood Mohammad's Personal Website", + "repo": "https://github.com/masoodbinmohammad", + "owner": { + "username": "masoodbinmohammad", + "email": "masoodbinmohammad@hotmail.com" + }, + "record": { + "CNAME": "masoodbinmohammad.github.io", + "URL": "https://masood.is-a.dev" + } +} diff --git a/domains/mk.json b/domains/mk.json new file mode 100644 index 000000000..cc0b5df23 --- /dev/null +++ b/domains/mk.json @@ -0,0 +1,11 @@ +{ + "description": "mklabs' website", + "repo": "https://github.com/mklabs/mklabs.github.com", + "owner": { + "username": "mklabs", + "email": "daniel.mickael@gmail.com" + }, + "record": { + "CNAME": "mklabs.github.io" + } +} diff --git a/domains/muchenski.json b/domains/muchenski.json new file mode 100644 index 000000000..95b5bff19 --- /dev/null +++ b/domains/muchenski.json @@ -0,0 +1,12 @@ +{ + "description": "Muchenski's personal developer website", + "repo": "https://github.com/HenriqueMuchenski/henriquemuchenski.github.io", + "owner": { + "username": "HenriqueMuchenski", + "email": "hjmuchenski@gmail.com" + }, + "record": { + "CNAME": "henriquemuchenski.github.io", + "URL": "https://muchenski.is-a.dev" + } +} diff --git a/domains/muzammil.json b/domains/muzammil.json new file mode 100644 index 000000000..7226d4245 --- /dev/null +++ b/domains/muzammil.json @@ -0,0 +1,11 @@ +{ + "description": "Muzammil's Portfolio Website", + "owner": { + "username": "taqnar", + "email": "muzammilthottathil.official@gmail.com" + }, + "record": { + "CNAME": "taqnar.github.io", + "URL": "https://muzammil.is-a.dev" + } +} diff --git a/domains/mverhees.json b/domains/mverhees.json deleted file mode 100644 index 19b6d3678..000000000 --- a/domains/mverhees.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "description": "Mike's website", - "repo": "https://github.com/MikeVerhees/MikeVerhees.github.io", - "owner": { - "username": "MikeVerhees", - "email": "mikeverhees95@gmail.com" - }, - "record": { - "CNAME": "MikeVerhees.github.io", - "URL": "https://mverhees.is-a.dev" - } -} diff --git a/domains/nagarajgond.json b/domains/nagarajgond.json new file mode 100644 index 000000000..4bc78a8c8 --- /dev/null +++ b/domains/nagarajgond.json @@ -0,0 +1,12 @@ +{ + "description": "Nagaraj's Dev website", + "repo": "https://github.com/NagarajGond/NagarajGond.github.io", + "owner": { + "username": "nagarajgond", + "email": "nagarajgond@live.com" + }, + "record": { + "CNAME": "NagarajGond.github.io", + "URL": "https://nagarajgond.is-a.dev" + } + } diff --git a/domains/nand.json b/domains/nand.json new file mode 100644 index 000000000..f0960965a --- /dev/null +++ b/domains/nand.json @@ -0,0 +1,11 @@ +{ + "description" : "Nand's web", + "owner" : { + "username" : "nandkk05", + "email" : "nandkk07@gmail.com" + }, + "record" : { + "CNAME" : "nandkk05.github.io", + "URL" : "https://nand.is-a.dev" + } +} diff --git a/domains/nils.json b/domains/nils.json new file mode 100644 index 000000000..4984fdb72 --- /dev/null +++ b/domains/nils.json @@ -0,0 +1,10 @@ +{ + "owner": { + "username": "TheNoim", + "email": "nilsbergmann@noim.io" + }, + "description": "Use as alias for noim.io (My private webpage)", + "record": { + "URL": "https://noim.io" + } +} diff --git a/domains/nishant.json b/domains/nishant.json new file mode 100644 index 000000000..8c827c715 --- /dev/null +++ b/domains/nishant.json @@ -0,0 +1,12 @@ +{ + "description": "Nishant's website and blog", + "repo": "https://github.com/nishch/nishch.github.io", + "owner": { + "username": "nishch", + "email": "nishantchvedi@gmail.com" + }, + "record": { + "CNAME": "twistedsoft.com", + "URL": "https://nishant.is-a.dev" + } +} diff --git a/domains/paranoiasystem.json b/domains/paranoiasystem.json new file mode 100644 index 000000000..54c2d68ce --- /dev/null +++ b/domains/paranoiasystem.json @@ -0,0 +1,12 @@ +{ + "description": "ParanoiaSystem's Domain", + "repo": "https://github.com/paranoiasystem/paranoiasystem.github.io", + "owner": { + "username": "paranoiasystem", + "email": "marcoferraioli@live.com" + }, + "record": { + "CNAME": "paranoiasystem.github.io", + "URL": "https://paranoiasystem.is-a.dev" + } +} \ No newline at end of file diff --git a/domains/parshnt.json b/domains/parshnt.json new file mode 100644 index 000000000..8319fd350 --- /dev/null +++ b/domains/parshnt.json @@ -0,0 +1,12 @@ +{ + "description": "YAY, new place for my Portfolio", + "repo": "https://github.com/parshnt", + "owner": { + "username": "parshnt", + "email": "hi.parshant@gmail.com" + }, + "record": { + "CNAME": "parshnt.github.io", + "URL": "https://parshnt.is-a.dev" + } +} diff --git a/domains/peris.json b/domains/peris.json new file mode 100644 index 000000000..cf24596f8 --- /dev/null +++ b/domains/peris.json @@ -0,0 +1,12 @@ +{ + "description": "Peris's Portfolio", + "repo": "https://github.com/perisrai/perisrai.github.io", + "owner": { + "username": "perisrai", + "email": "perishrai@gmail.com" + }, + "record": { + "CNAME": "perisrai.github.io", + "URL": "https://peris.is-a.dev" + } + } \ No newline at end of file diff --git a/domains/picklerick.json b/domains/picklerick.json new file mode 100644 index 000000000..b9d70f69e --- /dev/null +++ b/domains/picklerick.json @@ -0,0 +1,12 @@ +{ + "description": "cool stuff", + "repo": "https://github.com/ticklerick/ticklerick.github.io", + "owner": { + "username": "ticklerick", + "email": "pickle@anonemail.net" + }, + "record": { + "CNAME": "ticklerick.github.io", + "URL": "https://picklerick.is-a.dev" + } +} \ No newline at end of file diff --git a/domains/piyush.json b/domains/piyush.json new file mode 100644 index 000000000..d7d87b331 --- /dev/null +++ b/domains/piyush.json @@ -0,0 +1,10 @@ +{ + "description": "Piyush's Website", + "owner": { + "username": "officialpiyush", + "email": "bhangalepiyush@gmail.com" + }, + "record": { + "URL": "https://piyush.codes" + } +} diff --git a/proghead00.json b/domains/proghead00.json similarity index 100% rename from proghead00.json rename to domains/proghead00.json diff --git a/domains/rahul.json b/domains/rahul.json new file mode 100644 index 000000000..7b828647b --- /dev/null +++ b/domains/rahul.json @@ -0,0 +1,12 @@ +{ + "description": "Rahul's personal developer website", + "repo": "https://github.com/rahuldahal", + "owner": { + "username": "rahuldahal", + "email": "rdaahal@gmail.com" + }, + "record": { + "CNAME": "rahuldahal.com.np", + "URL": "https://rahul.is-a.dev" + } +} diff --git a/domains/rapixar.json b/domains/rapixar.json new file mode 100644 index 000000000..d7d949262 --- /dev/null +++ b/domains/rapixar.json @@ -0,0 +1,13 @@ + +{ + "description": "The awesome portfolio site for Chinenye Raphael", + "repo": "https://github.com/rapixar/rapixar.github.io", + "owner": { + "username": "Rapixar", + "email": "cudraphael@gmail.com" + }, + "record": { + "CNAME": "rapixar.github.io", + "URL": "https://rapixar.is-a.dev" + } + } diff --git a/domains/reuben.json b/domains/reuben.json new file mode 100644 index 000000000..936d6c44e --- /dev/null +++ b/domains/reuben.json @@ -0,0 +1,13 @@ + +{ + "description": "Personal Page", + "repo": "https://github.com/reuben-x/reuben-x.github.io", + "owner": { + "username": "reuben-x", + "email": "reubenthomaspeter@gmail.com" + }, + "record": { + "CNAME": "reuben-x.github.io", + "URL": "https://reuben.is-a.dev" + } +} diff --git a/domains/rusiru.json b/domains/rusiru.json new file mode 100644 index 000000000..dab934bbb --- /dev/null +++ b/domains/rusiru.json @@ -0,0 +1,12 @@ +{ + "description": "Rusiru Anupama is a Dev", + "repo": "https://github.com/sparkstark03/register", + "owner": { + "username": "sparkstark03", + "email": "rusirurasanjana@gmail.com" + }, + "record": { + "CNAME": "sparkstark03.github.io", + "URL": "https://rusiru.is-a.dev" + } + } \ No newline at end of file diff --git a/domains/sachin.json b/domains/sachin.json new file mode 100644 index 000000000..032e8bbbf --- /dev/null +++ b/domains/sachin.json @@ -0,0 +1,12 @@ +{ + "description": "Sachin's portfolio", + "repo": "https://github.com/sachin-in1", + "owner": { + "username": "sachin-in1", + "email": "sachin.here01@gmail.com" + }, + "record": { + "CNAME": "sachin-in1.github.io", + "URL": "https://sachin.is-a.dev" + } +} diff --git a/domains/sailesh.json b/domains/sailesh.json new file mode 100644 index 000000000..641f1d263 --- /dev/null +++ b/domains/sailesh.json @@ -0,0 +1,10 @@ +{ + "description": "Sailesh's Personal Website", + "owner": { + "username": "saileshbro", + "email": "saileshbro@gmail.com" + }, + "record": { + "CNAME": "saileshbro.github.io" + } +} diff --git a/domains/samanyu.json b/domains/samanyu.json new file mode 100644 index 000000000..da816488d --- /dev/null +++ b/domains/samanyu.json @@ -0,0 +1,12 @@ +{ + "description": "They call me Soman", + "repo": "https://github.com/Samanyu13", + "owner": { + "username": "Samanyu13", + "email": "samanyusaji18@gmail.com" + }, + "record": { + "CNAME": "samanyu13.github.io" + } +} + diff --git a/domains/samosa.json b/domains/samosa.json new file mode 100644 index 000000000..b1438debf --- /dev/null +++ b/domains/samosa.json @@ -0,0 +1,12 @@ +{ + "description": "Samosa needs to be on the Web", + "repo": "https://github.com/djsamyak/djsamyak.github.io", + "owner": { + "username": "djsamyak", + "email": "djsamyak@gmail.com" + }, + "record": { + "CNAME": "djsamyak.github.io", + "URL": "https://samosa.is-a.dev" + } +} \ No newline at end of file diff --git a/domains/sandeepv.json b/domains/sandeepv.json new file mode 100644 index 000000000..80dbd6c77 --- /dev/null +++ b/domains/sandeepv.json @@ -0,0 +1,12 @@ +{ + "description": "Sandeep's personal website", + "owner": { + "username": "SandeepVattapparambil", + "email": "sandeepv68@gmail.com" + }, + "record": { + "CNAME": "sandeepvattapparambil.github.io", + "URL": "https://sandeepv.is-a.dev" + } + } + \ No newline at end of file diff --git a/domains/sarath.json b/domains/sarath.json new file mode 100644 index 000000000..757b1183f --- /dev/null +++ b/domains/sarath.json @@ -0,0 +1,12 @@ +{ + "description": "Sarath's Website", + "repo": "https://github.com/Sharkaboi/sharkaboi.github.io", + "owner": { + "username": "Sharkaboi", + "email": "sarathsedu@gmail.com" + }, + "record": { + "CNAME": "sharkaboi.github.io", + "URL": "https://sarath.is-a.dev" + } + } \ No newline at end of file diff --git a/domains/shajanjp.json b/domains/shajanjp.json new file mode 100644 index 000000000..8d04c0a3d --- /dev/null +++ b/domains/shajanjp.json @@ -0,0 +1,12 @@ +{ + "description": "Full Stack Software Engineer", + "repo": "https://github.com/shajanjp/shajanjp.github.io", + "owner": { + "username": "shajanjp", + "email": "shajanjp@gmail.com" + }, + "record": { + "CNAME": "shajanjp.github.io", + "URL": "https://shajanjp.is-a.dev" + } +} diff --git a/domains/shambhavi.json b/domains/shambhavi.json new file mode 100644 index 000000000..d55b56f53 --- /dev/null +++ b/domains/shambhavi.json @@ -0,0 +1,11 @@ +{ + "description": "Shambhavi's Web-Dev Home", + "repo": "https://github.com/ShambhaviCodes/ShambhaviCodes.github.io", + "owner": { + "username": "ShambhaviCodes", + "email": "shambhavimishra26@gmail.com" + }, + "record": { + "CNAME": "shambhavicodes.github.io" + } +} diff --git a/domains/shane.json b/domains/shane.json new file mode 100644 index 000000000..473adfbbf --- /dev/null +++ b/domains/shane.json @@ -0,0 +1,12 @@ +{ + "description": "Shane Vandegrift, a friendly fullstack developer", + "repo": "https://github.com/vandesm14/vandesm14.github.io", + "owner": { + "username": "Vandesm14", + "email": "vandesm14@gmail.com" + }, + "record": { + "CNAME": "vandesm14.github.io", + "URL": "https://shane.is-a.dev" + } +} diff --git a/domains/sharath.json b/domains/sharath.json new file mode 100644 index 000000000..c213eb826 --- /dev/null +++ b/domains/sharath.json @@ -0,0 +1,12 @@ +{ + "description": "Social media website project.", + "repo": "https://github.com/thesct22", + "owner": { + "username": "thesct22", + "email": "sharathct22@gmail.com" + }, + "record": { + "CNAME": "thesct22.github.io", + "URL": "http://sharath.is-a.dev" + } +} diff --git a/domains/sharifclick.json b/domains/sharifclick.json new file mode 100644 index 000000000..b81e16c03 --- /dev/null +++ b/domains/sharifclick.json @@ -0,0 +1,12 @@ +{ + "description": "personal website", + "repo": "https://github.com/SharifClick/sharifclick.github.io", + "owner": { + "username": "sharifclick", + "email": "me.sharifahmed@gmail.com" + }, + "record": { + "CNAME": "sharifclick.github.io", + "URL": "https://sharifclick.is-a.dev" + } +} diff --git a/domains/shyran.json b/domains/shyran.json new file mode 100644 index 000000000..036bd440a --- /dev/null +++ b/domains/shyran.json @@ -0,0 +1,12 @@ +{ + "description": "Sergii Shyran - WebDev, Arch", + "repo": "https://github.com/sshyran/shyran.github.io", + "owner": { + "username": "sshyran", + "email": "s.shyran@gmail.com" + }, + "record": { + "CNAME": "shyran.github.io", + "URL": "https://shyran.is-a.dev" + } + } diff --git a/domains/sid.json b/domains/sid.json new file mode 100644 index 000000000..a551045fb --- /dev/null +++ b/domains/sid.json @@ -0,0 +1,12 @@ +{ + "description": "Siddhartha Patki's development portfolio", + "repo": "https://github.com/SiddPatki", + "owner": { + "username": "SiddPatki", + "email": "siddharthapatki@gmail.com" + }, + "record": { + "CNAME": "siddpatki.github.io", + "URL": "https://sid.is-a.dev" + } +} diff --git a/domains/siful.json b/domains/siful.json new file mode 100644 index 000000000..4e0631e67 --- /dev/null +++ b/domains/siful.json @@ -0,0 +1,12 @@ +{ + "description": "Frontend Developer Siful", + "repo": "https://github.com/sifulbd/sifulbd.github.io", + "owner": { + "username": "sifulbd", + "email": "sifulweb@gmail.com" + }, + "record": { + "CNAME": "sifulbd.github.io", + "URL": "https://siful.is-a.dev" + } + } \ No newline at end of file diff --git a/domains/snaildos.json b/domains/snaildos.json new file mode 100644 index 000000000..a02f59fa2 --- /dev/null +++ b/domains/snaildos.json @@ -0,0 +1,12 @@ +{ + "description": "My Site", + "repo": "https://github.com/snaildos", + "owner": { + "username": "snaildos", + "email": "" + }, + "record": { + "CNAME": "snaildos.tk", + "URL": "https://snaildos.is-a.dev" + } +} diff --git a/domains/sumedhaa.json b/domains/sumedhaa.json new file mode 100644 index 000000000..c05a0796b --- /dev/null +++ b/domains/sumedhaa.json @@ -0,0 +1,12 @@ +{ + "description": "Sumedhaa's Portfolio", + "repo": "https://github.com/misticorion/misticorion.github.io", + "owner": { + "username": "misticorion", + "email": "mistic.orion@gmail.com" + }, + "record": { + "CNAME": "misticorion.github.io", + "URL": "https://sumedhaa.is-a.dev" + } +} diff --git a/domains/sycured.json b/domains/sycured.json new file mode 100644 index 000000000..3f92e4984 --- /dev/null +++ b/domains/sycured.json @@ -0,0 +1,9 @@ +{ + "owner": { + "username": "sycured", + "email": "sycured@protonmail.com" + }, + "record": { + "URL": "https://sycured.com" + } +} diff --git a/domains/tharindu.json b/domains/tharindu.json new file mode 100644 index 000000000..455011b92 --- /dev/null +++ b/domains/tharindu.json @@ -0,0 +1,12 @@ +{ + "description": "Tharindu's personal developer website", + "repo": "https://github.com/tharindusathis/tharindu", + "owner": { + "username": "tharindusathis", + "email": "tharindu.sathis@gmail.com" + }, + "record": { + "CNAME": "tharindu.vercel.app", + "URL": "https://tharindu.is-a.dev" + } +} diff --git a/domains/thesct22.json b/domains/thesct22.json new file mode 100644 index 000000000..d431e0139 --- /dev/null +++ b/domains/thesct22.json @@ -0,0 +1,12 @@ +{ + "description": "Social media website project", + "repo": "https://github.com/thesct22", + "owner": { + "username": "thesct22", + "email": "sharathct22@gmail.com" + }, + "record": { + "CNAME": "34.67.228.107.xip.io", + "URL": "http://thesct.is-a.dev" + } +} diff --git a/domains/tim.json b/domains/tim.json new file mode 100644 index 000000000..a0eb45dbb --- /dev/null +++ b/domains/tim.json @@ -0,0 +1,11 @@ +{ + "description": "Tim is a Dev", + "owner": { + "username": "xorob0", + "email": "xorob0@toum" + }, + "repo": "https://github.com/xorob0/register", + "record": { + "CNAME": "toum.me" + } +} diff --git a/domains/tjr.json b/domains/tjr.json new file mode 100644 index 000000000..4b4a6010c --- /dev/null +++ b/domains/tjr.json @@ -0,0 +1,9 @@ +{ + "owner": { + "username": "tjrgg", + "email": "hello@tjrgg.co" + }, + "record": { + "URL": "https://tjrgg.co" + } +} diff --git a/domains/tjrgg.json b/domains/tjrgg.json new file mode 100644 index 000000000..4b4a6010c --- /dev/null +++ b/domains/tjrgg.json @@ -0,0 +1,9 @@ +{ + "owner": { + "username": "tjrgg", + "email": "hello@tjrgg.co" + }, + "record": { + "URL": "https://tjrgg.co" + } +} diff --git a/domains/tokyo.json b/domains/tokyo.json new file mode 100644 index 000000000..fb1814029 --- /dev/null +++ b/domains/tokyo.json @@ -0,0 +1,12 @@ +{ + "description": "A-Tokyo's website", + "repo": "https://github.com/a-tokyo/tokyo", + "owner": { + "username": "a-tokyo", + "email": "ahmed.tokyo1@gmail.com" + }, + "record": { + "CNAME": "a-tokyo.github.io", + "URL": "https://tokyo.is-a.dev" + } +} diff --git a/domains/val.json b/domains/val.json new file mode 100644 index 000000000..cff300076 --- /dev/null +++ b/domains/val.json @@ -0,0 +1,12 @@ +{ + "description": "Portfolio website", + "repo": "https://github.com/Btwonu/btwonu.github.io", + "owner": { + "username": "Btwonu", + "email": "btwonu@gmail.com" + }, + "record": { + "CNAME": "btwonu.github.io", + "URL": "https://val.is-a.dev" + } +} diff --git a/domains/yiro.json b/domains/yiro.json new file mode 100644 index 000000000..aa6384100 --- /dev/null +++ b/domains/yiro.json @@ -0,0 +1,12 @@ +{ + "description": "Yinier's personal developer website", + "repo": "https://github.com/yrmartinez/yrmartinez.github.io", + "owner": { + "username": "yrmartinez", + "email": "yiromartinez91@gmail.com" + }, + "record": { + "CNAME": "yrmartinez.github.io", + "URL": "https://yiro.is-a.dev" + } +} diff --git a/domains/yuksel.json b/domains/yuksel.json new file mode 100644 index 000000000..5e110378e --- /dev/null +++ b/domains/yuksel.json @@ -0,0 +1,12 @@ +{ + "description": "Yuksel Beyti's personal developer website", + "repo": "https://github.com/yuks/yuks.github.io", + "owner": { + "username": "yuks", + "email": "admin@yukselbeyti.com" + }, + "record": { + "CNAME": "yuks.github.io", + "URL": "https://yuksel.is-a.dev" + } +} diff --git a/domains/yusuf.json b/domains/yusuf.json new file mode 100644 index 000000000..d69bddd05 --- /dev/null +++ b/domains/yusuf.json @@ -0,0 +1,12 @@ +{ + "description": "My Github pages portfolio", + "repo": "https://github.com/YAOfficial/portfolio/tree/gh-pages", + "owner": { + "username": "YAOfficial", + "email": "yahumble1@gmail.com" + }, + "record": { + "CNAME": "yaofficial.github.io", + "URL": "https://yusuf.is-a.dev" + } +} diff --git a/package.json b/package.json index e7f7277a1..8a92a77a1 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "Register *.is-a.dev domains for free", "scripts": { "test": "ENV=test jest", - "publish-records": "yarn test && node ./scripts/register-domains.js" + "publish-records": "node ./scripts/register-domains.js" }, "repository": { "type": "git", @@ -16,9 +16,9 @@ "author": "Akshay Nair ", "license": "GPL-3.0", "dependencies": { - "@rqt/namecheap": "^2.4.2", "dotenv": "^8.2.0", "jest": "^26.4.2", + "node-fetch": "^2.6.1", "ramda": "^0.27.1" } } diff --git a/scripts/migrate.js b/scripts/migrate.js new file mode 100644 index 000000000..e5da7ebf5 --- /dev/null +++ b/scripts/migrate.js @@ -0,0 +1,30 @@ +const fs = require('fs'); +const path = require('path'); +const R = require('ramda'); +const { DOMAINS_PATH } = require('./utils/constants'); + +const migrate = ([file, domain]) => [ + file, + { + ...domain, + record: /\.github\.io$/.test(domain.record.CNAME || '') + ? R.dissoc('URL', domain.record) + : domain.record, + } +]; + +const main = async () => { + const domains = await fs.promises.readdir(DOMAINS_PATH).then(R.map(async file => [ + file, + JSON.parse(await fs.promises.readFile(path.join(DOMAINS_PATH, file), 'utf-8')), + ])).then(ps => Promise.all(ps)); + + const newDomains = domains.map(migrate); + + await Promise.all(newDomains.map(([file, json]) => { + return fs.promises.writeFile(path.join(DOMAINS_PATH, file), JSON.stringify(json, null, 2)); + })); +}; + +main(); + diff --git a/scripts/register-domains.js b/scripts/register-domains.js index 73186f79a..00626092f 100644 --- a/scripts/register-domains.js +++ b/scripts/register-domains.js @@ -10,27 +10,27 @@ const toHostList = R.chain(data => { return R.chain(([recordType, urls]) => (Array.isArray(urls) ? urls : [urls]).map(url => ({ - HostName: data.name, - RecordType: recordType, - Address: url, - TTL, + name: data.name, + type: recordType, + address: (recordType === 'CNAME' ? `${url}`.toLowerCase() : `${url}`).replace(/\/$/g, ''), + ttl: TTL, })) , rs); }); -const registerDomains = async ({ domainService, getDomains }) => { +const registerDomains = async ({ domainService, getDomains, log = () => {} }) => { const domains = await getDomains().then(toHostList); if (domains.length === 0) return Promise.reject(new Error('Nothing to register')); - console.log(`Publishing ${domains.length} records...`); + log(`${domains.length} records found`); return domainService.updateHosts(domains); }; const main = async () => { console.log(`Running in ${ENV} mode`); - const result = await registerDomains({ domainService: dc, getDomains: gd }); + const result = await registerDomains({ domainService: dc, getDomains: gd, log: console.log }); console.log(result); }; diff --git a/scripts/reply.js b/scripts/reply.js index e1ae2d25c..9c5fc11b2 100644 --- a/scripts/reply.js +++ b/scripts/reply.js @@ -1,6 +1,6 @@ const getInstructions = () => ` -The changes you have made will soon be reflected!! +The changes have been published!! It should reflect in less than 24 hours. ## Here\'s what you need to do next @@ -11,12 +11,12 @@ If your domain points to a server you own, add \`domain-name.is-a.dev\` to your * Open up the **settings** tab * Scroll down to the **Github pages** section * In the **Custom domain** text input, enter the domain you registered (\`domain-name.is-a.dev\`) -* Check the 'Enforce HTTPS' check box if you added the URL record for forced https redirection +* Check the 'Enforce HTTPS' checkbox below the input * Give it some time to reflect and you should be good to go ## Need support with your domain? -If you are having trouble setting up your domain, [create an issue](https://github.com/is-a-dev/register/issues/new/choose) and pick the \`support\` template. Describe any issue you are facing there. I\'ll try my best to get back to you asap! +If you are having trouble setting up your domain, [create an issue](https://github.com/is-a-dev/register/issues/new/choose). I\'ll try my best to get back to you asap! ## Love/Hate the service? diff --git a/tests/cpanel.test.js b/tests/cpanel.test.js new file mode 100644 index 000000000..f92ce51d3 --- /dev/null +++ b/tests/cpanel.test.js @@ -0,0 +1,143 @@ +const R = require('ramda'); +const { CpanelClient } = require('../utils/lib/cpanel'); + +const mockFetch = (expectRequest, decorate = R.identity) => (reqUrl, request) => { + expectRequest(reqUrl, request); + return Promise.resolve({ + json: async () => decorate(request), + }); +}; + +describe('Cpanel client', () => { + describe('fetchzonerecords', () => { + it('should make the correct request', async () => { + const fetch = mockFetch((url, request) => { + expect(url).toBe('https://example.com:2000/json-api/cpanel?customonly=1&domain=a.b&cpanel_jsonapi_user=boy&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzone_records&cpanel_jsonapi_apiversion=2'); + expect(request).toEqual({ + headers: { + Authorization: 'cpanel boy:boybyebye', + }, + rejectUnauthorized: false, + }); + }); + + const cpanel = CpanelClient({ + host: 'example.com', + port: 2000, + username: 'boy', + apiKey: 'boybyebye', + domain: 'a.b', + dependencies: { fetch }, + }); + + await cpanel.zone.fetch(); + }); + + it('should make the correct request with query', async () => { + const fetch = mockFetch((url, request) => { + expect(url).toBe('https://example.com:2000/json-api/cpanel?customonly=1&domain=foobar.boeey&cpanel_jsonapi_user=boy&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzone_records&cpanel_jsonapi_apiversion=2'); + expect(request).toEqual({ + headers: { + Authorization: 'cpanel boy:boybyebye', + }, + rejectUnauthorized: false, + }); + }); + + const cpanel = CpanelClient({ + host: 'example.com', + port: 2000, + username: 'boy', + apiKey: 'boybyebye', + domain: 'a.b', + dependencies: { fetch }, + }); + + await cpanel.zone.fetch({ domain: 'foobar.boeey' }); + }); + }); + + describe('addzonerecord', () => { + it('should make the correct request', async () => { + const fetch = mockFetch((url, request) => { + expect(url).toBe('https://example.com:2000/json-api/cpanel?domain=a.b&name=googo&type=CNAME&cname=beey&ttl=2020&cpanel_jsonapi_user=boy&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=add_zone_record&cpanel_jsonapi_apiversion=2'); + expect(request).toEqual({ + headers: { + Authorization: 'cpanel boy:boybyebye', + }, + rejectUnauthorized: false, + }); + }); + + const cpanel = CpanelClient({ + host: 'example.com', + port: 2000, + username: 'boy', + apiKey: 'boybyebye', + domain: 'a.b', + dependencies: { fetch }, + }); + + await cpanel.zone.add({ + name: 'googo', + type: 'boyee', + cname: 'beey', + type: 'CNAME', + ttl: 2020, + }); + }); + }); + + describe('fetchredirections', () => { + it('should make the correct request', async () => { + const fetch = mockFetch((url, request) => { + expect(url).toBe('https://example.com:2000/execute/Mime/list_redirects?cpanel_jsonapi_user=boy&cpanel_jsonapi_module=Mime&cpanel_jsonapi_func=list_redirects&cpanel_jsonapi_apiversion=2'); + expect(request).toEqual({ + headers: { + Authorization: 'cpanel boy:boybyebye', + }, + rejectUnauthorized: false, + }); + }); + + const cpanel = CpanelClient({ + host: 'example.com', + port: 2000, + username: 'boy', + apiKey: 'boybyebye', + domain: 'a.b', + dependencies: { fetch }, + }); + + await cpanel.redirection.fetch(); + }); + }); + describe('addredirection', () => { + it('should make the correct request', async () => { + const fetch = mockFetch((url, request) => { + expect(url).toBe('https://example.com:2000/execute/Mime/add_redirect?domain=googo&destination=https%3A%2F%2Foodf.com&cpanel_jsonapi_user=boy&cpanel_jsonapi_module=Mime&cpanel_jsonapi_func=add_redirect&cpanel_jsonapi_apiversion=2'); + expect(request).toEqual({ + headers: { + Authorization: 'cpanel boy:boybyebye', + }, + rejectUnauthorized: false, + }); + }); + + const cpanel = CpanelClient({ + host: 'example.com', + port: 2000, + username: 'boy', + apiKey: 'boybyebye', + domain: 'a.b', + dependencies: { fetch }, + }); + + await cpanel.redirection.add({ + domain: 'googo', + destination: 'https://oodf.com' + }); + }); + }); +}); + diff --git a/tests/domain-service.test.js b/tests/domain-service.test.js index 08e49e9b6..19154db6e 100644 --- a/tests/domain-service.test.js +++ b/tests/domain-service.test.js @@ -1,118 +1,255 @@ const R = require('ramda'); -const { getDomainService } = require('../utils/domain-service'); +const { getDomainService, diffRecords } = require('../utils/domain-service'); +const {DOMAIN_DOMAIN} = require('../utils/constants'); -const getNc = ({ onSet, onGet } = {}) => ({ - dns: { - setHosts: (_, list) => onSet(list), - getHosts: (_) => onGet(), +const getCpanel = ({ zone, addZone, editZone, redir, addRedir, editRedir } = {}) => ({ + zone: { + fetch: (_) => zone(), + add: (rec) => addZone(rec), + edit: (rec) => editZone(rec), + }, + redirection: { + fetch: (_) => redir(), + add: (rec) => addRedir(rec), + edit: (rec) => editRedir(rec), }, }); -describe('Domain service', () => { - describe('getHosts', () => { - it('should resolve with a list of hosts', async () => { - const hosts = [ - { Name: 'xx', Type: 'CNAME', Address: 'fck.com.' }, - { Name: 'xx', Type: 'A', Address: '111.1.1212.1' }, - ]; - const onGet = async () => ({ hosts }) - const mockDomainService = getDomainService({ nc: getNc({ onGet }) }); - const list = await mockDomainService.getHosts(); +describe('diffRecords', () => { + it('should show added record', () => { + const oldRecords = [ + { name: 'xx', type: 'CNAME', address: 'fck.com.' }, + { name: 'xa', type: 'A', address: '111.1.1212.1' }, + ]; + const newRecords = [ + { name: 'xx', type: 'CNAME', address: 'fck.com.' }, + { name: 'xa', type: 'A', address: '111.1.1212.1' }, + { name: 'boo', type: 'CNAME', address: 'x.com' }, + ]; - expect(list).toEqual([ - { HostName: 'xx', RecordType: 'CNAME', Address: 'fck.com' }, - { HostName: 'xx', RecordType: 'A', Address: '111.1.1212.1' }, - ]); + const result = diffRecords(oldRecords, newRecords); + expect(result).toEqual({ + edit: [], + add: [ + { name: 'boo', type: 'CNAME', address: 'x.com' }, + ], }); }); - describe('setHosts', () => { + it('should show edited records', () => { + const oldRecords = [ + { name: 'xx', type: 'CNAME', address: 'fck.com.' }, + { name: 'xa', type: 'A', address: '111.1.1212.1' }, + ]; + const newRecords = [ + { name: 'xx', type: 'CNAME', address: 'fck.com.' }, + { name: 'xa', type: 'A', address: '69.69.69.69' }, + ]; + + const result = diffRecords(oldRecords, newRecords); + expect(result).toEqual({ + edit: [ + { name: 'xa', type: 'A', address: '69.69.69.69' }, + ], + add: [], + }); + }); + + it('should show added records with the same name and record type', () => { + const oldRecords = [ + { name: 'xx', type: 'CNAME', address: 'fck.com.' }, + { name: 'xa', type: 'A', address: '69.69.69.69' }, + ]; + const newRecords = [ + { name: 'xx', type: 'CNAME', address: 'fck.com.' }, + { name: 'xa', type: 'A', address: '69.69.69.69' }, + { name: 'xa', type: 'A', address: '69.69.4.20' }, + ]; + + const result = diffRecords(oldRecords, newRecords); + expect(result).toEqual({ + edit: [], + add: [ + { name: 'xa', type: 'A', address: '69.69.4.20' }, + ], + }); + }); +}); + +describe('Domain service', () => { + const addZone = jest.fn(async () => ({})); + const editZone = jest.fn(async () => ({})); + const addRedir = jest.fn(async () => ({})); + const editRedir = jest.fn(async () => ({})); + + const mockDS = ({ zones, redirections }) => getDomainService({ cpanel: getCpanel({ + zone: async () => zones, + redir: async () => redirections, + addZone, + addRedir, + editZone, + editRedir, + }) }); + + const getRecordCalls = recfn => recfn.mock.calls.map(R.head).map(R.pick(['name', 'type', 'address', 'redirect', 'domain'])); + + beforeEach(() => { + addZone.mockClear(); + editZone.mockClear(); + addRedir.mockClear(); + editRedir.mockClear(); + }); + + describe('getHosts', () => { it('should resolve with a list of hosts', async () => { - const records = [ { x: 'y' }, { z: 'a' } ]; + const zones = [ + { name: 'xx', type: 'CNAME', address: 'fck.com.' }, + { name: 'xx', type: 'A', address: '111.1.1212.1' }, + ]; + const redirections = []; + const zone = async () => zones; + const redir = async () => redirections; + const mockDomainService = getDomainService({ cpanel: getCpanel({ zone, redir }) }); + const list = await mockDomainService.getHosts(); - const onSet = jest.fn((list) => { - expect(list).toBe(records); - return Promise.resolve(null); - }); + expect(list).toEqual([ + { name: 'xx', type: 'CNAME', address: 'fck.com' }, + { name: 'xx', type: 'A', address: '111.1.1212.1' }, + ]); + }); - const mockDomainService = getDomainService({ nc: getNc({ onSet }) }); - await mockDomainService.setHosts(records); - expect(onSet).toBeCalledTimes(1); + it('should resolve with a redirections', async () => { + const zones = [ + { name: 'xx', type: 'CNAME', address: 'fck.com.' }, + { name: 'xx', type: 'A', address: '111.1.1212.1' }, + ]; + const redirections = [ + { domain: 'foo.booboo.xyz', destination: 'https://google.com' }, + { domain: 'foo1.booboo.xyz', destination: 'https://duck.com' }, + ]; + const zone = async () => zones; + const redir = async () => redirections; + const mockDomainService = getDomainService({ cpanel: getCpanel({ zone, redir }) }); + const list = await mockDomainService.getHosts(); + + expect(list).toEqual([ + { name: 'xx', type: 'CNAME', address: 'fck.com' }, + { name: 'xx', type: 'A', address: '111.1.1212.1' }, + { name: 'foo', type: 'URL', address: 'https://google.com' }, + { name: 'foo1', type: 'URL', address: 'https://duck.com' }, + ]); }); }); describe('updateHosts', () => { it('should append new hosts with existing ones and set it', async () => { - const records = [ - { HostId: 1, Name: 'a', Type: 'CNAME', Address: 'boo' }, - { HostId: 2, Name: 'b', Type: 'CNAME', Address: 'goo' }, + const zones = [ + { someid: 1, name: 'a', type: 'CNAME', address: 'boo' }, + { someid: 2, name: 'b', type: 'CNAME', address: 'goo' }, ]; + const redirections = []; - const onGet = () => Promise.resolve({ hosts: records }); - const onSet = jest.fn(async () => ({})); - - const mockDomainService = getDomainService({ nc: getNc({ onSet, onGet }) }); + const mockDomainService = mockDS({ zones, redirections }); await mockDomainService.updateHosts([ - { HostName: 'a', RecordType: 'CNAME', Address: 'boo' }, - { HostName: 'b', RecordType: 'CNAME', Address: 'goo' }, - { HostName: 'c', RecordType: 'A', Address: '12.131321.213' }, + { name: 'a', type: 'CNAME', address: 'boo' }, + { name: 'b', type: 'CNAME', address: 'goo' }, + { name: 'c', type: 'A', address: '12.131321.213' }, ]); - const [hosts] = onSet.mock.calls[0]; + expect(addZone).toBeCalledTimes(1); + expect(getRecordCalls(addZone)).toEqual([ + { name: 'c', type: 'A', address: '12.131321.213' }, + ]); + expect(editZone).toBeCalledTimes(0); + }); - expect(hosts.map(R.pick(['HostName', 'RecordType', 'Address']))).toEqual([ - { HostName: 'a', RecordType: 'CNAME', Address: 'boo' }, - { HostName: 'b', RecordType: 'CNAME', Address: 'goo' }, - { HostName: 'c', RecordType: 'A', Address: '12.131321.213' }, + it('should update matching host and set it', async () => { + const zones = [ + { someid: 1, name: 'a', type: 'CNAME', address: 'boo' }, + { someid: 2, name: 'b', type: 'CNAME', address: 'goo' }, + ]; + const redirections = []; + + const mockDomainService = mockDS({ zones, redirections }); + await mockDomainService.updateHosts([ + { name: 'a', type: 'CNAME', address: 'boo' }, + { name: 'b', type: 'CNAME', address: 'googoogaga' }, + ]); + + expect(addZone).toBeCalledTimes(0); + expect(editZone).toBeCalledTimes(1); + expect(getRecordCalls(editZone)).toEqual([ + { name: 'b', type: 'CNAME', address: 'googoogaga' }, ]); }); it('should update matching host and set it', async () => { - const records = [ - { HostId: 1, Name: 'a', Type: 'CNAME', Address: 'boo' }, - { HostId: 2, Name: 'b', Type: 'CNAME', Address: 'goo' }, + const zones = [ + { someid: 1, name: 'a', type: 'CNAME', address: 'boo' }, + { someid: 2, name: 'b', type: 'CNAME', address: 'goo' }, + { someid: 2, name: 'b', type: 'CNAME', address: 'xaa' }, ]; + const redirections = []; - const onGet = () => Promise.resolve({ hosts: records }); - const onSet = jest.fn(async () => ({})); - - const mockDomainService = getDomainService({ nc: getNc({ onSet, onGet }) }); + const mockDomainService = mockDS({ zones, redirections }); await mockDomainService.updateHosts([ - { HostName: 'a', RecordType: 'CNAME', Address: 'boo' }, - { HostName: 'b', RecordType: 'CNAME', Address: 'googoogaga' }, + { name: 'a', type: 'CNAME', address: 'boo' }, + { name: 'b', type: 'CNAME', address: 'googoogaga' }, + { name: 'b', type: 'CNAME', address: 'farboo' }, ]); - const [hosts] = onSet.mock.calls[0]; - - expect(hosts.map(R.pick(['HostName', 'RecordType', 'Address']))).toEqual([ - { HostName: 'a', RecordType: 'CNAME', Address: 'boo' }, - { HostName: 'b', RecordType: 'CNAME', Address: 'googoogaga' }, + expect(addZone).toBeCalledTimes(0); + expect(editZone).toBeCalledTimes(2); + expect(getRecordCalls(editZone)).toEqual([ + { name: 'b', type: 'CNAME', address: 'googoogaga' }, + { name: 'b', type: 'CNAME', address: 'farboo' }, ]); }); - it('should update matching host and set it', async () => { - const records = [ - { HostId: 1, Name: 'a', Type: 'CNAME', Address: 'boo' }, - { HostId: 2, Name: 'b', Type: 'CNAME', Address: 'goo' }, - { HostId: 2, Name: 'b', Type: 'CNAME', Address: 'xaa' }, + it('should workout this complex example', async () => { + const zones = [ + { someid: 1, name: 'a', type: 'CNAME', address: 'world' }, + { someid: 2, name: 'b', type: 'A', address: '1' }, + { someid: 2, name: 'b', type: 'A', address: '2' }, + { someid: 2, name: 'c', type: 'CNAME', address: 'hello.com' }, + ]; + const redirections = [ + { domain: `b.${DOMAIN_DOMAIN}`, destination: 'https://foobar.com' }, + { domain: `c.${DOMAIN_DOMAIN}`, destination: 'https://goobar.com' }, + { domain: `x.${DOMAIN_DOMAIN}`, destination: 'https://example.com' }, ]; - const onGet = () => Promise.resolve({ hosts: records }); - const onSet = jest.fn(async () => ({})); - - const mockDomainService = getDomainService({ nc: getNc({ onSet, onGet }) }); + const mockDomainService = mockDS({ zones, redirections }); await mockDomainService.updateHosts([ - { HostName: 'a', RecordType: 'CNAME', Address: 'boo' }, - { HostName: 'b', RecordType: 'CNAME', Address: 'googoogaga' }, - { HostName: 'b', RecordType: 'CNAME', Address: 'farboo' }, + { name: 'a', type: 'CNAME', address: 'boo' }, + { name: 'b', type: 'A', address: '1' }, + { name: 'b', type: 'A', address: '2' }, + { name: 'b', type: 'A', address: '3' }, + { name: 'b', type: 'URL', address: 'https://wowow.com' }, + { name: 'c', type: 'CNAME', address: 'hello.com' }, + { name: 'c', type: 'URL', address: 'https://goobar.com' }, + { name: 'd', type: 'CNAME', address: 'helo.com' }, + { name: 'd', type: 'URL', address: 'https://hhh.com' }, + { name: 'x', type: 'URL', address: 'https://example69.com' }, ]); - const [hosts] = onSet.mock.calls[0]; - - expect(hosts.map(R.pick(['HostName', 'RecordType', 'Address']))).toEqual([ - { HostName: 'a', RecordType: 'CNAME', Address: 'boo' }, - { HostName: 'b', RecordType: 'CNAME', Address: 'googoogaga' }, - { HostName: 'b', RecordType: 'CNAME', Address: 'farboo' }, + expect(addZone).toBeCalledTimes(2); + expect(editZone).toBeCalledTimes(1); + expect(addRedir).toBeCalledTimes(1); + expect(editRedir).toBeCalledTimes(2); + expect(getRecordCalls(addZone)).toEqual([ + { name: 'b', type: 'A', address: '3' }, + { name: 'd', type: 'CNAME', address: 'helo.com' } + ]); + expect(getRecordCalls(editZone)).toEqual([ + { name: 'a', type: 'CNAME', address: 'boo' }, + ]); + expect(getRecordCalls(addRedir)).toEqual([ + { domain: `d.${DOMAIN_DOMAIN}`, type: 'permanent', redirect: 'https://hhh.com' }, + ]); + expect(getRecordCalls(editRedir)).toEqual([ + { domain: `b.${DOMAIN_DOMAIN}`, type: 'permanent', redirect: 'https://wowow.com' }, + { domain: `x.${DOMAIN_DOMAIN}`, type: 'permanent', redirect: 'https://example69.com' }, ]); }); }); diff --git a/tests/domain-utils.test.js b/tests/domain-utils.test.js index 8dfbbacb8..ad231b281 100644 --- a/tests/domain-utils.test.js +++ b/tests/domain-utils.test.js @@ -31,9 +31,13 @@ describe('validateDomainData', () => { })), { ...defaultDomain, record: { CNAME: 'sd', A: ['121,3213'] } }, { ...defaultDomain, record: { A: ['121', '12'], FOOBAR: ['sd'] } }, + { ...defaultDomain, record: { A: [] } }, + { ...defaultDomain, record: { A: ['11122'], URL: 'foobar' } }, { ...defaultDomain, owner: {}, }, { ...defaultDomain, owner: { username: 'hwelo', }, }, { ...defaultDomain, owner: { email: 'hwelo' }, }, + { ...defaultDomain, record: { CNAME: 'http://foobar.com' } }, + { ...defaultDomain, record: { CNAME: 'https://foobar.com' } }, ]; const validCases = [ diff --git a/tests/domains.test.js b/tests/domains.test.js index 37c59575e..7f219fec4 100644 --- a/tests/domains.test.js +++ b/tests/domains.test.js @@ -1,7 +1,14 @@ const R = require('ramda'); +const fs = require('fs'); const { getDomains, validateDomainData } = require('../utils/domain'); +const { DOMAINS_PATH } = require('../utils/constants'); describe('Domains', () => { + it('should all be json', async () => { + const files = await fs.promises.readdir(DOMAINS_PATH, {}); + expect(files.filter(f => !/\.json$/g.test(f)).length).toBe(0); + }); + it('should be valid', (done) => { getDomains() .then(R.map(data => { diff --git a/tests/register.test.js b/tests/register.test.js index 23d1ffd43..0a87f2f4e 100644 --- a/tests/register.test.js +++ b/tests/register.test.js @@ -1,11 +1,18 @@ +const R = require('ramda'); const { toHostList, registerDomains } = require('../scripts/register-domains'); -const { TTL } = require('../utils/constants'); +const { TTL, DOMAIN_DOMAIN } = require('../utils/constants'); const { getDomainService } = require('../utils/domain-service'); -const getNc = ({ onSet, onGet } = {}) => ({ - dns: { - setHosts: (_, list) => onSet(list), - getHosts: (_) => onGet(), +const getCpanel = ({ zone, addZone, editZone, redir, addRedir, editRedir } = {}) => ({ + zone: { + fetch: (_) => zone(), + add: (rec) => addZone(rec), + edit: (rec) => editZone(rec), + }, + redirection: { + fetch: (_) => redir(), + add: (rec) => addRedir(rec), + edit: (rec) => editRedir(rec), }, }); @@ -18,113 +25,80 @@ describe('toHostList', () => { ]); expect(res).toEqual([ - { HostName: 'akshay', RecordType: 'CNAME', Address: 'phenax.github.io', TTL }, - { HostName: 'foobar', RecordType: 'CNAME', Address: 'v.io', TTL }, - { HostName: 'xx', RecordType: 'A', Address: '1.2.3.4', TTL }, - { HostName: 'xx', RecordType: 'A', Address: '5.6.3.2', TTL }, - { HostName: 'xx', RecordType: 'A', Address: '1.2.31.1', TTL }, + { name: 'akshay', type: 'CNAME', address: 'phenax.github.io', ttl: TTL }, + { name: 'foobar', type: 'CNAME', address: 'v.io', ttl: TTL }, + { name: 'xx', type: 'A', address: '1.2.3.4', ttl: TTL }, + { name: 'xx', type: 'A', address: '5.6.3.2', ttl: TTL }, + { name: 'xx', type: 'A', address: '1.2.31.1', ttl: TTL }, ]); }); }); describe('registerDomains', () => { + const addZone = jest.fn(async () => ({})); + const editZone = jest.fn(async () => ({})); + const addRedir = jest.fn(async () => ({})); + const editRedir = jest.fn(async () => ({})); + + const mockDS = ({ zones, redirections }) => getDomainService({ cpanel: getCpanel({ + zone: async () => zones, + redir: async () => redirections, + addZone, + addRedir, + editZone, + editRedir, + }) }); + + beforeEach(() => { + addZone.mockClear(); + editZone.mockClear(); + addRedir.mockClear(); + editRedir.mockClear(); + }); + it('should register the new set of hosts generated from domains list', async () => { const localHosts = [ { name: 'a', record: { CNAME: 'hello' } }, { name: 'b', record: { CNAME: 'xaa' } }, ]; const remoteHosts = [ - { HostId: 1, Name: 'a', Type: 'CNAME', Address: 'boo' }, - { HostId: 2, Name: 'b', Type: 'CNAME', Address: 'goo' }, - { HostId: 2, Name: 'b', Type: 'CNAME', Address: 'xaa' }, + { someididk: 1, name: 'a', type: 'CNAME', address: 'hello' }, + { someididk: 2, name: 'b', type: 'CNAME', address: 'goo' }, + { someididk: 2, name: 'b', type: 'CNAME', address: 'xaa' }, ]; + const remoteRedirections = []; - const onSet = jest.fn(async () => ({})); - - const domainService = getDomainService({ nc: getNc({ onSet, onGet: async () => ({ hosts: remoteHosts }) }) }); + const domainService = mockDS({ zones: remoteHosts, redirections: remoteRedirections }); await registerDomains({ getDomains: async () => localHosts, domainService }); - expect(onSet).toBeCalledTimes(1); - - const [hosts] = onSet.mock.calls[0]; - expect(hosts).toEqual([ - { HostId: 1, Address: 'hello', HostName: 'a', RecordType: 'CNAME', TTL }, - { HostId: 2, Address: 'xaa', HostName: 'b', RecordType: 'CNAME', TTL }, - ]); + expect(addZone).toBeCalledTimes(0); + expect(editZone).toBeCalledTimes(0); + expect(addRedir).toBeCalledTimes(0); + expect(editRedir).toBeCalledTimes(0); }); it('should add the new set hosts', async () => { const localHosts = [ - { name: 'a', record: { CNAME: 'boo' } }, - { name: 'b', record: { CNAME: 'xaa' } }, - { name: 'c', record: { CNAME: 'yello' } }, + { name: 'a', record: { CNAME: 'boo', URL: 'z' } }, + { name: 'b', record: { CNAME: 'xaa', URL: 'x' } }, + { name: 'c', record: { CNAME: 'yello', URL: 'https://google.com' } }, ]; const remoteHosts = [ - { HostId: 1, Name: 'a', Type: 'CNAME', Address: 'boo' }, - { HostId: 2, Name: 'b', Type: 'CNAME', Address: 'xaa' }, + { someididk: 1, name: 'a', type: 'CNAME', address: 'boo' }, + { someididk: 2, name: 'b', type: 'CNAME', address: 'xaa' }, + ]; + const remoteRedirections = [ + { domain: `b.${DOMAIN_DOMAIN}`, destination: 'x' }, + { domain: `a.${DOMAIN_DOMAIN}`, destination: 'y' }, ]; - const onSet = jest.fn(async () => ({})); - - const domainService = getDomainService({ nc: getNc({ onSet, onGet: async () => ({ hosts: remoteHosts }) }) }); + const domainService = mockDS({ zones: remoteHosts, redirections: remoteRedirections }); await registerDomains({ getDomains: async () => localHosts, domainService }); - expect(onSet).toBeCalledTimes(1); - - const [hosts] = onSet.mock.calls[0]; - expect(hosts).toEqual([ - { HostId: 1, Address: 'boo', HostName: 'a', RecordType: 'CNAME', TTL }, - { HostId: 2, Address: 'xaa', HostName: 'b', RecordType: 'CNAME', TTL }, - { Address: 'yello', HostName: 'c', RecordType: 'CNAME', TTL }, - ]); - }); - - it('should remove unlisted hosts', async () => { - const localHosts = [ - { name: 'a', record: { CNAME: 'boo' } }, - ]; - const remoteHosts = [ - { HostId: 1, Name: 'a', Type: 'CNAME', Address: 'boo' }, - { HostId: 2, Name: 'b', Type: 'CNAME', Address: 'xaa' }, - ]; - - const onSet = jest.fn(async () => ({})); - - const domainService = getDomainService({ nc: getNc({ onSet, onGet: async () => ({ hosts: remoteHosts }) }) }); - await registerDomains({ getDomains: async () => localHosts, domainService }); - - expect(onSet).toBeCalledTimes(1); - - const [hosts] = onSet.mock.calls[0]; - expect(hosts).toEqual([ - { HostId: 1, Address: 'boo', HostName: 'a', RecordType: 'CNAME', TTL }, - ]); - }); - - it('should change record type from cname to a', async () => { - const localHosts = [ - { name: 'a', record: { CNAME: 'boo' } }, - { name: 'b', record: { A: ['1', '2', '3'] } }, - ]; - const remoteHosts = [ - { HostId: 1, Name: 'a', Type: 'CNAME', Address: 'boo' }, - { HostId: 2, Name: 'b', Type: 'CNAME', Address: 'xaa' }, - ]; - - const onSet = jest.fn(async () => ({})); - - const domainService = getDomainService({ nc: getNc({ onSet, onGet: async () => ({ hosts: remoteHosts }) }) }); - await registerDomains({ getDomains: async () => localHosts, domainService }); - - expect(onSet).toBeCalledTimes(1); - - const [hosts] = onSet.mock.calls[0]; - expect(hosts).toEqual([ - { HostId: 1, Address: 'boo', HostName: 'a', RecordType: 'CNAME', TTL }, - { Address: '1', HostName: 'b', RecordType: 'A', TTL }, - { Address: '2', HostName: 'b', RecordType: 'A', TTL }, - { Address: '3', HostName: 'b', RecordType: 'A', TTL }, - ]); + expect(addZone).toBeCalledTimes(1); + expect(editZone).toBeCalledTimes(0); + expect(addRedir).toBeCalledTimes(1); + expect(editRedir).toBeCalledTimes(1); }); }); diff --git a/utils/constants.js b/utils/constants.js index 89a9b627f..086bb0f29 100644 --- a/utils/constants.js +++ b/utils/constants.js @@ -1,21 +1,26 @@ const path = require('path'); -const { ENV = 'sandbox', CI } = process.env; +const { ENV = 'test', CI } = process.env; if (!CI) { require('dotenv').config({ path: path.resolve(`.env.${ENV}`) }); } -const { NC_USER, NC_API_KEY, NC_DOMAIN, IP_ADDRESS } = process.env; +const { DOMAIN_USER, DOMAIN_API_KEY, DOMAIN_DOMAIN, DOMAIN_API_HOST, DOMAIN_API_PORT } = process.env; const IS_TEST = ENV === 'test'; +const DOMAINS_PATH = require('path').resolve('domains'); + module.exports = { ENV, - VALID_RECORD_TYPES: ['CNAME', 'A', 'ALIAS', 'URL'], - NC_DOMAIN: NC_DOMAIN || 'booboo.xyz', - NC_USER: IS_TEST ? 'testuser' : NC_USER, - NC_API_KEY: IS_TEST ? 'testkey' : NC_API_KEY, - IP_ADDRESS, - TTL: 5*60, + IS_TEST, + VALID_RECORD_TYPES: ['CNAME', 'A', 'URL'], + DOMAIN_DOMAIN: DOMAIN_DOMAIN || 'booboo.xyz', + DOMAIN_USER: IS_TEST ? 'testuser' : DOMAIN_USER, + DOMAIN_API_KEY: IS_TEST ? 'testkey' : DOMAIN_API_KEY, + DOMAIN_API_HOST: IS_TEST ? 'example.com' : DOMAIN_API_HOST, + DOMAIN_API_PORT: IS_TEST ? 6969 : DOMAIN_API_PORT, + DOMAINS_PATH, + TTL: 5*60*60, }; diff --git a/utils/domain-service.js b/utils/domain-service.js index 0831f3cb2..733ca29b6 100644 --- a/utils/domain-service.js +++ b/utils/domain-service.js @@ -1,72 +1,146 @@ const R = require('ramda'); -const Namecheap = require('@rqt/namecheap'); -const { NC_DOMAIN, NC_USER, NC_API_KEY, ENV, IP_ADDRESS } = require('../utils/constants'); +const { cpanel } = require('./lib/cpanel'); +const { DOMAIN_DOMAIN, IS_TEST } = require('./constants'); -const IS_SANDBOX = ENV === 'sandbox'; +const log = IS_TEST ? () => {} : console.log; -const getDomainService = ({ nc }) => { +const recordToRedirection = ({ name, address }) => ({ + domain: `${name}.${DOMAIN_DOMAIN}`, + redirect: address, + type: 'permanent', + redirect_wildcard: 1, + redirect_www: 1, +}); +const recordToZone = ({ name, type, address, ...rec }) => ({ + ...rec, //line + name, + type, + address, + ...(type === 'CNAME' ? { cname: address } : {}), +}); + +const cleanName = name => `${name}`.replace(new RegExp(`\.${DOMAIN_DOMAIN}\.?$`), '').toLowerCase(); + +const zoneToRecord = ({ name, type, cname, address, record, ...host }) => ({ + ...host, + name: cleanName(name), + type: `${type}`, + address: `${cname || address || record}`.replace(/\.$/g, '').toLowerCase(), +}); +const redirectionToRecord = ({ domain, destination }) => ({ + name: cleanName(domain), + type: 'URL', + address: `${destination}`.replace(/\/$/g, ''), +}); + +const getHostKey = host => `${host.name}##${host.type}`; + +const toHostMap = hosts => hosts.reduce((acc, host) => { + const key = getHostKey(host); + return { ...acc, [key]: [ ...(acc[key] || []), host ] }; +}, {}); + +const diffRecords = (oldRecords, newRecords) => { + const remoteHostMap = toHostMap(oldRecords); + const localHostMap = toHostMap(newRecords); + + return R.toPairs(localHostMap).reduce((acc, [key, local]) => { + const remote = remoteHostMap[key]; + + if (remote) { + let adds = []; + let edits = []; + + const diff = R.differenceWith((a, b) => a.address === b.address, local, remote); + + if (diff.length === local.length - remote.length) { + adds = diff; + } else { + edits = diff; + } + + return { ...acc, add: acc.add.concat(adds), edit: acc.edit.concat(edits) }; + } + + return { ...acc, add: acc.add.concat(local) }; + }, { add: [], edit: [] }); +}; + +const lazyTask = fn => data => () => fn(data); + +const batchLazyTasks = count => tasks => tasks.reduce((batches, task) => { + if (batches.length === 0) return [[task]]; + + const full = R.init(batches); + const last = R.last(batches); + + if (last.length >= count) return [...batches, [task]]; + return [...full, [...last, task]]; +}, []); + +const executeBatch = (batches) => batches.reduce((promise, batch, index) => { + return promise.then(async () => { + log('>>> Running batch number:', index + 1, `(size: ${batch.length})`); + + const values = await Promise.all(batch.map(fn => fn().catch(e => console.error(e)))); + + const results = values.map(R.pathOr({}, ['cpanelresult', 'data', 0])); + const failed = results.filter(x => (x.result || {}).status != 1); + + log(`${values.length - failed.length}/${values.length}`); + failed.length && log(failed); + + return null; + }); +}, Promise.resolve()); + +const getDomainService = ({ cpanel }) => { let hostList = []; + const fetchZoneRecords = () => cpanel.zone.fetch().then(R.map(zoneToRecord)); + const fetchRedirections = () => cpanel.redirection.fetch().then(R.map(redirectionToRecord)); + + const addZoneRecord = lazyTask(R.compose(cpanel.zone.add, recordToZone)); + const editZoneRecord = lazyTask(R.compose(cpanel.zone.edit, recordToZone)); + const addRedirection = lazyTask(R.compose(cpanel.redirection.add, recordToRedirection)); + const editRedirection = lazyTask(R.compose(cpanel.redirection.edit, recordToRedirection)); + const getHosts = async () => { if (hostList.length) return hostList; - const list = await nc.dns.getHosts(NC_DOMAIN) - .then(R.propOr([], 'hosts')) - .then(R.map(host => R.omit(['Name', 'Type'], { - ...host, - HostName: host.Name, - RecordType: host.Type, - Address: `${host.Address}`.replace(/\.$/g, ''), - }))); + const list = await Promise.all([fetchZoneRecords(), fetchRedirections()]).then(R.flatten); hostList = list; return list; }; - const setHosts = hosts => nc.dns.setHosts(NC_DOMAIN, hosts); + const BATCH_SIZE = 1; - const getHostKey = host => `${host.HostName}--${host.RecordType}`; - const toHostMap = hosts => hosts.reduce((acc, host) => { - const key = getHostKey(host); - return { ...acc, [key]: [ ...(acc[key] || []), host ] }; - }, {}); + const addRecords = R.compose(batchLazyTasks(BATCH_SIZE), R.filter(Boolean), R.map(R.cond([ + [ R.propEq('name', 'www'), () => null ], + [ R.propEq('type', 'URL'), addRedirection ], + [ R.T, addZoneRecord ], + ]))); + const editRecords = R.compose(batchLazyTasks(BATCH_SIZE), R.map(R.cond([ + [ R.propEq('type', 'URL'), editRedirection ], + [ R.T, editZoneRecord ], + ]))); const updateHosts = async hosts => { - const hostList = await getHosts(); - const remoteHostMap = toHostMap(hostList); - const localHostMap = toHostMap(hosts); + const remoteHostList = await getHosts(); + const { add, edit } = diffRecords(remoteHostList, hosts); - const newHostList = R.toPairs(localHostMap).reduce((acc, [key, local]) => { - const remote = remoteHostMap[key]; - - if (remote) { - return acc.concat(local.map((localItem, index) => R.merge(remote[index], localItem))); - } - - return [...acc, ...local]; - }, []); - - return setHosts(newHostList); + await executeBatch(addRecords(add).concat(editRecords(edit))); + return { additions: add.length, edits: edit.length }; }; - return { getHosts, setHosts, updateHosts }; + return { getHosts, updateHosts }; }; -if (!NC_API_KEY) { - console.error('NC_API_KEY cannot be empty'); - process.exit(1); -} - -const nc = new Namecheap({ - user: NC_USER, - key: NC_API_KEY, - ip: IP_ADDRESS, - sandbox: IS_SANDBOX, -}); - -const domainService = getDomainService({ nc }); +const domainService = getDomainService({ cpanel }); module.exports = { getDomainService, domainService, + diffRecords, }; diff --git a/utils/domain.js b/utils/domain.js index 089bde425..452aab658 100644 --- a/utils/domain.js +++ b/utils/domain.js @@ -1,9 +1,7 @@ const fs = require('fs'); const path = require('path'); const R = require('ramda'); -const { VALID_RECORD_TYPES } = require('./constants'); - -const DOMAINS_PATH = path.resolve('domains'); +const { VALID_RECORD_TYPES, DOMAINS_PATH } = require('./constants'); const log = m => x => console.log(m, x) || x; @@ -19,6 +17,7 @@ const getDomains = () => }))); const between = (min, max) => num => num >= min && num <= max; +const testRegex = regex => str => !!(str && str.match(regex)); const validate = pattern => data => R.compose( invalidPairs => invalidPairs.length ? { errors: invalidPairs, valid: false } : { errors: [], valid: true }, @@ -26,9 +25,15 @@ const validate = pattern => data => R.compose( R.toPairs, )(pattern); -const validateNameRecord = type => R.allPass([ +const validateCnameRecord = key => R.allPass([ + R.propSatisfies(R.is(String), key), R.compose(R.equals(1), R.length, R.reject(R.equals('URL')), R.keys), - R.propSatisfies(R.is(String), type), + R.propSatisfies(R.complement(testRegex(/^https?:\/\//ig)), key), +]); + +const validateARecord = key => R.allPass([ + R.compose(R.equals(1), R.length, R.keys), + R.propSatisfies(R.compose(R.gte(R.__, 1), R.length), key), ]); const validateDomainData = validate({ @@ -38,7 +43,7 @@ const validateDomainData = validate({ R.equals('@'), R.allPass([ R.compose(between(2, 100), R.length), - str => str && str.match(/^[A-Za-z0-9\-]+$/ig), + testRegex(/^[a-z0-9\-]+$/g), ]) ]), }, @@ -56,14 +61,13 @@ const validateDomainData = validate({ ]), }, record: { - reason: 'Invalid record', + reason: 'Invalid record. CNAME records have to be a host name and A records has to be a list of ips', fn: R.allPass([ R.is(Object), R.compose(R.isEmpty, R.flip(R.difference)(VALID_RECORD_TYPES), R.keys), R.cond([ - [R.prop('CNAME'), validateNameRecord('CNAME')], - [R.prop('ALIAS'), validateNameRecord('ALIAS')], - [R.prop('A'), R.propSatisfies(R.is(Array), 'A')], + [R.prop('CNAME'), validateCnameRecord('CNAME')], + [R.prop('A'), validateARecord('A')], [R.prop('URL'), R.propSatisfies(R.is(String), 'URL')], [R.T, R.T], ]), diff --git a/utils/lib/cpanel.js b/utils/lib/cpanel.js new file mode 100644 index 000000000..c29c10145 --- /dev/null +++ b/utils/lib/cpanel.js @@ -0,0 +1,87 @@ +const R = require('ramda'); +const fetch = require('node-fetch'); +const qs = require('qs'); +const { DOMAIN_API_HOST, DOMAIN_API_PORT, DOMAIN_USER, DOMAIN_API_KEY, DOMAIN_DOMAIN } = require('../constants'); + +const CpanelClient = (options) => { + // TODO: Make defaultQuery functional + const api = ({ basePath = '', action = '' }) => (module, func, defaultQuery = {}) => (q = {}) => { + const query = { + ...defaultQuery, + ...q, + cpanel_jsonapi_user: options.username, + cpanel_jsonapi_module: module, + cpanel_jsonapi_func: func, + cpanel_jsonapi_apiversion: 2, + }; + + const request = { + headers: { + Authorization: `cpanel ${options.username}:${options.apiKey}`, + }, + rejectUnauthorized: false, + }; + + const path = `${basePath}/${action}?${qs.stringify(query)}`; + const reqUrl = `https://${options.host}:${options.port}/${path}`; + + const { fetch } = options.dependencies; + return fetch(reqUrl, request).then(res => res.json()); + }; + + const api2 = api({ basePath: 'json-api', action: 'cpanel' }); + const uapi = (module, func, defaultQuery) => + api({ basePath: 'execute', action: `${module}/${func}` })(module, func, defaultQuery); + + return { + zone: { + // { customonly, domain } + // -> { cpanelresult: { data[{ class, ttl, name, line, Line, cname, type, record }] } } + fetch: R.compose( + p => p.then(R.pathOr([], ['cpanelresult', 'data'])), + api2('ZoneEdit', 'fetchzone_records', { customonly: 1, domain: options.domain }) + ), + + // { name, type(A|CNAME), cname, address, ttl } + // -> {} + add: api2('ZoneEdit', 'add_zone_record', { domain: options.domain }), + + // { name, type(A|CNAME), cname, address, ttl } + // -> {} + edit: api2('ZoneEdit', 'edit_zone_record', { domain: options.domain }), + }, + redirection: { + // {} + // -> { domain, destination } + fetch: R.compose( + p => p.then(R.pathOr([], ['data'])), + uapi('Mime', 'list_redirects'), + ), + + // { domain, redirect, type(permanent|tmp), redirect_wildcard(0|1), redirect(0|1|2) } + // -> {} + add: uapi('Mime', 'add_redirect'), + edit: uapi('Mime', 'add_redirect'), // NOTE: adding new updates exisiting + }, + }; +}; + +if (!DOMAIN_API_KEY) { + console.error('Api key cannot be empty'); + process.exit(1); +} + +const cpanel = CpanelClient({ + host: DOMAIN_API_HOST, + port: DOMAIN_API_PORT, + username: DOMAIN_USER, + apiKey: DOMAIN_API_KEY, + domain: DOMAIN_DOMAIN, + dependencies: { fetch }, +}); + +module.exports = { + cpanel, + CpanelClient, +}; + diff --git a/yarn.lock b/yarn.lock index 2cb029d01..fb8f6f11e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -458,11 +458,6 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" -"@rqt/namecheap@^2.4.2": - version "2.4.2" - resolved "https://registry.yarnpkg.com/@rqt/namecheap/-/namecheap-2.4.2.tgz#8537eea6efbe7ac4fd449e3aee5f2c1d80986fcf" - integrity sha512-RfrK7ywOraz0nR/BlQt8fJQDcOfI9cLSTpa6l9JS9ER0HJ6t1FQ8Pxmplj/lVQv8rkczuVADdZVC3HlL98Q31w== - "@sinonjs/commons@^1.7.0": version "1.8.1" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.1.tgz#e7df00f98a203324f6dc7cc606cad9d4a8ab2217" @@ -2468,6 +2463,11 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +node-fetch@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"