Refactor components to remove Layout wrapper and pass it in the App component , implemented a skeleton feedback while loading page and improved API calls related to Dashboard/User Profile
107 lines
3.2 KiB
TypeScript
107 lines
3.2 KiB
TypeScript
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<string, Role | null>();
|
|
|
|
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);
|
|
});
|
|
}
|