Files
NianAIGC/lib/server/auth/current-user.ts
2026-05-29 15:54:13 +08:00

65 lines
1.8 KiB
TypeScript

import { cookies } from "next/headers";
import { SESSION_COOKIE_NAME, getAuthRuntimeConfig } from "@/lib/auth/config";
import { parseSessionCookieValue, 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: [],
scope: []
};
export async function getOptionalAuthSession(): Promise<AuthSession | null> {
const config = getAuthRuntimeConfig();
if (!config.sessionSecret) return null;
const cookieStore = await cookies();
return parseSessionCookieValue(cookieStore.get(SESSION_COOKIE_NAME)?.value, config.sessionSecret);
}
export async function requireAppUser(): Promise<AuthUser> {
const session = await getOptionalAuthSession();
if (session) return session.user;
const config = getAuthRuntimeConfig();
if (!config.required) return localUser;
if (!config.configured) {
throw new AuthConfigurationError(`认证配置不完整:${config.missing.join(", ") || "未知配置"}`);
}
throw new AuthRequiredError();
}
export async function getShellAuthState(): Promise<{
user: AuthUser | null;
authRequired: boolean;
authConfigured: boolean;
}> {
const config = getAuthRuntimeConfig();
const session = await getOptionalAuthSession();
return {
user: session?.user || null,
authRequired: config.required,
authConfigured: config.configured
};
}