From df83af90e856a9b6fb73d9710eb33e9753c3ff7b Mon Sep 17 00:00:00 2001 From: Mahdi Date: Mon, 10 Aug 2026 15:30:26 +0330 Subject: [PATCH] feat(auth): enforce admin permissions in UI Add can()/router meta, HomePage module filtering, Admins permission matrix, and hide write actions when the user lacks *:write. Co-authored-by: Cursor --- src/auth/permissions.ts | 54 ++++++ src/layouts/AppLayout.vue | 11 +- src/pages/AdminsPage.vue | 210 ++++++++++++++++++++++- src/pages/HamkarUiConfigPage.vue | 13 +- src/pages/HomePage.vue | 137 ++++++++++----- src/pages/KhanegiModularUiConfigPage.vue | 15 +- src/pages/PluginTenantPage.vue | 11 +- src/pages/ProductVersionsPage.vue | 20 ++- src/pages/ServerTenantPage.vue | 9 +- src/pages/SmsTenantPage.vue | 49 +++++- src/pages/SupportTenantPage.vue | 11 +- src/pages/TenantFormPage.vue | 20 ++- src/pages/UiConfigPage.vue | 27 ++- src/router/index.ts | 52 ++++++ src/stores/auth.ts | 35 +++- 15 files changed, 590 insertions(+), 84 deletions(-) create mode 100644 src/auth/permissions.ts diff --git a/src/auth/permissions.ts b/src/auth/permissions.ts new file mode 100644 index 0000000..8e5610d --- /dev/null +++ b/src/auth/permissions.ts @@ -0,0 +1,54 @@ +/** Mirror of API permission catalog for SuperAdmin web */ +export const PERMISSIONS = [ + 'sms:read', + 'sms:write', + 'servers:read', + 'servers:write', + 'plugins:read', + 'plugins:write', + 'support:read', + 'support:write', + 'hamkar:read', + 'hamkar:write', + 'khanegi:read', + 'khanegi:write', + 'admins:read', + 'admins:write', + 'audit:read', + 'settings:write', +] as const + +export type PermissionCode = (typeof PERMISSIONS)[number] + +export type PermissionModule = { + key: string + label: string + read?: PermissionCode + write?: PermissionCode +} + +export const PERMISSION_MODULES: PermissionModule[] = [ + { key: 'sms', label: 'پیامک', read: 'sms:read', write: 'sms:write' }, + { key: 'servers', label: 'سرور', read: 'servers:read', write: 'servers:write' }, + { key: 'plugins', label: 'افزونه', read: 'plugins:read', write: 'plugins:write' }, + { key: 'support', label: 'پشتیبانی', read: 'support:read', write: 'support:write' }, + { key: 'hamkar', label: 'همکار', read: 'hamkar:read', write: 'hamkar:write' }, + { key: 'khanegi', label: 'خانگی', read: 'khanegi:read', write: 'khanegi:write' }, + { key: 'admins', label: 'مدیران', read: 'admins:read', write: 'admins:write' }, + { key: 'audit', label: 'لاگ', read: 'audit:read' }, + { key: 'settings', label: 'تنظیمات حساس', write: 'settings:write' }, +] + +export function normalizePermissionList(codes: string[]): PermissionCode[] { + const set = new Set() + for (const raw of codes) { + const code = String(raw || '').trim() as PermissionCode + if (!(PERMISSIONS as readonly string[]).includes(code)) continue + set.add(code) + if (code.endsWith(':write')) { + const read = code.replace(/:write$/, ':read') as PermissionCode + if ((PERMISSIONS as readonly string[]).includes(read)) set.add(read) + } + } + return [...set] +} diff --git a/src/layouts/AppLayout.vue b/src/layouts/AppLayout.vue index dc56cd7..34ee4be 100644 --- a/src/layouts/AppLayout.vue +++ b/src/layouts/AppLayout.vue @@ -1,5 +1,5 @@