浏览代码

feat(auth): add role-based app filtering for dashboard tiles

Implement authorization checks to filter dashboard applications based on user roles and permissions. Users with admin role can access all apps, while customers require specific permissions for Cintas calendar summary access.
vidane 6 月之前
父节点
当前提交
0f72419aa4
共有 1 个文件被更改,包括 26 次插入2 次删除
  1. 26 2
      app/dashboard/page.tsx

+ 26 - 2
app/dashboard/page.tsx

@@ -21,7 +21,20 @@ export default function DashboardPage() {
   const roles = accessToken?.roles || [];
   const permissions = accessToken?.permissions || [];
 
-  const apps: AppTile[] = [
+  // Extract role keys for easier checking
+  const roleKeys = roles.map(role => role.key);
+
+  // Check if user has admin role
+  const hasAdminRole = isAuthenticated && roleKeys.includes('admin');
+
+  // Check if user has customer role and cintas_access permission
+  const hasCustomerRole = isAuthenticated && roleKeys.includes('customer');
+  const hasCintasAccess = permissions.includes('cintas_access');
+
+  // Check if user can access Cintas summary
+  const canAccessCintasSummary = hasAdminRole || (hasCustomerRole && hasCintasAccess);
+
+  const allApps: AppTile[] = [
     {
       id: 'files',
       title: 'Files',
@@ -73,6 +86,17 @@ export default function DashboardPage() {
     }
   ];
 
+  // Filter apps based on authentication and authorization
+  const filteredApps = allApps.filter(app => {
+    // All apps except Cintas require admin role
+    if (app.id !== 'cintas-calendar-summary') {
+      return hasAdminRole;
+    }
+
+    // Cintas summary has special access rules
+    return canAccessCintasSummary;
+  });
+
   const handleAppClick = (href: string) => {
     router.push(href);
   };
@@ -90,7 +114,7 @@ export default function DashboardPage() {
         </div>
 
         <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 max-w-6xl mx-auto">
-          {apps.map((app) => (
+          {filteredApps.map((app) => (
             <Card
               key={app.id}
               className="group cursor-pointer transition-all duration-300 hover:shadow-lg hover:scale-105 dark:bg-gray-800 dark:border-gray-700"