b2984fcf1a
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.
140 lines
3.5 KiB
TypeScript
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 },
|
|
},
|
|
]
|