This package has been deprecated

Author message:

this package has been deprecated, please don't use

express-endpoint-acl

0.2.5 • Public • Published

Express Endpoint ACL

In a webapp almost all of the user interaction will go through an endpoint. If you were to have an access control system in place, it can be endpoint based. For now, this module supports MySQL backed express applications.

Overview

You can implement Role Based Access Control using this module. Users can have a set of roles. Roles will have access to certain permissions.

User - Can be identified by an integer or string. (You create & handle users. Module just needs username of some sort)
Role - Has an id & a name with an optional description. (Library handles roles)
Permission - Basically any endpoint is a permission. A permission has id, name, endpoint, method and an optional description (Library creates & handles permissions)

Installation

npm install --save express-endpoint-acl

Run migrate & update-permission scripts after installing to create required tables in your db & inserting permissions rows in permission table.

How it works

This library stores roles, permissions, user role mapping & role permission mapping in tables role, permission, userRole, rolePermission respectively. After npm install a migration runs and creates these tables in your database. Configuration for database connection is obtained from acl.json. If you didn't have acl.json when you install the module, migration won't run. But, you can execute a script at later point to run the migration.

As mentioned permissions are endpoints, they are stored in permissions table automatically by a script. Users can be mapped to multiple roles using userRole table. Roles can have many permissions, rolePermission table handles that. Permissions are automatically fetched & updated in the table when you run update permission script. However, you have to make userRole & rolePermission entries as per your needs. Endpoints are provided with this library to ease the pain. You can build a UI on top of it if you want.

Permissions are always checked against roles. Roles of the incoming request will be determined by the module and it is checked for the permissions it has access to.

After needed rows are inserted into the table, the middleware provided by this library takes care of the access control. If an incoming request doesn't have access to an endpoint, 401 status code is sent as response.

Configuration

Middleware provided by this library has to be used before you define your routes and after the app object export. Also, you have to make sure username is always available in the userIdField (know more on this under acl.json section) of req object. Minimal example,

const express = require('express');
const { acl } = require('express-endpoint-acl');

const profile = require('./routes/profile');
const inventory = require('./routes/inventory');

const app = express();

// Middlware to set username
app.use((req, res, next) => {
    const jwtToken = req.headers.authorization;

    jwt.verify(_.split(jwtToken, ' ')[1], 'myjwtsecret', (err, decodedToken) => {
        if (token) {
            req.username = token && token.mobileNumber; // Setting username in the usernameField
        }

        return next();
    });
});

// Exporting app just before using acl middleware
module.exports = { app };

app.use(acl); //Access control kicks in!

// Routes are defined after using acl middleware
app.use('/', profile);
app.use('/', inventory);

This module works based on the configuration provided by config/acl.json. Your application's package.json & config directory must be inside same directory. Like this,

My Project
|- src
|- config/
    |- acl.json
|- node_modules/
    |- module1
    |- module2
    |- express-endpoint-acl
|- test/
|- app.js
|- package.json
|- package-lock.json

acl.json format

Below JSON has every single valid keys to have in acl.json. Purpose of every JSON key has been explained below.

{
    "appPath": "app",
    "connectionPath": "./utils/db",
    "userIdField": "username",
    "includeCheck": [],
    "endpointPrefix": "acl",
    "excludeCheck": [
        "\/public\/.*"
    ],
    "excludedRoleList": [
        "Admin"
    ]
}

appPath (Required)

Express app object path relative to package.json. NOTE: You've to export app object with the name app.

connectionPath (Required)

MySQL connection object path relative to package.json. NOTE: You've to export connection object with the name connection.

userIdField (Required)

Key from which username can be accessed from req object of express middleware. You have to make it available from req object. It is fetched from it and the roles of the user is found from userRole table.

includeCheck

Array of RegEx strings against which the endpoint (req.path) is tested and access check is carried out. In case of a clash with excludeCheck, includeCheck has higher priority and applied.

endpointPrefix

Prefix to add to the acl endpoints. If not provided, defaults to admin.

excludeCheck

Array of RegEx strings against which the endpoint (req.path) is tested and access check is skipped. In case of a clash with includeCheck, includeCheck takes priority.

excludedRoleList

Array of role names which will have access to all endpoints of the express app.

Scripts

This module comes with 2 bin scripts that can be executed at anytime. You can use npx, if you have installed or you can execute the bin with full path.

npx express-endpoint-acl migrate
// or
node node_modules/express-endpoint-acl/bin/express-endpoint-acl migrate

Migration

Creates the tables role, permission, userRole, rolePermission if they don't already exist in the database. If you forgot to add acl.json before installing, you can run the command mentioned below to create the tables.

npx express-endpoint-acl migrate

Update Permission

Updates the permission table with the endpoints you're using in your express app by running this script. It detects all the endpoins you are using in your app and creates rows in the table.

npx express-endpoint-acl update-permission

Endpoints

Handful of endpoints are provided with this library for making this library more usable. You can either build a UI on top of it or just use the API interface. You can change the admin prefix by using endpointPrefix config.

const { acl, aclEndpoint } = require('express-endpoint-acl');

app.use(acl);
app.use('/', aclEndpoint);

NOTE: You can also import and use aclEndpointUtils - source. This will come in handy, if you want to add something to the response that the default endpoints already provide.

Role list, /admin/role method: GET

Sample response

{
    "roleList": [
        {
            "id": 1,
            "name": "Admin",
            "description": "Manages everything"
        }
    ]
}

Permission list, /admin/permission method: GET

Sample response

{
    "permissionList": [
        {
            "id": 1,
            "name": "ROLE_GET",
            "endpoint": "/role",
            "method": "GET",
            "description": null
        },
        {
            "id": 2,
            "name": "PERMISSION_GET",
            "endpoint": "/permission",
            "method": "GET",
            "description": null
        },
    ]
}

Create/update role, /admin/role method: POST

If a role with the name already exists, it updates the description.

Body parameters (x-www-form-urlencoded)

{
    name: 'Admin', // mandatory
    description: 'Manages everything' // optional
}

Sample response

{
    "msg": "Role updated successfully",
    "id": 2
}

Create permission, /admin/permission method: POST

Though permissions represents endpoints, sometimes we can create and use custom permissions. If a permission with the name already exists, it updates the description.

Body parameters (x-www-form-urlencoded)

{
    name: 'SHOW_DELIVERY_STATUS', // mandatory
    description: 'Access to view delivery status on order page' // optional
}

Sample response

{
    "msg": "Permission updated successfully",
    "id": 4
}

Delete role, /admin/role method: DELETE

Body parameters (x-www-form-urlencoded)

{
    roleId: 2
}

Sample response

{
    "msg": "Role deleted successfully"
}

Get userRole list, /admin/userRole method: GET

Parameters

Pass anyone of the userId or roleId. Both to see if that combination available. You can query multiple user or role id by comma separating.

{
    userId: "9999999999",
    roleId: "1,2"
}

Sample response

{
    "userRoleList": [
        {
            "userId": "999999999",
            "roleId": 1,
            "roleName": "Admin",
            "roleDescription": "Manages everything"
        }
    ]
}

Get rolePermission list, /admin/rolePermission method: GET

Parameters

Pass anyone of the roleId or permissionId. Both to see if that combination available. You can query multiple role or permission id by comma separating.

{
    roleId: "1,2"
    permissionId: 1,
}

Sample response

{
    "rolePermissionList": [
        {
            "roleId": 1,
            "permissionId": 1,
            "permissionName": "REQUESTOTP_POST",
            "permissionDescription": null,
            "roleName": "Admin",
            "roleDescription: "Manages everything",
            "endpoint": "/requestOTP",
            "method": "POST"
        },
        {
            "roleId": 3,
            "permissionId": 1,
            "permissionName": "REQUESTOTP_POST",
            "permissionDescription": null,
            "roleName": "Marketer",
            "roleDescription: "Helps product reach more people",
            "endpoint": "/requestOTP",
            "method": "POST"
        }
    ]
}

Update/delete userRole, /admin/userRole method: POST/DELETE

Use POST method for adding a mapping entry and DELETE to remove.

Body parameters (x-www-form-urlencoded)

Pass either userId & roleId for single entry or userRole JSON string for multiple entries.

{
    userId: '999999999',
    roleId: 1,
    userRole: [
        {
            userId: '9999999999',
            roleId: 1
        },
        {
            userId: '8888888888',
            roleId: 1
        }
    ]
}

Sample response

{
    "msg": "User, role mapped succesfully"
}

Update/delete rolePermission, /admin/rolePermission method: POST/DELETE

Use POST method for adding a mapping entry and DELETE to remove.

Body parameters (x-www-form-urlencoded)

Pass either roleId & permissionId for single entry or rolePermission JSON string for multiple entries.

{
    roleId: 1,
    permissionId: 5,
    rolePermission: [
        {
            roleId: 1,
            permissionId: 1
        },
        {
            roleId: 1,
            permissionId: 2
        }
    ]
}

Sample response

{
    "msg": "Role, permission mapped succesfully"
}

License

MIT

Package Sidebar

Install

npm i express-endpoint-acl

Weekly Downloads

2

Version

0.2.5

License

MIT

Unpacked Size

33.1 kB

Total Files

12

Last publish

Collaborators

  • vicke4