// middleware/checkPageAccess.ts import { defineNuxtRouteMiddleware, navigateTo } from '#app'; import { useAuth } from '~/composables/useAuth'; import { usePermissionStore } from '~/stores/permissionStore'; export default defineNuxtRouteMiddleware(async (to, from) => { const publicPaths = ['/LoginPage', '/auth/login', '/index-legacy']; if (to.path === '/' || publicPaths.includes(to.path)) { return; } if (process.server) { return; } const { user, checkAuth } = useAuth(); if (!user.value) { await checkAuth(); } if (!user.value) { return navigateTo('/LoginPage'); } const permissionStore = usePermissionStore(); // Ensure permissions are loaded if (!permissionStore.isLoaded) { const roles = [ ...(user.value.realm_access?.roles || []), ...(user.value.roles || []) ]; const groups: string[] = []; const rawGroups = (user.value as any).groups || []; rawGroups.forEach((g: string) => { const parts = g.split('/').filter(Boolean); if (parts.length > 1) { groups.push(parts[1]); } else if (parts.length === 1) { groups.push(parts[0]); } }); const primaryRole = roles[0] || ''; const primaryGroup = groups[0] || ''; const username = user.value.preferred_username || user.value.email || user.value.name || ''; await permissionStore.load(primaryRole, primaryGroup, username); } let menuKey = ""; if (to.name) { menuKey = to.name.toString().toLowerCase().replace(/_|-/g, '-'); } // If no explicit route name, allow it for now. if (!menuKey) return; // The previous implementation allowed some pages implicitly. // If it's not configured, our can() method returns false. // We should allow access if it's explicitly allowed. let hasAccess = permissionStore.can(menuKey, 'canAccess'); // Default allow Dashboard for all authenticated users if (menuKey === 'dashboard') { hasAccess = true; } if (!hasAccess) { console.warn(`Access denied to ${to.path}. User lacks 'canAccess' for menuKey: ${menuKey}`); // Find a fallback page that the user CAN access const fallbackMenu = permissionStore.permissions.find(p => p.canAccess); if (fallbackMenu && fallbackMenu.menuKey) { // Note: menuKey might not be a valid path, but if we map routeName to menuKey, // we can try to navigate to the route name instead. return navigateTo({ name: fallbackMenu.menuKey }); } // Final fallback return navigateTo('/'); } });