1+ import { useCidReqStore } from "../store/cidReq"
2+ import { checkIsAllowedToEdit } from "../composables/userPermissions"
3+
4+ /**
5+ * Course Maintenance is a teacher-only course tool (admin category): students
6+ * and teachers of other courses must not reach any of its pages.
7+ *
8+ * Runs as beforeEnter (before beforeResolve), so the course context is loaded
9+ * here first, then edit permission is resolved for the current cid/sid. Mirrors
10+ * the backend gate (ROLE_CURRENT_COURSE_TEACHER / platform admin), so course
11+ * teachers and admins pass while everyone else is redirected away.
12+ *
13+ * @param {import('vue-router').RouteLocationNormalized } to
14+ * @returns {Promise<boolean|import('vue-router').RouteLocationRaw> }
15+ */
16+ async function courseMaintenanceBeforeEnter ( to ) {
17+ const courseId = parseInt ( to . query ?. cid ?? 0 )
18+ const sessionId = parseInt ( to . query ?. sid ?? 0 )
19+
20+ if ( ! courseId ) {
21+ return { name : "Home" , replace : true }
22+ }
23+
24+ const cidReqStore = useCidReqStore ( )
25+ await cidReqStore . setCourseAndSessionById ( courseId , sessionId )
26+
27+ if ( ! cidReqStore . course ) {
28+ return { name : "Home" , replace : true }
29+ }
30+
31+ const isAllowedToEdit = await checkIsAllowedToEdit ( )
32+
33+ if ( ! isAllowedToEdit ) {
34+ return { name : "CourseHome" , params : { id : courseId } , query : sessionId ? { sid : sessionId } : { } }
35+ }
36+
37+ return true
38+ }
39+
140export default {
241 path : "/resources/course_maintenance/:node(\\d+)" ,
342 meta : { requiresAuth : true , showBreadcrumb : true , breadcrumb : "Course maintenance" } ,
@@ -8,36 +47,42 @@ export default {
847 {
948 name : "CMImportBackup" ,
1049 path : "import" ,
50+ beforeEnter : courseMaintenanceBeforeEnter ,
1151 component : ( ) => import ( "../views/coursemaintenance/ImportBackup.vue" ) ,
1252 meta : { breadcrumb : "Import backup" } ,
1353 } ,
1454 {
1555 name : "CMCreateBackup" ,
1656 path : "create" ,
57+ beforeEnter : courseMaintenanceBeforeEnter ,
1758 component : ( ) => import ( "../views/coursemaintenance/CreateBackup.vue" ) ,
1859 meta : { breadcrumb : "Create backup" } ,
1960 } ,
2061 {
2162 name : "CMCopyCourse" ,
2263 path : "copy" ,
64+ beforeEnter : courseMaintenanceBeforeEnter ,
2365 component : ( ) => import ( "../views/coursemaintenance/CopyCourse.vue" ) ,
2466 meta : { breadcrumb : "Copy course" } ,
2567 } ,
2668 {
2769 name : "CMCc13" ,
2870 path : "cc13" ,
71+ beforeEnter : courseMaintenanceBeforeEnter ,
2972 component : ( ) => import ( "../views/coursemaintenance/Cc13.vue" ) ,
3073 meta : { breadcrumb : "IMS CC 1.3" } ,
3174 } ,
3275 {
3376 name : "CMRecycle" ,
3477 path : "recycle" ,
78+ beforeEnter : courseMaintenanceBeforeEnter ,
3579 component : ( ) => import ( "../views/coursemaintenance/RecycleCourse.vue" ) ,
3680 meta : { breadcrumb : "Recycle course" } ,
3781 } ,
3882 {
3983 name : "CMDelete" ,
4084 path : "delete" ,
85+ beforeEnter : courseMaintenanceBeforeEnter ,
4186 component : ( ) => import ( "../views/coursemaintenance/DeleteCourse.vue" ) ,
4287 meta : { breadcrumb : "Delete course" } ,
4388 } ,
0 commit comments