@@ -13,6 +13,7 @@ import {
1313 findMemberByUserId ,
1414} from "@dokploy/server/services/permission" ;
1515import {
16+ assertHostScheduleAccess ,
1617 createSchedule ,
1718 deleteSchedule ,
1819 findScheduleById ,
@@ -31,6 +32,8 @@ export const scheduleRouter = createTRPCRouter({
3132 create : protectedProcedure
3233 . input ( createScheduleSchema )
3334 . mutation ( async ( { input, ctx } ) => {
35+ await assertHostScheduleAccess ( ctx , input . scheduleType , input . serverId ) ;
36+
3437 const serviceId = input . applicationId || input . composeId ;
3538 if ( serviceId ) {
3639 await checkServicePermissionAndAccess ( ctx , serviceId , {
@@ -44,51 +47,14 @@ export const scheduleRouter = createTRPCRouter({
4447 ) ;
4548 }
4649 } else {
47- if ( input . scheduleType === "dokploy-server" && IS_CLOUD ) {
48- throw new TRPCError ( {
49- code : "FORBIDDEN" ,
50- message :
51- "Host-level schedules are not available in the cloud version." ,
52- } ) ;
53- }
54-
5550 await checkPermission ( ctx , { schedule : [ "create" ] } ) ;
5651
57- if (
58- input . scheduleType === "server" ||
59- input . scheduleType === "dokploy-server"
60- ) {
61- const member = await findMemberByUserId (
62- ctx . user . id ,
52+ if ( IS_CLOUD && input . scheduleType === "server" && input . serverId ) {
53+ await assertScheduledJobLimit (
6354 ctx . session . activeOrganizationId ,
55+ "server" ,
56+ input . serverId ,
6457 ) ;
65- if ( member . role !== "owner" && member . role !== "admin" ) {
66- throw new TRPCError ( {
67- code : "FORBIDDEN" ,
68- message :
69- "Only owners and admins can manage server-level schedules." ,
70- } ) ;
71- }
72- }
73-
74- if ( input . scheduleType === "server" && input . serverId ) {
75- const targetServer = await findServerById ( input . serverId ) ;
76- if (
77- targetServer . organizationId !== ctx . session . activeOrganizationId
78- ) {
79- throw new TRPCError ( {
80- code : "UNAUTHORIZED" ,
81- message : "You don't have access to this server." ,
82- } ) ;
83- }
84-
85- if ( IS_CLOUD ) {
86- await assertScheduledJobLimit (
87- ctx . session . activeOrganizationId ,
88- "server" ,
89- input . serverId ,
90- ) ;
91- }
9258 }
9359 }
9460 const newSchedule = await createSchedule ( {
@@ -135,54 +101,30 @@ export const scheduleRouter = createTRPCRouter({
135101 } ) ;
136102 }
137103
104+ await assertHostScheduleAccess (
105+ ctx ,
106+ existingSchedule . scheduleType ,
107+ existingSchedule . serverId ,
108+ ) ;
109+ if (
110+ input . scheduleType &&
111+ input . scheduleType !== existingSchedule . scheduleType
112+ ) {
113+ await assertHostScheduleAccess (
114+ ctx ,
115+ input . scheduleType ,
116+ input . serverId ?? existingSchedule . serverId ,
117+ ) ;
118+ }
119+
138120 const serviceId =
139121 existingSchedule . applicationId || existingSchedule . composeId ;
140122 if ( serviceId ) {
141123 await checkServicePermissionAndAccess ( ctx , serviceId , {
142124 schedule : [ "update" ] ,
143125 } ) ;
144126 } else {
145- if ( existingSchedule . scheduleType === "dokploy-server" && IS_CLOUD ) {
146- throw new TRPCError ( {
147- code : "FORBIDDEN" ,
148- message :
149- "Host-level schedules are not available in the cloud version." ,
150- } ) ;
151- }
152-
153127 await checkPermission ( ctx , { schedule : [ "update" ] } ) ;
154-
155- if (
156- existingSchedule . scheduleType === "server" ||
157- existingSchedule . scheduleType === "dokploy-server"
158- ) {
159- const member = await findMemberByUserId (
160- ctx . user . id ,
161- ctx . session . activeOrganizationId ,
162- ) ;
163- if ( member . role !== "owner" && member . role !== "admin" ) {
164- throw new TRPCError ( {
165- code : "FORBIDDEN" ,
166- message :
167- "Only owners and admins can manage server-level schedules." ,
168- } ) ;
169- }
170- }
171-
172- if (
173- existingSchedule . scheduleType === "server" &&
174- existingSchedule . serverId
175- ) {
176- const targetServer = await findServerById ( existingSchedule . serverId ) ;
177- if (
178- targetServer . organizationId !== ctx . session . activeOrganizationId
179- ) {
180- throw new TRPCError ( {
181- code : "UNAUTHORIZED" ,
182- message : "You don't have access to this server." ,
183- } ) ;
184- }
185- }
186128 }
187129 const updatedSchedule = await updateSchedule ( input ) ;
188130
@@ -222,50 +164,19 @@ export const scheduleRouter = createTRPCRouter({
222164 . input ( z . object ( { scheduleId : z . string ( ) } ) )
223165 . mutation ( async ( { input, ctx } ) => {
224166 const scheduleItem = await findScheduleById ( input . scheduleId ) ;
167+ await assertHostScheduleAccess (
168+ ctx ,
169+ scheduleItem . scheduleType ,
170+ scheduleItem . serverId ,
171+ ) ;
172+
225173 const serviceId = scheduleItem . applicationId || scheduleItem . composeId ;
226174 if ( serviceId ) {
227175 await checkServicePermissionAndAccess ( ctx , serviceId , {
228176 schedule : [ "delete" ] ,
229177 } ) ;
230178 } else {
231- if ( scheduleItem . scheduleType === "dokploy-server" && IS_CLOUD ) {
232- throw new TRPCError ( {
233- code : "FORBIDDEN" ,
234- message :
235- "Host-level schedules are not available in the cloud version." ,
236- } ) ;
237- }
238-
239179 await checkPermission ( ctx , { schedule : [ "delete" ] } ) ;
240-
241- if (
242- scheduleItem . scheduleType === "server" ||
243- scheduleItem . scheduleType === "dokploy-server"
244- ) {
245- const member = await findMemberByUserId (
246- ctx . user . id ,
247- ctx . session . activeOrganizationId ,
248- ) ;
249- if ( member . role !== "owner" && member . role !== "admin" ) {
250- throw new TRPCError ( {
251- code : "FORBIDDEN" ,
252- message :
253- "Only owners and admins can manage server-level schedules." ,
254- } ) ;
255- }
256- }
257-
258- if ( scheduleItem . scheduleType === "server" && scheduleItem . serverId ) {
259- const targetServer = await findServerById ( scheduleItem . serverId ) ;
260- if (
261- targetServer . organizationId !== ctx . session . activeOrganizationId
262- ) {
263- throw new TRPCError ( {
264- code : "UNAUTHORIZED" ,
265- message : "You don't have access to this server." ,
266- } ) ;
267- }
268- }
269180 }
270181 await deleteSchedule ( input . scheduleId ) ;
271182
@@ -389,50 +300,19 @@ export const scheduleRouter = createTRPCRouter({
389300 . input ( z . object ( { scheduleId : z . string ( ) . min ( 1 ) } ) )
390301 . mutation ( async ( { input, ctx } ) => {
391302 const scheduleItem = await findScheduleById ( input . scheduleId ) ;
303+ await assertHostScheduleAccess (
304+ ctx ,
305+ scheduleItem . scheduleType ,
306+ scheduleItem . serverId ,
307+ ) ;
308+
392309 const serviceId = scheduleItem . applicationId || scheduleItem . composeId ;
393310 if ( serviceId ) {
394311 await checkServicePermissionAndAccess ( ctx , serviceId , {
395312 schedule : [ "create" ] ,
396313 } ) ;
397314 } else {
398- if ( scheduleItem . scheduleType === "dokploy-server" && IS_CLOUD ) {
399- throw new TRPCError ( {
400- code : "FORBIDDEN" ,
401- message :
402- "Host-level schedules are not available in the cloud version." ,
403- } ) ;
404- }
405-
406315 await checkPermission ( ctx , { schedule : [ "create" ] } ) ;
407-
408- if (
409- scheduleItem . scheduleType === "server" ||
410- scheduleItem . scheduleType === "dokploy-server"
411- ) {
412- const member = await findMemberByUserId (
413- ctx . user . id ,
414- ctx . session . activeOrganizationId ,
415- ) ;
416- if ( member . role !== "owner" && member . role !== "admin" ) {
417- throw new TRPCError ( {
418- code : "FORBIDDEN" ,
419- message :
420- "Only owners and admins can manage server-level schedules." ,
421- } ) ;
422- }
423- }
424-
425- if ( scheduleItem . scheduleType === "server" && scheduleItem . serverId ) {
426- const targetServer = await findServerById ( scheduleItem . serverId ) ;
427- if (
428- targetServer . organizationId !== ctx . session . activeOrganizationId
429- ) {
430- throw new TRPCError ( {
431- code : "UNAUTHORIZED" ,
432- message : "You don't have access to this server." ,
433- } ) ;
434- }
435- }
436316 }
437317 try {
438318 await runCommand ( input . scheduleId ) ;
0 commit comments