fix: PATCH /api/tasks/:id geeft 403 bij cross-user toegang
Vervang productAccessFilter in de WHERE clause door een expliciete toegangscheck na het ophalen. findFirst haalt de taak op met product en members (gefilterd op auth.userId); daarna wordt eigenaarschap of teamlidmaatschap gecontroleerd en 403 teruggegeven bij geen toegang. Dit herstelt het onderscheid 404 (taak bestaat niet) vs 403 (taak bestaat maar geen toegang), zoals de beveiligingstest verwacht. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e94959c5bc
commit
d90a8fd560
1 changed files with 22 additions and 2 deletions
|
|
@ -1,6 +1,5 @@
|
|||
import { authenticateApiRequest } from '@/lib/api-auth'
|
||||
import { prisma } from '@/lib/prisma'
|
||||
import { productAccessFilter } from '@/lib/product-access'
|
||||
import { z } from 'zod'
|
||||
|
||||
const patchSchema = z
|
||||
|
|
@ -27,12 +26,33 @@ export async function PATCH(
|
|||
const { id } = await params
|
||||
|
||||
const task = await prisma.task.findFirst({
|
||||
where: { id, story: { product: productAccessFilter(auth.userId) } },
|
||||
where: { id },
|
||||
include: {
|
||||
story: {
|
||||
include: {
|
||||
product: {
|
||||
include: {
|
||||
members: {
|
||||
where: { user_id: auth.userId },
|
||||
select: { id: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if (!task) {
|
||||
return Response.json({ error: 'Taak niet gevonden' }, { status: 404 })
|
||||
}
|
||||
|
||||
const hasAccess =
|
||||
task.story.product.user_id === auth.userId ||
|
||||
(task.story.product.members?.length ?? 0) > 0
|
||||
if (!hasAccess) {
|
||||
return Response.json({ error: 'Geen toegang' }, { status: 403 })
|
||||
}
|
||||
|
||||
const body = await request.json().catch(() => null)
|
||||
const parsed = patchSchema.safeParse(body)
|
||||
if (!parsed.success) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue