Skip to content

Commit fd3ca87

Browse files
fix(schedules-perms): use regular perm system to view/edit schedule info (#901)
* fix(schedules-perms): use regular perm system to view schedule info * fix perms * improve logging
1 parent d264a6a commit fd3ca87

File tree

5 files changed

+392
-317
lines changed

5 files changed

+392
-317
lines changed

apps/sim/app/api/schedules/[id]/route.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { eq } from 'drizzle-orm'
33
import { type NextRequest, NextResponse } from 'next/server'
44
import { getSession } from '@/lib/auth'
55
import { createLogger } from '@/lib/logs/console/logger'
6+
import { getUserEntityPermissions } from '@/lib/permissions/utils'
67
import { db } from '@/db'
78
import { workflow, workflowSchedule } from '@/db/schema'
89

@@ -36,6 +37,7 @@ export async function DELETE(
3637
workflow: {
3738
id: workflow.id,
3839
userId: workflow.userId,
40+
workspaceId: workflow.workspaceId,
3941
},
4042
})
4143
.from(workflowSchedule)
@@ -48,7 +50,22 @@ export async function DELETE(
4850
return NextResponse.json({ error: 'Schedule not found' }, { status: 404 })
4951
}
5052

51-
if (schedules[0].workflow.userId !== session.user.id) {
53+
const workflowRecord = schedules[0].workflow
54+
55+
// Check authorization - either the user owns the workflow or has write/admin workspace permissions
56+
let isAuthorized = workflowRecord.userId === session.user.id
57+
58+
// If not authorized by ownership and the workflow belongs to a workspace, check workspace permissions
59+
if (!isAuthorized && workflowRecord.workspaceId) {
60+
const userPermission = await getUserEntityPermissions(
61+
session.user.id,
62+
'workspace',
63+
workflowRecord.workspaceId
64+
)
65+
isAuthorized = userPermission === 'write' || userPermission === 'admin'
66+
}
67+
68+
if (!isAuthorized) {
5269
logger.warn(`[${requestId}] Unauthorized schedule deletion attempt for schedule: ${id}`)
5370
return NextResponse.json({ error: 'Unauthorized' }, { status: 403 })
5471
}

apps/sim/app/api/schedules/[id]/status/route.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { eq } from 'drizzle-orm'
22
import { type NextRequest, NextResponse } from 'next/server'
33
import { getSession } from '@/lib/auth'
44
import { createLogger } from '@/lib/logs/console/logger'
5+
import { getUserEntityPermissions } from '@/lib/permissions/utils'
56

67
export const dynamic = 'force-dynamic'
78

@@ -42,7 +43,7 @@ export async function GET(req: NextRequest, { params }: { params: Promise<{ id:
4243
}
4344

4445
const [workflowRecord] = await db
45-
.select({ userId: workflow.userId })
46+
.select({ userId: workflow.userId, workspaceId: workflow.workspaceId })
4647
.from(workflow)
4748
.where(eq(workflow.id, schedule.workflowId))
4849
.limit(1)
@@ -52,7 +53,20 @@ export async function GET(req: NextRequest, { params }: { params: Promise<{ id:
5253
return NextResponse.json({ error: 'Workflow not found' }, { status: 404 })
5354
}
5455

55-
if (workflowRecord.userId !== session.user.id) {
56+
// Check authorization - either the user owns the workflow or has workspace permissions
57+
let isAuthorized = workflowRecord.userId === session.user.id
58+
59+
// If not authorized by ownership and the workflow belongs to a workspace, check workspace permissions
60+
if (!isAuthorized && workflowRecord.workspaceId) {
61+
const userPermission = await getUserEntityPermissions(
62+
session.user.id,
63+
'workspace',
64+
workflowRecord.workspaceId
65+
)
66+
isAuthorized = userPermission !== null
67+
}
68+
69+
if (!isAuthorized) {
5670
logger.warn(`[${requestId}] User not authorized to view this schedule: ${scheduleId}`)
5771
return NextResponse.json({ error: 'Not authorized to view this schedule' }, { status: 403 })
5872
}

0 commit comments

Comments
 (0)