test(auth): move the password-policy reset case onto hashed, attempt-counted codes

This commit is contained in:
Alexandre Brandizzi 2026-09-25 13:46:37 -03:00
parent 9bd22e9a74
commit ea1370847f

View file

@ -9,6 +9,7 @@ using Moq;
using SeaHaven.DataServices.Interfaces;
using SeaHaven.Services.Configuration;
using SeaHaven.Services.DTOs;
using SeaHaven.Services.Helpers;
using SeaHaven.Services.Implementation;
using SeaHaven.Services.Interfaces;
using Xunit;
@ -132,7 +133,8 @@ public sealed class PasswordPolicyTests : IAsyncDisposable
Microsoft.Extensions.Options.Options.Create(new JwtOptions { Secret = new string('x', 64) }),
Mock.Of<IUserDataService>(),
Mock.Of<IForgetPasswordDataService>(),
Mock.Of<IEmailSender>());
Mock.Of<IEmailSender>(),
TimeProvider.System);
var result = await service.ChangePasswordAsync(user.Id, CurrentPassword, "Next2@x", CancellationToken.None);
@ -169,10 +171,19 @@ public sealed class PasswordPolicyTests : IAsyncDisposable
{
var user = await CreateUserAsync();
var forget = new Mock<IForgetPasswordDataService>();
forget.Setup(f => f.ExistsByEmailAndCodeAsync(user.Email!, "123456", It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
var salt = PasswordResetCodeSecrets.NewSalt();
forget.Setup(f => f.GetByEmailAsync(user.Email!, It.IsAny<CancellationToken>()))
.ReturnsAsync(new ForgetPasswordCode { Email = user.Email!, UserId = user.Id, Code = "123456" });
.ReturnsAsync(new ForgetPasswordCode
{
Id = 7,
Email = user.Email!,
UserId = user.Id,
CodeSalt = salt,
CodeHash = PasswordResetCodeSecrets.Hash(salt, "123456"),
ExpiresAtUtc = DateTime.UtcNow.AddMinutes(10)
});
forget.Setup(f => f.TryConsumeAttemptAsync(7, It.IsAny<int>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
var service = NewAuthenticationService(forget);
var reset = await service.ResetPasswordAsync(user.Email!, "123456", "abcdef", CancellationToken.None);
@ -180,6 +191,7 @@ public sealed class PasswordPolicyTests : IAsyncDisposable
reset.Should().BeFalse();
(await UserManager.CheckPasswordAsync(user, CurrentPassword)).Should().BeTrue();
forget.Verify(f => f.RemoveByEmailAsync(It.IsAny<string>(), It.IsAny<CancellationToken>()), Times.Never);
forget.Verify(f => f.RefundAttemptAsync(7, It.IsAny<CancellationToken>()), Times.Once);
}
private async Task<IReadOnlyList<IdentityError>> ValidateAsync(ApplicationUser user, string password)
@ -208,7 +220,8 @@ public sealed class PasswordPolicyTests : IAsyncDisposable
Microsoft.Extensions.Options.Options.Create(new JwtOptions { Secret = new string('x', 64) }),
Mock.Of<IUserDataService>(),
(forget ?? new Mock<IForgetPasswordDataService>()).Object,
Mock.Of<IEmailSender>());
Mock.Of<IEmailSender>(),
TimeProvider.System);
public async ValueTask DisposeAsync()
{