npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

dynamic-acl

v2.0.6

Published

Dynamic Access Control List for Node.js to fully control your Roles, Resources, Privileges and Conditions using Promises

Downloads

7

Readme

node-dynamic-acl

Dynamic Access Control List for Node.js to fully control your Roles, Resources, Privileges and Conditions

#Install

$ npm install dynamic-acl

#Quick Start

var Acl = require('../dist').Acl;
var Role = require('../dist').Role;
var Resource = require('../dist').Resource;

var anonymous = {
roleId: 'visitor'
};
var bob = {
firstname: 'Bob',
lastname: 'Marley',
roleId: 'user'
};

var me = {
firtname: 'Timmmmy',
lastname: 'Timmmmy',
roleId: 'admin'
};

var page1 = {
id: 'page 1',
title: 'Go further with node',
resourceId: 'page'
};

var book = {
id: 'book 1',
title: 'Go further with JS',
resourceId: 'book'
};

var getUserRoleId = (user) => new Promise(resolve => resolve(user.roleId));

var getResourceId = (resource) => new Promise(resolve => resolve(resource.resourceId));

var userCanMarkPage = (user, page) => new Promise((resolve,reject) => {
if (user.firstname == 'Timmmmy')
return resolve();
return reject();
});

var acl = new Acl(getUserRoleId, getResourceId);
acl.addRole('visitor') // equivalent to acl.addRole(new Role('visitor', [], acl))
.addRole(new Role('user', ['visitor'], acl))
.addRole('admin', ['user']) //equivalent to acl.addRole(new Role('admin', ['user'], acl))
.addResource(new Resource('page', ['read', 'mark', 'change title']))
.addResource(new Resource('book'))
.build();

acl.allow('visitor', 'page', 'read')
.allow('user', 'page')
.allow('user', 'page', 'mark', userCanMarkPage)
.deny('user', 'page', 'change title')
.allow('admin', 'page', 'change title')
.allow('admin', 'book');

//console.log('---built permissions---');
//console.log('---visitor---');
//console.log(acl.getPermissions('visitor'));
//console.log('---user---');
//console.log(acl.getPermissions('user'));
//console.log('---admin---');
//console.log(acl.getPermissions('admin'));

//console.log('---anonymous permissions check---');
acl.isAllowed(anonymous, page1).then(
() => {
// anonymous should not be allowed
console.error('This should not be printed in console');
},
() => {
// anonymous is not allowed
console.log('anonymous isAllowed page1:* -> false');
}
);

acl.isAllowed(anonymous, page1, 'read').then(
// anonymous is allowed
() => {console.log('anonymous isAllowed page1:read -> true')},
() => {console.error('This should not be printed in console')}
);

acl.isAllowed(anonymous, page1, 'mark').then(
() => {console.error('This should not be printed in console')},
// anonymous is not allowed
() => {console.log('anonymous isAllowed page1:mark -> false')}
);

acl.isAllowed(anonymous, page1, 'change title').then(
() => {console.error('This should not be printed in console')},
// anonymous is not allowed
() => {console.log('anonymous isAllowed page1:change title -> false')}
);

acl.isAllowed(anonymous, book).then(
() => {console.error('This should not be printed in console')},
// anonymous is not allowed
() => {console.log('anonymous isAllowed book:* -> false')}
);

acl.isAllowed(anonymous, book, 'sell').then(
() => {console.error('This should not be printed in console')},
// anonymous is not allowed
() => {console.log('anonymous isAllowed book:sell -> false')}
);


//console.log('---user permissions check---');
acl.isAllowed(bob, page1).then(
() => {console.log('bob isAllowed page1:* -> true')},
() => {console.error('This should not be printed in console')}
);

acl.isAllowed(bob, page1, 'read').then(
() => {console.log('bob isAllowed page1:read -> true')},
() => {console.error('This should not be printed in console')}
);

acl.isAllowed(bob, page1, 'mark').then(
() => {console.error('This should not be printed in console')},
() => {console.log('bob isAllowed page1:mark -> false')}
);

acl.isAllowed(bob, page1, 'change title').then(
() => {console.error('This should not be printed in console')},
() => {console.log('bob isAllowed page1:change title -> false')}
);

acl.isAllowed(bob, book, 'book:*').then(
() => {console.error('This should not be printed in console')},
() => {console.log('bob isAllowed book:* -> false')}
);

acl.isAllowed(bob, book, 'book:sell').then(
() => {console.error('This should not be printed in console')},
() => {console.log('bob isAllowed book:sell -> false')}//privilege was not declared previously -> inherit from book:*
);

//console.log('---admin permissions check---');
acl.isAllowed(me, page1).then(
() => {console.log('me isAllowed page1:* -> true')},
() => {console.error('This should not be printed in console')}
);
acl.isAllowed(me, page1, 'read').then(
() => {console.log('me isAllowed page1:read -> true')},
() => {console.error('This should not be printed in console')}
);
acl.isAllowed(me, page1, 'mark').then(
() => {console.log('me isAllowed page1:mark -> true')},
() => {console.error('This should not be printed in console')}
);
acl.isAllowed(me, page1, 'change title').then(
() => {console.log('me isAllowed page1:change title -> true')},
() => {console.error('This should not be printed in console')}
);
acl.isAllowed(me, book).then(
() => {console.log('me isAllowed book:* -> true')},
() => {console.error('This should not be printed in console')}
);
acl.isAllowed(me, book, 'sell').then(
() => {console.log('me isAllowed book:sell -> true')},//privilege was not declared previously -> inherit from book:*
() => {console.error('This should not be printed in console')}
);

#API Reference

Acl

This class holds all information about Roles, Resources and Permissions

Kind: global class

new Acl(roleIdFetchFunc, resourceIdFetchFunc)

Constructor

| Param | Type | Description | | --- | --- | --- | | roleIdFetchFunc | fetchRoleIdFunc | function that will let Acl fetch Role id (default will return empty string) | | resourceIdFetchFunc | fetchResourceIdFunc | function that will let Acl fetch Resource id (default will return empty string) |

Example

var myAcl = new Acl(function(user){
		return Promise.resolve(user.getRole());
}, function(resource){
		return Promise.resolve(resource.getResourceId());
});

acl.setRoleIdFetchFunc(func) ⇒ Acl

Sets how Acl should retrieve Role Id

Kind: instance method of Acl
Returns: Acl - this instance for chaining

| Param | Type | Description | | --- | --- | --- | | func | fetchRoleIdFunc | that will let Acl fetch Role Id from an object that may have a role |

acl.setResourceIdFetchFunc(func) ⇒ Acl

Sets how Acl should retrieve Resource Id

Kind: instance method of Acl
Returns: Acl - this instance for chaining

| Param | Type | Description | | --- | --- | --- | | func | fetchResourceIdFunc | that will let Acl fetch Resource Id from an object that may be a resource |

acl.addRole(role, Parents) ⇒ Acl

Add a new Role to Access Control List

Kind: instance method of Acl
Returns: Acl - this instanc@e for chaining
Throws:

  • Error if role is not an instance of Role or a string

| Param | Type | Description | | --- | --- | --- | | role | Role | string | instance to add | | Parents | Array.<string> | Array.<Role> | default is empty array |

Example

acl.addRole('anonyme');
acl.addRole('user', ['anonyme']);
acl.addRole(new Role('admin', ['user'], acl));
acl.addRole('super', [new Role('normal', [], acl)]);

acl.removeRole(role) ⇒ Acl

Deletes role from the list of declared roles

Kind: instance method of Acl
Returns: Acl - this instance for chaining

| Param | Type | | --- | --- | | role | Role | string |

Example

acl.remove('anonymous');

acl.getRole(id) ⇒ Role

Retrieve an instance of Role identified by id. It must be added before calling this function

Kind: instance method of Acl
Returns: Role - a Role instance if it was previously added or null if not exists

| Param | Type | Description | | --- | --- | --- | | id | string | of Role to retrieve |

acl.addResource(resource) ⇒ Acl

Add a new resource to Access Control List

Kind: instance method of Acl
Returns: Acl - this instance for chaining
Throws:

  • Error if resource is not an instance of Acl

| Param | Type | Description | | --- | --- | --- | | resource | Resource | to add to Access Control List |

Example

acl.addResource(new Resource('page'));
acl.addResource(new Resource('book', ['read', 'buy']);

acl.removeResource(resource) ⇒ Acl

Removes a resource from Access Control List

Kind: instance method of Acl
Returns: Acl - this instance for chaining
Throws:

  • Error if resource is not an instance of Resource or of type string

| Param | Type | Description | | --- | --- | --- | | resource | Resource | string | to remove |

Example

acl.removeResource('page');
acl.removeResource(bookResourceInstance);

acl.getResource(id) ⇒ Resource | null

Get resource instance by its Id if it was previously added to Access Control List

Kind: instance method of Acl
Returns: Resource | null - Resource instance if it exists. will return null otherwise

| Param | Type | Description | | --- | --- | --- | | id | string | Resource | of resource to get |

Example

acl.getResource('page');

acl.build() ⇒ Acl

Build all permissions based on added Role and Resource. Permissions are initialized to allow = false and condition = null

Kind: instance method of Acl
Returns: Acl - this instance for chaining

acl.allow(roleId, resourceId, privilege, condition) ⇒ Acl

Allow User with Role Id to access Privileged Resource (which have Resource Id) under condition

Kind: instance method of Acl
Returns: Acl - this instance for chaining

| Param | Type | Default | Description | | --- | --- | --- | --- | | roleId | string | Role | | Role Id or Role instance | | resourceId | string | Resource | | Resource Id or Resource instance | | privilege | string | Array.<string> | "" | Privilege (default is '' all) | | condition | permissionConditionFunc | | Conditional permission function (default is null) |

Example

acl.allow('user', 'article', 'write')
   .allow('user', 'article', ['read', 'comment']);
   .allow('user', 'article', 'modify', function(user, blog){
		return user.id == article.author_id;
		});

acl.deny(roleId, resourceId, privilege, condition) ⇒ Acl

Deny User with Role Id to access Privileged Resource (which have Resource Id) under condition

Kind: instance method of Acl
Returns: Acl - this instance for chaining

| Param | Type | Default | Description | | --- | --- | --- | --- | | roleId | string | Role | | Role Id or Role instance | | resourceId | string | Resource | | Resource Id or Resource instance | | privilege | string | Array.<string> | "" | Privilege (default is '' all) | | condition | permissionConditionFunc | | Conditional permission function (default is null) |

Example

acl.deny('anonymous', 'article', 'write')
   .deny('anonymous', 'article', ['modify', 'comment'])
   .deny('anonymous', 'article', 'read', function(user, article){
		return article.is_public;
	  });

acl._allowOrDeny(allow, roleId, resourceId, privilege, condition)

Allow User with Role Id to access Privileged Resource (which have Resource Id) under condition

Kind: instance method of Acl

| Param | Type | Default | Description | | --- | --- | --- | --- | | allow | boolean | | true = allowed, false = denied | | roleId | string | Role | | Role Id or Role instance | | resourceId | string | Resource | | Resource Id or Resource instance | | privilege | string | "" | Privilege (default is '' all) | | condition | permissionConditionFunc | | Conditional permission function (default is null) |

acl.isAllowed(user, resource, privilege) ⇒ Promise

Checks if user is allowed to access resource with a given privilege. If yes, it checks condition

Kind: instance method of Acl

| Param | Type | Default | | --- | --- | --- | | user | * | | | resource | * | | | privilege | string | "*" |

Example

acl.isAllowed(userObject, resourceObject, 'read');
acl.isAllowed(userObject, resourceObject);

acl.isRoleAllowed(roleId, resourceId, privilege) ⇒ Promise

Checks if roleId has access to resourceId with privilege. If not, it will check if one of the related parents has access to resource id

Kind: instance method of Acl

| Param | Type | Default | | --- | --- | --- | | roleId | string | | | resourceId | string | | | privilege | string | "*" |

Example

acl.isRoleAllowed('user', 'book', 'read');
acl.isRoleAllow('user', 'page');

acl.isAnyParentAllowed(roleId, resourceId, privilege) ⇒ Promise

Checks if any role's parents is allowed to access resourceId with privileges

Kind: instance method of Acl

| Param | Type | | --- | --- | | roleId | string | | resourceId | string | | privilege | string |

acl.getPermissions(roleId) ⇒ Array.<Object>

Returns an object representing roleId permissions

Kind: instance method of Acl
Returns: Array.<Object> - Permissions for each resource

| Param | Type | | --- | --- | | roleId | string | Role |

Example

acl.getPermissions('user');
<a name="Role"></a>

Role

Role class

Kind: global class

new Role(id, parents, acl)

Creates a new role and attach it to Acl

Throws:

  • Error if acl is not an instance of {Acl} or given parents were not declared before

| Param | Type | Default | Description | | --- | --- | --- | --- | | id | string | | role's id | | parents | Array.<string> | Array.<Role> | | list of parents | | acl | Acl | | ACL to which this role will be attached |

role.setAcl(acl)

Sets the ACL to which this role will be attached

Kind: instance method of Role

| Param | Type | | --- | --- | | acl | Acl |

role.getAcl() ⇒ Acl | *

Returns the ACL to which this role is attached

Kind: instance method of Role

role.setId(id) ⇒ Role

Sets the role id of this instance

Kind: instance method of Role
Returns: Role - - This object
Throws:

  • Error - if id is not a string

| Param | Type | Description | | --- | --- | --- | | id | string | Role identification |

role.getId() ⇒ string

Returns this Role id

Kind: instance method of Role
Returns: string - id - Role id

role.setParents(parents) ⇒ Role

Sets role parents.

Kind: instance method of Role
Returns: Role - this instance for chaining
Throws:

  • Error if one of the given parents was not declared before

| Param | Type | Description | | --- | --- | --- | | parents | Array.<string> | Array.<Role> | null | Role parents: must be declared as individual roles before |

role.getParents() ⇒ Array | Array.<Role>

Returns parents roles of this instance

Kind: instance method of Role

role.getParent(role) ⇒ Role | null

Get a parent from this role

Kind: instance method of Role
Returns: Role | null - null if parent role was not found

| Param | Type | Description | | --- | --- | --- | | role | Role | string | id or role instance to retrieve |

role.addParent(role) ⇒ Role

Add parent to this role. If it already exists in parents list, it will be replaced

Kind: instance method of Role
Returns: Role - this instance for chaining
Throws:

  • Error if no Acl was attached to this role or if parent was not declared previously

| Param | Type | Description | | --- | --- | --- | | role | Role | string | Parent Role instance of its id |

role.addParents(roles) ⇒ Role

Add an array of parents role to this instance

Kind: instance method of Role
Returns: Role - this instance for chaining
Throws:

  • Error if no Acl was attached to this role or if one parent was not declared previously

| Param | Type | Description | | --- | --- | --- | | roles | Array.<Role> | Array.<string> | to add as parents to this instance |

role.removeParent({Role|string) ⇒ Role

Remove a parent from the list of this role's parents

Kind: instance method of Role
Returns: Role - this instance for chaining

| Param | Description | | --- | --- | | {Role|string | role Parent role isntance or its role id |

role.removeParents(roles) ⇒ Role

Remove a role from parent list

Kind: instance method of Role
Returns: Role - this instance for chaining

| Param | Type | Description | | --- | --- | --- | | roles | Array.<string> | Array.<Role> | to remove from parents list |

role.toString() ⇒ string

Returns

Kind: instance method of Role
Returns: string - - role Id

Resource

Kind: global class
Trows: Error if privileges is not an Array of strings

new Resource(id, privileges)

Constructor

| Param | Type | Description | | --- | --- | --- | | id | string | of this Resource | | privileges | Array.<string> | access privileges for this resource |

resource.setId(id) ⇒ Resource

Sets this resource Id

Kind: instance method of Resource
Returns: Resource - instance for chaining
Throws:

  • Error if id is not a string

| Param | Type | | --- | --- | | id | string |

resource.getId() ⇒ string

Retrieve resource id

Kind: instance method of Resource
Returns: string - id of this resource

resource.getPrivileges() ⇒ Array.<string>

Retrieve access privileges for this resource

Kind: instance method of Resource
Returns: Array.<string> - Array of access privileges

resource.setPrivileges(privileges) ⇒ Resource

Sets access privileges for this resource

Kind: instance method of Resource
Throws:

  • Error if privileges is not an array of strings

| Param | Type | Description | | --- | --- | --- | | privileges | Array.<string> | to set |

resource.addPrivilege(privilege) ⇒ Resource

Add an access privilege to this resource

Kind: instance method of Resource
Throw: Error - if privilege is not a string

| Param | Type | | --- | --- | | privilege | string |

resource.removePrivilege(privilege) ⇒ Resource

Removes access privilege from this resource

Kind: instance method of Resource
Returns: Resource - - this instance

| Param | Type | Description | | --- | --- | --- | | privilege | string | access privilege to remove |