permissions.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import { forbidden } from "@/lib/api/errors";
  2. /**
  3. * Role-Based Access Control (RBAC) helpers.
  4. *
  5. * @typedef {Object} Session
  6. * @property {"branch"|"admin"|"superadmin"|"dev"|string} role
  7. * @property {string=} branchId
  8. */
  9. /**
  10. * Returns true if the given session is allowed to access the requested branch.
  11. *
  12. * Rules:
  13. * - No session => not allowed (caller should return 401)
  14. * - role "branch" => allowed only for session.branchId === branchId
  15. * - role "admin" / "superadmin" / "dev" => allowed for any branch
  16. *
  17. * @param {Session|null} session
  18. * @param {string} branchId
  19. * @returns {boolean}
  20. */
  21. export function canAccessBranch(session, branchId) {
  22. if (!session) return false;
  23. if (!branchId) return false;
  24. if (session.role === "branch") {
  25. return session.branchId === branchId;
  26. }
  27. if (
  28. session.role === "admin" ||
  29. session.role === "superadmin" ||
  30. session.role === "dev"
  31. ) {
  32. return true;
  33. }
  34. return false;
  35. }
  36. /**
  37. * Filters a list of branch IDs for a session.
  38. *
  39. * - No session => []
  40. * - role "branch" => [session.branchId] if present in branchIds, else []
  41. * - role "admin" / "superadmin" / "dev" => all branchIds
  42. *
  43. * @param {Session|null} session
  44. * @param {string[]} branchIds
  45. * @returns {string[]}
  46. */
  47. export function filterBranchesForSession(session, branchIds) {
  48. if (!session) return [];
  49. if (!Array.isArray(branchIds)) return [];
  50. if (session.role === "branch") {
  51. const own = session.branchId;
  52. if (!own) return [];
  53. return branchIds.includes(own) ? [own] : [];
  54. }
  55. if (
  56. session.role === "admin" ||
  57. session.role === "superadmin" ||
  58. session.role === "dev"
  59. ) {
  60. return branchIds;
  61. }
  62. return [];
  63. }
  64. /**
  65. * Returns true if the given session can manage users (RHL-012 capability).
  66. *
  67. * Rules:
  68. * - dev / superadmin => true
  69. * - admin / branch / unknown => false
  70. *
  71. * @param {Session|null} session
  72. * @returns {boolean}
  73. */
  74. export function canManageUsers(session) {
  75. if (!session) return false;
  76. return session.role === "dev" || session.role === "superadmin";
  77. }
  78. /**
  79. * Guard helper for user-management endpoints (to be used in RHL-012).
  80. *
  81. * Throws a standardized 403 error when the session lacks user-management permission.
  82. *
  83. * @param {Session|null} session
  84. * @returns {void}
  85. */
  86. export function requireUserManagement(session) {
  87. if (!canManageUsers(session)) {
  88. throw forbidden("AUTH_FORBIDDEN_USER_MANAGEMENT", "Forbidden");
  89. }
  90. }