Refactor admin area and remove legacy root paths
CI / quality (push) Waiting to run

This commit is contained in:
MOH
2026-03-13 16:14:04 +01:00
parent e32ac4cacb
commit db897e22bf
65 changed files with 216 additions and 140 deletions
+71
View File
@@ -15,6 +15,75 @@ function getPassword(): string {
return process.env.ADMIN_PASSWORD ?? "";
}
function parseHostname(value: string | undefined): string | undefined {
if (!value) {
return undefined;
}
const trimmed = value.trim().toLowerCase();
if (!trimmed) {
return undefined;
}
try {
return new URL(trimmed).hostname.toLowerCase();
} catch {
return trimmed.replace(/^https?:\/\//, "").split("/")[0]?.replace(/:\d+$/, "") || undefined;
}
}
function isCookieDomainCandidate(hostname: string | undefined): hostname is string {
return Boolean(
hostname &&
hostname !== "localhost" &&
!hostname.endsWith(".localhost") &&
!/^\d{1,3}(\.\d{1,3}){3}$/.test(hostname) &&
!hostname.includes(":"),
);
}
function getSharedCookieHostname(hostnames: string[]): string | undefined {
const validHostnames = hostnames.filter(isCookieDomainCandidate);
if (validHostnames.length === 0) {
return undefined;
}
if (validHostnames.length === 1) {
return validHostnames[0];
}
const reversedSegments = validHostnames.map((hostname) => hostname.split(".").reverse());
const sharedSegments: string[] = [];
for (let index = 0; index < reversedSegments[0].length; index += 1) {
const segment = reversedSegments[0][index];
if (!segment || reversedSegments.some((parts) => parts[index] !== segment)) {
break;
}
sharedSegments.push(segment);
}
if (sharedSegments.length < 2) {
return validHostnames[0];
}
return sharedSegments.reverse().join(".");
}
function getAdminCookieDomain(): string | undefined {
const hostname = getSharedCookieHostname([
parseHostname(process.env.NEXT_PUBLIC_SITE_URL),
parseHostname(process.env.NEXT_PUBLIC_ADMIN_URL),
parseHostname(process.env.ADMIN_HOST),
].filter((value): value is string => Boolean(value)));
return hostname ? `.${hostname}` : undefined;
}
function signValue(value: string): string {
return createHmac("sha256", getSecret()).update(value).digest("hex");
}
@@ -71,6 +140,7 @@ export async function setAdminSessionCookie(): Promise<void> {
sameSite: "lax",
secure: process.env.NODE_ENV === "production",
path: "/",
domain: getAdminCookieDomain(),
maxAge: 60 * 60 * 8,
});
}
@@ -82,6 +152,7 @@ export async function clearAdminSessionCookie(): Promise<void> {
sameSite: "lax",
secure: process.env.NODE_ENV === "production",
path: "/",
domain: getAdminCookieDomain(),
maxAge: 0,
});
}