Files
latosa-escrima/frontend/lib/hasPermissions.ts

44 lines
1.5 KiB
TypeScript

import { Role } from "@/types/types";
type PermissionResult<T extends Record<string, readonly string[]>> = {
[K in keyof T]: {
[A in T[K][number]]: boolean;
} & { all: boolean }; // Per-resource 'all'
} & { all: boolean }; // Global 'all'
// hasPermissions function with 'all' flags
export default function hasPermissions<
T extends Record<string, readonly string[]>,
>(roles: Role[], permissions: T): PermissionResult<T> {
// Build permissions set
const permissionsSet: Map<string, null> = new Map();
for (const role of roles) {
if (!role.permissions) continue;
for (const perm of role.permissions) {
const key = `${perm.resource}:${perm.action}`;
permissionsSet.set(key, null);
}
}
// Build result
const result = { all: true } as PermissionResult<T>; // Initialize global 'all' as true
let globalAll = true; // Track global state
for (const resource in permissions) {
const actions = permissions[resource];
let resourceAll = true; // Track per-resource state
result[resource] = { all: true } as any; // Initialize resource object
for (const action of actions) {
const hasPerm = permissionsSet.has(`${resource}:${action}`);
(result[resource] as Record<string, boolean>)[action] = hasPerm;
resourceAll = resourceAll && hasPerm; // Update resource 'all'
}
result[resource].all = resourceAll; // Set resource 'all'
globalAll = globalAll && resourceAll; // Update global 'all'
}
result.all = globalAll; // Set global 'all'
return result as PermissionResult<T>;
}