Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
269b417
Adds functional plugin system for RBAC
phellipeandrade Sep 14, 2025
45217de
fix: build errors
phellipeandrade Sep 14, 2025
e73d2fc
fix: translate
phellipeandrade Sep 14, 2025
4929d57
fix: more translations
phellipeandrade Sep 14, 2025
b1bad4a
feat: more translations
phellipeandrade Sep 14, 2025
4212652
chore: update docs
phellipeandrade Sep 14, 2025
2eecb7b
fix: bugs on plugins
phellipeandrade Sep 14, 2025
35e2329
feat: setup jest
phellipeandrade Sep 14, 2025
49fa7b2
feat: setup new tests
phellipeandrade Sep 14, 2025
eaa21a9
feat: enhance hook utilities and improve error handling
phellipeandrade Sep 14, 2025
730e256
fix: standardize plugin descriptions to lowercase
phellipeandrade Sep 14, 2025
d4c79e7
feat: enhance plugin validation and cache plugin functionality
phellipeandrade Sep 14, 2025
f0dca9d
feat: enhance plugin system with event handling and configuration sup…
phellipeandrade Sep 14, 2025
4b755fe
refactor: improve plugin installation and validation error messages
phellipeandrade Sep 14, 2025
56805c5
fix: refine result handling in plugin system and update tests
phellipeandrade Sep 14, 2025
ba380fe
fix: stabilize plugin loader tests (#49)
phellipeandrade Sep 14, 2025
6bd0de7
test: improve PluginManager coverage (#50)
phellipeandrade Sep 14, 2025
13894a6
chore: update Jest configuration and tests
phellipeandrade Sep 27, 2025
40bd38d
feat: enhance logging and cleanup in cache and notification plugins
phellipeandrade Sep 27, 2025
d290016
test: add unit tests for RBAC and tenant role management
phellipeandrade Sep 27, 2025
a10679b
test: add unit tests for auto-plugin loader and cache plugin behavior
phellipeandrade Sep 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 30 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,39 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [2.2.0] - 2025-01-27
### Added
- Benchmark suite with `npm run bench` to measure permission checks
- Complete plugin system with hooks and community plugin support
- Built-in plugins: Cache, Audit, Notification, Validation, and Middleware
- Comprehensive plugin documentation and examples
- Community plugin template and development guidelines

### Changed
- Complete internationalization: All code, comments, and documentation translated to English
- Enhanced TypeScript support with improved type definitions
- Improved plugin management and error handling
- Updated README with comprehensive plugin system documentation

### Fixed
- All TypeScript compilation errors resolved
- Improved type safety across the entire codebase
- Better error handling in plugin system

## [2.1.0] - 2025-06-08
### Added
- Multi-tenant support via `createTenantRBAC`.
- Option to configure table and column names for database adapters.

### Changed
- Simplified helper utilities using TypeScript features
- Rebuild role hierarchy when roles change at runtime to improve permission checks
- Flatten inherited permissions for faster lookups
- Faster lookups using `Map` and cached regex/glob conversions
- Unified async handling for permission conditions

### Benchmark
- direct permission: ~457k ops/s
- inherited permission: ~435k ops/s
- glob permission: ~46k ops/s
- Improved CircleCI configuration.

## [2.0.0] - 2025-06-08
### Added
- Completely rewritten in TypeScript.
- Ability to update roles at runtime (`updateRoles`).
- Adapters for MongoDB, MySQL and PostgreSQL.
- Official middlewares for Express, NestJS and Fastify.

## [2.1.0] - 2025-06-08
### Added
Expand Down
191 changes: 189 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
* Optional database adapters (MongoDB, MySQL, PostgreSQL)
* Express, NestJS and Fastify middlewares
* Roles can be updated at runtime
* **Plugin System**: Extensible architecture with hooks and community plugins
* **Built-in Plugins**: Cache, Audit, Notification, Validation, and Middleware plugins
* **TypeScript Support**: Full type safety and IntelliSense support

## Thanks

Expand Down Expand Up @@ -176,7 +179,167 @@ const rbacTenantA = await createTenantRBAC(adapter, 'tenant-a');
await rbacTenantA.can('user', 'products:find'); // true
```

Want more? Check out the [examples](examples/) folder.
### Plugin System

RBAC v2.2.0 introduces a powerful plugin system that allows you to extend and customize the RBAC functionality. The plugin system provides hooks for intercepting and modifying permission checks, role updates, and other RBAC operations.

#### Key Features

- **Extensible Architecture**: Add custom functionality without modifying core RBAC code
- **Hook System**: Intercept operations at various points in the RBAC lifecycle
- **Plugin Management**: Install, configure, and manage plugins dynamically
- **Type Safety**: Full TypeScript support with comprehensive type definitions
- **Community Plugins**: Share and use community-developed plugins

#### Available Hooks

The plugin system provides several hooks that allow you to intercept and modify RBAC operations:

- `beforePermissionCheck`: Execute logic before permission validation
- `afterPermissionCheck`: Execute logic after permission validation
- `beforeRoleUpdate`: Execute logic before role updates
- `afterRoleUpdate`: Execute logic after role updates
- `beforeRoleAdd`: Execute logic before adding new roles
- `afterRoleAdd`: Execute logic after adding new roles
- `onError`: Handle errors that occur during RBAC operations
- `onStartup`: Execute logic when the plugin is initialized
- `onShutdown`: Execute logic when the plugin is uninstalled

#### Built-in Plugins

RBAC comes with several built-in plugins:

- **Cache Plugin**: Optimize permission checks with in-memory caching
- **Audit Plugin**: Track security activities and compliance events
- **Notification Plugin**: Send alerts for security events
- **Validation Plugin**: Validate roles, operations, and parameters
- **Middleware Plugin**: Express.js middleware for HTTP request handling

#### Basic Usage

```ts
import RBAC from '@rbac/rbac';
import { createCachePlugin, createAuditPlugin } from '@rbac/rbac/plugins';

// Create RBAC instance
const rbac = RBAC({ enableLogger: false })({
user: { can: ['products:read'] },
admin: { can: ['products:*'], inherits: ['user'] }
});

// Install plugins
await rbac.plugins.install(createCachePlugin({
enabled: true,
priority: 50,
settings: {
ttl: 300, // 5 minutes
maxSize: 1000,
strategy: 'lru'
}
}));

await rbac.plugins.install(createAuditPlugin({
enabled: true,
priority: 30,
settings: {
logLevel: 'info',
enableConsoleLogging: true
}
}));

// Use RBAC normally - plugins work automatically
const canRead = await rbac.can('user', 'products:read');
```

#### Creating Custom Plugins

You can create custom plugins by implementing the `RBACPlugin` interface:

```ts
import { RBACPlugin, PluginContext, PluginConfig } from '@rbac/rbac/plugins';

export class MyCustomPlugin implements RBACPlugin {
metadata = {
name: 'my-custom-plugin',
version: '1.0.0',
description: 'My custom RBAC plugin',
author: 'Your Name',
license: 'MIT'
};

async install(context: PluginContext): Promise<void> {
// Plugin initialization logic
context.logger('My custom plugin installed', 'info');
}

async uninstall(): Promise<void> {
// Plugin cleanup logic
}

getHooks() {
return {
beforePermissionCheck: this.beforePermissionCheck.bind(this),
afterPermissionCheck: this.afterPermissionCheck.bind(this)
};
}

private async beforePermissionCheck(data: any, context: PluginContext): Promise<any> {
// Custom logic before permission check
context.logger(`Checking permission: ${data.role} -> ${data.operation}`, 'info');
return data;
}

private async afterPermissionCheck(data: any, context: PluginContext): Promise<any> {
// Custom logic after permission check
context.logger(`Permission result: ${data.result}`, 'info');
return data;
}
}
```

#### Plugin Management

```ts
// List installed plugins
const plugins = rbac.plugins.getPlugins();
console.log('Installed plugins:', plugins);

// Get specific plugin
const plugin = rbac.plugins.getPlugin('cache-plugin');
console.log('Cache plugin:', plugin);

// Update plugin configuration
await rbac.plugins.updatePluginConfig('cache-plugin', {
enabled: true,
priority: 80,
settings: { ttl: 600 }
});

// Uninstall plugin
await rbac.plugins.uninstall('cache-plugin');
```

#### Community Plugins

The plugin system supports community-developed plugins. You can:

- Discover available plugins
- Install plugins from npm packages
- Validate plugin security and compatibility
- Share your own plugins with the community

```ts
import { createRBACWithAutoPlugins } from '@rbac/rbac/plugins';

// Auto-load community plugins
const rbacWithPlugins = await createRBACWithAutoPlugins(rbac, {
autoLoadCommunityPlugins: true,
validatePlugins: true,
strictMode: false
});
```

Want more? Check out the [examples](examples/) folder and the [plugin documentation](src/plugins/README.md).

### Middlewares

Expand Down Expand Up @@ -206,6 +369,24 @@ respectively with a similar API.
- [X] Async `when` callbacks
- [X] Database adapters (MongoDB, MySQL, PostgreSQL)
- [X] Middlewares for Express, NestJS and Fastify
- [X] Plugin system with hooks
- [X] Built-in plugins (Cache, Audit, Notification, Validation, Middleware)
- [X] Community plugin support
- [X] TypeScript support

## v2.2.0

- **Complete Internationalization**: All code, comments, and documentation translated to English
- **Enhanced Plugin System**: Improved plugin management and error handling
- **Better TypeScript Support**: Enhanced type definitions and IntelliSense
- **Improved Documentation**: Comprehensive README with plugin system documentation

## v2.1.0

- **Plugin System**: Extensible architecture with hooks and community plugins
- **Built-in Plugins**: Cache, Audit, Notification, Validation, and Middleware plugins
- **Community Plugin Support**: Share and use community-developed plugins
- **Enhanced TypeScript Support**: Full type safety and IntelliSense support

## v2.0.0

Expand Down Expand Up @@ -251,7 +432,13 @@ The baseline run shows @rbac/rbac leading all categories; the large dataset conf
3. Running the tests
* Run `yarn test`

4. Scripts
4. Plugin Development
* Check out the [plugin documentation](src/plugins/README.md) for detailed information
* Use the [community plugin template](src/plugins/community-template.ts) as a starting point
* Follow the [plugin development guidelines](src/plugins/COMMUNITY_PLUGINS.md)
* Test your plugins using the provided examples and test suites

5. Scripts
* `npm run build` - produces production version of your library under the `lib` folder and generates `lib/@rbac/rbac.min.js` via Vite
* `npm run dev` - produces development version of your library and runs a watcher
* `npm test` - well ... it runs the tests :)
Expand Down
9 changes: 4 additions & 5 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
const { createDefaultPreset } = require("ts-jest");

const tsJestTransformCfg = createDefaultPreset().transform;

/** @type {import("jest").Config} **/
module.exports = {
testEnvironment: "node",
transform: {
...tsJestTransformCfg,
"^.+\\.ts$": ["ts-jest", {
tsconfig: "tsconfig.test.json"
}]
},
collectCoverage: true,
collectCoverageFrom: ["src/**/*.{ts,tsx}", "!src/**/*.d.ts"],
coverageDirectory: "coverage",
setupFilesAfterEnv: ["<rootDir>/jest.setup.ts"],
testMatch: ["<rootDir>/test/**/*.spec.ts"],
preset: "ts-jest"
};
21 changes: 21 additions & 0 deletions jest.setup.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,23 @@
// Jest setup file used to configure the testing environment as needed.

// Silenciar logs durante os testes para reduzir ruído
const originalConsole = {
log: console.log,
info: console.info,
warn: console.warn,
error: console.error
};

// Silenciar logs de plugins durante os testes
console.log = jest.fn();
console.info = jest.fn();
console.warn = jest.fn();
console.error = jest.fn();

// Restaurar console após os testes
afterAll(() => {
console.log = originalConsole.log;
console.info = originalConsole.info;
console.warn = originalConsole.warn;
console.error = originalConsole.error;
});
Loading