UNPKG

@mamoorali295/rbac

Version:

Complete RBAC (Role-Based Access Control) system for Node.js with Express middleware, NestJS integration, GraphQL support, MongoDB & PostgreSQL support, modern admin dashboard, TypeScript support, and dynamic permission management

287 lines (286 loc) 11.1 kB
type ExpressRequest = any; type ExpressResponse = any; type ExpressNextFunction = any; import { RBACConfig, PermissionCheckOptions, RegisterUserOptions, AdminDashboardOptions } from "./types"; /** * Role-Based Access Control (RBAC) system for Node.js applications. * Provides middleware functions for authentication, authorization, and user management. * * @class RBACSystem */ declare class RBACSystem { private config; private initialized; private dbAdapter; /** * Initialize the RBAC system with the provided configuration. * Sets up database connection and creates standard permissions. * * @param {RBACConfig} config - Configuration object containing database connection and optional hooks * @returns {Promise<void>} Promise that resolves when initialization is complete * @throws {Error} If database connection fails or standard permissions cannot be created * * @example * ```typescript * // MongoDB configuration * await RBAC.init({ * database: { * type: 'mongodb', * connection: mongoose.connection * }, * authAdapter: async (req) => ({ user_id: req.user.id }), * defaultRole: 'user' * }); * * // PostgreSQL configuration * await RBAC.init({ * database: { * type: 'postgresql', * connection: pgPool * }, * authAdapter: async (req) => ({ user_id: req.user.id }), * defaultRole: 'user' * }); * * // Legacy MongoDB configuration (deprecated) * await RBAC.init({ * db: mongoose.connection, * authAdapter: async (req) => ({ user_id: req.user.id }), * defaultRole: 'user' * }); * ``` */ init(config: RBACConfig): Promise<void>; /** * Ensures that the RBAC system has been initialized before use. * * @private * @throws {Error} If the system has not been initialized */ private ensureInitialized; /** * Automatically infers the feature and permission from the HTTP request. * Uses the first path segment as the feature and HTTP method/path patterns for permission. * * @private * @param {ExpressRequest} req - Express request object * @returns {{feature: string, permission: string}} Inferred feature and permission * * @example * GET /billing/invoices -> { feature: 'billing', permission: 'read' } * POST /billing/create -> { feature: 'billing', permission: 'create' } * DELETE /billing/remove -> { feature: 'billing', permission: 'delete' } */ private inferFeatureAndPermission; /** * Extracts user identity from the request using authAdapter or fallback properties. * * @private * @param {ExpressRequest} req - Express request object * @returns {Promise<{user_id: string, email?: string}>} User identity object * @throws {Error} If user identity cannot be determined */ private getUserIdentity; /** * Express middleware that checks if the current user has the required permissions. * Can auto-infer permissions from the route or use explicitly provided options. * * @param {PermissionCheckOptions} options - Optional feature and permission specification * @returns {Function} Express middleware function * * @example * // Auto-inferred permissions * app.get('/billing/invoices', RBAC.checkPermissions(), handler); * * // Explicit permissions * app.post('/admin/reset', RBAC.checkPermissions({ * feature: 'admin', * permission: 'sudo' * }), handler); */ checkPermissions(options?: PermissionCheckOptions): (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction) => Promise<any>; /** * Express middleware that registers a new user in the RBAC system. * Automatically assigns default role if configured and calls registration hooks. * * @param {RegisterUserOptions} options - Optional user data extractor function * @returns {Function} Express middleware function * * @example * // Default extraction from req.body * app.post('/signup', RBAC.registerUser(), handler); * * // Custom user data extraction * app.post('/signup', RBAC.registerUser({ * userExtractor: (req) => ({ * user_id: req.body.id, * name: req.body.fullName, * email: req.body.emailAddress * }) * }), handler); */ registerUser(options?: RegisterUserOptions): (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction) => Promise<any>; /** * Manually register a user in the RBAC system without using middleware. * Useful for programmatic user registration outside of HTTP requests. * * @param {string} user_id - Unique identifier for the user * @param {Object} userData - User data object * @param {string} [userData.name] - User's display name * @param {string} [userData.email] - User's email address * @returns {Promise<void>} Promise that resolves when user is registered * @throws {Error} If user already exists or registration fails * * @example * ```typescript * await RBAC.registerUserManual('user123', { * name: 'John Doe', * email: 'john@example.com' * }); * ``` */ registerUserManual(user_id: string, userData: { name?: string; email?: string; }): Promise<void>; /** * Update user information in the RBAC system. * * @param {string} user_id - Unique identifier for the user * @param {Object} userData - User data to update * @param {string} [userData.name] - New display name * @param {string} [userData.email] - New email address * @returns {Promise<void>} Promise that resolves when user is updated * @throws {Error} If user is not found * * @example * ```typescript * await RBAC.updateUser('user123', { * name: 'John Smith', * email: 'johnsmith@example.com' * }); * ``` */ updateUser(user_id: string, userData: { name?: string; email?: string; }): Promise<void>; /** * Assign a role to a user in the RBAC system. * * @param {string} user_id - Unique identifier for the user * @param {string} roleName - Name of the role to assign * @returns {Promise<void>} Promise that resolves when role is assigned * @throws {Error} If user or role is not found * * @example * ```typescript * await RBAC.assignRole('user123', 'admin'); * ``` */ assignRole(user_id: string, roleName: string): Promise<void>; /** * Get the role name assigned to a user. * * @param {string} user_id - Unique identifier for the user * @returns {Promise<string | null>} Promise that resolves to the role name or null if no role assigned * * @example * ```typescript * const role = await RBAC.getUserRole('user123'); * console.log(role); // 'admin' or null * ``` */ getUserRole(user_id: string): Promise<string | null>; /** * Get all permissions a user has for a specific feature. * * @param {string} user_id - Unique identifier for the user * @param {string} featureName - Name of the feature to check permissions for * @returns {Promise<string[]>} Promise that resolves to an array of permission names * * @example * ```typescript * const permissions = await RBAC.getFeaturePermissions('user123', 'billing'); * console.log(permissions); // ['read', 'create', 'update'] * ``` */ getFeaturePermissions(user_id: string, featureName: string): Promise<string[]>; /** * Creates an Express router for the RBAC admin dashboard. * Provides a complete web interface for managing users, roles, features, and permissions. * * @param {AdminDashboardOptions} options - Dashboard configuration options * @param {string} options.user - Admin username for authentication * @param {string} options.pass - Admin password for authentication * @param {string} [options.sessionSecret] - Secret key for session encryption * @param {string} [options.sessionName] - Custom session cookie name * @returns {express.Router} Express router instance for the admin dashboard * * @example * ```typescript * app.use('/rbac-admin', RBAC.adminDashboard({ * user: 'admin', * pass: 'secure-password', * sessionSecret: 'your-secret-key', * sessionName: 'rbac.admin.sid' * })); * ``` */ adminDashboard(options: AdminDashboardOptions): any; /** * Provides access to internal controllers for advanced database operations. * These controllers offer direct database access for complex RBAC operations. * * @returns {Object} Object containing controller instances * @returns {Object} controllers.userRole - User role management controller * @returns {Object} controllers.feature - Feature management controller * * @example * ```typescript * const { userRole, feature } = RBAC.controllers; * const allRoles = await userRole.getAllRoles(); * const allFeatures = await feature.getAllFeatures(); * ``` */ get controllers(): { userRole: { getAllRoles: () => Promise<any>; createRole: (name: string, description: string, features: import("./mongo/models/UserRole").IFeaturePermission[]) => Promise<any>; deleteRole: (roleId: string) => Promise<any>; addFeatureToUserRole: (roleId: string, featureIds: string[]) => Promise<any>; removeFeatureFromUserRole: (roleId: string, featureIds: string[]) => Promise<any>; addPermissionToFeatureInUserRole: (roleId: string, featureIds: string[], permissionIds: string[]) => Promise<any>; removePermissionToFeatureInUserRole: (roleId: string, featureIds: string[], permissionIds: string[]) => Promise<any>; getPermissions: () => Promise<any>; }; feature: { getAllFeatures: () => Promise<any>; createFeature: (name: string, description: string) => Promise<any>; updateFeature: (featureId: string, name: string, description: string) => Promise<any>; deleteFeature: (featureId: string) => Promise<any>; }; }; } /** * Singleton instance of the RBACSystem class. * This is the main export that applications should use for all RBAC operations. * * @example * ```typescript * import { RBAC } from '@sheikh295/rbac'; * * // Initialize the system * await RBAC.init({ * db: mongoose.connection, * authAdapter: async (req) => ({ user_id: req.user.id }), * defaultRole: 'user' * }); * * // Use middleware * app.get('/protected', RBAC.checkPermissions(), handler); * app.use('/admin', RBAC.adminDashboard({ user: 'admin', pass: 'secret' })); * ``` */ export declare const RBAC: RBACSystem; export {};