Files
image-prompt-studio/app/api/admin/users/route.ts
2026-04-25 11:26:33 +08:00

73 lines
2.0 KiB
TypeScript

import { NextResponse, type NextRequest } from "next/server";
import { requireApiAdmin } from "@/lib/api-auth";
import { createUserRecord, getUserByUsername } from "@/lib/db";
import { hashPassword, toPublicUser } from "@/lib/auth";
import { getQuotaSnapshotForUser } from "@/lib/quota";
import { jsonError, normalizeError } from "@/lib/http";
export const runtime = "nodejs";
export async function POST(request: NextRequest) {
try {
requireApiAdmin(request);
const body = (await request.json()) as {
username?: unknown;
password?: unknown;
role?: unknown;
monthlyQuota?: unknown;
};
const username = String(body?.username ?? "")
.trim()
.toLowerCase();
const password = String(body?.password ?? "");
const role = body?.role === "admin" ? "admin" : "user";
const monthlyQuota =
typeof body?.monthlyQuota === "number" ||
typeof body?.monthlyQuota === "string"
? body.monthlyQuota
: undefined;
if (!username) {
return jsonError("用户名不能为空。", 400);
}
if (password.length < 8) {
return jsonError("密码至少需要 8 个字符。", 400);
}
if (getUserByUsername(username)) {
return jsonError("该用户名已存在。", 409);
}
const publicUser = toPublicUser(
createUserRecord({
username,
passwordHash: hashPassword(password),
role,
monthlyQuota: role === "admin" ? null : monthlyQuota,
}),
);
if (!publicUser) {
return jsonError("创建用户失败。", 500);
}
const quota = getQuotaSnapshotForUser(publicUser);
return NextResponse.json({
ok: true,
user: {
...publicUser,
usedThisPeriod: quota.used,
remaining: quota.remaining,
limit: quota.limit,
isUnlimited: quota.isUnlimited,
},
});
} catch (error) {
const normalizedError = normalizeError(error, "创建用户失败。");
return jsonError(normalizedError.message, normalizedError.statusCode);
}
}