85 lines
2.8 KiB
TypeScript
85 lines
2.8 KiB
TypeScript
// 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('/');
|
|
}
|
|
});
|