{"id":21243285,"url":"https://github.com/aclify/aclify","last_synced_at":"2025-08-14T05:32:59.673Z","repository":{"id":40813328,"uuid":"102502810","full_name":"Aclify/aclify","owner":"Aclify","description":":lock: Node Access Control Lists (ACL).","archived":false,"fork":false,"pushed_at":"2024-06-17T20:25:59.000Z","size":1262,"stargazers_count":60,"open_issues_count":4,"forks_count":6,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-12-15T10:05:48.992Z","etag":null,"topics":["acl","api","api-key","express","mongodb","mysql","node","postgresql","redis","resources","roles","sequelize"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Aclify.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-09-05T16:07:07.000Z","updated_at":"2024-06-12T09:34:07.000Z","dependencies_parsed_at":"2024-11-21T02:00:21.183Z","dependency_job_id":null,"html_url":"https://github.com/Aclify/aclify","commit_stats":{"total_commits":519,"total_committers":8,"mean_commits":64.875,"dds":"0.24277456647398843","last_synced_commit":"ffed05930d77b6f48f8117a42797086163fefb37"},"previous_names":["rimiti/aclify"],"tags_count":33,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aclify%2Faclify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aclify%2Faclify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aclify%2Faclify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aclify%2Faclify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Aclify","download_url":"https://codeload.github.com/Aclify/aclify/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229805179,"owners_count":18126807,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["acl","api","api-key","express","mongodb","mysql","node","postgresql","redis","resources","roles","sequelize"],"created_at":"2024-11-21T01:11:32.435Z","updated_at":"2024-12-15T10:05:58.051Z","avatar_url":"https://github.com/Aclify.png","language":"TypeScript","readme":"# @aclify/aclify\n\n[![Aclify](media/header.png)](https://github.com/Aclify)\n\n[![Dependencies][prod-dependencies-badge]][prod-dependencies]\n[![Coverage][coverage-badge]][coverage]\n[![Build Status][travis-badge]][travis-ci]\n[![MIT License][license-badge]][LICENSE]\n[![PRs Welcome][prs-badge]][prs]\n\n## Description\n\nThis module provides a Node Access Control Lists implementation inspired by Zend_ACL and node_acl package.\n\nWhen you develop a web site or application you will soon notice that sessions are not enough to protect all the\navailable resources. Avoiding that malicious users access other users content proves a much more\ncomplicated task than anticipated. ACL can solve this problem in a flexible and elegant way.\n\nCreate roles and assign roles to users. Sometimes it may even be useful to create one role per user,\nto get the finest granularity possible, while in other situations you will give the *asterisk* permission\nfor admin kind of functionality.\n\n## Install\n\n```\n$ yarn add @aclify/aclify\n```\n\n## Features\n\n- Users\n- Roles\n- Hierarchies\n- Resources\n- Express middleware for protecting resources.\n- Robust implementation with good unit test coverage.\n- Strict typing\n\n## Documentation\n\n* [addUserRoles](#addUserRoles)\n* [removeUserRoles](#removeUserRoles)\n* [removeUser](#removeUser)\n* [userRoles](#userRoles)\n* [roleUsers](#roleUsers)\n* [hasRole](#hasRole)\n* [addRoleParents](#addRoleParents)\n* [removeRoleParents](#removeRoleParents)\n* [removeRole](#removeRole)\n* [removeResource](#removeResource)\n* [allow](#allow)\n* [removeAllow](#removeAllow)\n* [allowedPermissions](#allowedPermissions)\n* [isAllowed](#isAllowed)\n* [areAnyRolesAllowed](#areAnyRolesAllowed)\n* [whatResources](#whatResources)\n* [middleware](#middleware)\n* [store](#store)\n\n## Stores\n\nAclify offers several possibilities to store your data:\n\n  - Memory\n  - Redis\n  - MongoDB\n\n\n## Examples\n\nCreate your acl module by requiring it and instantiating it with a valid store instance:\n\n**From import**\n\n```javascript\nimport * as Aclify from '@aclify/aclify';\n\n// Using Redis store\nconst acl = new Aclify.Acl(new Aclify.RedisStore(RedisClient, {prefix: 'acl_'}));\n\n// Or Using the Memory store\nconst acl = new Aclify.Acl(new Aclify.MemoryStore());\n\n// Or Using the MongoDB store\nconst acl = new Aclify.Acl(new Aclify.MongoDBStore(db, {prefix: 'acl_'}));\n```\n\nAll the following functions return a Promise.\n\nCreate roles implicitly by giving them permissions:\n\n```javascript\n// guest is allowed to view blogs\nawait acl.allow('guest', 'blogs', 'view');\n\n// allow function accepts arrays as any parameter\nawait acl.allow('member', 'blogs', ['edit', 'view', 'delete']);\n```\n\nUsers are likewise created implicitly by assigning them roles:\n\n```javascript\nawait acl.addUserRoles('joed', 'guest');\n```\n\nHierarchies of roles can be created by assigning parents to roles:\n\n```javascript\nawait acl.addRoleParents('baz', ['foo', 'bar']);\n```\n\nNote that the order in which you call all the functions is irrelevant (you can add parents first and assign permissions to roles later)\n\n```javascript\nawait acl.allow('foo', ['blogs', 'forums', 'news'], ['view', 'delete']);\n```\n\nUse the wildcard to give all permissions:\n\n```javascript\nawait acl.allow('admin', ['blogs', 'forums'], '*');\n```\n\nSometimes is necessary to set permissions on many different roles and resources. This would\nlead to unnecessary nested callbacks for handling errors. Instead use the following:\n\n```javascript\nawait acl.allow([\n    {\n        roles:['guest', 'member'],\n        allows:[\n            {resources:'blogs', permissions:'get'},\n            {resources:['forums', 'news'], permissions:['get', 'put', 'delete']}\n        ]\n    },\n    {\n        roles:['gold', 'silver'],\n        allows:[\n            {resources:'cash', permissions:['sell', 'exchange']},\n            {resources:['account', 'deposit'], permissions:['put', 'delete']}\n        ]\n    }\n]);\n```\n\nYou can check if a user has permissions to access a given resource with *isAllowed*:\n\n```javascript\nconst isAllowed = await acl.isAllowed('joed', 'blogs', 'view');\n\nif (isAllowed) {\n    console.log(\"User Joed is allowed to view blogs\");\n}\n```\n\nOf course arrays are also accepted in this function:\n\n```javascript\nawait acl.isAllowed('jsmith', 'blogs', ['edit', 'view', 'delete'])\n```\n\nNote that all permissions must be fulfilled in order to get *true*.\n\nSometimes is necessary to know what permissions a given user has over certain resources:\n\n```javascript\nconst permissions = await acl.allowedPermissions('james', ['blogs', 'forums']);\n```\n\nIt will return an array of resource:[permissions] like this:\n\n```javascript\n[\n  {\n    blogs: ['get', 'delete']\n  },\n  {\n    forums:['get', 'put']\n  }\n ]\n```\n\nFinally, we provide a middleware for Express for easy protection of resources.\n\n```javascript\nacl.middleware()\n```\n\nWe can protect a resource like this:\n\n```javascript\napp.put('/blogs/:id', acl.middleware(), function(req, res, next) {...}\n```\n\nThe middleware will protect the resource named by *req.url*, pick the user from *req.session.userId* and check the permission for *req.method*, so the above would be equivalent to something like this:\n\n```javascript\nawait acl.isAllowed(req.session.userId, '/blogs/12345', 'put')\n```\n\nThe middleware accepts 3 optional arguments, that are useful in some situations. For example, sometimes we\ncannot consider the whole url as the resource:\n\n```javascript\napp.put('/blogs/:id/comments/:commentId', acl.middleware(3), function(req, res, next) {…}\n```\n\nIn this case the resource will be just the three first components of the url (without the ending slash).\n\nIt is also possible to add a custom userId or check for other permissions than the method:\n\n```javascript\napp.put('/blogs/:id/comments/:commentId', acl.middleware(3, 'joed', 'post'), function(req, res, next) {…}\n```\n\n## Methods\n\n\u003ca name=\"addUserRoles\"/\u003e\n\n### addUserRoles( userId, roles )\n\nAdds roles to a given user id.\n\n__Arguments__\n\n```javascript\n    userId  {String|Number} User id.\n    roles   {String|Array} Role(s) to add to the user id.\n```\n\n---------------------------------------\n\n\u003ca name=\"removeUser\"/\u003e\n\n### removeUser( userId )\n\nRemove user.\n\n__Arguments__\n\n```javascript\n    userId  {String|Number} User id.\n```\n\n---------------------------------------\n\n\u003ca name=\"removeUserRoles\"/\u003e\n\n### removeUserRoles( userId, roles )\n\nRemove roles from a given user.\n\n__Arguments__\n\n```javascript\n    userId  {String|Number} User id.\n    roles   {String|Array} Role(s) to remove to the user id.\n```\n\n---------------------------------------\n\n\u003ca name=\"userRoles\" /\u003e\n\n### userRoles( userId )\n\nReturn all the roles from a given user.\n\n__Arguments__\n\n```javascript\n    userId  {String|Number} User id.\n```\n\n---------------------------------------\n\n\u003ca name=\"roleUsers\" /\u003e\n\n### roleUsers( rolename )\n\nReturn all users who has a given role.\n\n__Arguments__\n\n```javascript\n    rolename  {String|Number} User id.\n```\n\n---------------------------------------\n\n\u003ca name=\"hasRole\" /\u003e\n\n### hasRole( userId, rolename )\n\nReturn boolean whether user has the role\n\n__Arguments__\n\n```javascript\n    userId    {String|Number} User id.\n    rolename  {String|Number} role name.\n```\n\n---------------------------------------\n\n\u003ca name=\"addRoleParents\" /\u003e\n\n### addRoleParents( role, parents )\n\nAdds a parent or parent list to role.\n\n__Arguments__\n\n```javascript\n    role      {String} Child role.\n    parents   {String|Array} Parent role(s) to be added.\n```\n\n---------------------------------------\n\n\u003ca name=\"removeRoleParents\" /\u003e\n\n### removeRoleParents( role, parents )\n\nRemoves a parent or parent list from role.\n\nIf `parents` is not specified, removes all parents.\n\n__Arguments__\n\n```javascript\n    role      {String} Child role.\n    parents   {String|Array} Parent role(s) to be removed [optional].\n```\n\n---------------------------------------\n\n\u003ca name=\"removeRole\" /\u003e\n\n### removeRole( role )\n\nRemoves a role from the system.\n\n__Arguments__\n\n```javascript\n    role  {String} Role to be removed\n```\n\n---------------------------------------\n\n\u003ca name=\"removeResource\" /\u003e\n\n### removeResource( resource )\n\nRemoves a resource from the system\n\n__Arguments__\n\n```javascript\n    resource  {String} Resource to be removed\n```\n\n---------------------------------------\n\n\u003ca name=\"allow\" /\u003e\n\n### allow( roles, resources, permissions )\n\nAdds the given permissions to the given roles over the given resources.\n\n__Arguments__\n\n```javascript\n    roles         {String|Array} role(s) to add permissions to.\n    resources     {String|Array} resource(s) to add permisisons to.\n    permissions   {String|Array} permission(s) to add to the roles over the resources.\n```\n\n### allow( permissionsArray )\n\n__Arguments__\n\n```javascript\n    permissionsArray  {Array} Array with objects expressing what permissions to give.\n       [{roles: {String|Array}, allows: [{resources:{String|Array}, permissions:{String|Array}]]\n```\n\n---------------------------------------\n\n\u003ca name=\"removeAllow\" /\u003e\n\n###  removeAllow( role, resources, permissions )\n\nRemove permissions from the given roles owned by the given role.\n\nNote: we loose atomicity when removing empty role_resources.\n\n__Arguments__\n\n```javascript\n    role          {String}\n    resources     {String|Array}\n    permissions   {String|Array}\n```\n\n---------------------------------------\n\n\u003ca name=\"allowedPermissions\" /\u003e\n\n### allowedPermissions( userId, resources )\n\nReturns all the allowable permissions a given user have to\naccess the given resources.\n\nIt returns an array of objects where every object maps a\nresource name to a list of permissions for that resource.\n\n__Arguments__\n\n```javascript\n    userId      {String|Number} User id.\n    resources   {String|Array} resource(s) to ask permissions for.\n```\n\n---------------------------------------\n\n\u003ca name=\"isAllowed\" /\u003e\n\n### isAllowed( userId, resource, permissions )\n\nChecks if the given user is allowed to access the resource for the given\npermissions (note: it must fulfill all the permissions).\n\n__Arguments__\n\n```javascript\n    userId        {String|Number} User id.\n    resource      {String} resource to ask permissions for.\n    permissions   {String|Array} asked permissions.\n```\n\n---------------------------------------\n\u003ca name=\"areAnyRolesAllowed\" /\u003e\n\n### areAnyRolesAllowed( roles, resource, permissions )\n\nReturns true if any of the given roles have the right permissions.\n\n__Arguments__\n\n```javascript\n    roles         {String|Array} Role(s) to check the permissions for.\n    resource      {String} resource to ask permissions for.\n    permissions   {String|Array} asked permissions.\n```\n\n---------------------------------------\n\u003ca name=\"whatResources\" /\u003e\n\n### whatResources( role )\n\nReturns what resources a given role has permissions over.\n\n__Arguments__\n\n```javascript\n    role  {String|Array} Roles\n```\n\nwhatResources(role, permissions )\n\nReturns what resources a role has the given permissions over.\n\n__Arguments__\n\n```javascript\n    role          {String|Array} Roles\n    permissions   {String|Array} Permissions\n```\n\n---------------------------------------\n\n\u003ca name=\"middleware\" /\u003e\n\n### middleware( [numPathComponents, userId, permissions] )\n\nMiddleware for express.\n\nTo create a custom getter for userId, pass a function(req, res) which returns the userId when called (must not be async).\n\n__Arguments__\n\n```javascript\n    numPathComponents   {Number} number of components in the url to be considered part of the resource name.\n    userId              {String|Number|Function} the user id for the acl system (defaults to req.session.userId)\n    permissions         {String|Array} the permission(s) to check for (defaults to req.method.toLowerCase())\n```\n\n---------------------------------------\n\nCreates a new Redis store using Redis client `client`.\n\n## Tests\n\n    $ yarn test\n\n## Scripts\n\nRun using yarn \u003cscript\u003e command.\n\n    clean - Removes temporary files\n    build - Builds typescript files\n    build:watch - Builds typescript files in watch mode\n    lint - Checks lint\n    lint:fix - Auto lint fix\n    test - Runs tests in dockerized environment\n    test:coverage - Runs tests\n\n## License\n\nMIT © [Dimitri DO BAIRRO](https://github.com/Aclify/aclify/blob/master/LICENSE)\n\n[prod-dependencies-badge]: https://david-dm.org/Aclify/aclify/status.svg\n[prod-dependencies]: https://david-dm.org/Aclify/aclify\n[coverage-badge]: https://codecov.io/gh/Aclify/aclify/branch/master/graph/badge.svg\n[coverage]: https://codecov.io/gh/Aclify/aclify\n[node_acl]: https://github.com/OptimalBits/node_acl\n[travis-badge]: https://travis-ci.org/Aclify/aclify.svg?branch=master\n[travis-ci]: https://travis-ci.org/Aclify/aclify\n[license-badge]: https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square\n[license]: https://github.com/Aclify/aclify/blob/master/LICENSE\n[prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square\n[prs]: http://makeapullrequest.com","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faclify%2Faclify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faclify%2Faclify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faclify%2Faclify/lists"}