Add admin user management and password-change flow
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.
This commit is contained in:
@@ -112,6 +112,10 @@ Ich baue alleine neben meiner Ausbildung eine einfache self-hosted Web-App für
|
||||
- Klick auf Logo/Branding in der Topbar führt abhängig vom Auth-Status: angemeldet auf `Dashboard`, unangemeldet auf `Welcome`.
|
||||
- 404-Seite löst den Auth-Status auf und leitet automatisch weiter: angemeldet zu `Dashboard`, unangemeldet zu `Welcome`; 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/users` lädt die Benutzerliste aus `GET /auth/user`, `/admin/users/:userId` zeigt read-only Details aus `GET /auth/user/{id}`.
|
||||
- Der Router erzwingt Passwortwechsel global: bei `mustChangePassword=true` erfolgt 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 wie `Navigation`), sodass z. B. `Benutzer` nicht mehr direkt neben dem Dashboard steht.
|
||||
|
||||
## Änderungen durch Codex
|
||||
- Grundlegender UI-Neuaufbau der App-Shell (`GUI/src/Layout.vue`) inklusive Navigation, Footer und Seitenkontext.
|
||||
@@ -174,3 +178,12 @@ Ich baue alleine neben meiner Ausbildung eine einfache self-hosted Web-App für
|
||||
- Neue Migration `ReplaceIsAdminWithRoles` (`API/Migrations/20260420174609_ReplaceIsAdminWithRoles.cs`) ergänzt: migriert bestehende `Users.IsAdmin = true` idempotent in `UserRoles` (`admin`) und entfernt anschließend die Spalte `IsAdmin`.
|
||||
- `GET /auth/me` liefert jetzt `roles: string[]` statt `isAdmin`; `GUI/src/services/authSession.ts` wurde auf Rollen normalisiert und um `hasRole()` ergänzt.
|
||||
- Frontend-Autorisierung erweitert: Router unterstützt `meta.requiredRoles`, neue 403-Seite `GUI/src/routes/Forbidden.vue` und admin-spezifische Route `GUI/src/routes/admin/AdminUsers.vue` werden nur für Rolle `admin` zugänglich/angezeigt.
|
||||
- `API/Controllers/Auth/AppUserController.cs` erweitert: `GET /auth/user` liefert jetzt die Admin-Benutzerliste als `CurrentUserResponse[]`; zusätzlich ergänzt um `GET /auth/user/{id}` für read-only Detailabfragen.
|
||||
- `API/Controllers/Auth/AuthController.cs` (`POST /auth/password`) nachgeschärft: setzt nach erfolgreicher Änderung `MustChangePassword=false`, aktualisiert `UpdatedAt`, invalidiert Sessions via Security-Stamp und meldet anschließend ab.
|
||||
- Neue Frontend-Services: `GUI/src/services/adminUsers.ts` (typed Admin-User-Liste + Detail) und `GUI/src/services/authSession.ts` um typed `changePassword()` mit Fehler-Mapping (`message` + Validation-`errors`) erweitert.
|
||||
- Admin-UI ausgebaut: `GUI/src/routes/admin/AdminUsers.vue` zeigt die Benutzerliste mit den MVP-Werten (Benutzername, Rollen, Aktiv-Status, Passwortwechselpflicht) und Navigation zur neuen Detailseite `GUI/src/routes/admin/AdminUserDetail.vue`.
|
||||
- Passwort-Änderungsflow ergänzt: neue Route/Seite `GUI/src/routes/authentication/ChangePassword.vue`, globaler Guard in `GUI/src/router/index.ts` für erzwungenen Redirect und Login-Erfolgshinweis nach Passwortwechsel in `GUI/src/routes/authentication/Login.vue`.
|
||||
- User-Mapping zentralisiert: neue Extension `API/Contracts/Auth/CurrentUserResponseExtensions.cs` (`ToCurrentUserResponseAsync`), genutzt in `API/Controllers/Auth/AppUserController.cs` und `API/Controllers/Auth/AuthController.cs` (`GET /auth/me`) statt lokaler Mapper-Methode.
|
||||
- Footer-Höhe im Shell-Layout begrenzt: `GUI/src/Layout.vue` setzt für `.hoard-footer` jetzt `max-height` sowie feste Flex-/Height-Regeln, damit der Footer bei kurzen Seiten nicht ungewollt „aufbläht“.
|
||||
- Sidebar-Struktur in `GUI/src/Layout.vue` nachgezogen: primäre Navigation und adminpflichtige Navigation werden getrennt gerendert; bei vorhandenen Admin-Routen erscheint ein separater Abschnittstitel `Admin` mit 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 Abschnittslabel `Neues Passwort`.
|
||||
|
||||
Reference in New Issue
Block a user