// URL → 메뉴 권한 id 매핑 (admin.vue menuItems의 id와 동일) const URL_PERMISSION_MAP = [ { prefix: '/site-manager/dashboard', id: 'dashboard' }, { prefix: '/site-manager/admin', id: 'admin' }, { prefix: '/site-manager/field', id: 'field' }, { prefix: '/site-manager/area', id: 'field' }, { prefix: '/site-manager/onboard', id: 'fishing' }, { prefix: '/site-manager/fishing', id: 'fishing' }, { prefix: '/site-manager/challenge', id: 'challenge' }, { prefix: '/site-manager/quest', id: 'quest' }, { prefix: '/site-manager/item', id: 'item' }, { prefix: '/site-manager/species_challenge', id: 'species' }, { prefix: '/site-manager/species_quest', id: 'species' }, { prefix: '/site-manager/species', id: 'species' }, { prefix: '/site-manager/user', id: 'user' }, ] // URL에서 필요한 권한 id를 찾는다 (없으면 null = 인증만 통과하면 OK) const getRequiredPermission = (path) => { for (const m of URL_PERMISSION_MAP) { if (path.startsWith(m.prefix)) return m.id } return null } // 현재 로그인된 admin이 해당 권한을 가지고 있는지 const hasPermission = (user, menuId) => { if (menuId === 'dashboard') return true if (!user) return false if (user.role === 'super_admin') return true if (user.permissions === 'all') return true return Array.isArray(user.permissions) && user.permissions.includes(menuId) } export default defineNuxtRouteMiddleware((to) => { // SSR에서는 middleware 실행 안 함 (클라이언트에서만) if (import.meta.server) return // Admin 페이지가 아니면 패스 if (!to.path.startsWith('/site-manager')) return const token = localStorage.getItem('admin_token') // 로그인 페이지는 예외 처리 if (to.path === '/site-manager' || to.path === '/site-manager/') { if (token) return navigateTo('/site-manager/dashboard') return } // Admin 페이지 접근 시 토큰 체크 if (!token) { return navigateTo('/site-manager') } // 권한 체크 let user = null try { user = JSON.parse(localStorage.getItem('admin_user') || 'null') } catch { user = null } const requiredId = getRequiredPermission(to.path) if (requiredId && !hasPermission(user, requiredId)) { console.warn('[Auth] 권한 없음 — dashboard로 이동:', to.path, '필요 권한:', requiredId) return navigateTo('/site-manager/dashboard') } })