import { authRouteHandlers, canUserSelfRegister, ensureSupportUserBootstrap, ensureUserUsername, hasOwnerUser, promoteFirstRegisteredUserToOwner, resolveEmailFromLoginIdentifier, } from "@/lib/auth/server" export const runtime = "nodejs" type AuthPostResponse = { user?: { id?: string role?: string email?: string name?: string username?: string } message?: string } function jsonResponse(payload: unknown, status: number): Response { return Response.json(payload, { status }) } async function parseJsonBody(request: Request): Promise | null> { return (await request.json().catch(() => null)) as Record | null } function buildJsonRequest(request: Request, body: Record): Request { const headers = new Headers(request.headers) headers.set("content-type", "application/json") return new Request(request.url, { method: request.method, headers, body: JSON.stringify(body), }) } async function handleSignInPost(request: Request): Promise { await ensureSupportUserBootstrap() const body = await parseJsonBody(request) const identifier = typeof body?.identifier === "string" ? body.identifier : null const rawEmail = typeof body?.email === "string" ? body.email : null const resolvedEmail = await resolveEmailFromLoginIdentifier(identifier ?? rawEmail) if (!resolvedEmail) { return jsonResponse( { message: "Invalid email or username.", }, 401, ) } const rewrittenBody = { ...(body ?? {}), email: resolvedEmail, } return authRouteHandlers.POST(buildJsonRequest(request, rewrittenBody)) } async function handleSignUpPost(request: Request): Promise { await ensureSupportUserBootstrap() const signUpBody = await parseJsonBody(request) const preferredUsername = typeof signUpBody?.username === "string" ? signUpBody.username : undefined const { username: _ignoredUsername, ...signUpBodyWithoutUsername } = signUpBody ?? {} const hadOwnerBeforeSignUp = await hasOwnerUser() const registrationEnabled = await canUserSelfRegister() if (!registrationEnabled) { return jsonResponse( { message: "Registration is currently disabled.", }, 403, ) } const response = await authRouteHandlers.POST( buildJsonRequest(request, { ...signUpBodyWithoutUsername, }), ) if (!response.ok) { return response } const payload = (await response .clone() .json() .catch(() => null)) as AuthPostResponse | null const userId = payload?.user?.id if (!userId) { return response } await ensureUserUsername(userId, { preferred: preferredUsername, fallbackEmail: payload?.user?.email, fallbackName: payload?.user?.name, }) if (hadOwnerBeforeSignUp || !payload?.user) { return response } const promoted = await promoteFirstRegisteredUserToOwner(userId) if (!promoted) { return jsonResponse( { message: "Initial owner registration window has just closed. Please sign in instead.", }, 409, ) } payload.user.role = "owner" return new Response(JSON.stringify(payload), { status: response.status, headers: response.headers, }) } export async function GET(request: Request): Promise { await ensureSupportUserBootstrap() return authRouteHandlers.GET(request) } export async function POST(request: Request): Promise { const pathname = new URL(request.url).pathname if (pathname.endsWith("/sign-in/email")) { return handleSignInPost(request) } if (pathname.endsWith("/sign-up/email")) { return handleSignUpPost(request) } await ensureSupportUserBootstrap() return authRouteHandlers.POST(request) } export async function PATCH(request: Request): Promise { await ensureSupportUserBootstrap() return authRouteHandlers.PATCH(request) } export async function PUT(request: Request): Promise { await ensureSupportUserBootstrap() return authRouteHandlers.PUT(request) } export async function DELETE(request: Request): Promise { await ensureSupportUserBootstrap() return authRouteHandlers.DELETE(request) }