From d94743891e78fce519e0e92f2f5d2e8b6c5df58c Mon Sep 17 00:00:00 2001 From: Programmer-Develops Date: Sat, 18 Apr 2026 15:29:41 +0530 Subject: [PATCH 1/7] fix: add await to Grade.findOneAndUpdate in POST /api/grades --- app/api/grades/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/api/grades/route.ts b/app/api/grades/route.ts index b9da63d..d37502d 100644 --- a/app/api/grades/route.ts +++ b/app/api/grades/route.ts @@ -73,7 +73,7 @@ export async function POST(req: NextRequest) { const max = data.maxMarks! const term = data.term ?? 'Term 1' - const grade = Grade.findOneAndUpdate( + const grade = await Grade.findOneAndUpdate( { teacherId: userId, studentId: data.studentId, subject: data.subject, term }, { $set: { ...data, term, teacherId: userId, grade: calcGrade(data.marks, max) } }, { upsert: true, new: true } From 1ecb62597b21c6b039e661711e2342054c6f37d4 Mon Sep 17 00:00:00 2001 From: Programmer-Develops Date: Sat, 18 Apr 2026 15:30:10 +0530 Subject: [PATCH 2/7] fix: default maxMarks to 100 when undefined in calcGrade --- app/api/grades/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/api/grades/route.ts b/app/api/grades/route.ts index d37502d..b4ce7e5 100644 --- a/app/api/grades/route.ts +++ b/app/api/grades/route.ts @@ -70,7 +70,7 @@ export async function POST(req: NextRequest) { if (!parsed.success) return NextResponse.json({ error: parsed.error.flatten() }, { status: 400 }) const data = parsed.data - const max = data.maxMarks! + const max = data.maxMarks ?? 100 const term = data.term ?? 'Term 1' const grade = await Grade.findOneAndUpdate( From 7fe9517373dbd02865b61fc567d5f91de27d2d3a Mon Sep 17 00:00:00 2001 From: Programmer-Develops Date: Sat, 18 Apr 2026 15:34:19 +0530 Subject: [PATCH 3/7] fix: validate and use parsed result in POST /api/students --- app/api/students/route.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/api/students/route.ts b/app/api/students/route.ts index 8f3dcc2..5e30fdb 100644 --- a/app/api/students/route.ts +++ b/app/api/students/route.ts @@ -92,9 +92,10 @@ export async function POST(req: NextRequest) { return NextResponse.json({ error: 'Malformed JSON' }, { status: 400 }) } - StudentSchema.safeParse(body) + const parsed = StudentSchema.safeParse(body) + if (!parsed.success) return NextResponse.json({ error: z.treeifyError(parsed.error) }, { status: 400 }) - const student = await Student.create({ ...(body as Record), teacherId: userId }) + const student = await Student.create({ ...parsed.data, teacherId: userId }) return NextResponse.json(student, { status: 201 }) } catch (error) { if (error instanceof Error) { From 98b65c41aafb9f9bdca045a103be1dd28f6d095c Mon Sep 17 00:00:00 2001 From: Programmer-Develops Date: Sat, 18 Apr 2026 15:39:31 +0530 Subject: [PATCH 4/7] fix: prevent IDOR by ignoring queryUserId in GET /api/profile --- app/api/profile/route.ts | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/app/api/profile/route.ts b/app/api/profile/route.ts index a3d98bf..dbdebdc 100644 --- a/app/api/profile/route.ts +++ b/app/api/profile/route.ts @@ -3,15 +3,8 @@ import { NextRequest, NextResponse } from 'next/server' import { connectDB } from '@/lib/mongodb' import { Teacher } from '@/models/Teacher' -export async function GET(req: NextRequest) { - const { searchParams } = new URL(req.url) - const queryUserId = searchParams.get('userId') - - let userId: string | null = queryUserId - if (!userId) { - const session = await auth() - userId = session.userId - } +export async function GET() { + const { userId } = await auth() if (!userId) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) try { From 022ea013978e760cadaec11e4c3dc039037ab9df Mon Sep 17 00:00:00 2001 From: Programmer-Develops Date: Sat, 18 Apr 2026 15:49:01 +0530 Subject: [PATCH 5/7] fix: scope grade/student/assignment mutations to authenticated teacherId --- app/api/assignments/[id]/route.ts | 4 ++-- app/api/grades/[id]/route.ts | 4 ++-- app/api/students/[id]/route.ts | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/api/assignments/[id]/route.ts b/app/api/assignments/[id]/route.ts index 21fca1c..b041302 100644 --- a/app/api/assignments/[id]/route.ts +++ b/app/api/assignments/[id]/route.ts @@ -36,7 +36,7 @@ export async function PUT(req: NextRequest, ctx: { params: Promise<{ id: string } const assignment = await Assignment.findOneAndUpdate( - { _id: id }, + { _id: id, teacherId: userId }, sanitizedBody, { new: true } ) @@ -63,7 +63,7 @@ export async function DELETE(_req: NextRequest, ctx: { params: Promise<{ id: str } await connectDB() - const deleted = await Assignment.findOneAndDelete({ _id: id }) + const deleted = await Assignment.findOneAndDelete({ _id: id, teacherId: userId }) if (!deleted) { return NextResponse.json({ error: 'Not found' }, { status: 404 }) diff --git a/app/api/grades/[id]/route.ts b/app/api/grades/[id]/route.ts index 0141f63..a4e66ff 100644 --- a/app/api/grades/[id]/route.ts +++ b/app/api/grades/[id]/route.ts @@ -35,7 +35,7 @@ export async function PUT(req: NextRequest, ctx: { params: Promise<{ id: string await connectDB() const grade = await Grade.findOneAndUpdate( - { _id: id }, + { _id: id, teacherId: userId }, sanitizedBody, { new: true } ) @@ -56,7 +56,7 @@ export async function DELETE(_req: NextRequest, ctx: { params: Promise<{ id: str try { const { id } = await ctx.params await connectDB() - const deleted = await Grade.findOneAndDelete({ _id: id }) + const deleted = await Grade.findOneAndDelete({ _id: id, teacherId: userId }) if (!deleted) { return NextResponse.json({ error: 'Grade not found' }, { status: 404 }) diff --git a/app/api/students/[id]/route.ts b/app/api/students/[id]/route.ts index 2eaaf93..990037b 100644 --- a/app/api/students/[id]/route.ts +++ b/app/api/students/[id]/route.ts @@ -35,7 +35,7 @@ export async function PUT(req: NextRequest, ctx: { params: Promise<{ id: string await connectDB() const student = await Student.findOneAndUpdate( - { _id: id }, + { _id: id, teacherId: userId }, sanitizedBody, { new: true } ) @@ -65,7 +65,7 @@ export async function DELETE(_req: NextRequest, ctx: { params: Promise<{ id: str } await connectDB() - const deleted = await Student.findOneAndDelete({ _id: id }) + const deleted = await Student.findOneAndDelete({ _id: id, teacherId: userId }) if (!deleted) { return NextResponse.json({ error: 'Student not found' }, { status: 404 }) From 6638a800c5f837f770eecd40c7e8833379b18843 Mon Sep 17 00:00:00 2001 From: Programmer-Develops Date: Sat, 18 Apr 2026 15:51:36 +0530 Subject: [PATCH 6/7] fix: replace error.stack with generic message in error responses --- app/api/assignments/route.ts | 2 +- app/api/grades/route.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/api/assignments/route.ts b/app/api/assignments/route.ts index 19021d8..1d88b7e 100644 --- a/app/api/assignments/route.ts +++ b/app/api/assignments/route.ts @@ -52,7 +52,7 @@ export async function GET(req: NextRequest) { if (error instanceof Error) { console.error('GET /api/assignments error:', error.message) } - return NextResponse.json({ error: error instanceof Error ? error.stack : 'Internal server error' }, { status: 500 }) + return NextResponse.json({ error: 'Internal server error' }, { status: 500 }) } } diff --git a/app/api/grades/route.ts b/app/api/grades/route.ts index b4ce7e5..ee8a6be 100644 --- a/app/api/grades/route.ts +++ b/app/api/grades/route.ts @@ -83,6 +83,7 @@ export async function POST(req: NextRequest) { if (error instanceof Error) { console.error('POST /api/grades error:', error.message) } - return NextResponse.json({ error: error instanceof Error ? error.stack : 'Internal server error' }, { status: 500 }) + return NextResponse.json({ error: 'Internal server error' }, { status: 500 }) + } } From 3d9c508dfe588289c8e81477a1ee4da453dbe5a1 Mon Sep 17 00:00:00 2001 From: Programmer-Develops Date: Sat, 18 Apr 2026 15:53:07 +0530 Subject: [PATCH 7/7] fix: return 400 not 404 for invalid ObjectId in PUT /api/grades/[id] --- app/api/grades/[id]/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/api/grades/[id]/route.ts b/app/api/grades/[id]/route.ts index a4e66ff..fea3d08 100644 --- a/app/api/grades/[id]/route.ts +++ b/app/api/grades/[id]/route.ts @@ -15,7 +15,7 @@ export async function PUT(req: NextRequest, ctx: { params: Promise<{ id: string // Validate ObjectId if (!mongoose.Types.ObjectId.isValid(id)) { - return NextResponse.json({ error: 'Not found' }, { status: 404 }) + return NextResponse.json({ error: 'Invalid id' }, { status: 400 }) } let body