52 lines
1.4 KiB
TypeScript
52 lines
1.4 KiB
TypeScript
import { NextResponse, type NextRequest } from "next/server";
|
|
import {
|
|
SESSION_COOKIE_NAME,
|
|
authenticateUser,
|
|
createSessionForUser,
|
|
getSessionCookieOptions,
|
|
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 {
|
|
const body = (await request.json()) as {
|
|
username?: unknown;
|
|
password?: unknown;
|
|
};
|
|
const username = String(body?.username ?? "").trim();
|
|
const password = String(body?.password ?? "");
|
|
|
|
if (!username || !password) {
|
|
return jsonError("用户名和密码不能为空。", 400);
|
|
}
|
|
|
|
const user = authenticateUser(username, password);
|
|
|
|
if (!user) {
|
|
return jsonError("用户名或密码错误。", 401);
|
|
}
|
|
|
|
const session = createSessionForUser(user.id);
|
|
const response = NextResponse.json({
|
|
ok: true,
|
|
user: toPublicUser(user),
|
|
quota: getQuotaSnapshotForUser(user),
|
|
});
|
|
|
|
response.cookies.set(
|
|
SESSION_COOKIE_NAME,
|
|
session.sessionId,
|
|
getSessionCookieOptions(session.expiresAt),
|
|
);
|
|
|
|
return response;
|
|
} catch (error) {
|
|
const normalizedError = normalizeError(error, "登录失败。");
|
|
return jsonError(normalizedError.message, normalizedError.statusCode);
|
|
}
|
|
}
|