From 1e866e01e317938c40d5052eb352355d0d75b671 Mon Sep 17 00:00:00 2001 From: William Harrison Date: Sat, 19 Oct 2024 14:02:50 +0800 Subject: [PATCH] feat(ci): move to dnscontrol --- .github/CODEOWNERS | 4 +- .github/workflows/publish.yml | 32 ++++++++++++ .github/workflows/update-records.yml | 33 ------------- .github/workflows/validate.yml | 42 ++++++++++++++++ .github/workflows/validation.yml | 45 ----------------- .gitignore | 3 -- dnsconfig.js | 53 ++++++++++++++++++++ scripts/addRecords.js | 35 ------------- sub-logs/aniruddh.json | 2 +- sub-logs/anya.json | 2 +- sub-logs/arman.json | 2 +- sub-logs/avengers-sonarqube.json | 2 +- sub-logs/ionetty.json | 2 +- sub-logs/michaelbelete.json | 15 ------ sub-logs/oreki.json | 2 +- sub-logs/paul.json | 2 +- sub-logs/raja.json | 2 +- sub-logs/rehanplayz.json | 2 +- sub-logs/reserved/redirect.json | 2 +- sub-logs/themediocre.json | 4 +- sub-logs/tonywu.json | 2 +- sub-logs/vishal.json | 2 +- tests/json.test.js | 61 ----------------------- utils/checkInfo.js | 27 ---------- utils/checkRecords.js | 35 ------------- utils/getFileName.js | 13 ----- utils/getJSON.js | 36 -------------- utils/invalid-domains.json | 52 ------------------- utils/utils.js | 74 ---------------------------- 29 files changed, 143 insertions(+), 445 deletions(-) create mode 100644 .github/workflows/publish.yml delete mode 100644 .github/workflows/update-records.yml create mode 100644 .github/workflows/validate.yml delete mode 100644 .github/workflows/validation.yml delete mode 100644 .gitignore create mode 100644 dnsconfig.js delete mode 100644 scripts/addRecords.js delete mode 100644 sub-logs/michaelbelete.json delete mode 100644 tests/json.test.js delete mode 100644 utils/checkInfo.js delete mode 100644 utils/checkRecords.js delete mode 100644 utils/getFileName.js delete mode 100644 utils/getJSON.js delete mode 100644 utils/invalid-domains.json delete mode 100644 utils/utils.js diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 84d4fec..1b2eac7 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,5 +2,5 @@ /sub-logs/* @is-a-good-dev/helpers /.github/* @Tweak4141 -/scripts/* @Tweak4141 -/utils/* @Tweak4141 +/.github/workflows/* @Tweak4141 @wdhdev +/dnsconfig.js @Tweak4141 @wdhdev diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..29f273e --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,32 @@ +name: Publish + +on: + push: + branches: [main] + paths: + - "sub-logs/*" + - ".github/workflows/publish.yml" + - "dnsconfig.js" + + workflow_dispatch: + +concurrency: + group: ${{ github.ref }}-publish + cancel-in-progress: false + +jobs: + dns: + name: DNS + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Generate creds.json + run: echo '{"cloudflare":{"TYPE":"CLOUDFLAREAPI","apitoken":"$CLOUDFLARE_API_TOKEN"}}' > ./creds.json + + - name: Publish + uses: is-a-dev/dnscontrol-action@main + env: + CLOUDFLARE_API_TOKEN: ${{ secrets.API_KEY }} + with: + args: push diff --git a/.github/workflows/update-records.yml b/.github/workflows/update-records.yml deleted file mode 100644 index 7a11bb3..0000000 --- a/.github/workflows/update-records.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Update Records -on: - push: - branches: [main] - -jobs: - validation: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - uses: actions/setup-node@v3 - with: - node-version: 16 - - name: Get Files - id: changed-files - uses: tj-actions/changed-files@v34 - with: - files: | - sub-logs/** - reserved/** - - name: Install Modules - if: steps.changed-files.outputs.any_changed == 'true' - run: yarn - - name: Publish Records - if: steps.changed-files.outputs.any_changed == 'true' - id: tests - run: yarn add-records - env: - API_KEY: ${{ secrets.API_KEY }} - FILES: ${{ steps.changed-files.outputs.all_changed_files }} - actions_path: ${{ github.workspace }} diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml new file mode 100644 index 0000000..eb26253 --- /dev/null +++ b/.github/workflows/validate.yml @@ -0,0 +1,42 @@ +name: Validation + +on: + pull_request: + + push: + branches: [main] + paths: + - "sub-logs/*" + - ".github/workflows/validation.yml" + - "dnsconfig.js" + + workflow_dispatch: + +concurrency: + group: ${{ github.ref }}-validation + cancel-in-progress: true + +jobs: + dns: + name: DNS + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Check + uses: is-a-dev/dnscontrol-action@main + with: + args: check + + json: + name: JSON + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: JSON Syntax Check + uses: limitusus/json-syntax-check@v2 + with: + pattern: "\\.json$" + env: + BASE: "domains/" diff --git a/.github/workflows/validation.yml b/.github/workflows/validation.yml deleted file mode 100644 index 6fab734..0000000 --- a/.github/workflows/validation.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Validation -on: [pull_request] - -jobs: - validation: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: Get Files - id: changed-files - uses: tj-actions/changed-files@v34 - with: - files: | - sub-logs/** - reserved/** - - name: Install Modules - if: steps.changed-files.outputs.any_changed == 'true' - run: yarn - - name: Run Tests - if: steps.changed-files.outputs.any_changed == 'true' - id: tests - run: yarn test - env: - FILES: ${{ steps.changed-files.outputs.all_changed_files }} - actions_path: ${{ github.workspace }} - - name: Comment - if: steps.tests.outputs.shouldComment == 'true' - uses: mshick/add-pr-comment@v1 - with: - message: | - ## Validation Results - | Information Validation | Record Validation | - |-|-| - | ${{steps.tests.outputs.infoMessage}} ${{steps.tests.outputs.infoReason}} | ${{steps.tests.outputs.recordMessage}} ${{steps.tests.outputs.recordInfo}} | - - ### JSON File Content - ```json - ${{steps.tests.outputs.jsonData}} - ``` - repo-token: ${{ secrets.GITHUB_TOKEN }} - proxy-url: https://is-a-good-dev-gh-proxy.talosbot.xyz/ - repo-token-user-login: 'github-actions[bot]' # The user.login for temporary GitHub tokens - allow-repeats: false # Default: false diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 737bc52..0000000 --- a/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules/ -dist/ -package-lock.json \ No newline at end of file diff --git a/dnsconfig.js b/dnsconfig.js new file mode 100644 index 0000000..1beeb54 --- /dev/null +++ b/dnsconfig.js @@ -0,0 +1,53 @@ +function getDomainsList(filesPath) { + var result = []; + var files = glob.apply(null, [filesPath, true, ".json"]); + + for (var i = 0; i < files.length; i++) { + var name = files[i].split("/").pop().replace(/\.json$/, ""); + + result.push({ name: name, data: require(files[i]) }); + } + + return result; +} + +var domains = getDomainsList("./sub-logs"); +var commit = []; + +for (var subdomain in domains) { + var subdomainName = domains[subdomain].name; + var domainData = domains[subdomain].data; + var proxyState = domainData.proxied ? { cloudflare_proxy: "on" } : { cloudflare_proxy: "off" }; + + // Handle A records + if (domainData.record.A) { + for (var a in domainData.record.A.value) { + commit.push(A(domainData.record.A.name, IP(domainData.record.A.value[a]), proxyState)); + } + } + + // Handle AAAA records + if (domainData.record.AAAA) { + for (var aaaa in domainData.record.AAAA.value) { + commit.push(AAAA(domainData.record.AAAA.name, domainData.record.AAAA.value[aaaa], proxyState)); + } + } + + // Handle CNAME records + if (domainData.record.CNAME) { + // Allow CNAME record on root + if (subdomainName === "@") { + commit.push(ALIAS(subdomainName, domainData.record.CNAME + ".", proxyState)); + } else { + commit.push(CNAME(domainData.record.CNAME.name, domainData.record.CNAME.value + ".", proxyState)); + } + } + + // Handle TXT records + if (domainData.record.TXT) { + commit.push(TXT(domainData.record.TXT.name === "@" ? subdomainName : domainData.record.TXT.name + "." + subdomainName, domainData.record.TXT.value)); + } +} + +// Commit all DNS records +D("is-a-good.dev", NewRegistrar("none"), DnsProvider(NewDnsProvider("cloudflare")), commit); diff --git a/scripts/addRecords.js b/scripts/addRecords.js deleted file mode 100644 index 86406c5..0000000 --- a/scripts/addRecords.js +++ /dev/null @@ -1,35 +0,0 @@ -const fetch = require('node-fetch'); -const getJSON = require('../utils/getJSON.js'); -const data = getJSON(process.env.FILES); -const arrayRecordTypes = ["a", "aaaa"]; -async function addRecord(type, name, value) { - const response = await fetch(`https://api.is-a-good.dev/api/is-a-good-dev/zones/add?apiKey=${process.env.API_KEY}&type=${type.toUpperCase()}&name=${name}&content=${value}`); - const data = await response.json(); - - return data; -} - -(async () => { - try { - if (!data) return; - - const records = Object.keys(data.target); - for (const i in records) { - const recordType = records[i]; - const name = data.target[recordType].name; - const value = data.target[recordType].value; - console.log(`Adding record type ${recordType} with values ${name}, ${value}`); - if (arrayRecordTypes.includes(recordType.toLowerCase()) != true) { - let res = await addRecord(recordType, name, value); - return console.log(res); - } - for (const ip of value) { - let res = await addRecord(recordType, name, ip); - console.log(res); - } - } - } catch(e) { - console.log('Failed to add records.'); - console.log(e); - } -})(); diff --git a/sub-logs/aniruddh.json b/sub-logs/aniruddh.json index 643f51b..18fd6e0 100644 --- a/sub-logs/aniruddh.json +++ b/sub-logs/aniruddh.json @@ -9,7 +9,7 @@ "target": { "A": { "name": "aniruddh", - "value": "23.94.14.190" + "value": ["23.94.14.190"] } }, diff --git a/sub-logs/anya.json b/sub-logs/anya.json index b22ca0d..ce9c0b3 100644 --- a/sub-logs/anya.json +++ b/sub-logs/anya.json @@ -7,7 +7,7 @@ "target": { "A": { "name": "anya", - "value": "87.98.164.155" + "value": ["87.98.164.155"] } }, diff --git a/sub-logs/arman.json b/sub-logs/arman.json index f94c0e8..a3eaeac 100644 --- a/sub-logs/arman.json +++ b/sub-logs/arman.json @@ -7,7 +7,7 @@ "target": { "A": { "name": "arman", - "value": "89.106.200.1" + "value": ["89.106.200.1"] } }, diff --git a/sub-logs/avengers-sonarqube.json b/sub-logs/avengers-sonarqube.json index a7d5a93..dfd9308 100644 --- a/sub-logs/avengers-sonarqube.json +++ b/sub-logs/avengers-sonarqube.json @@ -13,7 +13,7 @@ }, "TXT": { - "name": "asuid.avengers-sonarqube", + "name": "asuid", "value": "2ADF2B3BF4F2D427644C6A908F1607F17C2A1AAE36C1A5E86A6FDFD7B56B2149" } }, diff --git a/sub-logs/ionetty.json b/sub-logs/ionetty.json index 6ca6f07..9d804c3 100644 --- a/sub-logs/ionetty.json +++ b/sub-logs/ionetty.json @@ -7,7 +7,7 @@ "target": { "A": { "name": "ionetty", - "value": "66.94.121.50" + "value": ["66.94.121.50"] } }, diff --git a/sub-logs/michaelbelete.json b/sub-logs/michaelbelete.json deleted file mode 100644 index bee6f32..0000000 --- a/sub-logs/michaelbelete.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "owner": { - "username": "michaelbelete", - "email": "it.michael.belete@gmail.com" - }, - - "target": { - "TXT": { - "name": "michaelbelete", - "value": "vc-domain-verify=michaelbelete.is-a-good.dev,c5ef3d006ace4ff62d3e" - } - }, - - "proxied": false -} diff --git a/sub-logs/oreki.json b/sub-logs/oreki.json index 3aed667..9714f7b 100644 --- a/sub-logs/oreki.json +++ b/sub-logs/oreki.json @@ -7,7 +7,7 @@ "target": { "A": { "name": "oreki", - "value": "164.132.74.251" + "value": ["164.132.74.251"] } }, diff --git a/sub-logs/paul.json b/sub-logs/paul.json index a5cd6eb..d1b79e0 100644 --- a/sub-logs/paul.json +++ b/sub-logs/paul.json @@ -7,7 +7,7 @@ "target": { "A": { "name": "paul", - "value": "192.95.42.75" + "value": ["192.95.42.75"] } }, diff --git a/sub-logs/raja.json b/sub-logs/raja.json index 0b9894b..8427702 100644 --- a/sub-logs/raja.json +++ b/sub-logs/raja.json @@ -7,7 +7,7 @@ "target": { "A": { "name": "Raja", - "value": "43.204.88.80" + "value": ["43.204.88.80"] } }, diff --git a/sub-logs/rehanplayz.json b/sub-logs/rehanplayz.json index d8cbd9d..5a482a0 100644 --- a/sub-logs/rehanplayz.json +++ b/sub-logs/rehanplayz.json @@ -7,7 +7,7 @@ "target": { "A": { "name": "rehanplayz", - "value": "198.251.81.131" + "value": ["198.251.81.131"] } }, diff --git a/sub-logs/reserved/redirect.json b/sub-logs/reserved/redirect.json index 7148adb..651a047 100644 --- a/sub-logs/reserved/redirect.json +++ b/sub-logs/reserved/redirect.json @@ -7,7 +7,7 @@ "target": { "A": { "name": "redirect", - "value": "52.72.49.79" + "value": ["52.72.49.79"] } }, diff --git a/sub-logs/themediocre.json b/sub-logs/themediocre.json index 0344398..27d024f 100644 --- a/sub-logs/themediocre.json +++ b/sub-logs/themediocre.json @@ -7,11 +7,11 @@ "target": { "A": { "name": "themediocre", - "value": "34.132.134.162" + "value": ["34.132.134.162"] }, "TXT": { - "name": "themediocre", + "name": "@", "value": "replit-verify=7a770ba4-a691-4406-b81a-e009a792e0ae" } }, diff --git a/sub-logs/tonywu.json b/sub-logs/tonywu.json index dbb089e..90c62c8 100644 --- a/sub-logs/tonywu.json +++ b/sub-logs/tonywu.json @@ -11,7 +11,7 @@ }, "TXT": { - "name": "_github-pages-challenge-vuquangthinh.tonywu", + "name": "_github-pages-challenge-vuquangthinh", "value": "0b9dc3e2752d1dc520c401ce8b7557" } }, diff --git a/sub-logs/vishal.json b/sub-logs/vishal.json index 7d82fd4..8b1c1e1 100644 --- a/sub-logs/vishal.json +++ b/sub-logs/vishal.json @@ -7,7 +7,7 @@ "target": { "A": { "name": "vishal", - "value": "43.205.87.144" + "value": ["43.205.87.144"] } }, diff --git a/tests/json.test.js b/tests/json.test.js deleted file mode 100644 index c185eea..0000000 --- a/tests/json.test.js +++ /dev/null @@ -1,61 +0,0 @@ -const core = require('@actions/core'); -const getJSON = require('../utils/getJSON.js'); -const checkInfo = require('../utils/checkInfo.js'); -const checkRecords = require('../utils/checkRecords.js'); -const getFileName = require('../utils/getFileName.js'); -const data = getJSON(process.env.FILES); - -function setupMessages() { - core.setOutput('infoMessage', "Could not validate info."); - core.setOutput('recordMessage', "Could not validate records."); - core.setOutput('jsonData', JSON.stringify(data, null, 2)) - core.setOutput('shouldComment', 'true') -}; - -function outputInvalidJsonFile() { - core.setOutput('infoMessage', "Could not validate info."); - core.setOutput('recordMessage', "Could not validate records."); - core.setOutput('jsonData', "Could not read the JSON file, did you have an error in your syntax?") - core.setOutput('shouldComment', 'true') -} - -beforeAll(() => { - setupMessages(); - if (data == 3) { - outputInvalidJsonFile(); - - console.log("ERROR: JSON file is invalid. Either the file is not JSON, or there is an error in the JSON syntax."); - return process.exit(1) - }; - - if (data == false) { - core.setOutput('shouldComment', 'false') - console.log('INFO: File is not a subdomain JSON file.') - return process.exit(0) - }; -}); - -test('check if json file has required info', async () => { - const passed = await checkInfo(data); - let infoMessage = passed === true ? "Valid information provided." : passed === "unknown" ? "Error verifying email address.\nA maintainer will have to manually verify your email address.\nReason:" : "Invalid information provided.\nPlease check your provided information.\nReason:"; - - core.setOutput('infoMessage', infoMessage); - expect(passed).toBeTruthy(); -}, 15000); - -test('Check if JSON file follows format', () => { - const passed = checkRecords(data); - let recordMessage = passed === true ? "Valid records provided." : "Invalid records provided.\nPlease check your provided records.\nThey should only be of type `A`, `CNAME` or `TXT`, and should follow their respective formats."; - - core.setOutput('recordMessage', recordMessage); - expect(passed).toBe(true); -}); - -test('Check if JSON file matches the value name', () => { - const passed = getFileName(process.env.FILES, data); - - let fileNameMessage = passed === true ? "File name matches target.RECORD_TYPE." : "File name does not match any target.RECORD_TYPE."; - - core.setOutput('fileNameMessage', fileNameMessage); - expect(passed).toBe(true); -}); diff --git a/utils/checkInfo.js b/utils/checkInfo.js deleted file mode 100644 index d2fd215..0000000 --- a/utils/checkInfo.js +++ /dev/null @@ -1,27 +0,0 @@ -const fetch = require('node-fetch'); -const core = require('@actions/core'); - -async function checkEmail(email) { - console.log(`Checking: ${email}`); - - const url = `https://api.is-a-good.dev/email-check?key=6lPyUV2dX8&email=${encodeURIComponent(email)}`; - - const options = { - method: 'GET' - } - - const res = await fetch(url, options).then(res => res.json()); - console.log(res); - - core.setOutput('infoReason', res.reason); - - if (res.data.valid) return true; - - return false; -} - -async function checkInfo(data) { - return await checkEmail(data.owner.email); -} - -module.exports = checkInfo; diff --git a/utils/checkRecords.js b/utils/checkRecords.js deleted file mode 100644 index 201d8e8..0000000 --- a/utils/checkRecords.js +++ /dev/null @@ -1,35 +0,0 @@ -const { checkIfValidIP, checkIfValidIPv6, checkIfValidFQDN, checkInvalidDomain, isString } = require('./utils.js'); - -function checkRecords(data) { - const recordType = Object.keys(data.target)[0]; - const value = data.target[recordType].value; - // Check if the domain is invalid - if (checkInvalidDomain(data.target[recordType].name) === true) return false; - - // Check AAAA record - if (recordType.toLowerCase() === 'aaaa') { - if (!Array.isArray(value)) return false; - for (const record of value) { - if (checkIfValidIPv6(record) == false) return false; - } - return true; - } - // Check A record - if (recordType.toLowerCase() === 'a') { - if (!Array.isArray(value)) return false; - for (const record of value) { - if (checkIfValidIP(record) == false) return false; - } - return true; - } - - // Check CNAME record - if (recordType.toLowerCase() === 'cname') { - if (!isString(value)) return false; - return checkIfValidFQDN(value); - } - - return false; -} - -module.exports = checkRecords; diff --git a/utils/getFileName.js b/utils/getFileName.js deleted file mode 100644 index 508fe66..0000000 --- a/utils/getFileName.js +++ /dev/null @@ -1,13 +0,0 @@ -const { stripExt } = require('./utils.js'); - -function getFileName(file, data) { - - const fileNameWithoutExt = stripExt(file); - - // Validate if the file name matches any of the target.RECORD_TYPE values - const recordTypes = Object.values(data.target); - - return recordTypes[0].name == fileNameWithoutExt.toLowerCase().split("/")[1]; -} - -module.exports = getFileName; diff --git a/utils/getJSON.js b/utils/getJSON.js deleted file mode 100644 index 077e3fc..0000000 --- a/utils/getJSON.js +++ /dev/null @@ -1,36 +0,0 @@ -const fs = require('fs'); -const { getFileExtension, stripExt } = require('./utils.js'); -const core = require('@actions/core'); - -function getJSON(file) { - - const path = `${process.env.actions_path}/${file}`; // File path. - - const ext = getFileExtension(file); - if (path.includes("sub-logs") && !ext || ext != 'json') return 3 //if file is subdomain file but has no ext or diff ext than .json - if (!ext) return false; // If no file extension, return. - if (ext != 'json') return false; // If file extension is not '.json' return. - - try { - if (fs.existsSync(path)) { // Check if file exists in domain directory - - // It exists - const rawdata = fs.readFileSync(path); // Read the file - const data = JSON.parse(rawdata); // Parse it - - return data; // Return the parsed data if validation passes - } - return 3; // It doesn't exist - } catch(err) { - - core.setOutput('infoMessage', "Could not validate info."); - core.setOutput('recordMessage', "Could not validate records."); - core.setOutput('jsonData', "Could not read the JSON file, did you have an error in your syntax?") - core.setOutput('shouldComment', 'true') - console.log(err); - return 3; - } - return 3; -} - -module.exports = getJSON; \ No newline at end of file diff --git a/utils/invalid-domains.json b/utils/invalid-domains.json deleted file mode 100644 index fa04c3a..0000000 --- a/utils/invalid-domains.json +++ /dev/null @@ -1,52 +0,0 @@ -[ - "*", - "_acme-challenge", - "_github-challenge-is-a-good-dev", - "_github-pages-challenge-is-a-good-dev", - "email", - "example", - "help", - "mail", - "no-reply", - "noreply", - "notification", - "notifications", - "support", - "will", - "ww", - "ww1", - "ww2", - "ww3", - "ww4", - "ww5", - "ww6", - "ww7", - "ww8", - "ww9", - "wwww", - "your-domain-name", - "www", - "docs", - "cdn", - "dashboard", - "create", - "documentation", - "doc", - "content", - "network", - "shop", - "test", - "php", - "js", - "html", - "css", - "wordpress", - "wp", - "info", - "information", - "admin", - "administration", - "json", - "dev", - "developer" -] diff --git a/utils/utils.js b/utils/utils.js deleted file mode 100644 index 8e90325..0000000 --- a/utils/utils.js +++ /dev/null @@ -1,74 +0,0 @@ -const invalidDomains = require('./invalid-domains.json'); -const fs = require('fs'); -const core = require('@actions/core'); - -function getFiles(path) { - // Get all files in path: returns array - const allFiles = fs.readdirSync(path); - - return allFiles; -} - -function getFileExtension(filename) { - // Get file extension - return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename) : undefined; -} - -function stripExt(filename) { - // Remove file extension - return filename.substr(0, filename.lastIndexOf('.')); -} - -function checkIfValidIP(str) { - // Check if the IP address is valid - const regexExp = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/gm; - - return regexExp.test(str); -} - -function checkIfValidIPv6(str) { - // Insane regex to check if IPv6 address is valid. - const regexExp = /^(?:(?:[a-fA-F\d]{1,4}:){7}(?:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){6}(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){5}(?::(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,2}|:)|(?:[a-fA-F\d]{1,4}:){4}(?:(?::[a-fA-F\d]{1,4}){0,1}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,3}|:)|(?:[a-fA-F\d]{1,4}:){3}(?:(?::[a-fA-F\d]{1,4}){0,2}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,4}|:)|(?:[a-fA-F\d]{1,4}:){2}(?:(?::[a-fA-F\d]{1,4}){0,3}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,5}|:)|(?:[a-fA-F\d]{1,4}:){1}(?:(?::[a-fA-F\d]{1,4}){0,4}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,6}|:)|(?::(?:(?::[a-fA-F\d]{1,4}){0,5}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,7}|:)))(?:%[0-9a-zA-Z]{1,})?$/gm; - - return regexExp.test(str); -} - -function checkIfValidFQDN(str) { - // Check if the FQDN is valid - const regexExp = /(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{0,62}[a-zA-Z0-9]\.)+[a-zA-Z]{2,63}$)/gi; - - return regexExp.test(str); -} - -function checkInvalidDomain(str) { - // Check invalid domains - if (invalidDomains.includes(str)) { - core.setOutput("recordInfo", "This subdomain has been blocked.") - return true; - } - - // Check reserved domains - const files = getFiles("./sub-logs/reserved/").map(file => stripExt(file)); - - if (files.includes(str)) { - core.setOutput("recordInfo", "This subdomain has been reserved by the is-a-good.dev team.") - return true; - } - - return false; -} - -function isString(value) { - return typeof value === 'string' || value instanceof String; -} - -module.exports = { - checkInvalidDomain, - checkIfValidFQDN, - checkIfValidIP, - checkIfValidIPv6, - stripExt, - getFileExtension, - getFiles, - isString -}