Revert "PHP Rebuild"

This reverts commit 2ef3654841.
This commit is contained in:
Stefan Lazic committed 2026-09-05 09:32:05 +01:00
1 parent a59f998f2b
commit 2aa8405006
690 files changed
+12045 -33943

No files matched your search

@@ -0,0 +1,79 @@
import { createHmac, timingSafeEqual } from "node:crypto";
import { cookies } from "next/headers";
import { isSecureDeployment } from "@/lib/security/cookie-security";
import { getManagerConfig } from "./manager-config";
const COOKIE_NAME = "nextchair_manager_session";
function signature(value: string, secret: string) {
return createHmac("sha256", secret).update(value).digest("hex");
}
export function isManagerConfigured() {
const config = getManagerConfig();
return Boolean(config.adminEmail && config.adminPassword && config.authSecret);
}
export function authenticateManager(email: string, password: string) {
const config = getManagerConfig();
if (!isManagerConfigured() || email.trim().toLowerCase() !== config.adminEmail.trim().toLowerCase()) return false;
const expected = Buffer.from(config.adminPassword);
const received = Buffer.from(password);
return expected.length === received.length && timingSafeEqual(expected, received);
}
export async function createManagerSession() {
const config = getManagerConfig();
const value = `${config.adminEmail.trim().toLowerCase()}.${Date.now()}`;
const store = await cookies();
// Remove sessions issued by older builds with Path=/manager. Browsers can
// retain both cookies, and the stale one may be selected first on /manager.
store.set(COOKIE_NAME, "", { path: "/manager", maxAge: 0 });
store.set(COOKIE_NAME, `${value}.${signature(value, config.authSecret)}`, {
httpOnly: true,
sameSite: "strict",
secure: isSecureDeployment(),
// The Manager UI is under /manager, but its authenticated API is under
// /api/manager, so the cookie must cover both paths.
path: "/",
maxAge: 60 * 60 * 8,
});
}
export async function clearManagerSession() {
const store = await cookies();
store.delete(COOKIE_NAME);
store.set(COOKIE_NAME, "", { path: "/manager", maxAge: 0 });
}
export async function isManagerAuthenticated() {
const config = getManagerConfig();
console.log("[manager-auth] auth secret:", config.authSecret ? "set" : "missing");
if (!config.authSecret) return false;
const cookieStore = await cookies();
const rawValue = cookieStore.get(COOKIE_NAME)?.value;
console.log("[manager-auth] cookie:", rawValue ? "received" : "missing");
const value = rawValue ? decodeURIComponent(rawValue) : undefined;
if (!value) return false;
const separator = value.lastIndexOf(".");
if (separator < 1) return false;
const payload = value.slice(0, separator);
const received = Buffer.from(value.slice(separator + 1));
const expected = Buffer.from(signature(payload, config.authSecret));
const valid =
received.length === expected.length &&
timingSafeEqual(received, expected);
console.log("[manager-auth] signature valid:", valid);
return valid;
}