mirror of
https://github.com/fosrl/pangolin.git
synced 2026-03-07 11:16:37 +00:00
subdomain validation consistent
This commit is contained in:
@@ -1,18 +1,24 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
|
|
||||||
export const subdomainSchema = z
|
export const subdomainSchema = z
|
||||||
.string()
|
.string()
|
||||||
.regex(
|
.regex(
|
||||||
/^(?!:\/\/)([a-zA-Z0-9-_]+\.)*[a-zA-Z0-9-_]+$/,
|
/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/,
|
||||||
"Invalid subdomain format"
|
"Invalid subdomain format"
|
||||||
)
|
)
|
||||||
.min(1, "Subdomain must be at least 1 character long")
|
.min(1, "Subdomain must be at least 1 character long")
|
||||||
|
.max(63, "Subdomain must not exceed 63 characters")
|
||||||
.transform((val) => val.toLowerCase());
|
.transform((val) => val.toLowerCase());
|
||||||
|
|
||||||
export const tlsNameSchema = z
|
export const tlsNameSchema = z
|
||||||
.string()
|
.string()
|
||||||
.regex(
|
.regex(
|
||||||
/^(?!:\/\/)([a-zA-Z0-9-_]+\.)*[a-zA-Z0-9-_]+$|^$/,
|
/^([a-z0-9](?:[a-z0-9-]*[a-z0-9])?)(\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)*$/,
|
||||||
"Invalid subdomain format"
|
"Invalid subdomain format"
|
||||||
)
|
).max(253, "Domain must not exceed 253 characters")
|
||||||
|
.refine((val) => {
|
||||||
|
const labels = val.split('.');
|
||||||
|
return labels.every((label) => label.length <= 63);
|
||||||
|
}, "Each part of the domain must not exceed 63 characters")
|
||||||
.transform((val) => val.toLowerCase());
|
.transform((val) => val.toLowerCase());
|
||||||
@@ -263,7 +263,7 @@ export default function DomainPicker2({
|
|||||||
|
|
||||||
if (baseDomain.type === "provided-search") {
|
if (baseDomain.type === "provided-search") {
|
||||||
return subdomain === "" || (
|
return subdomain === "" || (
|
||||||
/^[a-zA-Z0-9.-]+$/.test(subdomain) &&
|
/^[a-zA-Z0-9-]+$/.test(subdomain) &&
|
||||||
isValidSubdomainStructure(subdomain)
|
isValidSubdomainStructure(subdomain)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -274,7 +274,7 @@ export default function DomainPicker2({
|
|||||||
} else if (baseDomain.domainType === "ns" || baseDomain.domainType === "wildcard") {
|
} else if (baseDomain.domainType === "ns" || baseDomain.domainType === "wildcard") {
|
||||||
// NS and wildcard domains support multi-level subdomains with dots and hyphens
|
// NS and wildcard domains support multi-level subdomains with dots and hyphens
|
||||||
return subdomain === "" || (
|
return subdomain === "" || (
|
||||||
/^[a-zA-Z0-9.-]+$/.test(subdomain) &&
|
/^[a-zA-Z0-9-]+$/.test(subdomain) &&
|
||||||
isValidSubdomainStructure(subdomain)
|
isValidSubdomainStructure(subdomain)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -287,24 +287,17 @@ export default function DomainPicker2({
|
|||||||
if (!input) return "";
|
if (!input) return "";
|
||||||
return input
|
return input
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.replace(/[^a-z0-9.-]/g, "");
|
.replace(/[^a-z0-9-]/g, "");
|
||||||
};
|
};
|
||||||
|
|
||||||
const isValidSubdomainStructure = (subdomain: string): boolean => {
|
const isValidSubdomainStructure = (subdomain: string): boolean => {
|
||||||
if (!subdomain) return true;
|
if (!subdomain) return true;
|
||||||
|
|
||||||
// check for consecutive dots or hyphens
|
// Check for consecutive hyphens
|
||||||
if (/\.{2,}|-{2,}/.test(subdomain)) return false;
|
if (/--/.test(subdomain)) return false;
|
||||||
|
|
||||||
// check if starts or ends with hyphen or dot
|
// Check if starts or ends with hyphen
|
||||||
if (/^[-.]|[-.]$/.test(subdomain)) return false;
|
if (/^-|-$/.test(subdomain)) return false;
|
||||||
|
|
||||||
// check each label >> (part between dots)
|
|
||||||
const parts = subdomain.split(".");
|
|
||||||
for (const part of parts) {
|
|
||||||
if (!part) return false; // Empty label
|
|
||||||
if (/^-|-$/.test(part)) return false; // Label starts/ends with hyphen
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@@ -369,7 +362,7 @@ export default function DomainPicker2({
|
|||||||
if (value !== sanitized) {
|
if (value !== sanitized) {
|
||||||
toast({
|
toast({
|
||||||
title: "Invalid characters removed",
|
title: "Invalid characters removed",
|
||||||
description: `Only letters, numbers, hyphens, and dots are allowed`,
|
description: `Only letters, numbers, and hyphens are allowed`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user