Files
EpicNext-Cms/src/lib/access-guard.ts
T
openhands df38dccbf1
Local Build and Deploy / deploy (push) Failing after 46s
style: format code biome
2026-07-13 21:57:41 +02:00

87 lines
2.0 KiB
TypeScript

import { headers } from "next/headers";
import { redirect } from "next/navigation";
import { auth } from "@/lib/auth";
import { safeRedirect } from "@/lib/foundation/security";
import { logger } from "@/lib/logger";
import { prisma } from "@/lib/prisma";
import { isIpBlacklisted, recordRequest } from "@/lib/services/abuse-guard";
import { siteSettings } from "@/lib/services/site-settings";
const EXEMPT = [
"/banned",
"/maintenance",
"/login",
"/register",
"/forgot",
"/reset",
"/api",
];
function isExempt(path: string): boolean {
return EXEMPT.some((p) => path === p || path.startsWith(`${p}/`));
}
export async function enforceSiteAccess(): Promise<void> {
const h = await headers();
const path = h.get("x-pathname") ?? "/";
const ip =
h.get("x-real-client-ip") ??
h.get("x-forwarded-for")?.split(",")[0]?.trim() ??
"0.0.0.0";
void recordRequest(ip).catch(() => {});
if (isExempt(path)) return;
let target: string | null = null;
let checksDegraded = false;
try {
if (await isIpBlacklisted(ip)) target = "/banned";
} catch {
checksDegraded = true;
}
try {
const session = await auth();
const rank = session?.user?.rank ?? 0;
try {
if (
!target &&
(await siteSettings.getBool("maintenance_enabled", false))
) {
const minLogin =
Number(await siteSettings.get("min_maintenance_login_rank", "7")) ||
7;
if (rank < minLogin) target = "/maintenance";
}
} catch {
checksDegraded = true;
}
try {
if (!target && session?.user?.id) {
const now = Math.floor(Date.now() / 1000);
const ban = await prisma.ban.findFirst({
where: { userId: Number(session.user.id), banExpire: { gt: now } },
select: { id: true },
});
if (ban) target = "/banned";
}
} catch {
checksDegraded = true;
}
} catch {
checksDegraded = true;
}
if (target) {
redirect(safeRedirect(target, target));
}
if (checksDegraded) {
logger.warn("Access guard degraded — some checks skipped", { ip, path });
}
}