diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 9eefecd7b..ad78c7b61 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -1,21 +1,20 @@ name: StaleBOT on: - workflow_dispatch: - name: 'Force cleanup' - schedule: - - cron: "30 14 * * *" + workflow_dispatch: + schedule: + - cron: "30 14 * * *" jobs: - stale: - runs-on: ubuntu-latest - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - days-before-stale: 7 - days-before-close: 3 - stale-issue-message: 'This issue has been marked as stale due to inactivity and will be closed. Comment anything on this issue to prevent it' - stale-pr-message: 'This pull request has been marked as stale due to inactivity and will be closed. Comment anything on this PR to prevent it' - exempt-issue-labels: 'no-stale' - exempt-pr-labels: 'no-stale' + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + days-before-stale: 7 + days-before-close: 3 + stale-issue-message: "This issue has been marked as stale due to inactivity and will be closed. Comment anything on this issue to prevent it" + stale-pr-message: "This pull request has been marked as stale due to inactivity and will be closed. Comment anything on this PR to prevent it" + exempt-issue-labels: "no-stale" + exempt-pr-labels: "no-stale" diff --git a/.github/workflows/validation.yml b/.github/workflows/validation.yml index d48c9a347..6e86fabc5 100644 --- a/.github/workflows/validation.yml +++ b/.github/workflows/validation.yml @@ -36,6 +36,22 @@ 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 - - run: npm test + - name: Get all modified domain JSON files + if: github.event_name == 'pull_request' + id: changed-files + uses: tj-actions/changed-files@v45 + with: + files: domains/*.json + + - 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/face-recognition.shockbs.json b/domains/face-recognition.shockbs.json deleted file mode 100644 index 6000dc098..000000000 --- a/domains/face-recognition.shockbs.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "owner": { - "username": "shockbs", - "email": "apipherng@gmail.com" - }, - "record": { - "CNAME": "na-west1.surge.sh" - } -} 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/tests/pr.test.js b/tests/pr.test.js new file mode 100644 index 000000000..7bb79061b --- /dev/null +++ b/tests/pr.test.js @@ -0,0 +1,69 @@ +const t = require("ava"); +const fs = require("fs-extra"); +const path = require("path"); + +const PR_AUTHOR = process.env.PR_AUTHOR; +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"); + +async function getJSONContent(basePath, fileName) { + try { + return await fs.readJson(path.join(basePath, fileName)); + } catch { + return null; + } +} + +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}: Domain owner is ${domain.owner.username} but ${PR_AUTHOR} is the PR author` + ); + }); + + await Promise.all(checks); + t.pass(); +}); diff --git a/util/administrators.json b/util/administrators.json new file mode 100644 index 000000000..f85832ced --- /dev/null +++ b/util/administrators.json @@ -0,0 +1,4 @@ +[ + "wdhdev", + "DEV-DIBSTER" +] \ No newline at end of file diff --git a/util/reserved-domains.json b/util/reserved-domains.json index 67087b209..42a683c8c 100644 --- a/util/reserved-domains.json +++ b/util/reserved-domains.json @@ -8,7 +8,9 @@ "api", "auth", "authentication", + "authorisation", "authorise", + "authorization", "authorize", "aux", "billing", @@ -17,6 +19,7 @@ "cart", "catalog", "checkout", + "co", "com", "com[1-9]", "con", @@ -74,7 +77,6 @@ "payments", "portal", "postmaster", - "prn", "recovery", "redirect", "registrar",