@@ -161,6 +161,53 @@ courseRouter.get('/:id/enrolments', async (req: express.Request, res: express.Re
161
161
res . send ( chatInstance . enrolments )
162
162
} )
163
163
164
+ //checks if user is a admin or is responsible for the course, returns forbidden error if not
165
+ const enforceUserHasFullAccess = async ( user , chatInstance ) => {
166
+ const hasFullAccess =
167
+ user . isAdmin ||
168
+ chatInstance . responsibilities
169
+ ?. map ( ( r ) => r . userId )
170
+ . filter ( Boolean )
171
+ . includes ( user . id )
172
+
173
+ if ( ! hasFullAccess ) {
174
+ throw ApplicationError . Forbidden ( 'Unauthorized' )
175
+ }
176
+ return hasFullAccess
177
+ }
178
+
179
+ // returns a chatInstance, throws an chat instacne not found if not found
180
+ const getChatInstance = async ( id ) => {
181
+
182
+ const chatInstance = await ChatInstance . findOne ( {
183
+ where : { courseId : id } ,
184
+ include : [
185
+ {
186
+ model : Responsibility ,
187
+ as : 'responsibilities' ,
188
+ attributes : [ 'id' ] ,
189
+ include : [
190
+ {
191
+ model : User ,
192
+ as : 'user' ,
193
+ attributes : [ 'id' , 'username' , 'last_name' , 'first_names' ] ,
194
+ } ,
195
+ ] ,
196
+ } ,
197
+ {
198
+ model : Prompt ,
199
+ as : 'prompts' ,
200
+ } ,
201
+ ] ,
202
+ } )
203
+
204
+ if ( ! chatInstance ) {
205
+ throw ApplicationError . NotFound ( 'Chat instance not found' )
206
+ }
207
+
208
+ return chatInstance
209
+ }
210
+
164
211
const checkDiscussionAccess = async ( req : express . Request , res : express . Response , next : express . NextFunction ) => {
165
212
const request = req as unknown as RequestWithUser
166
213
const { user } = request
@@ -266,4 +313,48 @@ courseRouter.put('/:id', async (req, res) => {
266
313
res . send ( chatInstance )
267
314
} )
268
315
316
+ const userAssignedAsResponsible = ( userId , chatInstance ) => {
317
+
318
+ const isResponsible :boolean = chatInstance . responsibilities
319
+ ?. map ( ( r ) => r . userId )
320
+ . filter ( Boolean )
321
+ . includes ( userId )
322
+ return isResponsible
323
+ }
324
+
325
+
326
+ const getUser = async ( id : string ) => {
327
+
328
+ const user = await User . findByPk ( id )
329
+ if ( ! user ) {
330
+ throw ApplicationError . NotFound ( 'User not found' )
331
+ return null
332
+ }
333
+ return user
334
+ }
335
+ courseRouter . put ( '/:id/responsibilities/assign' , async ( req , res ) => {
336
+ const chatInstanceId = req . params . id
337
+ const body = req . body as {
338
+ assignedUserId : string
339
+ }
340
+ const assignedUserId :string = body . assignedUserId
341
+
342
+ const request = req as unknown as RequestWithUser
343
+ const { user} = request
344
+ const chatInstance = await getChatInstance ( chatInstanceId )
345
+ const hasPermission = await enforceUserHasFullAccess ( user , chatInstanceId )
346
+
347
+ const userToAssign = await getUser ( assignedUserId )
348
+ const userNotAssignedAlready = await ! userAssignedAsResponsible ( assignedUserId , chatInstance )
349
+ if ( hasPermission && userToAssign && userNotAssignedAlready ) {
350
+ await Responsibility . create ( {
351
+ userId : assignedUserId ,
352
+ chatInstanceId : chatInstance . id ,
353
+ createdByUserId : user . id
354
+ } )
355
+ }
356
+ } )
357
+
358
+
359
+
269
360
export default courseRouter
0 commit comments