using Domain.Entities; using Domain.Exceptions; using Infrastructure.Email; using Infrastructure.Email.Templates.Rendering; using Infrastructure.PasswordHashing; using Infrastructure.Repository.Auth; using Microsoft.Extensions.Logging; using Service.Emails; namespace Service.Auth; public class RegisterService( IAuthRepository authRepo, IPasswordInfrastructure passwordInfrastructure, ITokenService tokenService, IEmailService emailService ) : IRegisterService { private async Task ValidateUserDoesNotExist(UserAccount userAccount) { // Check if user already exists var existingUsername = await authRepo.GetUserByUsernameAsync( userAccount.Username ); var existingEmail = await authRepo.GetUserByEmailAsync( userAccount.Email ); if (existingUsername != null || existingEmail != null) { throw new ConflictException("Username or email already exists"); } } public async Task RegisterAsync( UserAccount userAccount, string password ) { await ValidateUserDoesNotExist(userAccount); // password hashing var hashed = passwordInfrastructure.Hash(password); // Register user with hashed password and get the created user with generated ID var createdUser = await authRepo.RegisterUserAsync( userAccount.Username, userAccount.FirstName, userAccount.LastName, userAccount.Email, userAccount.DateOfBirth, hashed ); var accessToken = tokenService.GenerateAccessToken(createdUser); var refreshToken = tokenService.GenerateRefreshToken(createdUser); var confirmationToken = tokenService.GenerateConfirmationToken(createdUser); if ( string.IsNullOrEmpty(accessToken) || string.IsNullOrEmpty(refreshToken) ) { return new RegisterServiceReturn(createdUser); } bool emailSent = false; try { // send confirmation email await emailService.SendRegistrationEmailAsync( createdUser, confirmationToken ); emailSent = true; } catch (Exception ex) { await Console.Error.WriteLineAsync(ex.Message); Console.WriteLine("Could not send email."); // ignored } return new RegisterServiceReturn( createdUser, accessToken, refreshToken, emailSent ); } }