-
-
Notifications
You must be signed in to change notification settings - Fork 10.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
538 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,4 @@ | ||
* @phenax @wdhdev | ||
* @wdhdev | ||
|
||
/.github/ @wdhdev | ||
/domains/ @is-a-dev/maintainers | ||
|
||
*.md @is-a-dev/maintainers | ||
/LICENSE @phenax | ||
/dnsconfig.js @wdhdev |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"devDependencies": { | ||
"ava": "^6.2.0", | ||
"fs-extra": "^11.2.0" | ||
}, | ||
"scripts": { | ||
"test": "npx ava tests/*.test.js" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
const t = require("ava"); | ||
const fs = require("fs-extra"); | ||
const path = require("path"); | ||
|
||
const domainsPath = path.resolve("domains"); | ||
const files = fs.readdirSync(domainsPath); | ||
|
||
// Nested subdomains should not exist if the parent subdomain does not exist | ||
t("Nested subdomains should not exist without a parent subdomain", (t) => { | ||
files.forEach((file) => { | ||
const subdomain = file.replace(".json", ""); | ||
|
||
if (subdomain.split(".").length > 1) { | ||
const parentSubdomain = subdomain.split(".").pop(); | ||
|
||
t.true( | ||
files.includes(`${parentSubdomain}.json`), | ||
`${file}: Parent subdomain does not exist` | ||
); | ||
} | ||
}); | ||
|
||
t.pass(); | ||
}); | ||
|
||
// Nested subdomains should not exist if the parent subdomain has NS records | ||
t("Nested subdomains should not exist if the parent subdomain has NS records", (t) => { | ||
files.forEach((file) => { | ||
const subdomain = file.replace(".json", ""); | ||
|
||
if (subdomain.split(".").length > 1) { | ||
const parentSubdomain = subdomain.split(".").pop(); | ||
const parentDomain = fs.readJsonSync(path.join(domainsPath, `${parentSubdomain}.json`)); | ||
|
||
t.is(parentDomain.record.NS, undefined, `${file}: Parent subdomain has NS records`); | ||
} | ||
}); | ||
|
||
t.pass(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
const t = require("ava"); | ||
const fs = require("fs-extra"); | ||
const path = require("path"); | ||
|
||
const requiredFields = { | ||
owner: "object", | ||
record: "object", | ||
}; | ||
|
||
const optionalFields = { | ||
proxied: "boolean", | ||
reserved: "boolean", | ||
}; | ||
|
||
const requiredOwnerFields = { | ||
username: "string", | ||
}; | ||
|
||
const optionalOwnerFields = { | ||
email: "string", | ||
}; | ||
|
||
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; | ||
const hostnameRegex = | ||
/^(?=.{1,253}$)(?:(?:[_a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)\.)+[a-zA-Z]{2,63}$/; | ||
|
||
const domainsPath = path.resolve("domains"); | ||
const files = fs.readdirSync(domainsPath); | ||
|
||
const validateRequiredFields = (t, obj, requiredFields, file) => { | ||
Object.keys(requiredFields).forEach((key) => { | ||
t.true(obj.hasOwnProperty(key), `${file}: Missing required field: ${key}`); | ||
t.is( | ||
typeof obj[key], | ||
requiredFields[key], | ||
`${file}: Field ${key} should be of type ${requiredFields[key]}` | ||
); | ||
}); | ||
}; | ||
|
||
const validateOptionalFields = (t, obj, optionalFields, file) => { | ||
Object.keys(optionalFields).forEach((key) => { | ||
if (obj.hasOwnProperty(key)) { | ||
t.is( | ||
typeof obj[key], | ||
optionalFields[key], | ||
`${file}: Field ${key} should be of type ${optionalFields[key]}` | ||
); | ||
} | ||
}); | ||
}; | ||
|
||
// Ensure all files are valid JSON | ||
t("All files should be valid JSON", (t) => { | ||
files.forEach((file) => { | ||
t.notThrows(() => fs.readJsonSync(path.join(domainsPath, file)), `${file}: Invalid JSON file`); | ||
}); | ||
}); | ||
|
||
// Ensure all files have the required fields | ||
t("All files should have valid file names", (t) => { | ||
files.forEach((file) => { | ||
t.true(file.endsWith(".json"), `${file}: File does not have .json extension`); | ||
t.false(file.includes(".is-a.dev"), `${file}: File name should not contain .is-a.dev`); | ||
|
||
// Ignore root domain | ||
if (file !== "@.json") { | ||
t.regex( | ||
file.replace(/\.json$/, "") + ".is-a.dev", | ||
hostnameRegex, | ||
`${file}: FQDN must be 1-253 characters, use letters, numbers, dots, or hyphens, and not start or end with a hyphen.` | ||
); | ||
} | ||
}); | ||
}); | ||
|
||
// Ensure all files have the required fields | ||
t("All files should have the required fields", (t) => { | ||
files.forEach((file) => { | ||
const data = fs.readJsonSync(path.join(domainsPath, file)); | ||
|
||
validateRequiredFields(t, data, requiredFields, file); | ||
validateRequiredFields(t, data.owner, requiredOwnerFields, file); | ||
|
||
if (!data.reserved) { | ||
t.true(Object.keys(data.record).length > 0, `${file}: No record types found`); | ||
} | ||
}); | ||
}); | ||
|
||
// Validate the optional fields | ||
t("All files should have valid optional fields", (t) => { | ||
files.forEach((file) => { | ||
const data = fs.readJsonSync(path.join(domainsPath, file)); | ||
|
||
validateOptionalFields(t, data, optionalFields, file); | ||
validateOptionalFields(t, data.owner, optionalOwnerFields, file); | ||
|
||
if (data.owner.email) { | ||
t.regex( | ||
data.owner.email, | ||
emailRegex, | ||
`${file}: Owner email should be a valid email address` | ||
); | ||
} | ||
}); | ||
}); |
Oops, something went wrong.