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 🙏

© 2024 – Pkg Stats / Ryan Hefner

rab-access

v2.2.11

Published

Role based access control

Downloads

789

Readme

Rab Access Control Middleware

A robust, flexible, and declarative access control library for Node.js applications. With rab-access, you can define and enforce fine-grained access policies using schemas, roles, and custom validations. It’s ideal for multi-role systems requiring granular control over resource access.


Features

  • Declarative Schema-Based Access Control: Define access policies for resources and operations.
  • Role-Based Permissions: Grant permissions based on roles and extend roles with additional access rights.
  • Dynamic Filters and Validators: Use dynamic data (e.g., user attributes, query parameters) to filter or validate access.
  • Middleware Generation: Seamlessly integrate with your Node.js apps via middleware.

Installation

Install the package using npm:

npm install rab-access

Getting Started

1. Import Required Modules

const { Rab } = require("rab-access");

2. Define Roles

Define the roles within your system:

const roles = {
  SYSTEM_ADMIN: "System Admin",
  ADMIN: "Admin",
  SUPERVISOR: "Supivisor",
};

3. Define Access Control Schema

Create a schema that specifies access rules for various operations:

const userAccessControl = Rab.schema({
  canReadUser: [
    Rab.alwaysGrant().ifEqual(Rab.user("user_id"), Rab.params("user_id")),
    Rab.grant(roles.SYSTEM_ADMIN).columns(["id"]),
    Rab.grant(roles.ADMIN).filters({
        "organization_id": Rab.user( "organization_id")
      })
      .columns(["id"]), 
    Rab.grant(roles.SUPERVISOR)
      .extend(roles.ADMIN, "canReadUser")
      .columns(["id", "name"]),
  ],
  canReadAllUsers: [Rab.grant(roles.SYSTEM_ADMIN).columns(["id"])],
  canDeleteUser: [
    Rab.alwaysGrant().ifEqual(Rab.user("user_id"), Rab.params("user_id")), 
    Rab.grant(roles.SYSTEM_ADMIN),
    Rab.grant(roles.SUPERVISOR).validator("customValidationFunction"),
  ],
});

4. Define Custom Validations

Add custom validation logic for specific scenarios:

const customValidations = {
  customValidationFunction: async (request) => {
    // Perform your custom validation
    return Promise.resolve();
  },
};

5. Generate Middleware

Create middleware to enforce your access policies:

const createMiddleware =
    (accessControl, validations) => (permission) => async (req, res, next) => {
        const { isAuthorized, fields, filters, lookupFilters } =
            await accessControl.can({
                validations,
                request: req,
                role: req.role,
                permission,
            });

        if (isAuthorized) {
            req.fields = fields;
            req.filters = filters;
            req.lookupFilters = lookupFilters;
            return next();
        }
        res.status(403).json({ error: "FORBIDDEN" });
    };

const accessMiddleware = createMiddleware(userAccessControl, customValidations);

6. Export and Use

Export the middleware and roles for use in your application:

module.exports = {
  accessMiddleware,
  roles,
};

Usage Example

Integrate the middleware into your application to secure routes:

const express = require("express");
const { accessMiddleware, roles } = require("./accessControl");

const app = express();

// Example route using middleware
app.get("/users/:userId", accessMiddleware("canReadUser"), (req, res) => {
  res.send("Access granted to a user data!");
});

app.get("/users", accessMiddleware("canReadAllUsers"), (req, res) => {
    res.send("Access granted to a users!");
});

app.listen(3000, () => console.log("Server running on port 3000"));

API Reference

Core Classes

Rab

The main class for managing access control. Use it to define schemas, manage roles, and evaluate permissions.

Methods
  • Rab.schema(config: Record<string, Permission[]>) Defines the access control schema with a configuration object mapping actions to role-based permissions.

    • Parameters:
      • config: An object where keys are permission names and values are arrays of Permission instances.
    • Example:
      Rab.schema({
        canReadUsers: [
          Rab.grant("Admin").columns(["id", "name"]),
        ],
      });
  • Rab.grant(role: string): Permission Creates a new Permission instance for a specific role.

  • Rab.user(path: string[] | string): string[] Retrieves the user's data path for dynamic access control rules.

  • Rab.params(path: string[] | string): string[] Retrieves the request parameters path for dynamic access control.

  • Rab.query(path: string[] | string): string[] Retrieves the query parameters path for dynamic access control.

  • Rab.can(options: Omit<EvaluatePermissionParams, "permissions"> & { permission: string }): Promise<Authorization> Checks if a user is authorized to perform a specific action.

    • Parameters:
      • options: Includes the role, request, and permission name.
    • Returns: A promise resolving to an Authorization object.
    • Example:
      const {isAuthorized} = await Rab.can({
        role: "Admin",
        request: req,
        permission: "canReadUsers",
      });

Permission

Defines the rules and constraints for a specific role's access.

Methods
  • columns(columns: string[]): this Specifies the columns that the role can access.

  • lookupFilters(filters: Record<string, any>): this Adds lookup filters to the permission.

  • filters(filters: Record<string, any>): this Adds filters to refine the permission further.

  • ifEqual(...fields: string[][]): this Adds an equality condition for the permission.

    • Parameters:
      • fields: Arrays of field pairs to compare for equality.
  • ifContains(...fields: string[][]): this Adds a containment condition for the permission.

    • Parameters:
      • fields: Arrays of field pairs to check for containment.
  • validator(method: string, variables?: Record<string, any>): this Adds a custom validator function to the permission.

    • Parameters:
      • method: The name of the custom validation method.
      • variables: Optional key-value map of variables.
  • extend(role: string, permission: string): this Extends another permission for the current role.

    • Parameters:
      • role: The base role.

      • permission: The name of the permission to extend.

Contributing

Contributions are welcome! Feel free to submit issues or pull requests to improve this library.


License

This project is licensed under the MIT License.