Files
web-antrean/middleware/permissions.ts
T
2026-01-08 12:44:40 +07:00

242 lines
7.4 KiB
TypeScript

// 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<any[]>('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<PermissionResponse>('/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);
// });
});