From bd261b686891bba9a21bb2b34791fa5aa73249e0 Mon Sep 17 00:00:00 2001 From: Jonas <77726472+kobolol@users.noreply.github.com> Date: Mon, 20 Apr 2026 19:39:43 +0200 Subject: [PATCH] Add change-password API and dynamic 404 redirect Introduce ChangePasswordRequest DTO and a new ChangePassword endpoint in AuthController that validates input, changes the user's password via UserManager, updates the security stamp, signs out the user to invalidate sessions, and returns localized messages. Add a simple authorized AppUserController stub (GET /auth/user). Update the 404 view to resolve auth status via fetchCurrentUser, show a dynamic CTA/icon (Dashboard vs Home), auto-redirect after a short delay with proper timer cleanup, and adjust navigation behavior. Update codexInfo.md to document the 404 behavior change. --- API/Contracts/Auth/ChangePasswordRequest.cs | 14 +++++ API/Controllers/Auth/AppUserController.cs | 18 ++++++ API/Controllers/Auth/AuthController.cs | 48 +++++++++++++- GUI/src/routes/404NotFound.vue | 69 +++++++++++++++++++-- codexInfo.md | 3 +- 5 files changed, 146 insertions(+), 6 deletions(-) create mode 100644 API/Contracts/Auth/ChangePasswordRequest.cs create mode 100644 API/Controllers/Auth/AppUserController.cs diff --git a/API/Contracts/Auth/ChangePasswordRequest.cs b/API/Contracts/Auth/ChangePasswordRequest.cs new file mode 100644 index 0000000..ddeae4f --- /dev/null +++ b/API/Contracts/Auth/ChangePasswordRequest.cs @@ -0,0 +1,14 @@ +using System.ComponentModel.DataAnnotations; + +namespace API.Contracts.Auth +{ + public class ChangePasswordRequest + { + [Required] + public string OldPassword { get; set; } = string.Empty; + [Required] + public string NewPassword { get; set; } = string.Empty; + [Required] + public string NewPasswordConfirm { get; set; } = string.Empty; + } +} diff --git a/API/Controllers/Auth/AppUserController.cs b/API/Controllers/Auth/AppUserController.cs new file mode 100644 index 0000000..df8f95b --- /dev/null +++ b/API/Controllers/Auth/AppUserController.cs @@ -0,0 +1,18 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; + +namespace API.Controllers.Auth +{ + [ApiController] + [Route("auth/user")] + public class AppUserController : ControllerBase + { + [HttpGet] + [Authorize] + public async Task GetAppUsers() + { + return Ok(); + } + } +} diff --git a/API/Controllers/Auth/AuthController.cs b/API/Controllers/Auth/AuthController.cs index 3e0ce89..8884b47 100644 --- a/API/Controllers/Auth/AuthController.cs +++ b/API/Controllers/Auth/AuthController.cs @@ -67,5 +67,51 @@ namespace API.Controllers.Auth MustChangePassword = user.MustChangePassword }); } + + [HttpPost("password")] + [Authorize] + public async Task ChangePassword([FromBody] ChangePasswordRequest pwChangeDto) + { + var user = await userManager.GetUserAsync(User); + if (user is null) + return Unauthorized(); + + if (string.IsNullOrWhiteSpace(pwChangeDto.NewPassword) || + string.IsNullOrWhiteSpace(pwChangeDto.OldPassword) || + string.IsNullOrWhiteSpace(pwChangeDto.NewPasswordConfirm)) + { + return BadRequest(new { message = "Alle Passwörter müssen einen Wert enthalten." }); + } + + if (pwChangeDto.NewPassword != pwChangeDto.NewPasswordConfirm) + { + return BadRequest(new { message = "Die neuen Passwörter stimmen nicht überein." }); + } + + var result = await userManager.ChangePasswordAsync( + user, + pwChangeDto.OldPassword, + pwChangeDto.NewPassword + ); + + if (!result.Succeeded) + { + return BadRequest(new + { + message = "Passwort konnte nicht geändert werden.", + errors = result.Errors.Select(e => e.Description) + }); + } + + var stampResult = await userManager.UpdateSecurityStampAsync(user); + if (!stampResult.Succeeded) + { + return StatusCode(500, new { message = "Passwort geändert, aber Sessions konnten nicht invalidiert werden." }); + } + + await signInManager.SignOutAsync(); + + return Ok(new { message = "Passwort geändert. Du wurdest auf allen Geräten abgemeldet." }); + } } -} +} \ No newline at end of file diff --git a/GUI/src/routes/404NotFound.vue b/GUI/src/routes/404NotFound.vue index 11b82e5..19c36f9 100644 --- a/GUI/src/routes/404NotFound.vue +++ b/GUI/src/routes/404NotFound.vue @@ -1,18 +1,74 @@