75 lines
2.1 KiB
TypeScript
75 lines
2.1 KiB
TypeScript
export const ROLES = {
|
|
CITIZEN: 'CITIZEN',
|
|
OPERATOR: 'OPERATOR',
|
|
ADMIN: 'ADMIN'
|
|
} as const
|
|
|
|
export type Role = keyof typeof ROLES
|
|
export type NegatedRole = `!${Role}`
|
|
export type MetaRoleRequirement = Role | NegatedRole | Array<Role | NegatedRole>
|
|
|
|
export const ROLE_LEVELS: Record<string, number> = {
|
|
[ROLES.CITIZEN]: 1,
|
|
[ROLES.OPERATOR]: 2,
|
|
[ROLES.ADMIN]: 3
|
|
}
|
|
|
|
export function normalizeRole(role?: string | null): string {
|
|
return role?.trim().toUpperCase() ?? ''
|
|
}
|
|
|
|
export function isRole(userRole: string | undefined | null, targetRole: string): boolean {
|
|
return normalizeRole(userRole) === normalizeRole(targetRole)
|
|
}
|
|
|
|
export function hasMinimumRole(userRole: string | undefined | null, requiredRole: string): boolean {
|
|
const userLvl = ROLE_LEVELS[normalizeRole(userRole)] || 0
|
|
const reqLvl = ROLE_LEVELS[normalizeRole(requiredRole)] || 0
|
|
return userLvl >= reqLvl
|
|
}
|
|
|
|
export function isAdmin(userRole?: string | null): boolean {
|
|
return isRole(userRole, ROLES.ADMIN)
|
|
}
|
|
|
|
export function isOperator(userRole?: string | null): boolean {
|
|
return isRole(userRole, ROLES.OPERATOR)
|
|
}
|
|
|
|
export function isCitizen(userRole?: string | null): boolean {
|
|
return isRole(userRole, ROLES.CITIZEN)
|
|
}
|
|
|
|
export function canAccess(userRole: string | undefined | null, requiredRole: string): boolean {
|
|
return hasMinimumRole(userRole, requiredRole)
|
|
}
|
|
|
|
export function checkRoleAccess(userRole: string | undefined | null, requirement: MetaRoleRequirement | undefined): boolean {
|
|
if (!requirement) return true
|
|
|
|
const normalizedUserRole = normalizeRole(userRole)
|
|
if (!normalizedUserRole) return false
|
|
|
|
const requirements = Array.isArray(requirement) ? requirement : [requirement]
|
|
|
|
for (const req of requirements) {
|
|
const isNegated = req.startsWith('!')
|
|
|
|
const rawTarget = isNegated ? req.substring(1) : req
|
|
const targetRole = normalizeRole(rawTarget)
|
|
|
|
if (isNegated) {
|
|
console.log("negated", normalizedUserRole, targetRole)
|
|
if (normalizedUserRole === targetRole) {
|
|
return false
|
|
}
|
|
} else {
|
|
if (!hasMinimumRole(normalizedUserRole, targetRole)) {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|