ForgotPassword

This commit is contained in:
Loretta 2024-08-02 17:58:19 +02:00
parent 30c0e69144
commit 4cd37c39df
9 changed files with 105 additions and 28 deletions

View File

@ -55,5 +55,7 @@
DisableAddUser = 44,
PhoneNumberFormatIsNotValid = 45,
RefreshTokenUpdateError = 50,
EmailIsNullOrEmpty = 55,
}
}

View File

@ -1,4 +1,5 @@
using System.Net;
using AyCode.Core.Consts;
using AyCode.Interfaces.Addresses;
using AyCode.Interfaces.Logins;
using AyCode.Interfaces.Profiles;
@ -21,4 +22,6 @@ public interface IAcLoginServiceServer<TResultLoggedInModel, TUser, TUserToken,
public TResultLoggedInModel Login(string? email, string password);
public Task<TResultLoggedInModel> LoginAsync(string? email, string password);
public AcErrorCode UpdatePassword(TUser user, string password);
}

View File

@ -23,4 +23,7 @@ public interface IAcLoginServiceCommon<TUser, TProfile, TCompany, TUserToService
public AcErrorCode ChangePassword(Guid userId, string oldPassword, string newPassword);
public Task<AcErrorCode> ChangePasswordAsync(Guid userId, string oldPassword, string newPassword);
public AcErrorCode ForgotPassword(string email, string newPassword);
public Task<AcErrorCode> ForgotPasswordAsync(string email, string newPassword);
}

View File

@ -6,19 +6,18 @@ using System.Threading.Tasks;
namespace AyCode.Models.Users
{
public abstract class AcChangePasswordDto
public abstract class AcChangePasswordDto : AcPasswordDtoBase
{
public Guid UserId { get; set; }
public string OldPassword { get; set; }
public string NewPassword { get; set; }
protected AcChangePasswordDto() { }
protected AcChangePasswordDto() : base()
{ }
protected AcChangePasswordDto(Guid userId, string oldPassword, string newPassword) : this()
protected AcChangePasswordDto(Guid userId, string oldPassword, string newPassword) : base(newPassword)
{
UserId = userId;
OldPassword = oldPassword;
NewPassword = newPassword;
}
}
}

View File

@ -0,0 +1,14 @@
namespace AyCode.Models.Users;
public abstract class AcForgotPasswordDto : AcPasswordDtoBase
{
public string Email { get; set; }
protected AcForgotPasswordDto() : base()
{ }
protected AcForgotPasswordDto(string email, string newPassword) : base(newPassword)
{
Email = email;
}
}

View File

@ -0,0 +1,13 @@
namespace AyCode.Models.Users;
public abstract class AcPasswordDtoBase
{
public string NewPassword { get; set; }
protected AcPasswordDtoBase() { }
protected AcPasswordDtoBase(string newPassword) : this()
{
NewPassword = newPassword;
}
}

View File

@ -101,32 +101,38 @@ namespace AyCode.Services.Server.Tests.LoginServices
}
[DataTestMethod]
[DataRow(["", "", "", ""])]
public virtual void AcBase_ChangePassword_ReturnUser_WhenUserLoggedInWithNewPassword(string[] userIdOldPasswordNewPasswordDbBackupHashStrings)
[DataRow(["", "", ""])]
public virtual void AcBase_ChangePassword_ReturnUser_WhenUserLoggedInWithNewPassword(string[] userIdOriginalPasswordNewPasswordStrings)
{
var userId = Guid.Parse(userIdOldPasswordNewPasswordDbBackupHashStrings[0]);
var oldPassword = userIdOldPasswordNewPasswordDbBackupHashStrings[1];
var newPassword = userIdOldPasswordNewPasswordDbBackupHashStrings[2];
var oldPasswordBackupHash = userIdOldPasswordNewPasswordDbBackupHashStrings[3];
var user = Dal.GetUserById(userId, false)!;
//Visszaállítjuk az eredeti jelszót... - J.
if (!PasswordHasher.VerifyPassword(oldPassword, user.Password, PasswordHasher.GenerateDynamicSalt(userId)))
{
user.Password = oldPasswordBackupHash;
Dal.UpdateUser(user);
}
var userId = Guid.Parse(userIdOriginalPasswordNewPasswordStrings[0]);
var originalPassword = userIdOriginalPasswordNewPasswordStrings[1];
var newPassword = userIdOriginalPasswordNewPasswordStrings[2];
var loginService = Activator.CreateInstance(typeof(TLoginServiceServer), Dal, AcEnv.AppConfiguration) as TLoginServiceServer;
Assert.IsNotNull(loginService);
var errorCode = loginService.ChangePassword(userId, oldPassword, newPassword);
var user = Dal.GetUserById(userId, false)!;
RestoreOriginalPassword(loginService, user, originalPassword);
var errorCode = loginService.ChangePassword(userId, originalPassword, newPassword);
Assert.IsTrue(errorCode == AcErrorCode.Unset, $"{errorCode}");
var loggedInModel = loginService.Login(user.EmailAddress, newPassword);
Assert.IsNotNull(loggedInModel);
Assert.IsTrue(loggedInModel.IsLoggedIn);
Assert.IsTrue(loggedInModel.LoggedInUser.Id == userId);
Assert.IsTrue(PasswordHasher.VerifyPassword(newPassword, loggedInModel.LoggedInUser.Password, PasswordHasher.GenerateDynamicSalt(userId)));
RestoreOriginalPassword(loginService, loggedInModel.LoggedInUser, originalPassword);
}
protected void RestoreOriginalPassword(TLoginServiceServer loginService, TUser user, string originalPassword)
{
if (PasswordHasher.VerifyPassword(originalPassword, user.Password, PasswordHasher.GenerateDynamicSalt(user.Id))) return;
loginService.UpdatePassword(user, originalPassword);
}
}
}

View File

@ -117,6 +117,10 @@ public class AcLoginServiceServer<TResultLoggedInModel, TDal, TDbContext, TUser,
public virtual Task<AcErrorCode> RegistrationAsync(Guid userId, string email, string password, string? phoneNumber = null, Guid? referralId = null)
=> TaskHelper.ToThreadPoolTask(() => Registration(userId, email, password, phoneNumber, referralId));
public virtual Task<AcErrorCode> ChangePasswordAsync(Guid userId, string oldPassword, string newPassword)
=> TaskHelper.ToThreadPoolTask(() => ChangePassword(userId, oldPassword, newPassword));
public virtual AcErrorCode ChangePassword(Guid userId, string oldPassword, string newPassword)
{
try
@ -127,11 +131,7 @@ public class AcLoginServiceServer<TResultLoggedInModel, TDal, TDbContext, TUser,
var user = userDal.GetUserById(userId, false); //TODO: csak az EmailConfirmed user password-öket lehessen change-elni! - J.
if (user == null) return AcErrorCode.EntityIsNull;
if (!PasswordHasher.VerifyPassword(oldPassword, user.Password, PasswordHasher.GenerateDynamicSalt(user.Id))) return AcErrorCode.WrongLoginData;
user.Password = PasswordHasher.HashPassword(newPassword, PasswordHasher.GenerateDynamicSalt(userId));
return userDal.UpdateUser(user) == null ? AcErrorCode.DatabaseError : AcErrorCode.Unset;
return PasswordHasher.VerifyPassword(oldPassword, user.Password, PasswordHasher.GenerateDynamicSalt(user.Id)) ? UpdatePassword(user, newPassword) : AcErrorCode.WrongLoginData;
}
catch (Exception)
{
@ -141,8 +141,35 @@ public class AcLoginServiceServer<TResultLoggedInModel, TDal, TDbContext, TUser,
return AcErrorCode.UnknownError;
}
public virtual Task<AcErrorCode> ChangePasswordAsync(Guid userId, string oldPassword, string newPassword)
=> TaskHelper.ToThreadPoolTask(() => ChangePassword(userId, oldPassword, newPassword));
public Task<AcErrorCode> ForgotPasswordAsync(string email, string newPassword)
=> TaskHelper.ToThreadPoolTask(() => ForgotPassword(email, newPassword));
public AcErrorCode ForgotPassword(string email, string newPassword)
{
try
{
if (email.IsNullOrEmpty()) return AcErrorCode.EmailIsNullOrEmpty;
if (!AcValidate.IsValidPasswordFormat(newPassword, out var errorCode)) return errorCode;
var user = userDal.GetUserByEmail(email, false);
return user == null ? AcErrorCode.EntityIsNull : UpdatePassword(user, newPassword);
}
catch (Exception)
{
// ignored
}
return AcErrorCode.UnknownError;
}
public AcErrorCode UpdatePassword(TUser user, string password)
{
user.Password = PasswordHasher.HashPassword(password, PasswordHasher.GenerateDynamicSalt(user.Id));
return userDal.UpdateUser(user) == null ? AcErrorCode.DatabaseError : AcErrorCode.Unset;
}
public virtual bool SendConfirmationToken(string? email, string confirmationToken)
{

View File

@ -66,4 +66,14 @@ public class AcLoginServiceClient<TUser, TProfile, TCompany, TUserToServiceProvi
{
throw new NotImplementedException();
}
public AcErrorCode ForgotPassword(string email, string newPassword)
{
throw new NotImplementedException();
}
public async Task<AcErrorCode> ForgotPasswordAsync(string email, string newPassword)
{
throw new NotImplementedException();
}
}