import { cookies } from "next/headers"; import { SESSION_COOKIE_NAME, getAuthRuntimeConfig } from "@/lib/auth/config"; import { hasAdminAccess } from "@/lib/auth/permissions"; import { parseSessionCookieValue, readChunkedCookieValue, type AuthSession, type AuthUser } from "@/lib/auth/session"; import { DEFAULT_OWNER_ID } from "@/lib/server/runtime"; export class AuthRequiredError extends Error { status = 401; constructor(message = "请先登录。") { super(message); this.name = "AuthRequiredError"; } } export class AuthConfigurationError extends Error { status = 503; constructor(message: string) { super(message); this.name = "AuthConfigurationError"; } } const localUser: AuthUser = { id: DEFAULT_OWNER_ID, subject: DEFAULT_OWNER_ID, username: "demo", displayName: "智念演示用户", clientId: "local-dev", authorities: ["zhinian_admin"], scope: [] }; function localSession(): AuthSession { const now = Math.floor(Date.now() / 1000); return { version: 1, user: localUser, issuedAt: now, expiresAt: now + 24 * 60 * 60 }; } export async function getOptionalAuthSession(): Promise { const config = getAuthRuntimeConfig(); if (!config.sessionSecret) return null; const cookieStore = await cookies(); return parseSessionCookieValue( readChunkedCookieValue(SESSION_COOKIE_NAME, (name) => cookieStore.get(name)?.value), config.sessionSecret ); } export async function requireAppSession(): Promise { const session = await getOptionalAuthSession(); if (session) return session; const config = getAuthRuntimeConfig(); if (!config.required) return localSession(); if (!config.configured) { throw new AuthConfigurationError(`认证配置不完整:${config.missing.join(", ") || "未知配置"}`); } throw new AuthRequiredError(); } export async function requireAppUser(): Promise { return (await requireAppSession()).user; } export class AdminRequiredError extends Error { status = 403; constructor(message = "需要管理员权限。") { super(message); this.name = "AdminRequiredError"; } } export async function requireAdminUser(): Promise { return (await requireAdminSession()).user; } export async function requireAdminSession(): Promise { const session = await requireAppSession(); if (!hasAdminAccess(session.user)) throw new AdminRequiredError(); return session; } export async function getShellAuthState(): Promise<{ user: AuthUser | null; authRequired: boolean; authConfigured: boolean; isAdmin: boolean; }> { const config = getAuthRuntimeConfig(); const session = await getOptionalAuthSession(); const user = session?.user || (!config.required ? localUser : null); return { user, authRequired: config.required, authConfigured: config.configured, isAdmin: hasAdminAccess(user) }; }