import { EntityWithRoles, Role } from "@/interfaces/entity"; import { PermissionType } from "@/interfaces/permissions"; import { User, Type, userTypes } from "@/interfaces/user"; import { RolePermission } from "@/resources/entityPermissions"; import axios from "axios"; import { findBy, mapBy } from "."; import { isAdmin } from "./users"; export function checkAccess(user: User, types: Type[], permissions?: PermissionType[], permission?: PermissionType) { if (!user) { return false; } // if(user.type === '') { if (!user?.type) { return false; } if (types.length === 0) { return false; } if (!types.includes(user.type)) { return false; } // we may not want a permission check as most screens dont even havr a specific permission if (permission) { // this works more like a blacklist // therefore if we don't find the permission here, he can't do it if (!(permissions || []).includes(permission)) { return false; } } return true; } export function groupAllowedEntitiesByPermissions( user: User, entities: EntityWithRoles[], permissions: RolePermission[] ): { [key: string]: EntityWithRoles[] } { if (["admin", "developer"].includes(user?.type)) { return permissions.reduce((acc, permission) => { acc[permission] = entities; return acc; }, {} as { [key: string]: EntityWithRoles[] }); } const userEntityMap = new Map(user.entities.map(e => [e.id, e])); const roleCache = new Map(); return entities.reduce((acc, entity) => { const userEntity = userEntityMap.get(entity.id); const role = userEntity ? roleCache.get(userEntity.role) ?? (() => { const foundRole = entity.roles.find(r => r.id === userEntity.role) || null; roleCache.set(userEntity.role, foundRole); return foundRole; })() : null; permissions.forEach(permission => { if (!acc[permission]) acc[permission] = []; if (role && role.permissions.includes(permission)) { acc[permission].push(entity); } }); return acc; }, {} as { [key: string]: EntityWithRoles[] }); } export function findAllowedEntities(user: User, entities: EntityWithRoles[], permission: RolePermission) { if (["admin", "developer"].includes(user?.type)) return entities const allowedEntities = entities.filter((e) => doesEntityAllow(user, e, permission)) return allowedEntities } export function findAllowedEntitiesSomePermissions(user: User, entities: EntityWithRoles[], permissions: RolePermission[]) { if (["admin", "developer"].includes(user?.type)) return entities const allowedEntities = entities.filter((e) => permissions.some((p) => doesEntityAllow(user, e, p))) return allowedEntities } export function doesEntityAllow(user: User, entity: EntityWithRoles, permission: RolePermission) { if (isAdmin(user)) return true const userEntity = findBy(user.entities, 'id', entity?.id) if (!userEntity) return false const role = findBy(entity.roles, 'id', userEntity.role) if (!role) return false return role.permissions.includes(permission) } export function getTypesOfUser(types: Type[]) { // basicly generate a list of all types except the excluded ones return userTypes.filter((userType) => { return !types.includes(userType); }); }