rab-access
v2.2.11
Published
Role based access control
Downloads
789
Maintainers
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 ofPermission
instances.
- Example:
Rab.schema({ canReadUsers: [ Rab.grant("Admin").columns(["id", "name"]), ], });
- Parameters:
Rab.grant(role: string): Permission
Creates a newPermission
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", });
- Parameters:
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.
- Parameters:
ifContains(...fields: string[][]): this
Adds a containment condition for the permission.- Parameters:
fields
: Arrays of field pairs to check for containment.
- Parameters:
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.
- Parameters:
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.
- Parameters:
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.