public async Task <RegisterVolunteerResponse> Handle(RegisterVolunteer request, CancellationToken cancellationToken) { var invitation = await _invitationRepository.GetInvitationAsync(request.Email, cancellationToken); if (invitation is null) { throw new InvitationNotFoundException(); } if (_clock.UtcNow - invitation.CreatedAt > TimeSpan.FromHours(24)) { throw new InvitationHasExpiredException(); } if (invitation.Attempts >= 3) { throw new InvitationHasBeenRevokedException(); } if (!invitation.Code.ToLower().Equals(request.Code.ToLower())) { invitation.Attempts += 1; await _invitationRepository.UpdateAsync(invitation, cancellationToken); throw new InvalidInvitationCodeException(); } if (await _volunteerRepository.ExitsAsync(invitation.Email, cancellationToken)) { throw new VolunteerAlreadyExistsException(); } var passwordHash = _passwordHasher.HashPassword(null, request.Password); var user = new User { FirstName = request.FirstName, LastName = request.LastName, Brand = request.Brand, PhoneNumber = request.PhoneNumber, Email = request.Email, PasswordHash = passwordHash, Role = UserRoleEnum.Volunteer }; invitation.Status = InvitationStateEnum.Accepted; await _volunteerRepository.AddAsync(user, cancellationToken); var jwtToken = _jwtGenerator.Generate(user); return(new RegisterVolunteerResponse(user.UserId, jwtToken)); }