892e47d017
## Multi-Administrator System
- Add role-based access control (RBAC) with predefined roles (Super Admin, Admin, Editor, Viewer)
- Add granular permissions system for all admin operations
- Add admin user management page with invite functionality
- Add email invitation system for new administrators
- Add permission middleware protecting all admin routes
- Add PermissionGate component for frontend permission checks
- Track event creator (created_by) for audit purposes
## Backup & Restore Fixes
- Fix S3 backup: endpoint URL handling, manifest loading, field name compatibility
- Fix S3 restore: add list-backups endpoint, transform S3 config from frontend format
- Fix PostgreSQL compatibility: add .returning('id') for insert operations
- Fix disk space check: use df command, handle unknown space gracefully
- Fix dry-run validation to not block on warnings
- Fix req.user → req.admin in restore routes
## Database Migrations
- 054: Add roles table with predefined roles
- 055: Add permissions table
- 056: Add role_permissions junction table
- 057: Add role_id to admin_users
- 058: Add admin_invitations table
- 059: Add admin email templates
- 060: Add created_by to events table
## Other Improvements
- Update .gitignore to exclude planning docs and local backup directory
- Remove SQLite database file from tracking
- Add i18n translations for user management (EN/DE)
61 lines
1.7 KiB
TypeScript
61 lines
1.7 KiB
TypeScript
import React from 'react';
|
|
import type { ReactNode } from 'react';
|
|
import { usePermissions } from '../../contexts/PermissionsContext';
|
|
|
|
interface PermissionGateProps {
|
|
permission?: string;
|
|
permissions?: string[];
|
|
requireAll?: boolean;
|
|
fallback?: ReactNode;
|
|
children: ReactNode;
|
|
}
|
|
|
|
/**
|
|
* PermissionGate component that conditionally renders children based on user permissions.
|
|
*
|
|
* @param permission - A single permission to check
|
|
* @param permissions - An array of permissions to check
|
|
* @param requireAll - If true, requires all permissions (AND logic). If false, requires any permission (OR logic). Default: false
|
|
* @param fallback - Content to render if permission check fails. Default: null
|
|
* @param children - Content to render if permission check passes
|
|
*/
|
|
export const PermissionGate: React.FC<PermissionGateProps> = ({
|
|
permission,
|
|
permissions,
|
|
requireAll = false,
|
|
fallback = null,
|
|
children,
|
|
}) => {
|
|
const { hasPermission, hasAnyPermission, hasAllPermissions, isSuperAdmin } = usePermissions();
|
|
|
|
// Super admin bypasses all permission checks
|
|
if (isSuperAdmin) {
|
|
return <>{children}</>;
|
|
}
|
|
|
|
// Check single permission
|
|
if (permission) {
|
|
if (hasPermission(permission)) {
|
|
return <>{children}</>;
|
|
}
|
|
return <>{fallback}</>;
|
|
}
|
|
|
|
// Check multiple permissions
|
|
if (permissions && permissions.length > 0) {
|
|
const hasAccess = requireAll
|
|
? hasAllPermissions(permissions)
|
|
: hasAnyPermission(permissions);
|
|
|
|
if (hasAccess) {
|
|
return <>{children}</>;
|
|
}
|
|
return <>{fallback}</>;
|
|
}
|
|
|
|
// If no permissions specified, render children (allow access)
|
|
return <>{children}</>;
|
|
};
|
|
|
|
PermissionGate.displayName = 'PermissionGate';
|