242 lines
7.4 KiB
TypeScript
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);
|
|
// });
|
|
});
|