mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-07-16 17:47:22 +00:00
Format ./web/backend/Features/Features.Auth
This commit is contained in:
@@ -7,4 +7,4 @@ namespace Features.Auth.Commands.ConfirmUser;
|
||||
/// Validates a confirmation token and confirms the corresponding user account.
|
||||
/// </summary>
|
||||
/// <param name="Token">The confirmation token issued to the user, typically delivered via email.</param>
|
||||
public record ConfirmUserCommand(string Token) : IRequest<ConfirmationPayload>;
|
||||
public record ConfirmUserCommand(string Token) : IRequest<ConfirmationPayload>;
|
||||
|
||||
@@ -13,22 +13,26 @@ namespace Features.Auth.Commands.ConfirmUser;
|
||||
/// </summary>
|
||||
/// <param name="authRepository">Repository used to look up and confirm user accounts.</param>
|
||||
/// <param name="tokenService">Service used to validate the confirmation token.</param>
|
||||
public class ConfirmUserHandler(
|
||||
IAuthRepository authRepository,
|
||||
ITokenService tokenService
|
||||
) : IRequestHandler<ConfirmUserCommand, ConfirmationPayload>
|
||||
public class ConfirmUserHandler(IAuthRepository authRepository, ITokenService tokenService)
|
||||
: IRequestHandler<ConfirmUserCommand, ConfirmationPayload>
|
||||
{
|
||||
/// <exception cref="UnauthorizedException">
|
||||
/// Thrown when the confirmation token is invalid or expired, or when the associated user account cannot be found.
|
||||
/// </exception>
|
||||
public async Task<ConfirmationPayload> Handle(ConfirmUserCommand request, CancellationToken cancellationToken)
|
||||
public async Task<ConfirmationPayload> Handle(
|
||||
ConfirmUserCommand request,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
ValidatedToken validatedToken = await tokenService.ValidateConfirmationTokenAsync(request.Token);
|
||||
ValidatedToken validatedToken = await tokenService.ValidateConfirmationTokenAsync(
|
||||
request.Token
|
||||
);
|
||||
|
||||
UserAccount? user = await authRepository.ConfirmUserAccountAsync(validatedToken.UserId);
|
||||
|
||||
if (user == null) throw new UnauthorizedException("User account not found");
|
||||
if (user == null)
|
||||
throw new UnauthorizedException("User account not found");
|
||||
|
||||
return new ConfirmationPayload(user.UserAccountId, DateTime.UtcNow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,4 +7,4 @@ namespace Features.Auth.Commands.RefreshToken;
|
||||
/// Exchanges a valid refresh token for a new access/refresh token pair. Bound directly from the
|
||||
/// request body of <c>POST /api/auth/refresh</c>.
|
||||
/// </summary>
|
||||
public record RefreshTokenCommand(string RefreshToken) : IRequest<LoginPayload>;
|
||||
public record RefreshTokenCommand(string RefreshToken) : IRequest<LoginPayload>;
|
||||
|
||||
@@ -12,10 +12,17 @@ namespace Features.Auth.Commands.RefreshToken;
|
||||
public class RefreshTokenHandler(ITokenService tokenService)
|
||||
: IRequestHandler<RefreshTokenCommand, LoginPayload>
|
||||
{
|
||||
public async Task<LoginPayload> Handle(RefreshTokenCommand request, CancellationToken cancellationToken)
|
||||
public async Task<LoginPayload> Handle(
|
||||
RefreshTokenCommand request,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
RefreshTokenResult result = await tokenService.RefreshTokenAsync(request.RefreshToken);
|
||||
return new LoginPayload(result.UserAccount.UserAccountId, result.UserAccount.Username, result.RefreshToken,
|
||||
result.AccessToken);
|
||||
return new LoginPayload(
|
||||
result.UserAccount.UserAccountId,
|
||||
result.UserAccount.Username,
|
||||
result.RefreshToken,
|
||||
result.AccessToken
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,6 @@ public class RefreshTokenValidator : AbstractValidator<RefreshTokenCommand>
|
||||
/// </summary>
|
||||
public RefreshTokenValidator()
|
||||
{
|
||||
RuleFor(x => x.RefreshToken)
|
||||
.NotEmpty()
|
||||
.WithMessage("Refresh token is required");
|
||||
RuleFor(x => x.RefreshToken).NotEmpty().WithMessage("Refresh token is required");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,4 +25,4 @@ public record RegisterUserCommand(
|
||||
string Email,
|
||||
DateTime DateOfBirth,
|
||||
string Password
|
||||
) : IRequest<RegistrationPayload>;
|
||||
) : IRequest<RegistrationPayload>;
|
||||
|
||||
@@ -28,7 +28,10 @@ public class RegisterUserHandler(
|
||||
/// <exception cref="ConflictException">
|
||||
/// Thrown when an existing account already has the same username or email address.
|
||||
/// </exception>
|
||||
public async Task<RegistrationPayload> Handle(RegisterUserCommand request, CancellationToken cancellationToken)
|
||||
public async Task<RegistrationPayload> Handle(
|
||||
RegisterUserCommand request,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
await ValidateUserDoesNotExist(request.Username, request.Email);
|
||||
|
||||
@@ -48,14 +51,23 @@ public class RegisterUserHandler(
|
||||
string confirmationToken = tokenService.GenerateConfirmationToken(createdUser);
|
||||
|
||||
if (string.IsNullOrEmpty(accessToken) || string.IsNullOrEmpty(refreshToken))
|
||||
return new RegistrationPayload(createdUser.UserAccountId, createdUser.Username, string.Empty, string.Empty,
|
||||
false);
|
||||
return new RegistrationPayload(
|
||||
createdUser.UserAccountId,
|
||||
createdUser.Username,
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
false
|
||||
);
|
||||
|
||||
bool emailSent = false;
|
||||
try
|
||||
{
|
||||
await mediator.Send(
|
||||
new SendRegistrationEmailCommand(createdUser.FirstName, createdUser.Email, confirmationToken),
|
||||
new SendRegistrationEmailCommand(
|
||||
createdUser.FirstName,
|
||||
createdUser.Email,
|
||||
confirmationToken
|
||||
),
|
||||
cancellationToken
|
||||
);
|
||||
emailSent = true;
|
||||
@@ -67,8 +79,13 @@ public class RegisterUserHandler(
|
||||
// ignored
|
||||
}
|
||||
|
||||
return new RegistrationPayload(createdUser.UserAccountId, createdUser.Username, refreshToken, accessToken,
|
||||
emailSent);
|
||||
return new RegistrationPayload(
|
||||
createdUser.UserAccountId,
|
||||
createdUser.Username,
|
||||
refreshToken,
|
||||
accessToken,
|
||||
emailSent
|
||||
);
|
||||
}
|
||||
|
||||
/// <exception cref="ConflictException">
|
||||
@@ -82,4 +99,4 @@ public class RegisterUserHandler(
|
||||
if (existingUsername != null || existingEmail != null)
|
||||
throw new ConflictException("Username or email already exists");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,8 +61,6 @@ public class RegisterUserValidator : AbstractValidator<RegisterUserCommand>
|
||||
.Matches("[0-9]")
|
||||
.WithMessage("Password must contain at least one number")
|
||||
.Matches("[^a-zA-Z0-9]")
|
||||
.WithMessage(
|
||||
"Password must contain at least one special character"
|
||||
);
|
||||
.WithMessage("Password must contain at least one special character");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,4 +6,4 @@ namespace Features.Auth.Commands.ResendConfirmationEmail;
|
||||
/// Resends the account confirmation email to a user, generating a fresh confirmation token.
|
||||
/// </summary>
|
||||
/// <param name="UserId">The unique identifier of the user requesting the resend.</param>
|
||||
public record ResendConfirmationEmailCommand(Guid UserId) : IRequest;
|
||||
public record ResendConfirmationEmailCommand(Guid UserId) : IRequest;
|
||||
|
||||
@@ -23,12 +23,17 @@ public class ResendConfirmationEmailHandler(
|
||||
IMediator mediator
|
||||
) : IRequestHandler<ResendConfirmationEmailCommand>
|
||||
{
|
||||
public async Task Handle(ResendConfirmationEmailCommand request, CancellationToken cancellationToken)
|
||||
public async Task Handle(
|
||||
ResendConfirmationEmailCommand request,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
UserAccount? user = await authRepository.GetUserByIdAsync(request.UserId);
|
||||
if (user == null) return; // Silent return to prevent user enumeration
|
||||
if (user == null)
|
||||
return; // Silent return to prevent user enumeration
|
||||
|
||||
if (await authRepository.IsUserVerifiedAsync(request.UserId)) return; // Already confirmed, no-op
|
||||
if (await authRepository.IsUserVerifiedAsync(request.UserId))
|
||||
return; // Already confirmed, no-op
|
||||
|
||||
string confirmationToken = tokenService.GenerateConfirmationToken(user);
|
||||
await mediator.Send(
|
||||
@@ -36,4 +41,4 @@ public class ResendConfirmationEmailHandler(
|
||||
cancellationToken
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user