From 8a9a9ba08638521ecb5ff11e1b7b3ab5dc92ddc4 Mon Sep 17 00:00:00 2001 From: Christian Beeznest Date: Fri, 7 Nov 2025 00:47:37 -0500 Subject: [PATCH] Internal: admin-only; redirect unauthorized to Home - refs #6327 --- assets/vue/router/admin.js | 2 +- assets/vue/router/index.js | 49 +++++++++++++++++++++++++++++--------- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/assets/vue/router/admin.js b/assets/vue/router/admin.js index ed0b34d8424..bd3e398e423 100644 --- a/assets/vue/router/admin.js +++ b/assets/vue/router/admin.js @@ -43,7 +43,7 @@ export default { { name: "TermsConditionsView", path: "terms-conditions/view", - meta: { requiresAdmin: true, showBreadcrumb: true, }, + meta: { showBreadcrumb: true, }, component: () => import("../views/terms/Terms.vue"), }, ], diff --git a/assets/vue/router/index.js b/assets/vue/router/index.js index 779d0632355..6597afde57c 100644 --- a/assets/vue/router/index.js +++ b/assets/vue/router/index.js @@ -264,8 +264,13 @@ const router = createRouter({ ], }) +let navWaitTimer router.beforeEach(async (to, from, next) => { document.body.classList.add("cursor-wait") + if (navWaitTimer) clearTimeout(navWaitTimer) + navWaitTimer = window.setTimeout(() => { + document.body.classList.remove("cursor-wait") + }, 4000) const securityStore = useSecurityStore() @@ -307,26 +312,48 @@ router.beforeEach(async (to, from, next) => { } } - if (to.matched.some((record) => record.meta.requiresAuth)) { - if (!securityStore.isLoading) { + try { + if (!securityStore.user && !securityStore.isLoading) { await securityStore.checkSession() } - if (securityStore.isAuthenticated) { - next() - } else { + const needsAuth = to.matched.some(r => r.meta?.requiresAuth) + if (needsAuth && !securityStore.isAuthenticated) { sessionStorage.clear() - next({ - path: "/login", - query: { redirect: to.fullPath }, - }) + return next({ path: "/login", query: { redirect: to.fullPath } }) } - } else { - next() + + const wantsAdmin = to.matched.some(r => r.meta?.requiresAdmin === true) + const wantsSessionAdmin = to.matched.some(r => r.meta?.requiresSessionAdmin === true) + + let allowed = true + if (wantsAdmin && wantsSessionAdmin) { + allowed = !!securityStore.isAdmin || !!securityStore.isSessionAdmin + } else if (wantsAdmin) { + allowed = !!securityStore.isAdmin + } else if (wantsSessionAdmin) { + allowed = !!securityStore.isSessionAdmin + } + + if (!allowed) { + return next({ name: "Home", replace: true }) + } + + return next() + } catch (err) { + console.error("[RouterGuard] Unhandled error:", err) + return next({ name: "Home", replace: true }) } }) router.afterEach(() => { + if (navWaitTimer) clearTimeout(navWaitTimer) + document.body.classList.remove("cursor-wait") +}) + +router.onError((err) => { + console.error("[Router] onError:", err) + if (navWaitTimer) clearTimeout(navWaitTimer) document.body.classList.remove("cursor-wait") })