diff --git a/.github/workflows/validation.yml b/.github/workflows/validation.yml index 4f9863fc7..6e86fabc5 100644 --- a/.github/workflows/validation.yml +++ b/.github/workflows/validation.yml @@ -36,6 +36,9 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Clone is-a-dev/register + run: git clone https://github.com/is-a-dev/register.git register-${{ github.run_id }} + - run: npm install - name: Get all modified domain JSON files @@ -45,17 +48,10 @@ jobs: with: files: domains/*.json - - name: testing - run: | - ls - ls ../ - echo ${{ steps.changed-files.outputs.all_changed_files }} - for file in ${{ steps.changed-files.outputs.all_changed_files }}; do - cat $file - done - - - run: npm test + - name: Run tests + run: npx ava tests/*.test.js env: EVENT: ${{ github.event_name }} + RUN_ID: ${{ github.run_id }} PR_AUTHOR: ${{ github.event.pull_request.user.login }} MODIFIED_FILES: ${{ steps.changed-files.outputs.all_changed_files }} diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index fa62aa12d..49cc4532e 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -14,7 +14,7 @@ The abuse reports will be investigated and the necessary action will be taken. - Online stores/shopping websites - Gambling websites - Game cheat sites -- CDNs distributing potentially malicious content (APKs, executables) +- CDNs distributing potentially malicious content (e.g. APKs, executables) - 'Unblocked' gaming websites - Alternate URLs for commonly blocked websites (e.g. gambling/casino websites) - Websites containing 18+ content @@ -28,3 +28,4 @@ The abuse reports will be investigated and the necessary action will be taken. - Online services for identity theft or forgery - Platforms promoting self-harm or violence - Illegal drug marketplaces +- Proxy sites (e.g. embedding other websites) diff --git a/domains/2.json b/domains/2.json index d6fc683e0..5e6f21eae 100644 --- a/domains/2.json +++ b/domains/2.json @@ -1,11 +1,10 @@ { "description": "LIGMATV's URL Manager (aka 2)", - "repo": "https://github.com/LIGMATV/links", "owner": { "username": "LIGMATV", "email": "ligmatv.id@gmail.com" }, "record": { - "CNAME": "ligmatv.github.io" + "CNAME": "ligmatv-links.vercel.app" } } diff --git a/domains/_discord.justwinstuff.json b/domains/_discord.justwinstuff.json new file mode 100644 index 000000000..f846fd946 --- /dev/null +++ b/domains/_discord.justwinstuff.json @@ -0,0 +1,9 @@ +{ + "owner": { + "username": "enderfoxbg", + "discord": "970380468090437672" + }, + "record": { + "TXT": ["dh=75e9bdc423ca4351bb8938087b552bc2ee9a3e16"] + } +} diff --git a/domains/_vercel.2.json b/domains/_vercel.2.json new file mode 100644 index 000000000..24db2720e --- /dev/null +++ b/domains/_vercel.2.json @@ -0,0 +1,10 @@ +{ + "description": "LIGMATV's URL Manager (aka 2)", + "owner": { + "username": "LIGMATV", + "email": "ligmatv.id@gmail.com" + }, + "record": { + "TXT": ["vc-domain-verify=2.is-a.dev,ea014a1b9a6ec8986aa0"] + } +} diff --git a/domains/_vercel.alisa.json b/domains/_vercel.alisa.json new file mode 100644 index 000000000..efc76ec48 --- /dev/null +++ b/domains/_vercel.alisa.json @@ -0,0 +1,10 @@ +{ + "owner": { + "username": "lunas-private-dungeon", + "email": "luna.tsx@proton.me", + "discord": "507625218467168257" + }, + "record": { + "TXT": ["vc-domain-verify=alisa.is-a.dev,01abd793050b01c5d63f"] + } +} diff --git a/domains/ajtabs.json b/domains/ajtabs.json new file mode 100644 index 000000000..5cb58c59c --- /dev/null +++ b/domains/ajtabs.json @@ -0,0 +1,9 @@ +{ + "owner": { + "username": "ajtabjs", + "email": "oro10jua@gmail.com" + }, + "record": { + "CNAME": "ajtabjs.github.io" + } +} diff --git a/domains/alisa.json b/domains/alisa.json new file mode 100644 index 000000000..78dae86ba --- /dev/null +++ b/domains/alisa.json @@ -0,0 +1,10 @@ +{ + "owner": { + "username": "lunas-private-dungeon", + "email": "luna.tsx@proton.me", + "discord": "507625218467168257" + }, + "record": { + "CNAME": "alisa-win95.vercel.app" + } +} diff --git a/domains/hash-cracker.json b/domains/hash-cracker.json new file mode 100644 index 000000000..3c63d2ca7 --- /dev/null +++ b/domains/hash-cracker.json @@ -0,0 +1,11 @@ +{ + "description": "A portfolio website", + "repo": "https://github.com/hash-cracker/hash-cracker.github.io", + "owner": { + "username": "Hash-Cracker", + "email": "tspamiitesh@gmail.com" + }, + "record": { + "CNAME": "hash-cracker.github.io" + } +} diff --git a/domains/manish-madi.json b/domains/manish-madi.json new file mode 100644 index 000000000..fe4f90072 --- /dev/null +++ b/domains/manish-madi.json @@ -0,0 +1,11 @@ +{ + "description": "Manish's Personal Website", + "repo": "https://github.com/m-manish03/m-manish03", + "owner": { + "username": "m-manish03", + "email": "manish.rebel14@gmail.com" + }, + "record": { + "CNAME": "m-manish03.github.io" + } +} diff --git a/tests/pr.test.js b/tests/pr.test.js index 5de425a0f..7bb79061b 100644 --- a/tests/pr.test.js +++ b/tests/pr.test.js @@ -3,28 +3,67 @@ const fs = require("fs-extra"); const path = require("path"); const PR_AUTHOR = process.env.PR_AUTHOR; -let MODIFIED_FILES = process.env.MODIFIED_FILES.split(" "); - -for (let i = 0; i < MODIFIED_FILES.length; i++) { - MODIFIED_FILES[i] = MODIFIED_FILES[i].substring(MODIFIED_FILES[i].lastIndexOf("/") + 1); -} +const MODIFIED_FILES = (process.env.MODIFIED_FILES || "").split(" ").map((file) => file.replace(/^domains\//, "")); +const EVENT = process.env.EVENT; +const RUN_ID = process.env.RUN_ID; const domainsPath = path.resolve("domains"); +const headDomainsPath = path.resolve(`register-${RUN_ID}/domains`); const admins = require("../util/administrators.json"); -t("Modified JSON files must be owned by the PR author", (t) => { - if(process.env.EVENT !== "pull_request") { - t.pass(); - return; +async function getJSONContent(basePath, fileName) { + try { + return await fs.readJson(path.join(basePath, fileName)); + } catch { + return null; } +} - MODIFIED_FILES.forEach((file) => { - const domain = fs.readJsonSync(path.join(domainsPath, file)); +t("Modified JSON files must be owned by the PR author", async (t) => { + if (EVENT !== "pull_request") return t.pass(); + + const checks = MODIFIED_FILES.map(async (file) => { + const [modifiedDomain, currentDomain] = await Promise.all([ + getJSONContent(domainsPath, file), + getJSONContent(headDomainsPath, file) + ]); + + const domainToCheck = currentDomain || modifiedDomain; + + if (!modifiedDomain || !domainToCheck) { + t.fail(`${file}: Unable to read domain data`); + return; + } + + t.true( + domainToCheck.owner.username === PR_AUTHOR || admins.includes(PR_AUTHOR), + `${file}: Domain owner is ${domainToCheck.owner.username} but ${PR_AUTHOR} is the PR author` + ); + }); + + await Promise.all(checks); + t.pass(); +}); + +t("New JSON files must be owned by the PR author", async (t) => { + if (EVENT !== "pull_request") return t.pass(); + + const [newFiles, currentFiles] = await Promise.all([fs.readdir(domainsPath), fs.readdir(headDomainsPath)]); + + const newDomainFiles = newFiles.filter((file) => !currentFiles.includes(file)); + + const checks = newDomainFiles.map(async (file) => { + const domain = await getJSONContent(domainsPath, file); + + if (!domain) return t.fail(`${file}: Unable to read domain data`); t.true( domain.owner.username === PR_AUTHOR || admins.includes(PR_AUTHOR), - `${file}: Owner is ${domain.owner.username} but ${PR_AUTHOR} is the PR author` + `${file}: Domain owner is ${domain.owner.username} but ${PR_AUTHOR} is the PR author` ); }); + + await Promise.all(checks); + t.pass(); });