import { cookies, headers } from "next/headers" import { redirect } from "next/navigation" import { getCookieCache } from "better-auth/cookies" import { env } from "@/lib/env" import { isAdmin, isStaff } from "@/lib/authz" type ServerSession = Awaited> async function serializeCookies() { const store = await cookies() return store.getAll().map((cookie) => `${cookie.name}=${cookie.value}`).join("; ") } async function buildRequest() { const cookieHeader = await serializeCookies() const headerList = await headers() const userAgent = headerList.get("user-agent") ?? "" const ip = headerList.get("x-forwarded-for") || headerList.get("x-real-ip") || headerList.get("cf-connecting-ip") || headerList.get("x-client-ip") || undefined // Evitar fallback para localhost em produção: tenta BETTER_AUTH_URL, // depois NEXT_PUBLIC_APP_URL e, por fim, o host do próprio request. const forwardedProto = headerList.get("x-forwarded-proto") const forwardedHost = headerList.get("x-forwarded-host") ?? headerList.get("host") const requestOrigin = forwardedProto && forwardedHost ? `${forwardedProto}://${forwardedHost}` : undefined const baseUrl = env.BETTER_AUTH_URL || env.NEXT_PUBLIC_APP_URL || requestOrigin || "http://localhost:3000" return new Request(baseUrl, { headers: { cookie: cookieHeader, "user-agent": userAgent, ...(ip ? { "x-forwarded-for": ip } : {}), }, }) } export async function getServerSession(): Promise { try { const request = await buildRequest() const session = await getCookieCache(request) return session ?? null } catch (error) { console.error("Failed to read Better Auth session", error) return null } } export async function assertAuthenticatedSession() { const session = await getServerSession() return session?.user ? session : null } export async function requireAuthenticatedSession() { const session = await assertAuthenticatedSession() if (!session) { redirect("/login") } return session } export async function assertStaffSession() { const session = await assertAuthenticatedSession() if (!session) return null if (!isStaff(session.user.role)) { return null } return session } export async function requireStaffSession() { const session = await assertStaffSession() if (!session) { redirect("/portal") } return session } export async function assertAdminSession() { const session = await assertAuthenticatedSession() if (!session) return null if (!isAdmin(session.user.role)) { return null } return session } export async function requireAdminSession() { const session = await assertAdminSession() if (!session) { redirect("/dashboard") } return session }