Package Exports
- @strapi/permissions
- @strapi/permissions/lib/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@strapi/permissions) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Strapi Permissions
Highly customizable permission engine made for Strapi
Get Started
yarn add @strapi/permissionsconst permissions = require('@strapi/permissions');
const engine = permissions.engine.new({ providers });
const ability = await engine.generateAbility([
{ action: 'read' },
{ action: 'delete', subject: 'foo' },
{ action: 'update', subject: 'bar', properties: { fields: ['foobar'] } },
{
action: 'create',
subject: 'foo',
properties: { fields: ['foobar'] },
conditions: ['isAuthor'],
},
]);
ability.can('read'); // true
ability.can('publish'); // false
ability.can('update', 'foo'); // false
ability.can('update', 'bar'); // true- You need to give both an action and a condition provider as parameters when instantiating a new permission engine instance. They must be contained in a
providersobject property. - You can also pass an
abilityBuilderFactoryto customize what kind of ability thegenerateAbilitymethod will return. By default it'll use a@casl/abilitybuilder.
You can also register to some hooks for each engine instance.
See lib/engine/hooks.js -> createEngineHooks for available hooks.
const permissions = require('@strapi/permissions');
const engine = permissions.engine
.new({ providers })
.on('before-format::validate.permission', ({ permission }) => {
if (permission.action === 'read') {
return false;
}
});
const ability = await engine.generateAbility([
{ action: 'read' },
{ action: 'delete', subject: 'foo' },
{ action: 'update', subject: 'bar', properties: { fields: ['foobar'] } },
{
action: 'create',
subject: 'foo',
properties: { fields: ['foobar'] },
conditions: ['isAuthor'],
},
]);
ability.can('read'); // false since the validation hook prevents the engine from registering the permission
ability.can('publish'); // false
ability.can('update', 'foo'); // false
ability.can('update', 'bar'); // trueThe format.permission hook can be used to modify the permission.
const permissions = require('@strapi/permissions');
const engine = permissions.engine
.new({ providers })
.on('before-format::validate.permission', ({ permission }) => {
if (permission.action === 'modify') {
return false;
}
})
.on('after-format::validate.permission', ({ permission }) => {
if (permission.action === 'update') {
return false;
}
})
.on('format.permission', ({ permission }) => {
if (permission.action === 'update') {
return {
...permission,
action: 'modify',
};
}
if (permission.action === 'delete') {
return {
...permission,
action: 'remove',
};
}
return permission;
});
const ability = await engine.generateAbility([{ action: 'update' }, { action: 'delete' }]);
ability.can('update'); // false
ability.can('modify'); // true, because create was changed to 'modify'
ability.can('delete'); // false, doesn't exist because it was changed by format.permission
ability.can('remove'); // true, before-format::validate.permission validates before format.permission changed it