All files / src/composables useRole.ts

83.78% Statements 31/37
75% Branches 3/4
25% Functions 1/4
83.78% Lines 31/37

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 531x 1x                         1x 8x 8x 8x 8x 8x 8x     8x   8x 8x 8x 8x   8x         8x   8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x  
import { computed } from "vue"
import { useAuthStore } from "@/stores/auth.store"
import type { App, Deployment, Course, UserRole as Role } from "@/types"
 
/**
 * Single source of truth for role + capability reads in the UI.
 *
 * Phase 4 of the RBAC plan replaces the old ``usePermissions`` and the
 * ``authStore.isAdmin`` / ``authStore.isTeacherOrAdmin`` direct reads
 * with this composable. The ``can*`` helpers mirror the backend
 * capabilities in ``backend/app/utils/capabilities.py`` — they are
 * purely cosmetic (controlling button visibility, route guards), the
 * authoritative check still happens in the API layer.
 */
export function useRole() {
  const auth = useAuthStore()
  const role = computed<Role | null>(() => auth.user?.role ?? null)
  const isAdmin = computed(() => role.value === "admin")
  const isTeacher = computed(() => role.value === "teacher")
  const isStudent = computed(() => role.value === "student")
  const isStaff = computed(() => isAdmin.value || isTeacher.value)
 
  // Capability-Mirror (rein kosmetisch, schützt keine Daten)
  const canEditApp = (app: App) =>
    isAdmin.value || app.userId === auth.user?.userId
  const canDeleteApp = canEditApp
  const canSubmitAppVersion = canEditApp
  const canApproveApp = computed(() => isAdmin.value)
  const canOperateDeployment = (d: Deployment) =>
    isAdmin.value || d.userId === auth.user?.userId
  const canEditCourse = (c: Course) =>
    isAdmin.value ||
    ((c as Course & { teacherIds?: string[] }).teacherIds?.includes(
      auth.user?.userId ?? ""
    ) ?? false)
  const canChangeUserRole = computed(() => isAdmin.value)
 
  return {
    role,
    isAdmin,
    isTeacher,
    isStudent,
    isStaff,
    canEditApp,
    canDeleteApp,
    canSubmitAppVersion,
    canApproveApp,
    canOperateDeployment,
    canEditCourse,
    canChangeUserRole,
  }
}