b05e074456
Co-authored-by: ISMAIL MASSERAN <topaz@ISMAILs-Macbook.local> Co-authored-by: ISMAIL MASSERAN <topaz@Mac.dlinkrouter.local> Reviewed-on: #11
119 lines
3.5 KiB
TypeScript
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
|