Files
caddy-proxy-manager/src/lib/proxy-host-domains.ts
fuomag9 73c90894b1 Handle wildcard proxy hosts and stabilize test coverage
- accept wildcard proxy host domains like *.example.com with validation and normalization
- make exact hosts win over overlapping wildcards in generated routes and TLS policies
- add unit coverage for host-pattern priority and wildcard domain handling
- add a single test:all entry point and clean up lint/typecheck issues so the suite runs cleanly
- run mobile layout Playwright checks under both chromium and mobile-iphone
2026-03-14 01:03:34 +01:00

53 lines
1.3 KiB
TypeScript

import { isIP } from "node:net";
const HOST_LABEL_REGEX = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
function isValidHostname(value: string) {
if (!value || value.length > 253) {
return false;
}
return value.split(".").every((label) => HOST_LABEL_REGEX.test(label));
}
export function isValidProxyHostDomain(value: string) {
const normalized = value.trim().toLowerCase().replace(/\.$/, "");
if (!normalized) {
return false;
}
if (normalized.startsWith("*.")) {
const baseDomain = normalized.slice(2);
return !baseDomain.includes("*") && isValidHostname(baseDomain);
}
if (normalized.includes("*")) {
return false;
}
return isIP(normalized) !== 0 || isValidHostname(normalized);
}
export function normalizeProxyHostDomains(domains: string[]) {
const normalizedDomains = Array.from(
new Set(
domains
.map((domain) => domain.trim().toLowerCase().replace(/\.$/, ""))
.filter(Boolean)
)
);
if (normalizedDomains.length === 0) {
throw new Error("At least one domain must be specified");
}
const invalidDomain = normalizedDomains.find((domain) => !isValidProxyHostDomain(domain));
if (invalidDomain) {
throw new Error(
`Invalid domain "${invalidDomain}". Wildcards are supported only as the left-most label, for example "*.example.com".`
);
}
return normalizedDomains;
}