Files
Hoard/GUI/src/plugins/routesLayout.ts
T
Jonas b2984fcf1a Replace IsAdmin with role-based admin
Switch user admin handling from an AppUser boolean to ASP.NET Identity roles. Removed AppUser.IsAdmin and related configuration/model entries; added migration ReplaceIsAdminWithRoles to copy Users.IsAdmin=true into a persistent admin role and drop the IsAdmin column. CurrentUserResponse now exposes roles (string[]), AuthController returns ordered roles from UserManager, and IdentitySeedService now ensures the admin role exists and assigns/creates an initial admin user in that role. Program.cs registers an Admin-only policy (PolicyNames/RoleNames), adjusts cookie auth events to return 401/403 for API requests, and wires up authorization. Frontend updated to use roles: authSession normalizes roles, adds hasRole and ROLE_ADMIN, router and layout support meta.requiredRoles, and new Forbidden and AdminUsers pages/route are added. codexInfo.md updated to reflect the migration to role-based auth.
2026-04-20 19:57:49 +02:00

140 lines
3.5 KiB
TypeScript

import type { RouteRecordRaw } from 'vue-router'
import Home from '@/routes/Home.vue'
import Dashboard from '@/routes/dashboard/Dashboard.vue'
import NotFound from '@/routes/404NotFound.vue'
import Forbidden from '@/routes/Forbidden.vue'
import Login from '@/routes/authentication/Login.vue'
import AdminUsers from '@/routes/admin/AdminUsers.vue'
import Impressum from '@/routes/Impressum.vue'
import { ROLE_ADMIN } from '@/services/authSession'
export enum Visibility {
Hidden,
Authenticated,
Unauthenticated,
Authorized,
Public,
Footer,
Route,
}
export interface LayoutRoute {
path: string
name: string
description: string
icon: string
disableFooter?: boolean
visible: Visibility
visibilityRoute?: string | string[]
requiredRoles?: string[]
meta?: RouteRecordRaw
}
/**
* Kurzanleitung fuer Sidebar-Sichtbarkeit:
* - `Visibility.Public`: Eintrag ist immer in der Sidebar sichtbar.
* - `Visibility.Route`: Eintrag ist nur sichtbar, wenn die aktuelle URL im angegebenen Bereich liegt.
* - Ohne `visibilityRoute` wird automatisch `path` als Bereich verwendet.
* - Szenario 1: `path: '/dash'` -> sichtbar bei `/dash` und `/dash/*`.
* - Szenario 2: `visibilityRoute: '/admin'` -> Eintrag wird nur im Admin-Bereich gezeigt.
* - Szenario 3: `visibilityRoute: ['/dash', '/projects']` -> sichtbar in beiden Bereichen.
* - `Visibility.Footer` und `Visibility.Hidden`: nicht in der Sidebar sichtbar.
*/
export const routes: LayoutRoute[] = [
{
path: '/welcome',
name: 'Startseite',
description: 'Self-hosted Datei-Workspace für Hoard',
icon: 'mdi-home',
visible: Visibility.Unauthenticated,
meta: {
name: 'Home',
path: '/welcome',
component: Home,
},
},
{
path: '/',
name: 'Dashboard',
description: 'Geschützter Bereich für dein Konto',
icon: 'mdi-view-dashboard-outline',
visible: Visibility.Authenticated,
meta: {
name: 'Dashboard',
path: '/',
component: Dashboard,
meta: {
requiresAuth: true,
},
},
},
{
path: '/admin/users',
name: 'Benutzer',
description: 'Adminbereich für Benutzerverwaltung',
icon: 'mdi-shield-account-outline',
visible: Visibility.Authorized,
requiredRoles: [ROLE_ADMIN],
meta: {
name: 'AdminUsers',
path: '/admin/users',
component: AdminUsers,
meta: {
requiresAuth: true,
requiredRoles: [ROLE_ADMIN],
},
},
},
{
path: '/login',
name: 'Login',
description: 'Logge dich ein',
icon: 'mdi-login',
visible: Visibility.Unauthenticated,
meta: {
path: '/login',
name: 'Login',
component: Login,
meta: {
guestOnly: true,
},
},
},
{
path: '/impressum',
name: 'Impressum',
description: 'Impressum der Anwendung',
icon: 'mdi-file-document',
visible: Visibility.Footer,
meta: {
path: '/impressum',
name: 'Impressum',
component: Impressum,
},
},
{
path: '/forbidden',
name: 'Kein Zugriff',
description: 'Du hast keine Berechtigung für diese Seite',
icon: 'mdi-alert-circle-outline',
visible: Visibility.Hidden,
meta: {
path: '/forbidden',
name: 'Forbidden',
component: Forbidden,
meta: {
requiresAuth: true,
},
},
},
{
path: '/notFound',
name: 'Nicht gefunden',
description: 'Diese Seite wurde nicht gefunden',
icon: 'mdi-information-outline',
visible: Visibility.Hidden,
meta: { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },
},
]