Files
security-alert-center/frontend/src/router.ts
T
PTah 141fc44099 feat: SAC 0.7.3 custom error pages 401/403/404/429
Centered logo pages with event explanation and allowed actions; router
and apiFetch redirect to them on auth, permission, not-found, and rate-limit errors.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-01 11:06:21 +10:00

71 lines
2.3 KiB
TypeScript

import { createRouter, createWebHistory } from "vue-router";
import { getToken, isAdmin, setRole, fetchMe } from "./api";
import EventsView from "./views/EventsView.vue";
import EventDetailView from "./views/EventDetailView.vue";
import HostsView from "./views/HostsView.vue";
import LoginView from "./views/LoginView.vue";
import ErrorPageView from "./views/ErrorPageView.vue";
import ProblemsView from "./views/ProblemsView.vue";
import ProblemDetailView from "./views/ProblemDetailView.vue";
import DashboardView from "./views/DashboardView.vue";
import ReportsView from "./views/ReportsView.vue";
import SettingsView from "./views/SettingsView.vue";
import UsersView from "./views/UsersView.vue";
const PUBLIC_PATHS = new Set(["/login", "/401", "/403", "/404", "/429"]);
const errorRoute = (code: 401 | 403 | 404 | 429) => ({
path: `/${code}`,
component: ErrorPageView,
props: { code },
meta: { standalone: true },
});
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: "/", redirect: "/dashboard" },
{ path: "/dashboard", component: DashboardView },
{ path: "/login", component: LoginView },
errorRoute(401),
errorRoute(403),
errorRoute(404),
errorRoute(429),
{ path: "/events", component: EventsView },
{ path: "/events/:id", component: EventDetailView, props: true },
{ path: "/reports", component: ReportsView },
{ path: "/hosts", component: HostsView },
{ path: "/problems", component: ProblemsView },
{ path: "/problems/:id", component: ProblemDetailView, props: true },
{ path: "/settings", component: SettingsView, meta: { adminOnly: true } },
{ path: "/users", component: UsersView, meta: { adminOnly: true } },
{
path: "/:pathMatch(.*)*",
component: ErrorPageView,
props: { code: 404 },
meta: { standalone: true },
},
],
});
router.beforeEach(async (to) => {
if (PUBLIC_PATHS.has(to.path)) return true;
if (!getToken()) return { path: "/login", query: { redirect: to.fullPath } };
if (to.meta.adminOnly && !isAdmin()) {
return { path: "/403" };
}
return true;
});
export default router;
export async function refreshSessionRole(): Promise<void> {
if (!getToken()) return;
try {
const me = await fetchMe();
setRole(me.role);
} catch {
/* 401 handled in apiFetch */
}
}