From e70ac784758af7678d24dee1ef53fbd4b70bf362 Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Sun, 22 Jun 2025 14:39:04 +0200 Subject: [PATCH] feat: use zod for validation --- apps/web/src/app/api/waitlist/route.ts | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/apps/web/src/app/api/waitlist/route.ts b/apps/web/src/app/api/waitlist/route.ts index e949ea6..f0b1c1f 100644 --- a/apps/web/src/app/api/waitlist/route.ts +++ b/apps/web/src/app/api/waitlist/route.ts @@ -4,6 +4,11 @@ import { waitlist } from "@/lib/db/schema"; import { eq } from "drizzle-orm"; import { nanoid } from "nanoid"; import { waitlistRateLimit } from "@/lib/rate-limit"; +import { z } from "zod"; + +const waitlistSchema = z.object({ + email: z.string().email("Invalid email format").min(1, "Email is required"), +}); export async function POST(request: NextRequest) { // Rate limit check @@ -18,20 +23,8 @@ export async function POST(request: NextRequest) { } try { - const { email } = await request.json(); - - if (!email || typeof email !== "string") { - return NextResponse.json({ error: "Email is required" }, { status: 400 }); - } - - // Validate email format - const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; - if (!emailRegex.test(email)) { - return NextResponse.json( - { error: "Invalid email format" }, - { status: 400 } - ); - } + const body = await request.json(); + const { email } = waitlistSchema.parse(body); // Check if email already exists const existingEmail = await db @@ -58,6 +51,11 @@ export async function POST(request: NextRequest) { { status: 201 } ); } catch (error) { + if (error instanceof z.ZodError) { + const firstError = error.errors[0]; + return NextResponse.json({ error: firstError.message }, { status: 400 }); + } + console.error("Waitlist signup error:", error); return NextResponse.json( { error: "Internal server error" },