diff --git a/src/server/api/routers/networkRouter.ts b/src/server/api/routers/networkRouter.ts index cb378867..0a7570dd 100644 --- a/src/server/api/routers/networkRouter.ts +++ b/src/server/api/routers/networkRouter.ts @@ -14,7 +14,7 @@ import { Prisma, Role } from "@prisma/client"; import { HookType, NetworkConfigChanged, NetworkDeleted } from "~/types/webhooks"; import { sendWebhook } from "~/utils/webhook"; import { fetchZombieMembers, syncMemberPeersAndStatus } from "../services/memberService"; -import { isValidCIDR, isValidDomain, isValidIP } from "../utils/ipUtils"; +import { isValidCIDR, isValidDns, isValidIP } from "../utils/ipUtils"; import { networkProvisioningFactory } from "../services/networkService"; import { Address4, Address6 } from "ip-address"; @@ -913,7 +913,7 @@ export const networkRouter = createTRPCRouter({ clearDns: z.boolean().optional(), dns: z .object({ - domain: z.string().refine(isValidDomain, { + domain: z.string().refine(isValidDns, { message: "Invalid DNS domain provided", }), servers: z.array( diff --git a/src/server/api/utils/ipUtils.ts b/src/server/api/utils/ipUtils.ts index cc42fdcf..4063b58a 100644 --- a/src/server/api/utils/ipUtils.ts +++ b/src/server/api/utils/ipUtils.ts @@ -127,3 +127,25 @@ export function isValidDomain(domain: string): boolean { const domainRegex = /^(?!-)[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z]{2,}$/; return domainRegex.test(domain); } + +/** + * Checks if a given dns is valid according to ZeroTier's DNS system requirements. + * https://github.com/zerotier/ZeroTierOne/blob/f176e2539e10e8c0f61eb1d2e1f0e690a267a646/include/ZeroTierOne.h#L976C1-L981C1 + * + * @param domain - The domain to be validated. + * @returns `true` if the domain is valid, `false` otherwise. + */ +export function isValidDns(domain: string): boolean { + // Check if the domain is empty or exceeds 128 characters + if (domain.length === 0 || domain.length > 128) { + return false; + } + + // Check if the domain contains any invalid characters + const invalidChars = /[^a-zA-Z0-9.-]/; + if (invalidChars.test(domain)) { + return false; + } + + return true; +}