diff --git a/back/src/Kyoo.Authentication/Models/DTO/PasswordResetRequest.cs b/back/src/Kyoo.Authentication/Models/DTO/PasswordResetRequest.cs new file mode 100644 index 00000000..b0cebb57 --- /dev/null +++ b/back/src/Kyoo.Authentication/Models/DTO/PasswordResetRequest.cs @@ -0,0 +1,38 @@ +// Kyoo - A portable and vast media library solution. +// Copyright (c) Kyoo. +// +// See AUTHORS.md and LICENSE file in the project root for full license information. +// +// Kyoo is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// Kyoo is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Kyoo. If not, see . + +using System.ComponentModel.DataAnnotations; + +namespace Kyoo.Authentication.Models.DTO; + +/// +/// A model only used on password resets. +/// +public class PasswordResetRequest +{ + /// + /// The old password + /// + public string OldPassword { get; set; } + + /// + /// The new password + /// + [MinLength(4, ErrorMessage = "The password must have at least {1} characters")] + public string NewPassword { get; set; } +} diff --git a/back/src/Kyoo.Authentication/Views/AuthApi.cs b/back/src/Kyoo.Authentication/Views/AuthApi.cs index 11d9ac46..9222066d 100644 --- a/back/src/Kyoo.Authentication/Views/AuthApi.cs +++ b/back/src/Kyoo.Authentication/Views/AuthApi.cs @@ -185,6 +185,31 @@ namespace Kyoo.Authentication.Views } } + /// + /// Reset your password + /// + /// + /// Change your password. + /// + /// The old and new password + /// Your account info. + /// The old password is invalid. + [HttpPost("password-reset")] + [UserOnly] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status403Forbidden, Type = typeof(RequestError))] + public async Task> ResetPassword([FromBody] PasswordResetRequest request) + { + User user = await _users.Get(User.GetIdOrThrow()); + if (!BCryptNet.Verify(request.OldPassword, user.Password)) + return Forbid(new RequestError("The old password is invalid.")); + return await _users.Patch(user.Id, (user) => + { + user.Password = BCryptNet.HashPassword(request.NewPassword); + return user; + }); + } + /// /// Get authenticated user. /// @@ -262,6 +287,8 @@ namespace Kyoo.Authentication.Views { if (patch.Id.HasValue && patch.Id != userId) throw new ArgumentException("Can't edit your user id."); + if (patch.ContainsKey(nameof(Abstractions.Models.User.Password))) + throw new ArgumentException("Can't edit your password via a PATCH. Use /auth/password-reset"); return await _users.Patch(userId, patch.Apply); } catch (ItemNotFoundException)