import { NextRequest } from "next/server"; import { auth } from "@/lib/auth"; import { prisma } from "@/lib/prisma"; // eslint-disable-next-line @typescript-eslint/no-require-imports const disposableDomains = require("disposable-email-domains") as string[]; async function verifyTurnstile(token: string): Promise { try { const res = await fetch("https://challenges.cloudflare.com/turnstile/v0/siteverify", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ secret: process.env.TURNSTILE_SECRET_KEY, response: token, }), }); const data = await res.json() as { success: boolean }; return data.success; } catch { return false; } } function jsonError(message: string, status: number, code?: string) { return new Response(JSON.stringify({ message, code }), { status, headers: { "Content-Type": "application/json" }, }); } export async function POST(request: NextRequest) { let body: Record; try { body = await request.json() as Record; } catch { return jsonError("Неверный формат запроса", 400); } const { name, email, password, website, cfTurnstileResponse } = body; // Honeypot — bots fill this field, humans don't see it if (website) { return jsonError("Registration failed", 400); } // Disposable email check const domain = email?.split("@")[1]?.toLowerCase(); if (domain && disposableDomains.includes(domain)) { return jsonError("Пожалуйста, используйте постоянный email-адрес", 400); } // Turnstile check if (process.env.TURNSTILE_SECRET_KEY) { if (!cfTurnstileResponse) { return jsonError("Пожалуйста, подтвердите, что вы не робот", 400); } if (!(await verifyTurnstile(cfTurnstileResponse))) { return jsonError("Проверка капчи не пройдена. Попробуйте ещё раз", 400); } } // Email уже зарегистрирован? Сообщаем явно, а не молчаливым «успехом» // от Better Auth — частый случай после миграции (у людей уже есть аккаунт). if (email) { const existing = await prisma.user.findFirst({ where: { email: { equals: email, mode: "insensitive" } }, select: { id: true }, }); if (existing) { return jsonError("Аккаунт с таким email уже зарегистрирован", 409, "EMAIL_TAKEN"); } } const baseUrl = process.env.BETTER_AUTH_URL ?? `https://${request.headers.get("host")}`; return auth.handler( new Request(`${baseUrl}/api/auth/sign-up/email`, { method: "POST", headers: new Headers({ "Content-Type": "application/json", Origin: baseUrl, }), body: JSON.stringify({ name, email, password, callbackURL: "/dashboard" }), }) ); }