feat: add global auth settings and pending users

This commit is contained in:
2026-07-02 06:27:32 -07:00
parent f6b7924d0c
commit 4bb4312b08
24 changed files with 2831 additions and 23 deletions

View File

@@ -61,6 +61,7 @@ export async function PATCH(request: Request, context: RouteContext): Promise<Re
const oidcClientSecret = readString(body, "oidcClientSecret");
const oidcScopes = readString(body, "oidcScopes");
const oidcRedirectUri = readString(body, "oidcRedirectUri");
const oidcAvatarClaim = readString(body, "oidcAvatarClaim");
const status = "status" in body ? readStatus(body.status) : null;
if ("status" in body && !status) {
return jsonFailure("机构状态无效");
@@ -77,6 +78,9 @@ export async function PATCH(request: Request, context: RouteContext): Promise<Re
if ("oidcAutoProvision" in body && oidcAutoProvision === null) {
return jsonFailure("OIDC自动开户配置无效");
}
if (oidcEnabled === true && (!oidcIssuerUrl || !oidcClientId)) {
return jsonFailure("启用 OIDC 前请填写 Issuer URL 和 Client ID");
}
if (
!name &&
@@ -89,6 +93,7 @@ export async function PATCH(request: Request, context: RouteContext): Promise<Re
!oidcClientSecret &&
!oidcScopes &&
!oidcRedirectUri &&
!oidcAvatarClaim &&
oidcAutoProvision === null
) {
return jsonFailure("请至少填写一个要更新的字段");
@@ -105,6 +110,7 @@ export async function PATCH(request: Request, context: RouteContext): Promise<Re
oidcClientSecret?: string;
oidcScopes?: string;
oidcRedirectUri?: string;
oidcAvatarClaim?: string;
oidcAutoProvision?: boolean;
updatedAt: Date;
} = {
@@ -141,6 +147,9 @@ export async function PATCH(request: Request, context: RouteContext): Promise<Re
if (oidcRedirectUri) {
updateValues.oidcRedirectUri = oidcRedirectUri;
}
if (oidcAvatarClaim) {
updateValues.oidcAvatarClaim = oidcAvatarClaim;
}
if (oidcAutoProvision !== null) {
updateValues.oidcAutoProvision = oidcAutoProvision;
}

View File

@@ -6,6 +6,7 @@ import { requirePermission } from "@/modules/core/server/auth";
import { getDatabase } from "@/modules/core/server/db";
import { seedOrganizationRoles } from "@/modules/core/server/permissions";
import { organizations } from "@/modules/core/server/schema";
import { getSystemSettings } from "@/modules/core/server/system-settings";
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -28,11 +29,14 @@ function createSlug(name: string): string {
export async function GET(): Promise<Response> {
const database = getDatabase();
const rows = await database.select().from(organizations).where(eq(organizations.status, "active"));
const [settings, rows] = await Promise.all([
getSystemSettings(),
database.select().from(organizations).where(eq(organizations.status, "active")),
]);
return jsonSuccess("机构列表已加载", {
organizations: rows
.filter((organization) => organization.registrationEnabled)
.filter((organization) => settings.registrationEnabled && organization.registrationEnabled)
.map((organization) => ({
id: organization.id,
name: organization.name,
@@ -45,6 +49,7 @@ export async function GET(): Promise<Response> {
oidcHasClientSecret: organization.oidcClientSecret.length > 0,
oidcScopes: organization.oidcScopes,
oidcRedirectUri: organization.oidcRedirectUri,
oidcAvatarClaim: organization.oidcAvatarClaim,
oidcAutoProvision: organization.oidcAutoProvision,
createdAt: organization.createdAt.toISOString(),
updatedAt: organization.updatedAt.toISOString(),