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 @@