You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

76 lines
2.3 KiB

import { cookies } from "next/headers";
import { fail, ok } from "@/lib/response";
import { isKnownCustomerAsync } from "@/modules/auth/service-token";
import { isKnownCustomer } from "@/modules/auth/service-token-env";
import { isDbCustomerActive, verifyCustomerEmbedPassword } from "@/modules/customer/customer-service";
import {
EMBED_DEMO_COOKIE,
signEmbedDemoToken,
} from "@/modules/embed-demo/auth";
import {
defaultMarkupDto,
serializeMarkupConfig,
} from "@/modules/pricing/markup-service";
import { prisma } from "@/lib/prisma";
async function isEmbedCustomerAllowed(customerId: string): Promise<boolean> {
if (isKnownCustomer(customerId)) {
return true;
}
return isDbCustomerActive(customerId);
}
async function loadMarkup(customerId: string) {
const markupRow = await prisma.markupConfig.findFirst({
where: { customerId, isDeleted: false },
});
return markupRow
? serializeMarkupConfig(markupRow)
: defaultMarkupDto(customerId);
}
/** POST /api/embed-demo/login — 客户 ID + 演示密码 */
export async function POST(request: Request) {
let body: { customer_id?: unknown; password?: unknown };
try {
body = (await request.json()) as { customer_id?: unknown; password?: unknown };
} catch {
return fail("VALIDATION_FAILED", "请求体格式无效", 400);
}
const customerId =
typeof body.customer_id === "string" ? body.customer_id.trim() : "";
const password = typeof body.password === "string" ? body.password : "";
if (!customerId) {
return fail("VALIDATION_FAILED", "请填写客户编号", 400);
}
if (!password) {
return fail("VALIDATION_FAILED", "请填写密码", 400);
}
if (!(await isKnownCustomerAsync(customerId))) {
return fail("UNAUTHORIZED", "客户编号或密码错误", 401);
}
if (!(await isEmbedCustomerAllowed(customerId))) {
return fail("FORBIDDEN", "客户已停用", 403);
}
if (!(await verifyCustomerEmbedPassword(customerId, password))) {
return fail("UNAUTHORIZED", "客户编号或密码错误", 401);
}
const token = await signEmbedDemoToken(customerId);
const cookieStore = await cookies();
cookieStore.set(EMBED_DEMO_COOKIE, token, {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
sameSite: "lax",
path: "/",
});
return ok({
customer_id: customerId,
markup: await loadMarkup(customerId),
});
}