feat: add admin accounts and image templates

This commit is contained in:
inman
2026-07-03 11:25:25 +08:00
parent d98e58adfa
commit c3ea9f0eb1
61 changed files with 7016 additions and 199 deletions

View File

@@ -1,6 +1,7 @@
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 { 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 {
@@ -27,38 +28,77 @@ const localUser: AuthUser = {
username: "demo",
displayName: "智念演示用户",
clientId: "local-dev",
authorities: [],
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<AuthSession | null> {
const config = getAuthRuntimeConfig();
if (!config.sessionSecret) return null;
const cookieStore = await cookies();
return parseSessionCookieValue(cookieStore.get(SESSION_COOKIE_NAME)?.value, config.sessionSecret);
return parseSessionCookieValue(
readChunkedCookieValue(SESSION_COOKIE_NAME, (name) => cookieStore.get(name)?.value),
config.sessionSecret
);
}
export async function requireAppUser(): Promise<AuthUser> {
export async function requireAppSession(): Promise<AuthSession> {
const session = await getOptionalAuthSession();
if (session) return session.user;
if (session) return session;
const config = getAuthRuntimeConfig();
if (!config.required) return localUser;
if (!config.required) return localSession();
if (!config.configured) {
throw new AuthConfigurationError(`认证配置不完整:${config.missing.join(", ") || "未知配置"}`);
}
throw new AuthRequiredError();
}
export async function requireAppUser(): Promise<AuthUser> {
return (await requireAppSession()).user;
}
export class AdminRequiredError extends Error {
status = 403;
constructor(message = "需要管理员权限。") {
super(message);
this.name = "AdminRequiredError";
}
}
export async function requireAdminUser(): Promise<AuthUser> {
return (await requireAdminSession()).user;
}
export async function requireAdminSession(): Promise<AuthSession> {
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: session?.user || null,
user,
authRequired: config.required,
authConfigured: config.configured
authConfigured: config.configured,
isAdmin: hasAdminAccess(user)
};
}