import { toNextJsHandler } from "better-auth/next-js"; import { eq, sql } from "drizzle-orm"; import { getDb } from "@/db"; import { accounts } from "@/db/schema"; import { getAuth, getCustomerSession } from "@/lib/auth/server"; import { errorResponse, HttpError, readJson, requireSameOrigin } from "@/lib/security/http"; const handlers = toNextJsHandler((request) => getAuth().handler(request)); export async function GET(request: Request) { return handlers.GET(request); } async function mutate(request: Request) { try { requireSameOrigin(request); const input = await readJson(request.clone()); const path = new URL(request.url).pathname; if (["/admin/create-user", "/admin/set-user-password"].some((endpoint) => path.endsWith(endpoint))) { const password = input && typeof input === "object" && "password" in input ? input.password : undefined; const newPassword = input && typeof input === "object" && "newPassword" in input ? input.newPassword : undefined; const value = password ?? newPassword; if (typeof value !== "string" || value.length < 6 || value.length > 128) { throw new HttpError(400, "invalid-password-length"); } } if (path === "/api/auth/unlink-account") { const accountId = input && typeof input === "object" && "accountId" in input && typeof input.accountId === "string" ? input.accountId : null; const session = accountId ? await getCustomerSession() : null; if (accountId && session) { const linkedAccounts = await getDb().select({ id: accounts.id, providerId: accounts.providerId, hasPassword: sql`${accounts.password} is not null`, }).from(accounts).where(eq(accounts.userId, session.user.id)); const accountExists = linkedAccounts.some((account) => account.id === accountId); const hasAlternativeSignIn = linkedAccounts.some((account) => account.id !== accountId && (account.providerId !== "credential" || account.hasPassword)); if (accountExists && !hasAlternativeSignIn) { return Response.json({ code: "LAST_AUTH_METHOD", message: "กรุณาตั้งรหัสผ่านหรือเชื่อมต่อวิธีเข้าสู่ระบบอื่นก่อนยกเลิกการเชื่อมต่อ Google", }, { status: 409, headers: { "Cache-Control": "no-store" } }); } } } return await getAuth().handler(request); } catch (cause) { return errorResponse(cause); } } export const POST = mutate; export const PATCH = mutate; export const PUT = mutate; export const DELETE = mutate;