A robust Role-Based Access Control (RBAC) and Attribute-Based Access Control (ABAC) system implemented in TypeScript for React applications. This package provides a comprehensive permission management solution with React hooks, components, and utilities.
- RBAC (Role-Based Access Control): Users are assigned roles, and roles have permissions
- ABAC (Attribute-Based Access Control): Access control based on user attributes and context
- React Hooks: Easy-to-use hooks for permission checking in components
- React Components: Conditional rendering components based on permissions
- TypeScript Support: Full TypeScript support with comprehensive type definitions
- High Test Coverage: 100% test coverage with Jest and React Testing Library
- Customizable: Extensible permission system with custom ABAC rules
- Performance Optimized: Memoized hooks and efficient permission checking
npm install react-permission-auth
# or
yarn add react-permission-auth
# or
pnpm add react-permission-auth
import React from "react";
import { usePermissions, PermissionGuard } from "react-permission-auth";
// Estructura simple del usuario (como viene del login)
const user = {
id: "user123",
roles: ["admin", "moderator"],
permissions: ["add-user", "delete-user", "create-post", "read-post"],
};
const MyComponent = () => {
const { checkPermission, userPermissions } = usePermissions(user);
return (
<div>
{/* Verificar permisos con strings */}
{checkPermission("add-user") && <button>Add User</button>}
{/* Verificar roles */}
{checkRole("admin") && <AdminPanel />}
{/* Componente protegido */}
<PermissionGuard user={user} permission="delete-user">
<button>Delete User</button>
</PermissionGuard>
{/* Mostrar permisos del usuario */}
<div>Your permissions: {userPermissions.join(", ")}</div>
</div>
);
};
import { Permission } from "react-permission-auth";
// TambiΓ©n puedes usar los enums si prefieres
{
checkPermission(Permission.CREATE_USER) && <button>Create User</button>;
}
### Setting Up Users and Roles
```tsx
import { RBACABAC, Permission } from 'react-permission-auth';
// Initialize the permission system
const rbac = new RBACABAC();
// Create users with roles
const adminUser = rbac.createUser('1', 'admin@example.com', ['admin']);
const authorUser = rbac.createUser('2', 'author@example.com', ['author']);
const readerUser = rbac.createUser('3', 'reader@example.com', ['reader']);
// Check permissions
const canCreateUser = rbac.checkPermission(adminUser, Permission.CREATE_USER); // true
const canDeletePost = rbac.checkPermission(authorUser, Permission.DELETE_POST); // false
- Permissions: Granular actions that can be performed (create, read, update, delete)
- Roles: Collections of permissions that define user capabilities
- Users: Entities that have one or more roles
- Permission Checker: Functions that validate if a user has a specific permission
- ABAC Rules: Context-based permission rules (time, location, user attributes)
export enum Permission {
// User Management
CREATE_USER = "create_user",
READ_USER = "read_user",
UPDATE_USER = "update_user",
DELETE_USER = "delete_user",
// Post Management
CREATE_POST = "create_post",
READ_POST = "read_post",
UPDATE_POST = "update_post",
DELETE_POST = "delete_post",
// Comment Management
CREATE_COMMENT = "create_comment",
READ_COMMENT = "read_comment",
UPDATE_COMMENT = "update_comment",
DELETE_COMMENT = "delete_comment",
// System Management
MANAGE_SYSTEM = "manage_system",
VIEW_LOGS = "view_logs",
MANAGE_ROLES = "manage_roles",
}
The main hook that provides all permission checking functionality:
const {
userPermissions,
checkPermission,
checkAnyPermission,
checkAllPermissions,
checkRole,
checkAnyRole,
checkAllRoles,
checkABACPermissionWithContext,
hasUser,
} = usePermissions(user);
Hook for checking a specific permission:
const { hasPermission, checkPermission } = usePermission(
user,
Permission.CREATE_USER
);
// Check with context
const canCreate = checkPermission({ resource: "user", action: "create" });
Hook for checking multiple permissions:
const { hasAnyPermission, hasAllPermissions } = useMultiplePermissions(user, [
Permission.CREATE_USER,
Permission.DELETE_USER,
]);
Hook for checking user roles:
const { checkRole, checkAnyRole, checkAllRoles } = useRoles(user);
const isAdmin = checkRole("admin");
const isModeratorOrAdmin = checkAnyRole(["moderator", "admin"]);
Conditionally render content based on a single permission:
<PermissionGuard
user={user}
permission={Permission.CREATE_USER}
fallback={<div>Access Denied</div>}
>
<AdminPanel />
</PermissionGuard>
Conditionally render content based on multiple permissions:
<MultiplePermissionGuard
user={user}
permissions={[Permission.CREATE_USER, Permission.DELETE_USER]}
requireAll={true} // User must have ALL permissions
fallback={<div>Access Denied</div>}
>
<AdminPanel />
</MultiplePermissionGuard>
Conditionally render content based on user roles:
<RoleGuard user={user} role="admin" fallback={<div>Admin Access Required</div>}>
<AdminPanel />
</RoleGuard>
Conditionally render content based on multiple roles:
<MultipleRoleGuard
user={user}
roles={["admin", "moderator"]}
requireAll={false} // User must have ANY of the roles
fallback={<div>Access Denied</div>}
>
<ModeratorPanel />
</MultipleRoleGuard>
The system supports context-based permission checking:
const context = {
user,
resource: "post",
action: "update",
time: new Date(),
location: "office",
environment: {
postOwnerId: "123",
},
};
const result = checkABACPermission(user, Permission.UPDATE_POST, context);
Create custom business rules:
import { createABACRule } from "react-permission-auth";
const financeRule = createABACRule(
"finance-rule",
"Finance Department Rule",
(context) => context.user.attributes?.department === "finance",
[Permission.APPROVE_INVOICE],
"Only finance department can approve invoices"
);
rbac.addCustomRule(financeRule);
The system includes several built-in ABAC checks:
- Time-based restrictions: Deny system management during off-hours
- Location-based restrictions: Deny sensitive operations in public locations
- User attribute checks: Age restrictions, account status, etc.
- Resource ownership: Users can only modify their own resources
Protect components with permission requirements:
const ProtectedAdminComponent = withPermission(
AdminComponent,
Permission.CREATE_USER
);
// Usage
<ProtectedAdminComponent user={user} title="Admin Panel" />;
Protect components with role requirements:
const ProtectedAdminComponent = withRole(AdminComponent, "admin");
// Usage
<ProtectedAdminComponent user={user} title="Admin Panel" />;
- Full system access
- User management (CRUD)
- Content management (CRUD)
- System configuration
- View logs
- Content moderation
- Post and comment management
- User information viewing
- View logs
- No user management
- Content creation
- Post creation and editing
- Comment management
- No content deletion
- Content consumption
- Post and comment reading
- Comment creation
- No content modification
Extend the Permission enum for your business needs:
// Extend the Permission enum
export enum Permission {
// ... existing permissions
// Custom business permissions
APPROVE_INVOICE = "approve_invoice",
VIEW_SALARY = "view_salary",
MANAGE_PROJECTS = "manage_projects",
}
Check multiple permissions efficiently:
// Check if user has any of the permissions
const canManageUsers = hasAnyPermission(user, [
Permission.CREATE_USER,
Permission.UPDATE_USER,
Permission.DELETE_USER,
]);
// Check if user has all permissions
const canFullyManageUsers = hasAllPermissions(user, [
Permission.CREATE_USER,
Permission.UPDATE_USER,
Permission.DELETE_USER,
]);
For high-performance applications, consider caching user permissions:
const { userPermissions } = usePermissions(user);
// Cache permissions in localStorage or state management
useEffect(() => {
if (userPermissions.length > 0) {
localStorage.setItem("userPermissions", JSON.stringify(userPermissions));
}
}, [userPermissions]);
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverage
# Build the project
npm run build
The project maintains 100% test coverage including:
- β Core Functions: Permission checking, role validation
- β React Hooks: All hook functionality and edge cases
- β React Components: Component rendering and permission logic
- β ABAC System: Context-based permission evaluation
- β Edge Cases: Invalid inputs, null users, empty roles
- β Business Logic: Role-specific permission validation
{
"compilerOptions": {
"target": "ES2020",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"jsx": "react-jsx",
"strict": true,
"esModuleInterop": true
}
}
module.exports = {
preset: "ts-jest",
testEnvironment: "jsdom",
setupFilesAfterEnv: ["<rootDir>/src/setupTests.ts"],
collectCoverage: true,
coverageThreshold: {
global: {
branches: 100,
functions: 100,
lines: 100,
statements: 100,
},
},
};
- Permission caching: Cache user permissions for frequently accessed users
- Role optimization: Minimize role lookups in high-traffic scenarios
- Batch operations: Check multiple permissions in single calls when possible
- Memoization: Hooks are memoized to prevent unnecessary re-renders
- Efficient algorithms: Optimized permission checking algorithms
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Add tests for new functionality
- Ensure all tests pass (
npm test
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
# Clone the repository
git clone https://github.com/yourusername/react-permission-auth.git
cd react-permission-auth
# Install dependencies
npm install
# Start development mode
npm run dev
# Run tests
npm test
# Build the project
npm run build
This project is licensed under the ISC License - see the LICENSE file for details.
If you encounter any issues or have questions:
- Check the documentation
- Search existing issues
- Create a new issue
- React team for the amazing framework
- TypeScript team for the type system
- Jest team for the testing framework
- All contributors who help improve this package
Made with β€οΈ for the React community