UNPKG

@appsemble/lang-sdk

Version:

Language SDK for Appsemble

147 lines 6.85 kB
import { AppPermission, predefinedAppRolePermissions, } from './types/index.js'; function checkAppPermissions(acquiredPermissions, requiredPermissions) { const customAppResourcePermissionPattern = /^\$resource:[^:]+:(get|history:get|query|create|delete|patch|update)$/; const customAppOwnResourcePermissionPattern = /^\$resource:[^:]+:own:(get|query|delete|patch|update)$/; const customAppResourceViewPermissionPattern = /^\$resource:[^:]+:(get|query):[^:]+$/; return requiredPermissions.every((p) => { if (acquiredPermissions.includes(p)) { return true; } if (customAppResourcePermissionPattern.test(p)) { const [, , resourceAction, resourceExtenstion] = p.split(':'); return acquiredPermissions.includes(`$resource:all:${resourceAction}${resourceExtenstion ? `:${resourceExtenstion}` : ''}`); } if (customAppOwnResourcePermissionPattern.test(p)) { const [, resourceName, , resourceAction] = p.split(':'); return (acquiredPermissions.includes(`$resource:all:${resourceAction}`) || acquiredPermissions.includes(`$resource:all:own:${resourceAction}`) || acquiredPermissions.includes(`$resource:${resourceName}:${resourceAction}`)); } if (customAppResourceViewPermissionPattern.test(p)) { const [, resourceName, resourceAction, view] = p.split(':'); return (acquiredPermissions.includes(`$resource:${resourceName}:${resourceAction}`) || acquiredPermissions.includes(`$resource:all:${resourceAction}`) || acquiredPermissions.includes(`$resource:all:${resourceAction}:${view}`)); } }); } export function getAppInheritedRoles(appSecurityDefinition, roles, accumulatedRoles = []) { if (!appSecurityDefinition || !roles) { return []; } for (const role of roles) { if (!accumulatedRoles.includes(role)) { accumulatedRoles.push(role); const roleDefinition = appSecurityDefinition.roles?.[role]; if (roleDefinition && roleDefinition.inherits) { accumulatedRoles.push(...getAppInheritedRoles(appSecurityDefinition, roleDefinition.inherits, accumulatedRoles)); } } } return Array.from(new Set(accumulatedRoles)); } export function getAppRolePermissions(appSecurityDefinition, roles) { const accumulatedPermissions = []; const inheritedRoles = getAppInheritedRoles(appSecurityDefinition, roles); for (const role of inheritedRoles) { const roleDefinition = appSecurityDefinition.roles?.[role]; if (roleDefinition) { const rolePermissions = roleDefinition.permissions; if (rolePermissions) { accumulatedPermissions.push(...rolePermissions); } } else { const predefinedRolePermissions = predefinedAppRolePermissions[role]; if (predefinedRolePermissions) { accumulatedPermissions.push(...predefinedRolePermissions); } } } return Array.from(new Set(accumulatedPermissions)); } export function getGuestAppPermissions(appSecurityDefinition) { if (!appSecurityDefinition || !appSecurityDefinition.guest) { return []; } return [ ...(appSecurityDefinition.guest.permissions || []), ...getAppRolePermissions(appSecurityDefinition, appSecurityDefinition.guest.inherits ?? []), ]; } export function checkGuestAppPermissions(appSecurityDefinition, requiredPermissions) { const guestPermissions = getGuestAppPermissions(appSecurityDefinition); return checkAppPermissions(guestPermissions, requiredPermissions); } export function getAppRoles(appSecurityDefinition) { return Array.from(new Set(Object.keys(appSecurityDefinition?.roles || {}))); } export function getAppPossibleGuestPermissions(appDefinition) { const possibleAllViews = {}; const resourceDefinitions = Object.values(appDefinition.resources || {}); for (const resourceDefinition of resourceDefinitions) { for (const view of Object.keys(resourceDefinition.views || {})) { possibleAllViews[view] = true; } } for (const view of Object.keys(possibleAllViews)) { if (resourceDefinitions.some((resourceDefinition) => !resourceDefinition.views?.[view])) { possibleAllViews[view] = false; } } for (const view in possibleAllViews) { if (!possibleAllViews[view]) { delete possibleAllViews[view]; } } return [ ...Object.values(AppPermission), ...Object.entries(appDefinition.resources || {}).flatMap(([resourceName, resourceDefinition]) => [ `$resource:${resourceName}:create`, `$resource:${resourceName}:query`, `$resource:${resourceName}:get`, `$resource:${resourceName}:history:get`, `$resource:${resourceName}:update`, `$resource:${resourceName}:patch`, `$resource:${resourceName}:delete`, ...Object.keys(resourceDefinition.views || {}).flatMap((resourceView) => [ `$resource:${resourceName}:query:${resourceView}`, `$resource:${resourceName}:get:${resourceView}`, ]), ...Object.keys(possibleAllViews).flatMap((view) => [ `$resource:all:query:${view}`, `$resource:all:get:${view}`, ]), ]), ]; } export function getAppPossiblePermissions(appDefinition) { return [ ...getAppPossibleGuestPermissions(appDefinition), ...Object.keys(appDefinition.resources || {}).flatMap((resourceName) => [ `$resource:${resourceName}:own:query`, `$resource:${resourceName}:own:get`, `$resource:${resourceName}:own:update`, `$resource:${resourceName}:own:patch`, `$resource:${resourceName}:own:delete`, ]), ]; } export function getAppRolesByPermissions(appSecurityDefinition, requiredPermissions) { const roles = getAppRoles(appSecurityDefinition); const compliantRoles = []; for (const role of roles) { if (checkAppPermissions(getAppRolePermissions(appSecurityDefinition, [role]), requiredPermissions)) { compliantRoles.push(role); } } if (checkAppPermissions(getGuestAppPermissions(appSecurityDefinition), requiredPermissions)) { compliantRoles.push('Guest'); } return compliantRoles; } export function checkAppRoleAppPermissions(appSecurityDefinition, appRole, requiredPermissions) { const appRolePermissions = getAppRolePermissions(appSecurityDefinition, [appRole]); return checkAppPermissions(appRolePermissions, requiredPermissions); } //# sourceMappingURL=authorization.js.map