Skip to content

Latest commit

 

History

History
537 lines (399 loc) · 12.4 KB

File metadata and controls

537 lines (399 loc) · 12.4 KB

React Permission Auth

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.

🎯 Features

  • 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

🚀 Installation

npm install react-permission-auth
# or
yarn add react-permission-auth
# or
pnpm add react-permission-auth

📚 Quick Start

Basic Usage

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>
  );
};

Compatibilidad con Enums (Opcional)

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

🏗️ Architecture

Core Components

  • 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)

Permission Types

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",
}

🔧 React Hooks

usePermissions

The main hook that provides all permission checking functionality:

const {
  userPermissions,
  checkPermission,
  checkAnyPermission,
  checkAllPermissions,
  checkRole,
  checkAnyRole,
  checkAllRoles,
  checkABACPermissionWithContext,
  hasUser,
} = usePermissions(user);

usePermission

Hook for checking a specific permission:

const { hasPermission, checkPermission } = usePermission(
  user,
  Permission.CREATE_USER
);

// Check with context
const canCreate = checkPermission({ resource: "user", action: "create" });

useMultiplePermissions

Hook for checking multiple permissions:

const { hasAnyPermission, hasAllPermissions } = useMultiplePermissions(user, [
  Permission.CREATE_USER,
  Permission.DELETE_USER,
]);

useRoles

Hook for checking user roles:

const { checkRole, checkAnyRole, checkAllRoles } = useRoles(user);

const isAdmin = checkRole("admin");
const isModeratorOrAdmin = checkAnyRole(["moderator", "admin"]);

🎨 React Components

PermissionGuard

Conditionally render content based on a single permission:

<PermissionGuard
  user={user}
  permission={Permission.CREATE_USER}
  fallback={<div>Access Denied</div>}
>
  <AdminPanel />
</PermissionGuard>

MultiplePermissionGuard

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>

RoleGuard

Conditionally render content based on user roles:

<RoleGuard user={user} role="admin" fallback={<div>Admin Access Required</div>}>
  <AdminPanel />
</RoleGuard>

MultipleRoleGuard

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>

🔐 ABAC (Attribute-Based Access Control)

Context-Based Permissions

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);

Custom ABAC Rules

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);

Built-in ABAC Checks

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

🎭 Higher-Order Components

withPermission

Protect components with permission requirements:

const ProtectedAdminComponent = withPermission(
  AdminComponent,
  Permission.CREATE_USER
);

// Usage
<ProtectedAdminComponent user={user} title="Admin Panel" />;

withRole

Protect components with role requirements:

const ProtectedAdminComponent = withRole(AdminComponent, "admin");

// Usage
<ProtectedAdminComponent user={user} title="Admin Panel" />;

📊 Role Hierarchy

Administrator

  • Full system access
  • User management (CRUD)
  • Content management (CRUD)
  • System configuration
  • View logs

Moderator

  • Content moderation
  • Post and comment management
  • User information viewing
  • View logs
  • No user management

Author

  • Content creation
  • Post creation and editing
  • Comment management
  • No content deletion

Reader

  • Content consumption
  • Post and comment reading
  • Comment creation
  • No content modification

🚀 Advanced Usage

Custom Permission Types

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",
}

Dynamic Permission Checking

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,
]);

Permission Caching

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]);

🧪 Testing

Running Tests

# 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

Test Coverage

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

🔧 Configuration

TypeScript Configuration

{
  "compilerOptions": {
    "target": "ES2020",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "jsx": "react-jsx",
    "strict": true,
    "esModuleInterop": true
  }
}

Jest Configuration

module.exports = {
  preset: "ts-jest",
  testEnvironment: "jsdom",
  setupFilesAfterEnv: ["<rootDir>/src/setupTests.ts"],
  collectCoverage: true,
  coverageThreshold: {
    global: {
      branches: 100,
      functions: 100,
      lines: 100,
      statements: 100,
    },
  },
};

📈 Performance Considerations

  • 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

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Add tests for new functionality
  4. Ensure all tests pass (npm test)
  5. Commit your changes (git commit -m 'Add amazing feature')
  6. Push to the branch (git push origin feature/amazing-feature)
  7. Open a Pull Request

Development Setup

# 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

📄 License

This project is licensed under the ISC License - see the LICENSE file for details.

🔗 Related Resources

🆘 Support

If you encounter any issues or have questions:

  1. Check the documentation
  2. Search existing issues
  3. Create a new issue

🙏 Acknowledgments

  • 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