feat: add local auth billing and usage management

This commit is contained in:
inman committed 2026-08-12 12:13:06 +08:00
1 parent f642b5e71f
commit 196fdde83f
119 files changed
+15695 -2650

No files matched your search

+48 -8
View File
@@ -1,8 +1,10 @@
import { cookies } from "next/headers";
import { SESSION_COOKIE_NAME, getAuthRuntimeConfig } from "@/lib/auth/config";
import { hasAdminAccess } from "@/lib/auth/permissions";
import { hasAdminSessionAccess, hasSuperAdminAccess } from "@/lib/auth/permissions";
import { parseSessionCookieValue, readChunkedCookieValue, type AuthSession, type AuthUser } from "@/lib/auth/session";
import { DEFAULT_OWNER_ID } from "@/lib/server/runtime";
import { getPlatformOrganization, getPlatformUserById } from "@/lib/server/account-store";
import { authUserFromPlatformRecord } from "@/lib/server/auth/local";
export class AuthRequiredError extends Error {
status = 401;
@@ -25,9 +27,13 @@ export class AuthConfigurationError extends Error {
const localUser: AuthUser = {
id: DEFAULT_OWNER_ID,
subject: DEFAULT_OWNER_ID,
username: "demo",
displayName: "智念演示用户",
username: "13800000000",
phone: "13800000000",
displayName: "智念用户",
clientId: "local-dev",
role: "super_admin",
organizationId: "org-demo",
organizationName: "演示组织",
authorities: ["zhinian_admin"],
scope: []
};
@@ -36,6 +42,7 @@ function localSession(): AuthSession {
const now = Math.floor(Date.now() / 1000);
return {
version: 1,
authMode: "admin",
user: localUser,
issuedAt: now,
expiresAt: now + 24 * 60 * 60
@@ -46,10 +53,22 @@ export async function getOptionalAuthSession(): Promise<AuthSession | null> {
const config = getAuthRuntimeConfig();
if (!config.sessionSecret) return null;
const cookieStore = await cookies();
return parseSessionCookieValue(
const session = await parseSessionCookieValue(
readChunkedCookieValue(SESSION_COOKIE_NAME, (name) => cookieStore.get(name)?.value),
config.sessionSecret
);
if (!session || session.user.clientId !== "platform") return null;
const account = await getPlatformUserById(session.user.id);
if (!account || account.status !== "active") return null;
if (session.sessionVersion && session.sessionVersion !== account.sessionVersion) return null;
const organization = account.organizationId ? await getPlatformOrganization(account.organizationId) : null;
if (account.role !== "super_admin" && account.organizationId && (!organization || organization.status !== "active")) return null;
return {
...session,
authMode: account.role === "user" ? "user" : "admin",
user: authUserFromPlatformRecord(account, organization),
sessionVersion: account.sessionVersion
};
}
export async function requireAppSession(): Promise<AuthSession> {
@@ -82,23 +101,44 @@ export async function requireAdminUser(): Promise<AuthUser> {
export async function requireAdminSession(): Promise<AuthSession> {
const session = await requireAppSession();
if (!hasAdminAccess(session.user)) throw new AdminRequiredError();
if (!hasAdminSessionAccess(session)) throw new AdminRequiredError();
return session;
}
export class SuperAdminRequiredError extends Error {
status = 403;
constructor(message = "需要超级管理员权限。") {
super(message);
this.name = "SuperAdminRequiredError";
}
}
export async function requireSuperAdminSession(): Promise<AuthSession> {
const session = await requireAppSession();
if (!hasSuperAdminAccess(session.user)) throw new SuperAdminRequiredError();
return session;
}
export async function requireSuperAdminUser(): Promise<AuthUser> {
return (await requireSuperAdminSession()).user;
}
export async function getShellAuthState(): Promise<{
user: AuthUser | null;
authRequired: boolean;
authConfigured: boolean;
isAdmin: boolean;
isSuperAdmin: boolean;
}> {
const config = getAuthRuntimeConfig();
const session = await getOptionalAuthSession();
const user = session?.user || (!config.required ? localUser : null);
const shellSession = session || (!config.required ? localSession() : null);
return {
user,
user: shellSession?.user || null,
authRequired: config.required,
authConfigured: config.configured,
isAdmin: hasAdminAccess(user)
isAdmin: hasAdminSessionAccess(shellSession),
isSuperAdmin: hasSuperAdminAccess(shellSession?.user)
};
}