hellth-hub/apps/admin/app/_components/auth-guard.tsx

110 lines
3 KiB
TypeScript
Raw Permalink Normal View History

"use client";
import { useSession } from "@/lib/auth-client";
import { hasCompletedHealthProfile } from "@/lib/hellth-data";
import { trpc } from "@/lib/trpc";
import { usePathname, useRouter } from "next/navigation";
import { useEffect } from "react";
const PLATFORM_ALLOWED_PREFIXES = [
"/",
"/aktivitaeten",
"/benutzer",
"/einstellungen",
"/erinnerungen",
"/hellfireclub",
"/einkaufsliste",
"/lebensmittel",
"/maerkte",
"/onboarding",
"/planung",
"/rezepte",
"/ziele",
"/wochenbudget",
"/sicherheit/2fa-setup",
];
export function AuthGuard({ children }: { children: React.ReactNode }) {
const { data: session, isPending } = useSession();
const router = useRouter();
const pathname = usePathname();
const platformAdminEmails = (
process.env.NEXT_PUBLIC_PLATFORM_ADMIN_EMAILS ?? "admin@onl1.eu"
)
.split(",")
.map((email) => email.trim().toLowerCase())
.filter(Boolean);
const userRole = ((session?.user as { role?: string } | undefined)?.role ?? "").toLowerCase();
const userEmail = (session?.user?.email ?? "").toLowerCase();
const isPlatformAdmin =
userRole === "admin" ||
userRole === "platform_admin" ||
platformAdminEmails.includes(userEmail);
const securityQuery = trpc.security.status.useQuery(undefined, {
enabled: !!session && !isPending,
retry: false,
});
const requiresTwoFactorSetup = securityQuery.data?.requiresTwoFactorSetup ?? false;
useEffect(() => {
if (!isPending && !session) {
router.push("/login");
return;
}
if (!isPending && session) {
if (securityQuery.isLoading) return;
if (requiresTwoFactorSetup && !pathname.startsWith("/sicherheit/2fa-setup")) {
router.push("/sicherheit/2fa-setup");
return;
}
if (isPlatformAdmin) {
const isAllowed = PLATFORM_ALLOWED_PREFIXES.some((prefix) =>
prefix === "/" ? pathname === "/" : pathname.startsWith(prefix),
);
if (!isAllowed) {
router.push("/");
return;
}
} else {
const userKey = session.user.id ?? session.user.email ?? null;
const onboardingComplete = hasCompletedHealthProfile(userKey);
if (!onboardingComplete && !pathname.startsWith("/onboarding")) {
router.push("/onboarding");
return;
}
if (pathname.startsWith("/benutzer") || pathname.startsWith("/einstellungen")) {
router.push("/");
}
}
}
}, [
session,
isPending,
isPlatformAdmin,
pathname,
router,
requiresTwoFactorSetup,
securityQuery.isLoading,
]);
if (isPending || (!!session && securityQuery.isLoading)) {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50">
<div className="flex flex-col items-center gap-3">
<div className="w-8 h-8 border-2 border-[#0F766E] border-t-transparent rounded-full animate-spin" />
<p className="text-sm text-gray-400">Laden...</p>
</div>
</div>
);
}
if (!session) return null;
return <>{children}</>;
}