37 lines
1.1 KiB
TypeScript
37 lines
1.1 KiB
TypeScript
export const Role = {
|
|
SUPER_ADMIN: 'super_admin',
|
|
TENANT_ADMIN: 'tenant_admin',
|
|
MANAGER: 'manager',
|
|
TECHNICIAN: 'technician',
|
|
VIEWER: 'viewer',
|
|
} as const;
|
|
|
|
export type Role = (typeof Role)[keyof typeof Role];
|
|
|
|
export const ALL_ROLES: readonly Role[] = Object.values(Role);
|
|
|
|
/**
|
|
* Numeric hierarchy level per role.
|
|
* Higher number = more powerful role.
|
|
* Used for hierarchy-aware authorization checks.
|
|
*/
|
|
const ROLE_LEVEL: Record<string, number> = {
|
|
[Role.SUPER_ADMIN]: 100,
|
|
[Role.TENANT_ADMIN]: 80,
|
|
[Role.MANAGER]: 60,
|
|
[Role.TECHNICIAN]: 40,
|
|
[Role.VIEWER]: 20,
|
|
};
|
|
|
|
/**
|
|
* Check if any of the user's roles satisfies the required role level.
|
|
* A higher-level role always satisfies a lower-level requirement.
|
|
*
|
|
* Example: user with ['manager'] satisfies 'technician' because manager(60) >= technician(40).
|
|
*/
|
|
export function satisfiesRole(userRoles: string[], requiredRole: string): boolean {
|
|
const requiredLevel = ROLE_LEVEL[requiredRole];
|
|
if (requiredLevel === undefined) return false;
|
|
return userRoles.some((r) => (ROLE_LEVEL[r] ?? 0) >= requiredLevel);
|
|
}
|