Files
service-finder/frontend/admin/middleware/auth.global.ts
2026-03-23 21:43:40 +00:00

83 lines
3.1 KiB
TypeScript

import { useAuthStore } from '~/stores/auth'
export default defineNuxtRouteMiddleware((to, from) => {
// Skip auth checks on server-side (SSR) - localStorage not available
if (process.server) {
return
}
const authStore = useAuthStore()
const nuxtApp = useNuxtApp()
// Public routes that don't require authentication
const publicRoutes = ['/login', '/forgot-password', '/reset-password']
// Check if route requires authentication
const requiresAuth = !publicRoutes.includes(to.path)
// If route requires auth and user is not authenticated, redirect to login
if (requiresAuth && !authStore.isAuthenticated) {
return navigateTo('/login')
}
// If user is authenticated and trying to access login page, redirect to dashboard
if (to.path === '/login' && authStore.isAuthenticated) {
return navigateTo('/dashboard')
}
// Check role-based access for protected routes
if (requiresAuth && authStore.isAuthenticated) {
const routeMeta = to.meta || {}
const requiredRole = routeMeta.requiredRole as string | undefined
const minRank = routeMeta.minRank as number | undefined
const requiredPermission = routeMeta.requiredPermission as string | undefined
// Check role requirement
if (requiredRole && authStore.getUserRole !== requiredRole) {
console.warn(`Access denied: Route requires role ${requiredRole}, user has ${authStore.getUserRole}`)
return navigateTo('/unauthorized')
}
// Check rank requirement
if (minRank !== undefined && !authStore.hasRank(minRank)) {
console.warn(`Access denied: Route requires rank ${minRank}, user has rank ${authStore.getUserRank}`)
return navigateTo('/unauthorized')
}
// Check permission requirement
if (requiredPermission && !authStore.hasPermission(requiredPermission)) {
console.warn(`Access denied: Route requires permission ${requiredPermission}`)
return navigateTo('/unauthorized')
}
// Check geographical scope for scoped routes
const requiredScopeId = routeMeta.requiredScopeId as number | undefined
const requiredRegionCode = routeMeta.requiredRegionCode as string | undefined
if (requiredScopeId || requiredRegionCode) {
if (!authStore.canAccessScope(requiredScopeId || 0, requiredRegionCode)) {
console.warn(`Access denied: User cannot access requested scope`)
return navigateTo('/unauthorized')
}
}
}
// Add auth headers to all API requests if authenticated
if (process.client && authStore.isAuthenticated && authStore.token) {
const { $api } = nuxtApp
if ($api && $api.defaults) {
$api.defaults.headers.common['Authorization'] = `Bearer ${authStore.token}`
// Add geographical scope headers for backend filtering
if (authStore.getScopeId) {
$api.defaults.headers.common['X-Scope-Id'] = authStore.getScopeId.toString()
}
if (authStore.getRegionCode) {
$api.defaults.headers.common['X-Region-Code'] = authStore.getRegionCode
}
if (authStore.getScopeLevel) {
$api.defaults.headers.common['X-Scope-Level'] = authStore.getScopeLevel
}
}
}
})