From ebf9eff608e61787eba4b279854f7343675d1f68 Mon Sep 17 00:00:00 2001 From: ash1shkumar Date: Sun, 24 May 2026 18:30:55 +0530 Subject: [PATCH 1/3] feat: add centralized schema validation for auth APIs --- backend/package-lock.json | 6 ++-- frontend/app/api/auth/signup/route.ts | 49 +++++++++++---------------- frontend/app/lib/validations/auth.ts | 35 +++++++++++++++++++ package-lock.json | 20 ++++++----- package.json | 3 +- 5 files changed, 70 insertions(+), 43 deletions(-) create mode 100644 frontend/app/lib/validations/auth.ts diff --git a/backend/package-lock.json b/backend/package-lock.json index 507edf0..04e8836 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -12,9 +12,9 @@ "cors": "^2.8.6", "dotenv": "^16.6.1", "express": "^4.22.2", - "next": "*", - "react": "*", - "react-dom": "*", + "next": "latest", + "react": "latest", + "react-dom": "latest", "socket.io": "^4.7.2" }, "devDependencies": { diff --git a/frontend/app/api/auth/signup/route.ts b/frontend/app/api/auth/signup/route.ts index 1feb83f..24295ef 100644 --- a/frontend/app/api/auth/signup/route.ts +++ b/frontend/app/api/auth/signup/route.ts @@ -2,6 +2,7 @@ import { createClient } from "@supabase/supabase-js"; import { NextRequest, NextResponse } from "next/server"; import { randomUUID } from "crypto"; +import { signupSchema } from "@/lib/validations/auth"; export const runtime = "nodejs"; @@ -21,41 +22,29 @@ type ProjectRow = { export async function POST(req: NextRequest) { try { const payload = await req.json(); - const { email, password, name, username, mobile, description, members, due, tags } = payload || {}; - - // Input validation - if (!email || !password || !name || !username) { + const validation = signupSchema.safeParse(payload); + if (!validation.success) { return NextResponse.json( - { error: "Missing required fields: email, password, name, username are required." }, - { status: 400 } - ); - } - - // Email format validation - const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; - if (!emailRegex.test(email)) { - return NextResponse.json( - { error: "Invalid email format." }, + { + error: validation.error.errors[0].message, + }, { status: 400 } ); } - // Password strength - if (password.length < 6) { - return NextResponse.json( - { error: "Password must be at least 6 characters long." }, - { status: 400 } - ); - } - - // Username validation - if (username.length < 3 || username.length > 20) { - return NextResponse.json( - { error: "Username must be between 3-20 characters." }, - { status: 400 } - ); - } - + const { + email, + password, + name, + username, + mobile, + description, + members, + due, + tags, + } = validation.data; + + // Environment variables check if (!process.env.SUPABASE_URL || !process.env.SUPABASE_SERVICE_KEY) { console.error("Missing Supabase environment variables"); diff --git a/frontend/app/lib/validations/auth.ts b/frontend/app/lib/validations/auth.ts new file mode 100644 index 0000000..d3abb3d --- /dev/null +++ b/frontend/app/lib/validations/auth.ts @@ -0,0 +1,35 @@ +import { z } from "zod"; + +export const signupSchema = z.object({ + name: z + .string() + .min(2, "Name must be at least 2 characters"), + + username: z + .string() + .min(3, "Username must be at least 3 characters") + .max(20, "Username must be under 20 characters") + .regex( + /^[a-zA-Z0-9_]+$/, + "Username can only contain letters, numbers, and underscores" + ), + + email: z.string().email("Invalid email address"), + + password: z + .string() + .min(8, "Password must be at least 8 characters") + .regex(/[A-Z]/, "Password must contain an uppercase letter") + .regex(/[a-z]/, "Password must contain a lowercase letter") + .regex(/[0-9]/, "Password must contain a number"), + + mobile: z.string().optional(), + + description: z.string().optional(), + + members: z.union([z.string(), z.number()]).optional(), + + due: z.string().optional(), + + tags: z.any().optional(), +}); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 9cacf96..e9f31d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,8 @@ "@supabase/supabase-js": "^2.103.0", "lucide": "^1.8.0", "react": "^19.2.4", - "react-dom": "^19.2.4" + "react-dom": "^19.2.4", + "zod": "^4.4.3" } }, "frontend": { @@ -4001,14 +4002,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "frontend/node_modules/zod": { - "version": "4.3.6", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "frontend/node_modules/zod-validation-error": { "version": "4.0.2", "dev": true, @@ -6507,6 +6500,15 @@ "engines": { "node": ">=0.4.0" } + }, + "node_modules/zod": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", + "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index 2d9b12e..860b2bd 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@supabase/supabase-js": "^2.103.0", "lucide": "^1.8.0", "react": "^19.2.4", - "react-dom": "^19.2.4" + "react-dom": "^19.2.4", + "zod": "^4.4.3" } } From 1b34ae58d58e9ff07c2541fbd8af805f4ddf8e2e Mon Sep 17 00:00:00 2001 From: ash1shkumar Date: Sun, 24 May 2026 22:38:32 +0530 Subject: [PATCH 2/3] resolve building errors --- frontend/{app => }/lib/validations/auth.ts | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename frontend/{app => }/lib/validations/auth.ts (100%) diff --git a/frontend/app/lib/validations/auth.ts b/frontend/lib/validations/auth.ts similarity index 100% rename from frontend/app/lib/validations/auth.ts rename to frontend/lib/validations/auth.ts From 9936a3cec924419503c66c256f7bfe34ffbe6220 Mon Sep 17 00:00:00 2001 From: ash1shkumar Date: Sun, 24 May 2026 22:41:33 +0530 Subject: [PATCH 3/3] fix: resolve zod validation import and schema handling --- frontend/app/api/auth/signup/route.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/app/api/auth/signup/route.ts b/frontend/app/api/auth/signup/route.ts index 24295ef..796c49e 100644 --- a/frontend/app/api/auth/signup/route.ts +++ b/frontend/app/api/auth/signup/route.ts @@ -2,7 +2,7 @@ import { createClient } from "@supabase/supabase-js"; import { NextRequest, NextResponse } from "next/server"; import { randomUUID } from "crypto"; -import { signupSchema } from "@/lib/validations/auth"; +import { signupSchema } from "../../../../lib/validations/auth"; export const runtime = "nodejs"; @@ -26,7 +26,7 @@ export async function POST(req: NextRequest) { if (!validation.success) { return NextResponse.json( { - error: validation.error.errors[0].message, + error: validation.error.issues[0].message, }, { status: 400 } );