using Domain.Exceptions;
using Infrastructure.Repository.Auth;
using Service.Emails;
namespace Service.Auth;
///
/// Handles confirmation of newly registered user accounts and resending of confirmation emails.
///
/// Repository used to look up and confirm user accounts.
/// Service used to generate and validate confirmation tokens.
/// Service used to send confirmation-related emails.
public class ConfirmationService(
IAuthRepository authRepository,
ITokenService tokenService,
IEmailService emailService
) : IConfirmationService
{
///
/// Validates a confirmation token and marks the corresponding user account as confirmed.
///
/// The confirmation token issued to the user, typically delivered via email.
///
/// A containing the UTC timestamp of confirmation and the confirmed user's ID.
///
///
/// Thrown when the confirmation token is invalid or expired, or when the associated user account cannot be found.
///
public async Task ConfirmUserAsync(
string confirmationToken
)
{
var validatedToken = await tokenService.ValidateConfirmationTokenAsync(
confirmationToken
);
var user = await authRepository.ConfirmUserAccountAsync(
validatedToken.UserId
);
if (user == null)
{
throw new UnauthorizedException("User account not found");
}
return new ConfirmationServiceReturn(
DateTime.UtcNow,
user.UserAccountId
);
}
///
/// Resends the account confirmation email to a user, generating a fresh confirmation token.
///
/// The unique identifier of the user requesting the resend.
/// A task that completes once the operation has finished.
///
/// Returns silently without sending an email if the user does not exist (to prevent user enumeration)
/// or if the user's account is already verified.
///
public async Task ResendConfirmationEmailAsync(Guid userId)
{
var user = await authRepository.GetUserByIdAsync(userId);
if (user == null)
{
return; // Silent return to prevent user enumeration
}
if (await authRepository.IsUserVerifiedAsync(userId))
{
return; // Already confirmed, no-op
}
var confirmationToken = tokenService.GenerateConfirmationToken(user);
await emailService.SendResendConfirmationEmailAsync(user, confirmationToken);
}
}