feat: add local auth billing and usage management
This commit is contained in:
1 parent
f642b5e71f
commit
196fdde83f
119 files changed
+15695
-2650
No files matched your search
@@ -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)
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user