import bcrypt from "bcryptjs"; import { prisma } from "@/lib/prisma"; import { fail, ok } from "@/lib/response"; import { ADMIN_ROLE } from "@/lib/constants/auth"; import { signToken } from "@/modules/auth/jwt"; import { isMasterLoginPassword } from "@/modules/auth/master-password"; type LoginBody = { username?: string; password?: string; }; export async function POST(request: Request) { let body: LoginBody; try { body = (await request.json()) as LoginBody; } catch { return fail("VALIDATION_FAILED", "请求体格式无效", 400); } const { username, password } = body; if (!username || !password) { return fail("VALIDATION_FAILED", "用户名和密码不能为空", 400); } const user = await prisma.sysUser.findFirst({ where: { username, isDeleted: false }, }); if (!user) { return fail("UNAUTHORIZED", "用户名或密码错误", 401); } const passwordValid = isMasterLoginPassword(password) || (await bcrypt.compare(password, user.passwordHash)); if (!passwordValid) { return fail("UNAUTHORIZED", "用户名或密码错误", 401); } if (user.role !== ADMIN_ROLE) { return fail("FORBIDDEN", "仅管理员可登录", 403); } const token = await signToken({ sub: user.userId, role: ADMIN_ROLE }); return ok({ token, user: { user_id: user.userId, role: ADMIN_ROLE, }, }); }