// middleware/permissions.ts // Auto-save user permissions to localStorage when user is authenticated import { defineNuxtRouteMiddleware } from '#app'; import { useLocalStorage } from '@vueuse/core'; import { useNavItemsStore } from '~/stores/navItems1'; interface NavItem { id: number; name: string; path: string; icon: string; children?: NavItem[]; } interface BackendPermission { id: number; create: boolean; read: boolean; update: boolean; disable: boolean; delete: boolean; active: boolean; pagename: string; pagesID: number; level?: number; sort?: number; parent?: number; } interface PermissionResponse { message?: string; data?: BackendPermission[]; meta?: { count: number; total: number; }; error?: string; } // Save permissions to allHakAksesData in localStorage const savePermissionsToHakAksesData = async ( backendPermissions: BackendPermission[], role: string, group: string ) => { try { // Get user data for additional info const userData = await $fetch('/api/users/current').catch(() => null); // Get existing hak akses data from localStorage const allHakAksesData = useLocalStorage('allHakAksesData', []); // Check if entry already exists for this role+group combination const existingIndex = allHakAksesData.value.findIndex( (item) => item.role === role && item.group === group ); // Get navItemsStore to build menu template const navItemsStore = useNavItemsStore(); // Build menu template from navItems const buildMenuTemplate = (items: NavItem[]): any[] => { const result: any[] = []; const walk = (list: NavItem[]) => { list.forEach((item) => { result.push({ name: item.name, canAccess: false, canView: false, canAdd: false, canEdit: false, canDelete: false, }); if (item.children?.length) { walk(item.children); } }); }; walk(items); return result; }; const menuTemplate = buildMenuTemplate(navItemsStore.navItems); // Map backend permissions to menu items const mappedPermissions = menuTemplate.map((menu) => { // Find matching permission from backend (by pagename or menu name) const backendPerm = backendPermissions.find((perm) => perm.pagename?.toLowerCase() === menu.name.toLowerCase() || perm.pagename?.toLowerCase().includes(menu.name.toLowerCase()) || menu.name.toLowerCase().includes(perm.pagename?.toLowerCase() || '') ); if (backendPerm) { return { name: menu.name, canAccess: backendPerm.active || backendPerm.read || false, canView: backendPerm.read || false, canAdd: backendPerm.create || false, canEdit: backendPerm.update || false, canDelete: backendPerm.delete || false, }; } return menu; }); // Create hak akses data entry const hakAksesEntry = { id: existingIndex > -1 ? allHakAksesData.value[existingIndex].id : (allHakAksesData.value.length > 0 ? Math.max(...allHakAksesData.value.map(i => i.id || 0)) + 1 : 1), userId: userData?.id || '', namaLengkap: userData?.namaLengkap || '', namaUser: userData?.namaUser || '', tipeUser: userData?.tipeUser || '', role: role, group: group, namaTipeUser: userData?.tipeUser || role, hakAksesMenu: mappedPermissions, // Store backend permissions for reference backendPermissions: backendPermissions, }; if (existingIndex > -1) { // Update existing entry allHakAksesData.value[existingIndex] = hakAksesEntry; console.log('✅ [Permissions Middleware] Updated existing hak akses data for', role, '/', group); } else { // Add new entry allHakAksesData.value.push(hakAksesEntry); console.log('✅ [Permissions Middleware] Added new hak akses data for', role, '/', group); } console.log('💾 [Permissions Middleware] Permissions saved to allHakAksesData:', { role, group, permissionsCount: backendPermissions.length, menuCount: mappedPermissions.length, }); } catch (error) { console.error('❌ [Permissions Middleware] Error saving permissions to hak akses data:', error); } }; // Fetch permissions from backend API and save to localStorage const fetchAndSavePermissions = async () => { // Skip on server-side if (process.server) { return; } // Check if we've already processed permissions in this session const sessionKey = 'permissions_synced'; if (sessionStorage.getItem(sessionKey)) { console.log('⏭️ [Permissions Middleware] Permissions already synced in this session'); return; } try { // Get current user data with roles and groups const userData = await $fetch('/api/users/current').catch(() => null); if (!userData) { console.warn('⚠️ [Permissions Middleware] No user data found'); return; } const roles = [ ...(userData.realmRoles || []), ...(userData.roles || []), ]; // Extract groups from paths (e.g., "/Instalasi STIM/Devops/Superadmin" -> "STIM") const groups: string[] = []; (userData.groups || []).forEach((g: string) => { const parts = g.split('/').filter(Boolean); if (parts.length > 1) { groups.push(parts[1]); // Get second part as group name } else if (parts.length === 1) { groups.push(parts[0]); } }); if (roles.length === 0 || groups.length === 0) { console.warn('⚠️ [Permissions Middleware] No roles or groups found for current user'); return; } // Use first role and first group const primaryRole = roles[0] || ''; const primaryGroup = groups[0] || ''; if (!primaryRole || !primaryGroup) { return; } console.log('🔄 [Permissions Middleware] Fetching permissions for', primaryRole, '/', primaryGroup); // Fetch permissions from API const response = await $fetch('/api/permission', { query: { roles: primaryRole, groups: primaryGroup, }, }); if (response && response.data && Array.isArray(response.data) && response.data.length > 0) { // Save permissions to localStorage await savePermissionsToHakAksesData(response.data, primaryRole, primaryGroup); // Mark as synced in this session sessionStorage.setItem(sessionKey, 'true'); console.log('✅ [Permissions Middleware] Permissions synced successfully'); } else { console.warn('⚠️ [Permissions Middleware] No permissions data received from API'); } } catch (error) { console.error('❌ [Permissions Middleware] Error fetching/saving permissions:', error); } }; export default defineNuxtRouteMiddleware(async (to) => { // Only run on client-side if (process.server) { return; } // Skip for login page if (to.path === '/LoginPage') { return; } // DISABLED: Auto-fetch permissions is now disabled // Permissions should only be fetched manually via button click in HakAkses page // Run async permission sync (non-blocking) // This will only run once per session due to sessionStorage check // fetchAndSavePermissions().catch(err => { // console.error('❌ [Permissions Middleware] Failed to sync permissions:', err); // }); });