Introduce full admin user listing/detail endpoints and a forced password-change flow. Backend: make CurrentUserResponse.UserName nullable and add ToCurrentUserResponseAsync extension; AppUserController now exposes GET /auth/user (list) and GET /auth/user/{id} (detail) using UserManager and Admin-only policy; AuthController uses the new mapper and after successful password change clears MustChangePassword, updates UpdatedAt and persists changes (with error handling) before updating security stamp. Frontend: add admin users pages (list + detail), ChangePassword page and route, adminUsers and enhanced authSession services (typed responses, changePassword API, error mapping), router guard to redirect users with mustChangePassword=true to the change-password flow, and show success banner on login after password change. UI tweaks: separate admin section in sidebar, add password-change entries in account menu, footer sizing fixes, and various layout/UX improvements. These changes enable admin account management and enforce secure password updates across the app.
24 KiB
Projektübersicht – self-hosted Datei- und Markdown-App
Projektidee
Ich baue eine einfache self-hosted Web-App, die sich funktional zwischen Google Drive, Notion und Obsidian einordnet. Der Schwerpunkt liegt aber klar auf einer Google-Drive-artigen Oberfläche mit Dateien und Ordnern. Markdown-Dateien sollen direkt im Browser bearbeitet werden können, andere Dateien sollen gespeichert und – wenn möglich – als Vorschau angezeigt werden.
Ziel des Projekts
Das Projekt ist ein kleines, bewusst einfach gehaltenes Solo-Projekt neben meiner Ausbildung. Es soll mehrere Benutzer unterstützen, aber technisch und funktional schlank bleiben. Wichtig ist ein realistisches MVP, das sauber läuft und später erweitert werden kann.
Geplanter Tech-Stack
- Frontend: Vue 3
- Markdown-Editor: md-editor-v3
- Backend: ASP.NET Core mit C#
- Datenbank: PostgreSQL
- Dateispeicher: MinIO als S3-kompatibler Storage
- Authentifizierung: klassische Cookie-basierte Authentifizierung, keine JWTs
- Deployment: self-hosted Web-App auf meinem eigenen Server
Kernfunktionen für das MVP
- Login mit bestehenden Accounts
- Kein öffentliches Registrieren
- Ein initialer Admin-Account wird zuerst erstellt
- Weitere Benutzer werden später nur manuell durch den Admin angelegt
- Dateien und Ordner anlegen, hochladen und öffnen
- Durch Ordnerstrukturen navigieren
- Google-Drive-artige Hauptansicht mit Dateiliste und Vorschau
- Markdown-Dateien direkt im Browser bearbeiten
- PDFs und Bilder als Vorschau anzeigen
- Andere Dateien einfach speichern und bei Bedarf herunterladen oder öffnen
Was bewusst nicht Teil des MVP ist
- Keine Registrierung für normale Nutzer
- Kein Teilen oder Freigeben von Dateien
- Keine Suche
- Keine Versionierung oder Dateihistorie
- Keine Echtzeit-Zusammenarbeit
- Keine Desktop-App oder Mobile-App
- Keine komplizierte Rechteverwaltung
- Keine JWT-, OAuth- oder SSO-Lösung
Gewünschter Stil der Anwendung
Die Oberfläche soll sich eher an Google Drive orientieren als an Notion oder Obsidian. Wichtig sind Übersicht, einfache Navigation und ein klarer Fokus auf Dateien, Ordner, Vorschau und Bearbeitung. Die App soll schlicht, pragmatisch und gut allein umsetzbar sein.
Sprachregel für UI-Texte
- Umlaute sind ausdrücklich erwünscht (
ä,ö,ü,Ä,Ö,Ü). - Keine Umschreibungen mit
ae,oe,uein sichtbaren deutschen Texten.
Wie die App später wirken soll
Die Anwendung soll wie eine einfache Dateiverwaltung im Browser wirken. Man meldet sich an, sieht seine Ordner und Dateien, kann sich durch die Struktur klicken, PDFs und Bilder direkt ansehen und Markdown-Dateien öffnen und bearbeiten. Der Fokus liegt auf Einfachheit statt auf vielen Sonderfunktionen.
Technische Leitidee
Das Projekt soll möglichst einfach aufgebaut werden. Dateimetadaten liegen in PostgreSQL, die eigentlichen Dateien in MinIO. Das Backend verwaltet Login, Benutzer, Ordner, Dateien und Vorschau-Informationen. Das Frontend bildet hauptsächlich die Dateiverwaltung, Vorschau und Markdown-Bearbeitung ab. Die gesamte Architektur soll bewusst schlank bleiben, damit sie für ein Solo-Projekt realistisch ist.
Projektbeschreibung für eine KI
Ich baue alleine neben meiner Ausbildung eine einfache self-hosted Web-App für mehrere Benutzer. Die App kombiniert eine Google-Drive-artige Dateiverwaltung mit einfacher Markdown-Bearbeitung. Benutzer sollen durch Ordner und Dateien navigieren können, Bilder und PDFs in einer Vorschau sehen und Markdown-Dateien direkt im Browser bearbeiten. Es gibt keine öffentliche Registrierung, kein Teilen, keine Suche und keine Versionierung. Benutzerkonten werden manuell angelegt, beginnend mit einem initialen Admin-Account. Der Tech-Stack besteht aus Vue 3 im Frontend, md-editor-v3 als Markdown-Editor, ASP.NET Core mit C# im Backend, PostgreSQL für Metadaten, MinIO als S3-kompatiblen Dateispeicher und Cookie-basierter Authentifizierung.
Frontend-Designquelle (Style Guide)
- Es gibt einen zentralen Design-Guide unter
GUI/style.md. - Dieser Guide definiert die visuelle Richtung für Hoard: light-first, dateiorientiert, ruhige Flächen, gezielte Verwendung von Grün als Markenfarbe.
- Enthalten sind Farbpalette, Typografie, Spacing, Border-Radien, Schatten, Komponentenregeln und Interaktionsprinzipien.
Angelegte globale CSS-Basis
- Statt
app.csswurde eine zentrale globale DateiGUI/src/global.cssangelegt und verwendet. - Diese Datei wird in
GUI/src/main.tsüberimport './global.css'eingebunden. - Zusätzlich wurden modulare globale CSS-Dateien angelegt:
GUI/src/styles/global/page-layouts.cssundGUI/src/styles/global/surface-patterns.css. - Beide Module werden ebenfalls zentral in
GUI/src/main.tseingebunden und bündeln wiederkehrende Layout-/Surface-Patterns. - Inhaltlich stellt
global.cssbereit:- Design-Tokens als CSS-Variablen (
:root) für Farben, Spacing, Radius, Schatten, Typografie und Statusfarben. - Globale Basisstile für
html,body, Links, Überschriften, Fokuszustände und Scrollbars. - Vuetify-nahe globale Anpassungen für App-Shell und Standardkomponenten (Topbar, Sidebar, Cards, Buttons, Inputs, Tabellen).
- Wiederverwendbare Utility-/Pattern-Klassen für Hoard-Seiten, z. B.
hoard-panel,hoard-toolbar,hoard-list-row,hoard-empty-state,hoard-status. - Responsive Verhalten für kleinere Viewports per Media Query.
- Design-Tokens als CSS-Variablen (
Anleitung: CSS-Patterns verwenden
- Neue Seiten standardmäßig mit
hoard-pageaufbauen; für zentrierte Vollhöhen-Ansichten zusätzlichhoard-page--centered. - Karten-/Shell-Container als
hoard-shell-grid hoard-panelverwenden; Breite/Abstände pro Seite über CSS-Variablen setzen (--hoard-shell-width,--hoard-shell-gap,--hoard-shell-padding). - Wiederkehrende Headlines/Kicker mit
hoard-kickernutzen, Varianten bei Bedarf mithoard-kicker--wideoderhoard-kicker--xs. - Button-/Link-Aktionszeilen mit
hoard-action-rowbauen statt pro Seite eigene Flex-Definitionen zu duplizieren. - Gradient-Flächen über
hoard-panel-gradient+ Variablen steuern (--hoard-gradient-angle,--hoard-gradient-start,--hoard-gradient-end,--hoard-gradient-end-stop), nicht pro Seite komplett neu definieren. - Lokales
scopedCSS nur für wirklich seitenspezifische Styles verwenden; alles Wiederverwendbare zuerst inGUI/src/styles/global/page-layouts.cssoderGUI/src/styles/global/surface-patterns.cssergänzen.
Aktueller Stand
GUI/src/Layout.vuebildet die zentrale App-Shell mit Topbar, Sidebar, Footer, Routen-Kontext und responsivem Drawer-Verhalten.- Darkmode (
light/dark) ist global integriert (Toggle in der Topbar, Persistenz inlocalStorage, Theme-Tokens in CSS/Vuetify). - Öffentliche Kernseiten sind im einheitlichen Hoard-Stil umgesetzt:
Home.vue(Landingpage),Login.vue,404NotFound.vue,Impressum.vue. - Das Topbar-Branding nutzt das App-Icon aus
GUI/src/assets/images/icon.svg. - Globale CSS-Struktur ist aktiv:
GUI/src/global.css(Tokens/Basis) sowieGUI/src/styles/global/page-layouts.cssundGUI/src/styles/global/surface-patterns.cssfür wiederverwendbare Patterns. - Sidebar-Sichtbarkeit unterstützt
Visibility.Routemit optionalemvisibilityRouteinGUI/src/plugins/routesLayout.ts. - Mobile-Touch-Optimierung ist für alle aktuellen öffentlichen Oberflächen aktiv (Shell, Home, Login, Impressum, 404), inklusive Safe-Area-Unterstützung.
- Desktop-Ansicht bleibt unverändert, da alle neuen Anpassungen ausschließlich in mobilen Breakpoints (
<= 960px, Feinschliff<= 600px) umgesetzt sind. - Backend-API enthält aktuell Basis-Endpunkte für Health (
GET /api/health) und Auth (POST /auth/login,POST /auth/logout,GET /auth/me). - Swagger/OpenAPI ist im Backend nur im Development-Modus aktiv (
/swagger). - Frontend-Build (
npm run buildimGUI-Projekt) schreibt direkt nachAPI/wwwroot; das Backend liefert die SPA und statische Assets aus. - Backend nutzt jetzt PostgreSQL über
ConnectionStrings:Postgresmit EF Core (ApplicationDbContext) und führt Migrationen beim Start automatisch aus. - Backend nutzt ASP.NET Identity mit
AppUser(Guid-Key,IsActive,MustChangePassword,CreatedAt,UpdatedAt) über PostgreSQL; Admin-Rechte laufen über Rollen (admin) statt User-Flag. ApplicationDbContextbasiert aufIdentityDbContext; Identity-Tabellen sind aufUsers,Roles,UserRoles,UserClaims,UserLogins,RoleClaimsundUserTokensgemappt.- Migration
InitIdentity(API/Migrations/20260418192723_InitIdentity.cs) erstellt das Identity-Schema und wird beim Start automatisch angewendet. - Temporäre Test-Entity und Test-CRUD-Endpunkt (
api/test-items) wurden wieder entfernt. - Nach den Migrationen wird per
IdentitySeedServicedie Rolleadminsichergestellt und einem initialen Admin-Account zugewiesen, falls noch kein Admin in dieser Rolle existiert. - Für lokale Entwicklung liegt unter
API/Dev/docker-compose.ymlein Stack mit PostgreSQL (localhost:5432) und pgAdmin (localhost:5050). - API lädt optional
API/appsettings.custom.json; wenn vorhanden, überschreibt sie Werte ausappsettings.json. API/appsettings.custom.jsonist in.gitignorehinterlegt, damit lokale Konfigurationswerte nicht versehentlich committed werden.- Backend-Logging ist aktiviert mit strukturierter Console-Ausgabe (inkl. Zeitstempel) sowie HTTP-Request-Logging.
- Beim Identity-Seeding wird explizit geloggt, wenn ein Admin-Account neu angelegt wurde.
- Frontend-Auth ist jetzt aktiv: Login-Form (
GUI/src/routes/authentication/Login.vue) sendet anPOST /auth/loginund zeigt API-Fehler als sichtbare Meldung. - Dashboard ist als geschützte Route auf
/umgesetzt (GUI/src/routes/dashboard/Dashboard.vue) und zeigt die Antwort vonGET /auth/me. - Router-Guards in
GUI/src/router/index.tsleiten nicht eingeloggte Nutzer von geschützten Routen auf/loginum und leiten eingeloggte Nutzer von/loginzurück aufs Dashboard. - Öffentliche Landingpage wurde auf
/welcomeverschoben;404- und Impressum-Links zur Startseite zeigen entsprechend auf/welcome. - Sidebar-Navigation berücksichtigt Auth-Status differenziert:
Startseitewird nur unangemeldet angezeigt (inkl. unterem Drawer-Link),Dashnur angemeldet. - Topbar zeigt bei aktiver Anmeldung den Benutzernamen; die Abmelden-Aktion erscheint im Hover-Menü unter dem Benutzernamen (Desktop) bzw. im Account-Menü (Mobile).
- Fehler werden jetzt global über einen Banner-Stack am unteren Seitenrand angezeigt (routeübergreifend, stapelbar, manuell schließbar).
- Der globale Banner-Stack im Layout nutzt einen kontrollierten
z-indexund opake Hintergründe, damit Fehlermeldungen im Vordergrund bleiben und kaum durchscheinende Inhalte zeigen. - Klick auf Logo/Branding in der Topbar führt abhängig vom Auth-Status: angemeldet auf
Dashboard, unangemeldet aufWelcome. - 404-Seite löst den Auth-Status auf und leitet automatisch weiter: angemeldet zu
Dashboard, unangemeldet zuWelcome; primärer CTA ist entsprechend dynamisch. - Brand-Klick ist gegen Auth-Timing abgesichert: bei vorhandener Session führt Logo/Titel auch bei noch nicht synchronisiertem Layout-Status zuverlässig auf
Dashboard. - Admin-Benutzerverwaltung zeigt jetzt echte Kontodaten:
/admin/userslädt die Benutzerliste ausGET /auth/user,/admin/users/:userIdzeigt read-only Details ausGET /auth/user/{id}. - Der Router erzwingt Passwortwechsel global: bei
mustChangePassword=trueerfolgt vor normaler Navigation ein Redirect auf/password/change; nach erfolgreicher Änderung führt der Flow auf Login zurück. - Im Account-Menü der Topbar gibt es jetzt zusätzlich zur Abmeldung einen direkten Einstieg auf
Passwort ändern(Desktop und Mobile). - Sidebar-Navigation trennt adminpflichtige Seiten jetzt in einem eigenen Abschnitt
Admin(gleicher grüner Kicker-Stil wieNavigation), sodass z. B.Benutzernicht mehr direkt neben dem Dashboard steht.
Änderungen durch Codex
- Grundlegender UI-Neuaufbau der App-Shell (
GUI/src/Layout.vue) inklusive Navigation, Footer und Seitenkontext. - Einführung eines globalen Theme-Managements (
light/dark) überGUI/src/plugins/vuetify.ts,GUI/src/global.cssundlocalStorage. - Überarbeitung der zentralen öffentlichen Seiten (
Home.vue,Login.vue,404NotFound.vue,Impressum.vue) auf ein einheitliches Hoard-Design. - Erweiterung von
GUI/src/plugins/routesLayout.tsum routeabhängige Sidebar-Sichtbarkeit (Visibility.Route,visibilityRoute). - Konsolidierung der UI-Texte auf deutsche Umlaute gemäß Sprachregel.
- Aufbau und fortlaufende Konsolidierung der globalen CSS-Basis (
global.css) inkl. Fokus-/Auswahl-Polish. - CSS-Debloat-Refactor: gemeinsame Oberflächen-Patterns in
GUI/src/styles/global/page-layouts.cssundGUI/src/styles/global/surface-patterns.cssausgelagert und zentral inGUI/src/main.tseingebunden. codexInfo.mdum eine kompakte Nutzunganleitung für die globalen CSS-Patterns ergänzt.- Mobile-Usability über globale Styles erweitert: größere Touch-Ziele (
v-btn, Navigationspunkte), Safe-Area-Paddings und mobile Spacing-Feinschliff inGUI/src/global.csssowie den globalen Pattern-Dateien. GUI/src/Layout.vuefür Mobile optimiert: entzerrte App-Bar-Abstände, touchfreundlicher Bottom-Sheet-Drawer und besser bedienbarer Footer auf kleinen Viewports.- Mobile-spezifische Detailoptimierungen in
Home.vue,Login.vue,Impressum.vueund404NotFound.vueergänzt (Actions, Card-/Form-Spacing, CTA-Stacking), ohne Desktop-Basislayout zu verändern. GUI/style.mdum einen verbindlichen Abschnitt „Umsetzungsstandard Responsivität“ ergänzt (Breakpoints, Touch-Zielgrößen, Safe-Area, globale Pattern-Nutzung, QA-Checkliste), damit Folgeaufgaben denselben Stil beibehalten.- Topbar-Kontext in
GUI/src/Layout.vuefür schmalere Breiten beruhigt: auf Mobile wird der Seitenkontext komplett ausgeblendet, auf mittleren Breiten bleibt nur der Seitentitel (ohne Unterzeile), damit das Header-Layout sauber und nicht gequetscht wirkt. - Backend-Template-Code bereinigt:
WeatherForecastControllerundWeatherForecastentfernt, OpenAPI-Templatepaket ausAPI/API.csprojentfernt. - Neuen Test-Controller
API/Controllers/HealthController.csangelegt (GET /api/health), der200 OKzurückgibt. GUI/vite.config.tsBuild-Ausgabe aufAPI/wwwrootumgestellt (outDir) und Bereinigung des Zielordners beim Build aktiviert (emptyOutDir: true).API/Program.cserweitert, damit statische Dateien auswwwrootinkl. SPA-Fallback (index.html) ausgeliefert werden.- SPA-Fallback im Backend aufgeteilt: Frontend-Routen liefern
index.html, unbekannte/api/*-Routen bleiben korrekt404statt auf die SPA zu fallen. - Swagger im Backend ergänzt:
Swashbuckle.AspNetCoreeingebunden, Services registriert und UI nur inDevelopmentaktiviert. - PostgreSQL-Integration im Backend umgesetzt:
Npgsql.EntityFrameworkCore.PostgreSQL+Microsoft.EntityFrameworkCore.DesigninAPI/API.csprojergänzt und Connection StringConnectionStrings:Postgresin den Settings hinterlegt. API/Database/ApplicationDbContext.csmit Test-EntityAPI/Models/Test/TestItem.csangelegt; erste Migrationen inAPI/Migrationserstellt.API/Program.csumAddDbContext(Postgres) undDatabase.Migrate()beim Start erweitert, damit Migrationen automatisch angewendet werden.API/Controllers/TestItemsController.csals einfacher CRUD-Testcontroller (GET/POST/PUT/DELETE) unterapi/test-itemsergänzt.- Dev-Stack für lokale Datenbankarbeit ergänzt:
API/Dev/docker-compose.ymlstartet PostgreSQL + pgAdmin. API/Program.csso erweitert, dass optionalappsettings.custom.jsongeladen wird und bei vorhandener Datei bevorzugte lokale Overrides möglich sind.- Neue lokale Konfigurationsdatei
API/appsettings.custom.jsonaus der bisherigenappsettings.jsonangelegt und in.gitignoreergänzt. - Test-Datentyp und Test-API wieder entfernt:
API/Models/Test/TestItem.csundAPI/Controllers/TestItemsController.csgelöscht,ApplicationDbContextbereinigt. - Neue Migration
RemoveTestItemserstellt (API/Migrations/20260418153650_RemoveTestItems.cs), die Tabelletest_itemsentfernt und den Snapshot aktualisiert. API/API.csprojumMicrosoft.AspNetCore.Identity.EntityFrameworkCoreergänzt undMicrosoft.EntityFrameworkCore.Designauf10.0.6angehoben.- ASP.NET Identity eingeführt:
API/Models/AppUser.csangelegt undAPI/Database/ApplicationDbContext.csaufIdentityDbContext<AppUser, IdentityRole<Guid>, Guid>umgestellt. API/Database/Configurations/AppUserConfiguration.csergänzt, damitAppUseraufUsersliegt und projektspezifische Pflichtfelder sauber konfiguriert sind.- Migration
InitIdentityergänzt (API/Migrations/20260418192723_InitIdentity.cs+ Designer + Snapshot-Update) für User-/Role-/Claim-Tabellen. - Auth-Basis implementiert: DTOs unter
API/Contracts/Auth/*undAPI/Controllers/Auth/AuthController.csmitPOST /auth/login,POST /auth/logout,GET /auth/me. API/Program.csum Identity-Service-Registrierung, Cookie-Konfiguration (hoard.auth),UseAuthentication/UseAuthorizationund Startup-Seeding erweitert.- Backend-Logging in
API/Program.csergänzt:AddSimpleConsole(Zeitstempel, Single-Line),AddDebugundAddHttpLogging/UseHttpLoggingfür Request-Logs. API/Services/IdentitySeedService.csneu ergänzt: erstellt beim ersten Start einen initialen Admin ausSeedAdmin:*und loggt Erfolg/Fehler nachvollziehbar.- Neues Frontend-Auth-Modul
GUI/src/services/authSession.tsergänzt (Login-Request, Session-Abfrage via/auth/me, Fehler-Mapping und Session-Cache). - Routing für Auth ergänzt: neue geschützte Dashboard-Route (
/) mitmeta.requiresAuth, Login alsguestOnlyund globaler Guard inGUI/src/router/index.ts. - Neue Seite
GUI/src/routes/dashboard/Dashboard.vueergänzt, die die/auth/me-Nutzerdaten anzeigt. GUI/src/routes/authentication/Login.vuevon statischer Maske auf echten Login-Flow mit Loading-State, Fehlermeldung und Redirect nach erfolgreicher Anmeldung umgestellt.- Öffentliche Home/Landing-Route auf
/welcomeverschoben und Navigation inLayout.vue,404NotFound.vueundImpressum.vueentsprechend angepasst. GUI/src/services/authSession.tsumlogout()fürPOST /auth/logoutergänzt; Session-Cache wird beim Abmelden zuverlässig geleert.GUI/src/plugins/routesLayout.tsangepasst: Dashboard-Navigationseintrag alsDashmitVisibility.Authenticatedund Reihenfolge hinterStartseite.GUI/src/Layout.vueerweitert: Sidebar filtert jetzt auchVisibility.Authenticated/Visibility.Unauthenticated, zeigt Trennlinie vor Auth-Einträgen, Topbar zeigt Benutzernamen bei Login und bietet Abmelden (Desktop + Mobile) inkl. Fehler-Snackbar.GUI/src/plugins/routesLayout.tsweiter angepasst:Startseitenutzt jetztVisibility.Unauthenticated, damit sie in der Sidebar nach Login nicht mehr auswählbar ist.GUI/src/Layout.vueTopbar angepasst: separater Logout-Button entfernt; Logout ist jetzt als Menüpunkt unter dem Benutzernamen verfügbar (open-on-hoverauf Desktop, Menü auf Mobile).GUI/src/routes/authentication/Login.vueum Alert-Polish ergänzt: Fehler-Alert nutzt eigene Klasse mit stabiler Mindesthöhe und erhöhter Zeilenhöhe, damit Meldungen vollständig sichtbar sind.- Neuer Store
GUI/src/stores/appBanners.tsergänzt: globale Meldungen können aus jeder Seite perpush/pushErrorhinzugefügt und einzeln geschlossen werden. GUI/src/Layout.vueauf globalen Banner-Stack umgestellt: mehrere Meldungen werden unten rechts gestapelt angezeigt und bleiben beim Navigieren erhalten.GUI/src/routes/authentication/Login.vuevon lokalem Inline-Fehler-Alert auf globale Banner-Meldungen umgestellt.GUI/src/Layout.vueBanner-Polish: Banner-Hintergründe je Typ explizit opak getönt, Overlay-/Underlay-Transparenz deaktiviert undz-indexauf2100zurückgesetzt.GUI/src/Layout.vueBrand-Navigation ergänzt: Logo/Titel-Button nutzt jetztnavigateToBrandTarget()und leitet eingeloggte Nutzer aufDashboard, sonst aufHome(/welcome).GUI/src/routes/404NotFound.vueangepasst: primärer CTA zeigt jetztZum Dashboard(RouteDashboard), Text aktualisiert undnavigateBack()fällt ohne History ebenfalls aufDashboardzurück.GUI/src/Layout.vueBrand-Navigation nachgeschärft:navigateToBrandTarget()löst bei Klick zuerst die Session viafetchCurrentUser()auf (falls lokal nochnull) und verhindert dadurch Fehlnavigation aufWelcome; Mobile-Account-Menütext aufZum Dashboardvereinheitlicht.- Neuer globaler Skill
codexinfo-komprimierenunterC:/Users/famil/.codex/skills/codexinfo-komprimierenerstellt; er liestcodexInfo.md, verdichtetÄnderungen durch Codexauf drei Kernzeilen und enthält ein Hilfsskript zum robusten Abschnitts-Update. GUI/src/routes/404NotFound.vueerweitert: Seite ermittelt beim Laden den Login-Status überfetchCurrentUser(), setzt CTA/Icon dynamisch aufZum DashboardoderZur Startseiteund leitet nach kurzer Verzögerung automatisch auf das passende Ziel weiter.- Rollenbasiertes Auth-Modell umgesetzt:
IsAdminausAppUser/Konfiguration entfernt, neue Rolle-Konstanteadmineingeführt und Admin-Prüfungen auf Policy/Rollen (API/Security/*,Authorize(Policy = admin-only)) umgestellt. - Neue Migration
ReplaceIsAdminWithRoles(API/Migrations/20260420174609_ReplaceIsAdminWithRoles.cs) ergänzt: migriert bestehendeUsers.IsAdmin = trueidempotent inUserRoles(admin) und entfernt anschließend die SpalteIsAdmin. GET /auth/meliefert jetztroles: string[]stattisAdmin;GUI/src/services/authSession.tswurde auf Rollen normalisiert und umhasRole()ergänzt.- Frontend-Autorisierung erweitert: Router unterstützt
meta.requiredRoles, neue 403-SeiteGUI/src/routes/Forbidden.vueund admin-spezifische RouteGUI/src/routes/admin/AdminUsers.vuewerden nur für Rolleadminzugänglich/angezeigt. API/Controllers/Auth/AppUserController.cserweitert:GET /auth/userliefert jetzt die Admin-Benutzerliste alsCurrentUserResponse[]; zusätzlich ergänzt umGET /auth/user/{id}für read-only Detailabfragen.API/Controllers/Auth/AuthController.cs(POST /auth/password) nachgeschärft: setzt nach erfolgreicher ÄnderungMustChangePassword=false, aktualisiertUpdatedAt, invalidiert Sessions via Security-Stamp und meldet anschließend ab.- Neue Frontend-Services:
GUI/src/services/adminUsers.ts(typed Admin-User-Liste + Detail) undGUI/src/services/authSession.tsum typedchangePassword()mit Fehler-Mapping (message+ Validation-errors) erweitert. - Admin-UI ausgebaut:
GUI/src/routes/admin/AdminUsers.vuezeigt die Benutzerliste mit den MVP-Werten (Benutzername, Rollen, Aktiv-Status, Passwortwechselpflicht) und Navigation zur neuen DetailseiteGUI/src/routes/admin/AdminUserDetail.vue. - Passwort-Änderungsflow ergänzt: neue Route/Seite
GUI/src/routes/authentication/ChangePassword.vue, globaler Guard inGUI/src/router/index.tsfür erzwungenen Redirect und Login-Erfolgshinweis nach Passwortwechsel inGUI/src/routes/authentication/Login.vue. - User-Mapping zentralisiert: neue Extension
API/Contracts/Auth/CurrentUserResponseExtensions.cs(ToCurrentUserResponseAsync), genutzt inAPI/Controllers/Auth/AppUserController.csundAPI/Controllers/Auth/AuthController.cs(GET /auth/me) statt lokaler Mapper-Methode. - Footer-Höhe im Shell-Layout begrenzt:
GUI/src/Layout.vuesetzt für.hoard-footerjetztmax-heightsowie feste Flex-/Height-Regeln, damit der Footer bei kurzen Seiten nicht ungewollt „aufbläht“. - Sidebar-Struktur in
GUI/src/Layout.vuenachgezogen: primäre Navigation und adminpflichtige Navigation werden getrennt gerendert; bei vorhandenen Admin-Routen erscheint ein separater AbschnittstitelAdminmit eigenem Trenner. - Passwort-Ändern-Form (
GUI/src/routes/authentication/ChangePassword.vue) visuell gegliedert: zwischen altem Passwort und den beiden neuen Passwortfeldern trennt jetzt ein Divider mit AbschnittslabelNeues Passwort.