Files
forkmessager/backend/src/Modules/Auth/Application/Users/Register/RegisterUserCommandHandler.cs
T

88 lines
3.0 KiB
C#

using BCrypt.Net;
using Knot.Contracts.Auth.Application.Abstractions;
using Knot.Contracts.Auth.Application.Auth.DTOs;
using Knot.Contracts.Settings.Application.Abstractions;
using Knot.Contracts.Settings.Application.DTOs;
using Knot.Modules.Auth.Domain;
using Knot.Shared.Kernel;
namespace Knot.Modules.Auth.Application.Users.Register;
public sealed record RegisterUserCommand(
string Username,
string Password,
string DisplayName,
string? Email,
string? Bio) : ICommand<AuthResponseDto>;
internal sealed class RegisterUserCommandHandler : ICommandHandler<RegisterUserCommand, AuthResponseDto>
{
private readonly IUserRepository _userRepository;
private readonly IAuthUnitOfWork _unitOfWork;
private readonly ISystemSettings _settings;
private readonly IJwtTokenProvider _tokenProvider;
public RegisterUserCommandHandler(
IUserRepository userRepository,
IAuthUnitOfWork unitOfWork,
ISystemSettings settings,
IJwtTokenProvider tokenProvider)
{
_userRepository = userRepository;
_unitOfWork = unitOfWork;
_settings = settings;
_tokenProvider = tokenProvider;
}
public async Task<Result<AuthResponseDto>> Handle(RegisterUserCommand request, CancellationToken cancellationToken)
{
if (!_settings.Current.EnableRegistration)
{
return Result.Failure<AuthResponseDto>(AuthErrors.IdentityRegistrationDisabled);
}
if (!await _userRepository.IsUsernameUniqueAsync(request.Username, cancellationToken))
{
return Result.Failure<AuthResponseDto>(AuthErrors.IdentityUsernameNotUnique);
}
string passwordHash = BCrypt.Net.BCrypt.HashPassword(request.Password);
var user = User.Create(
request.Username,
passwordHash,
request.DisplayName,
request.Email,
request.Bio);
var repoImpl = _userRepository as Infrastructure.Persistence.UserRepository;
repoImpl?.Add(user);
await _unitOfWork.SaveChangesAsync(cancellationToken);
// Get the saved user as contract
var userContract = await _userRepository.GetByUsernameAsync(request.Username, cancellationToken);
if (userContract == null)
{
return Result.Failure<AuthResponseDto>(AuthErrors.IdentityRegistrationFailed);
}
string token = _tokenProvider.Generate(userContract.Id, userContract.Username, userContract.DisplayName, userContract.Avatar);
string refreshToken = _tokenProvider.GenerateRefreshToken();
DateTime refreshExpiry = _tokenProvider.GetRefreshTokenExpiry();
userContract.SetRefreshToken(refreshToken, refreshExpiry);
await _userRepository.UpdateAsync(userContract, cancellationToken);
return Result.Success(new AuthResponseDto
{
AccessToken = token,
RefreshToken = refreshToken,
UserId = userContract.Id,
Username = userContract.Username,
DisplayName = userContract.DisplayName
});
}
}