Files
bssapp/ui/src/router/index.js
2026-02-19 12:28:13 +03:00

111 lines
2.1 KiB
JavaScript

import { route } from 'quasar/wrappers'
import { createRouter, createWebHashHistory } from 'vue-router'
import routes from 'src/router/routes.js'
import { useAuthStore } from 'stores/authStore'
import { usePermissionStore } from 'stores/permissionStore'
export default route(function () {
const router = createRouter({
history: createWebHashHistory(),
routes
})
if (typeof window !== 'undefined' && process.env.DEV) {
window.__router = router
}
/* ============================================================
🔐 GLOBAL GUARD
============================================================ */
router.beforeEach(async (to, from, next) => {
const auth = useAuthStore()
const perm = usePermissionStore()
if (typeof window !== 'undefined') {
console.warn('🧭 ROUTE GUARD HIT:', {
path: to.fullPath,
meta: to.meta
})
}
if (typeof window !== 'undefined' && process.env.DEV) {
window.__auth = auth
window.__perm = perm
}
/* ================= PUBLIC ================= */
if (to.meta?.public === true) {
return next()
}
/* ================= LOGIN ================= */
if (!auth.isAuthenticated) {
return next('/login')
}
/* ================= PASSWORD ================= */
if (
auth.mustChangePassword &&
to.path !== '/first-password-change'
) {
return next('/first-password-change')
}
/* ================= ADMIN ================= */
if (auth.isAdmin) {
return next()
}
/* ================= LOAD PERMS ================= */
if (!perm.loaded) {
try {
await perm.fetchPermissions()
} catch (e) {
console.error('Permission load failed', e)
}
}
/* ================= CHECK ================= */
const required = to.meta?.permission
if (!required) {
return next()
}
const allowed = perm.hasApiPermission(required)
if (!allowed) {
console.warn('⛔ ACCESS DENIED:', {
path: to.fullPath,
permission: required
})
return next('/unauthorized')
}
next()
})
return router
})