mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 17:43:47 +00:00
feat: add RBAC permission system to admin cabinet frontend
- Permission store (Zustand) with wildcard matching and role level checks - PermissionRoute guard for route-level access control - PermissionGate component for element-level visibility - Admin Roles page: CRUD, permission editor, role assignment - Admin Policies page: ABAC policy management (time/IP conditions) - Admin Audit Log page: filterable log viewer with CSV export - AdminPanel sidebar navigation gated by permissions - 4 locale files updated (en, ru, zh, fa) with RBAC translations - API client module for all RBAC endpoints
This commit is contained in:
@@ -835,7 +835,8 @@
|
||||
"marketing": "Marketing",
|
||||
"system": "System",
|
||||
"tariffs": "Tariffs & Sales",
|
||||
"users": "Users"
|
||||
"users": "Users",
|
||||
"security": "Security"
|
||||
},
|
||||
"nav": {
|
||||
"title": "Admin",
|
||||
@@ -862,7 +863,11 @@
|
||||
"pinnedMessages": "Pinned Messages",
|
||||
"partners": "Partners",
|
||||
"withdrawals": "Withdrawals",
|
||||
"channelSubscriptions": "Required Channels"
|
||||
"channelSubscriptions": "Required Channels",
|
||||
"roles": "Roles",
|
||||
"roleAssign": "Role Assignment",
|
||||
"policies": "Access Policies",
|
||||
"auditLog": "Audit Log"
|
||||
},
|
||||
"panel": {
|
||||
"title": "Admin Panel",
|
||||
@@ -890,7 +895,11 @@
|
||||
"pinnedMessagesDesc": "Manage pinned messages for users",
|
||||
"partnersDesc": "Manage partner applications and commissions",
|
||||
"withdrawalsDesc": "Review and process withdrawal requests",
|
||||
"channelSubscriptionsDesc": "Manage required channel subscriptions"
|
||||
"channelSubscriptionsDesc": "Manage required channel subscriptions",
|
||||
"rolesDesc": "Manage admin roles and permissions",
|
||||
"roleAssignDesc": "Assign and revoke user roles",
|
||||
"policiesDesc": "Configure ABAC access policies",
|
||||
"auditLogDesc": "Review system activity and access history"
|
||||
},
|
||||
"trafficUsage": {
|
||||
"title": "Traffic Usage",
|
||||
@@ -2920,6 +2929,274 @@
|
||||
"unhealthy": "Unhealthy",
|
||||
"components": "Components",
|
||||
"uptime": "Uptime"
|
||||
},
|
||||
"roles": {
|
||||
"title": "Roles & Permissions",
|
||||
"subtitle": "Manage admin roles and their permissions",
|
||||
"createRole": "Create Role",
|
||||
"noRoles": "No roles found",
|
||||
"systemBadge": "System",
|
||||
"inactiveBadge": "Inactive",
|
||||
"levelLabel": "Level",
|
||||
"usersCount_one": "{{count}} user",
|
||||
"usersCount_other": "{{count}} users",
|
||||
"permissionsCount_one": "{{count}} permission",
|
||||
"permissionsCount_other": "{{count}} permissions",
|
||||
"stats": {
|
||||
"totalRoles": "Total roles",
|
||||
"active": "Active",
|
||||
"system": "System"
|
||||
},
|
||||
"actions": {
|
||||
"edit": "Edit",
|
||||
"delete": "Delete"
|
||||
},
|
||||
"modal": {
|
||||
"createTitle": "Create Role",
|
||||
"editTitle": "Edit Role",
|
||||
"close": "Close"
|
||||
},
|
||||
"form": {
|
||||
"name": "Role name",
|
||||
"namePlaceholder": "e.g. Moderator",
|
||||
"description": "Description",
|
||||
"descriptionPlaceholder": "What this role is for...",
|
||||
"level": "Priority level",
|
||||
"levelValue": "Level value",
|
||||
"levelHint": "Higher level = more authority. Users can only manage roles with a lower level than their own.",
|
||||
"color": "Color",
|
||||
"presets": "Permission presets",
|
||||
"permissions": "Permissions",
|
||||
"toggleSection": "Toggle all {{section}} permissions",
|
||||
"selectedPermissions_one": "{{count}} permission selected",
|
||||
"selectedPermissions_other": "{{count}} permissions selected",
|
||||
"cancel": "Cancel",
|
||||
"saving": "Saving...",
|
||||
"save": "Save"
|
||||
},
|
||||
"presets": {
|
||||
"moderator": "Moderator",
|
||||
"marketer": "Marketer",
|
||||
"support": "Support"
|
||||
},
|
||||
"confirm": {
|
||||
"title": "Delete role?",
|
||||
"text": "This role will be permanently deleted. Users with this role will lose its permissions.",
|
||||
"cancel": "Cancel",
|
||||
"delete": "Delete",
|
||||
"deleting": "Deleting..."
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Failed to load roles",
|
||||
"createFailed": "Failed to create role",
|
||||
"updateFailed": "Failed to update role",
|
||||
"nameRequired": "Role name is required"
|
||||
}
|
||||
},
|
||||
"roleAssign": {
|
||||
"title": "Role Assignment",
|
||||
"subtitle": "Assign and manage user roles",
|
||||
"assignSection": "Assign Role",
|
||||
"userLabel": "User",
|
||||
"searchPlaceholder": "Search by name, username, Telegram ID, or email...",
|
||||
"clearUser": "Clear selected user",
|
||||
"noUsersFound": "No users found",
|
||||
"roleLabel": "Role",
|
||||
"selectRole": "Select a role...",
|
||||
"expiresLabel": "Expires at (optional)",
|
||||
"expiresHint": "Leave empty for permanent assignment",
|
||||
"assignButton": "Assign",
|
||||
"assigning": "Assigning...",
|
||||
"assignSuccess": "Role assigned successfully",
|
||||
"currentAssignments": "Current Assignments",
|
||||
"totalAssignments_one": "{{count}} assignment total",
|
||||
"totalAssignments_other": "{{count}} assignments total",
|
||||
"noAssignments": "No role assignments found",
|
||||
"unknownUser": "Unknown user",
|
||||
"system": "System",
|
||||
"permanent": "Permanent",
|
||||
"expired": "expired",
|
||||
"revoke": "Revoke",
|
||||
"revokeAriaLabel": "Revoke role {{role}} from {{user}}",
|
||||
"table": {
|
||||
"user": "User",
|
||||
"role": "Role",
|
||||
"assignedBy": "Assigned by",
|
||||
"assignedAt": "Assigned at",
|
||||
"expires": "Expires",
|
||||
"actions": "Actions"
|
||||
},
|
||||
"pagination": {
|
||||
"showing": "{{from}}-{{to}} of {{total}}",
|
||||
"prev": "Previous page",
|
||||
"next": "Next page"
|
||||
},
|
||||
"confirm": {
|
||||
"title": "Revoke role?",
|
||||
"text": "This user will immediately lose all permissions associated with this role.",
|
||||
"cancel": "Cancel",
|
||||
"revoke": "Revoke",
|
||||
"revoking": "Revoking..."
|
||||
},
|
||||
"errors": {
|
||||
"userRequired": "Please select a user",
|
||||
"roleRequired": "Please select a role",
|
||||
"assignFailed": "Failed to assign role"
|
||||
}
|
||||
},
|
||||
"policies": {
|
||||
"title": "Access Policies",
|
||||
"subtitle": "Manage ABAC access control policies",
|
||||
"createPolicy": "Create Policy",
|
||||
"noPolicies": "No policies found",
|
||||
"inactiveBadge": "Inactive",
|
||||
"effectAllow": "Allow",
|
||||
"effectDeny": "Deny",
|
||||
"global": "Global",
|
||||
"unknownRole": "Unknown role",
|
||||
"roleLabel": "Role",
|
||||
"priorityLabel": "Priority",
|
||||
"stats": {
|
||||
"total": "Total policies",
|
||||
"allow": "Allow",
|
||||
"deny": "Deny",
|
||||
"active": "Active"
|
||||
},
|
||||
"actions": {
|
||||
"edit": "Edit",
|
||||
"delete": "Delete"
|
||||
},
|
||||
"modal": {
|
||||
"createTitle": "Create Policy",
|
||||
"editTitle": "Edit Policy",
|
||||
"close": "Close"
|
||||
},
|
||||
"form": {
|
||||
"name": "Policy name",
|
||||
"namePlaceholder": "e.g. Block night access",
|
||||
"description": "Description",
|
||||
"descriptionPlaceholder": "What this policy does...",
|
||||
"effect": "Effect",
|
||||
"resource": "Resource",
|
||||
"selectResource": "Select a resource...",
|
||||
"actions": "Actions",
|
||||
"role": "Role (optional)",
|
||||
"globalOption": "Global (all roles)",
|
||||
"roleHint": "Leave as Global to apply the policy to all roles.",
|
||||
"priority": "Priority",
|
||||
"priorityHint": "Higher priority policies are evaluated first. Deny overrides Allow at equal priority.",
|
||||
"conditions": "Conditions",
|
||||
"cancel": "Cancel",
|
||||
"saving": "Saving...",
|
||||
"save": "Save"
|
||||
},
|
||||
"conditions": {
|
||||
"timeRange": "Time range",
|
||||
"timeStart": "Start time",
|
||||
"timeEnd": "End time",
|
||||
"ipWhitelist": "IP whitelist",
|
||||
"ipPlaceholder": "Enter IP and press Enter...",
|
||||
"removeIp": "Remove {{ip}}",
|
||||
"ipCount_one": "{{count}} IP",
|
||||
"ipCount_other": "{{count}} IPs",
|
||||
"rateLimit": "Rate limit",
|
||||
"rateLimitValue": "Rate limit value",
|
||||
"rateValue": "{{count}}/hr",
|
||||
"perHour": "actions per hour"
|
||||
},
|
||||
"confirm": {
|
||||
"title": "Delete policy?",
|
||||
"text": "This policy will be permanently deleted. Access control rules will be recalculated.",
|
||||
"cancel": "Cancel",
|
||||
"delete": "Delete",
|
||||
"deleting": "Deleting..."
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Failed to load policies",
|
||||
"createFailed": "Failed to create policy",
|
||||
"updateFailed": "Failed to update policy",
|
||||
"nameRequired": "Policy name is required",
|
||||
"resourceRequired": "Please select a resource",
|
||||
"actionsRequired": "Please select at least one action"
|
||||
}
|
||||
},
|
||||
"auditLog": {
|
||||
"title": "Audit Log",
|
||||
"subtitle": "Review system activity and access history",
|
||||
"back": "Back",
|
||||
"exportCsv": "Export CSV",
|
||||
"exporting": "Exporting...",
|
||||
"refresh": "Refresh",
|
||||
"unknownUser": "Unknown user",
|
||||
"noEntries": "No audit log entries found",
|
||||
"totalEntries_one": "{{count}} entry",
|
||||
"totalEntries_other": "{{count}} entries",
|
||||
"autoRefresh": {
|
||||
"label": "Auto-refresh",
|
||||
"tooltip": "Auto-refresh every 30 seconds"
|
||||
},
|
||||
"filters": {
|
||||
"title": "Filters",
|
||||
"active": "Active",
|
||||
"action": "Action",
|
||||
"actionPlaceholder": "Search by action...",
|
||||
"resource": "Resource type",
|
||||
"allResources": "All resources",
|
||||
"status": "Status",
|
||||
"allStatuses": "All statuses",
|
||||
"dateFrom": "Date from",
|
||||
"dateTo": "Date to",
|
||||
"apply": "Apply",
|
||||
"clear": "Clear"
|
||||
},
|
||||
"status": {
|
||||
"success": "Success",
|
||||
"denied": "Denied",
|
||||
"error": "Error"
|
||||
},
|
||||
"resourceTypes": {
|
||||
"users": "Users",
|
||||
"tickets": "Tickets",
|
||||
"roles": "Roles",
|
||||
"policies": "Policies",
|
||||
"settings": "Settings",
|
||||
"broadcasts": "Broadcasts",
|
||||
"tariffs": "Tariffs",
|
||||
"servers": "Servers",
|
||||
"payments": "Payments",
|
||||
"campaigns": "Campaigns",
|
||||
"promocodes": "Promo Codes"
|
||||
},
|
||||
"details": {
|
||||
"userAgent": "User Agent",
|
||||
"requestPath": "Request Path",
|
||||
"ipAddress": "IP Address",
|
||||
"timestamp": "Timestamp",
|
||||
"before": "Before",
|
||||
"after": "After",
|
||||
"fullDetails": "Full Details"
|
||||
},
|
||||
"time": {
|
||||
"justNow": "Just now",
|
||||
"minutesAgo_one": "{{count}} min ago",
|
||||
"minutesAgo_other": "{{count}} min ago",
|
||||
"hoursAgo_one": "{{count}} hr ago",
|
||||
"hoursAgo_other": "{{count}} hrs ago",
|
||||
"daysAgo_one": "{{count}} day ago",
|
||||
"daysAgo_other": "{{count}} days ago"
|
||||
},
|
||||
"pagination": {
|
||||
"pageSize": "Per page:",
|
||||
"pageOf": "{{current}} / {{total}}",
|
||||
"first": "First page",
|
||||
"previous": "Previous page",
|
||||
"next": "Next page",
|
||||
"last": "Last page"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Failed to load audit log",
|
||||
"retry": "Try again"
|
||||
}
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
|
||||
Reference in New Issue
Block a user