@elsikora/nestjs-crud-automator
Version:
A library for automating the creation of CRUD operations in NestJS.
114 lines (111 loc) • 4.67 kB
JavaScript
import { ApiSubscriberBase } from '../../subscriber/base.class.js';
import '../../../../enum/class/authorization/cache-mode.enum.js';
import '../../../../enum/class/authorization/decision-type.enum.js';
import { EApiPolicyEffect } from '../../../../enum/class/authorization/effect.enum.js';
import '../../../../enum/class/authorization/mode.enum.js';
import { EApiAuthorizationPermissionMatch } from '../../../../enum/class/authorization/permission-match.enum.js';
import '../../../../enum/class/authorization/policy/attachment-type.enum.js';
import '../../../../enum/class/authorization/policy/on-type.enum.js';
import '../../../../enum/class/authorization/policy/source-type.enum.js';
import '../../../../enum/class/authorization/policy/status.enum.js';
import '../../../../enum/class/authorization/principal-type.enum.js';
import { AuthorizationPermissionSetMatches } from '../../../../utility/authorization/permission/set-matches.utility.js';
import 'typeorm';
/**
* Base class for all authorization policies. It mirrors ApiFunctionSubscriberBase
* and provides helper methods to create allow/deny rules that are later executed by the policy executor.
* @template E - Entity type extending IApiBaseEntity
*/
class ApiAuthorizationPolicyBase extends ApiSubscriberBase {
allow(rule = {}) {
return [
{
effect: EApiPolicyEffect.ALLOW,
...rule,
},
];
}
allowForPermissions(requiredPermissions, options = {}) {
const permissionOptions = options;
const matchMode = permissionOptions.match ?? EApiAuthorizationPermissionMatch.ANY;
return [
{
condition: async (context) => {
if (!AuthorizationPermissionSetMatches(context.permissions, requiredPermissions, { match: matchMode })) {
return false;
}
if (!permissionOptions.condition) {
return true;
}
const result = await permissionOptions.condition(context);
return result === true;
},
description: permissionOptions.description,
effect: EApiPolicyEffect.ALLOW,
priority: permissionOptions.priority,
resultTransform: permissionOptions.resultTransform,
scope: permissionOptions.scope,
},
];
}
allowForRoles(roles, rule = {}) {
return [
{
condition: ({ principal }) => roles.some((role) => principal.roles.includes(role)),
effect: EApiPolicyEffect.ALLOW,
...rule,
},
];
}
deny(rule = {}) {
return [
{
effect: EApiPolicyEffect.DENY,
...rule,
},
];
}
denyForPermissions(requiredPermissions, options = {}) {
const permissionOptions = options;
const matchMode = permissionOptions.match ?? EApiAuthorizationPermissionMatch.ANY;
return [
{
condition: async (context) => {
if (!AuthorizationPermissionSetMatches(context.permissions, requiredPermissions, { match: matchMode })) {
return false;
}
if (!permissionOptions.condition) {
return true;
}
const result = await permissionOptions.condition(context);
return result === true;
},
description: permissionOptions.description,
effect: EApiPolicyEffect.DENY,
priority: permissionOptions.priority,
resultTransform: permissionOptions.resultTransform,
scope: permissionOptions.scope,
},
];
}
scopeToOwner(ownerField = "ownerId", rule = {}, options = {}) {
const ownerFieldName = String(ownerField);
const isRelation = options.isRelation ?? !ownerFieldName.endsWith("Id");
return [
{
effect: EApiPolicyEffect.ALLOW,
scope: ({ principal }) => {
const ownerCondition = isRelation ? { id: principal.id } : principal.id;
return {
where: {
[ownerFieldName]: ownerCondition,
},
};
},
...rule,
},
];
}
}
export { ApiAuthorizationPolicyBase };
//# sourceMappingURL=base.class.js.map