Files
NewSmoop/management-ui/src/router.ts

100 lines
2.6 KiB
TypeScript

import { createRouter, createWebHistory } from 'vue-router';
import Admin from '@/pages/Admin.vue';
import Login from '@/pages/Login.vue';
import Settings from '@/pages/Settings.vue';
import Devices from '@/pages/Devices.vue';
import DeviceView from './pages/DeviceView.vue';
import Forbidden from './pages/Forbidden.vue';
import Create from './pages/Create.vue';
import { auth } from './lib/auth';
declare module 'vue-router' {
interface RouteMeta {
requiresAuth?: boolean
roles?: string[] // allowed roles
}
}
const routes = [
{
path: '/login',
name: 'Login',
component: Login,
meta: { requiresAuth: false }
},
{
path: '/',
redirect: '/devices', // Optional: Redirect the root path to /home
},
{
path: '/devices',
name: 'Devices',
component: Devices,
meta: { requiresAuth: true }
},
{
path: '/settings',
name: 'Settings',
component: Settings,
meta: { requiresAuth: true }
},
{
path: '/admin',
name: 'Admin',
component: Admin,
meta: { requiresAuth: true, roles: ['admin'] }
},
{
path: '/device/:guid', // ← new dynamic segment
name: 'DeviceView',
component: DeviceView,
props: true, // so `guid` shows up as a prop
meta: { requiresAuth: true }
},
{
path: '/forbidden',
name: 'Forbidden',
component: Forbidden,
meta: { requiresAuth: false }
},
{
path: '/create',
name: 'Create',
component: Create,
meta: { requiresAuth: true, roles: ['admin'] }
}
]
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes,
})
// Navigation guard for protected routes.
// For any route except "Login", we force a full page load so that the server-side session check occurs.
router.beforeEach((to, _from, next) => {
const requiresAuth = to.meta.requiresAuth !== false && to.name !== 'Login'
// 1) Not authenticated → /login?redirect=<original>
if (requiresAuth && !auth.isAuthenticated.value) {
return next({ name: 'Login', query: { redirect: to.fullPath } })
}
// 2) Role check (if any)
const allowed = to.meta.roles
if (allowed && allowed.length > 0) {
const hasRole = allowed.some((r) => auth.roles.value.includes(r))
if (!hasRole) {
return next({ name: 'Forbidden' })
}
}
next()
})
export default router