Files
My-KOPKB/fe/src/router/index.ts
T
ismailmasseran b05e074456 Feature/phone register (#11)
Co-authored-by: ISMAIL MASSERAN <topaz@ISMAILs-Macbook.local>
Co-authored-by: ISMAIL MASSERAN <topaz@Mac.dlinkrouter.local>
Reviewed-on: #11
2026-07-14 12:03:22 +08:00

119 lines
3.5 KiB
TypeScript

import { createRouter, createWebHistory } from 'vue-router'
import Layout from '@/themes'
import { hasAnyActiveRolePermission } from '@/core/utils/activeRolePermission'
import { getRouteRequiredPermissions } from '@/core/utils/routePermission'
import { authPublicRoutes, resolvePostAuthRoute } from '@/modules/auth'
import { membershipApplicationPublicRoutes, membershipApplicationLayoutRoutes } from '@/modules/membership-application'
import { profileLayoutRoutes, profilePublicRoutes } from '@/modules/profile'
import { pinia } from '@/pinia'
import { useAuthStore } from '@/stores/auth'
import { userLayoutRoutes } from '@/modules/user'
import { roleLayoutRoutes } from '@/modules/role'
import { activityLayoutRoutes } from '@/modules/activity'
import { dashboardLayoutRoutes } from '@/modules/dashboard'
import { externalSystemLayoutRoutes } from '@/modules/external-system'
import { activityLogLayoutRoutes } from '@/modules/activity-log'
import { feedbackPublicRoutes, feedbackLayoutRoutes } from '@/modules/feedback'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
// Main Layout
path: '/',
component: Layout,
children: [
...dashboardLayoutRoutes,
...profileLayoutRoutes,
...userLayoutRoutes,
...roleLayoutRoutes,
...activityLogLayoutRoutes,
...activityLayoutRoutes,
...externalSystemLayoutRoutes,
...membershipApplicationLayoutRoutes,
...feedbackLayoutRoutes,
],
},
...authPublicRoutes,
...membershipApplicationPublicRoutes,
...feedbackPublicRoutes,
...profilePublicRoutes,
],
})
const PUBLIC_ROUTE_NAMES = new Set(['login', 'register', 'membership-application-apply', 'feedback-submit'])
router.beforeEach(async (to) => {
const authStore = useAuthStore(pinia)
const routeName = String(to.name ?? '')
// Hydrate session on public auth entry pages.
if (PUBLIC_ROUTE_NAMES.has(routeName) && !authStore.isAuthenticated && !authStore.loading) {
await authStore.fetchSession()
}
// Pending-approval page: authenticated pending users only.
if (routeName === 'account-pending') {
if (!authStore.isAuthenticated && !authStore.loading) {
await authStore.fetchSession()
}
if (!authStore.isAuthenticated) {
return { name: 'login' }
}
if (!authStore.isAccountPending) {
return resolvePostAuthRoute(authStore.user)
}
return true
}
if (
authStore.isAuthenticated &&
PUBLIC_ROUTE_NAMES.has(routeName) &&
routeName !== 'membership-application-apply' &&
routeName !== 'feedback-submit'
) {
return resolvePostAuthRoute(authStore.user)
}
// Public routes (auth pages, membership application, privacy, terms, etc.).
if (to.meta?.public === true || to.meta?.module === 'auth' || PUBLIC_ROUTE_NAMES.has(routeName)) {
return true
}
// Protected routes: require session.
if (!authStore.isAuthenticated && !authStore.loading) {
await authStore.fetchSession()
}
if (!authStore.isAuthenticated) {
return {
name: 'login',
query: { redirect: to.fullPath },
}
}
if (authStore.isAccountPending) {
return { name: 'account-pending' }
}
const requiredPermissions = getRouteRequiredPermissions(to)
if (
requiredPermissions.length &&
!hasAnyActiveRolePermission(
authStore.user,
authStore.activeRole,
requiredPermissions,
)
) {
return { name: 'forbidden' }
}
return true
})
export default router