
gittech. site
for different kinds of informations and explorations.
Durin β A Permissions Guardian
Published at
19 hours ago
Main Article
πͺ Durin
Speak friend and enter: A lightweight TypeScript-based permissions guardian for React applications
Features
- π― Simple, lightweight role-based access control
- π Type-safe permission management
- βοΈ React-first design
- πͺΆ Zero dependencies
- π¦ Tree-shakeable
- π§ͺ Thoroughly tested
Installation
npm install @sparkforge/durin
# or
yarn add @sparkforge/durin
# or
pnpm add @sparkforge/durin
Quick Start
import { PermissionProvider, Protected, usePermissions } from 'durin';
// Define your roles and permissions
const roles = [
{
name: 'admin',
permissions: ['create:users', 'edit:users', 'delete:users']
},
{
name: 'editor',
permissions: ['edit:users']
}
];
// Wrap your app with the provider
function App() {
const userRoles = ['editor']; // Get this from your auth system
return (
<PermissionProvider roles={roles} userRoles={userRoles}>
<YourApp />
</PermissionProvider>
);
}
// Use the Protected component
function UserManagement() {
return (
<div>
<Protected
requiredPermission="edit:users"
fallback={<p>Access denied</p>}
>
<EditUserForm />
</Protected>
</div>
);
}
// Or use the hook directly
function AdminPanel() {
const { hasPermission, hasRole } = usePermissions();
if (!hasRole('admin')) {
return <p>Admin access required</p>;
}
return <div>Admin Panel Content</div>;
}
API Reference
PermissionProvider
The root provider component that manages permissions state.
Props
{
roles: Array<{
name: string;
permissions: string[];
}>;
userRoles: string[];
children: ReactNode;
}
Protected
A component wrapper that conditionally renders based on permissions.
Props
{
requiredPermission?: string;
requiredRole?: string;
fallback?: ReactNode;
children: ReactNode;
}
usePermissions
A hook for programmatically checking permissions.
const {
hasPermission: (permission: string) => boolean,
hasRole: (role: string) => boolean,
userRoles: Array<{ name: string; permissions: string[] }>
} = usePermissions();
Best Practices
Define Clear Permission Names
- Use colon-separated format:
resource:action
- Example:
users:create
,posts:edit
- Use colon-separated format:
Role Hierarchies
- Keep role structures flat when possible
- Include all required permissions explicitly
Error Handling
- Always provide fallback content
- Handle loading states appropriately
Type Safety
- Define permission and role types
- Use string literals for better type inference
Examples
Nested Permissions
<Protected requiredPermission="users:edit">
<div>
<h1>User Settings</h1>
<Protected requiredPermission="users:delete">
<DeleteUserButton />
</Protected>
</div>
</Protected>
Combined Role and Permission Checks
<Protected
requiredRole="admin"
requiredPermission="settings:edit"
>
<AdminSettings />
</Protected>
Dynamic Permissions
function FeatureFlag({ feature, children }) {
const { hasPermission } = usePermissions();
return hasPermission(`feature:${feature}`) ? children : null;
}
Contributing
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create your feature branch
- Make your changes
- Run the tests (
npm test
) - Submit a pull request
License
MIT Β© [SparkForge]
"Not all those who wander are lost, but some just don't have the right permissions." - Gandalf, probably