Files
NianAIGC/app/api/auth/password/route.ts

46 lines
1.8 KiB
TypeScript

import { getAuthRuntimeConfig, safeNextPath } from "@/lib/auth/config";
import { jsonError, jsonOk, readJsonBody } from "@/lib/server/api";
import { authenticatePlatformUser } from "@/lib/server/account-store";
import {
checkIpLoginRateLimit,
clearIpLoginRateLimit,
clientIpFromRequest,
createPlatformSession,
setPlatformSessionCookie
} from "@/lib/server/auth/local";
export const runtime = "nodejs";
export const dynamic = "force-dynamic";
export async function POST(request: Request) {
const ip = clientIpFromRequest(request);
try {
const config = getAuthRuntimeConfig();
if (!config.configured || !config.sessionSecret) {
throw Object.assign(new Error(`账号认证配置不完整:${config.missing.join(", ") || "ZHINIAN_AUTH_SESSION_SECRET"}`), { status: 503 });
}
checkIpLoginRateLimit(ip);
const body = await readJsonBody<Record<string, unknown>>(request);
const phone = stringValue(body.phone) || stringValue(body.username);
const password = stringValue(body.password);
if (!phone || !password) throw Object.assign(new Error("手机号和密码不能为空。"), { status: 400 });
const user = await authenticatePlatformUser(phone, password);
clearIpLoginRateLimit(ip);
const session = await createPlatformSession(user);
const response = jsonOk({
ok: true,
redirectTo: safeNextPath(stringValue(body.next)),
user: session.user,
authMode: session.authMode
});
await setPlatformSessionCookie(response, request.url, session);
return response;
} catch (error) {
return jsonError(error, 401, { request, source: "api.auth.password", logClientErrors: false });
}
}
function stringValue(value: unknown): string | undefined {
return typeof value === "string" && value.trim() ? value.trim() : undefined;
}