Example #1
0
        public async Task <bool> UsernameIsAvailable(string username, string subjectId = null)
        {
            // In this user store, usernames are restricted to email addresses
            if (!EmailAddressChecker.EmailIsValid(username))
            {
                return(false);
            }
            var response = await GetUserByUsernameAsync(username);

            if (response.IsOk)
            {
                return(response.Result.SubjectId == subjectId);
            }
            return(true);
        }
 private bool IsValidEmailAddress(string sendTo)
 {
     return(EmailAddressChecker.EmailIsValid(sendTo));
 }
Example #3
0
        public async Task <WebStatus> SendOneTimeCodeAsync(SendCodeInputModel model)
        {
            _logger.LogDebug("Begin send one time code for {0}", model.Username);

            if (!ApplicationIdIsNullOrValid(model.ApplicationId))
            {
                return(WebStatus.Error(_localizer["Invalid application id."], HttpStatusCode.BadRequest));
            }

            // Note: Need to keep messages generic as to not reveal whether an account exists or not.
            var usernameIsValidEmail = EmailAddressChecker.EmailIsValid(model.Username);
            var defaultMessage       = usernameIsValidEmail
                ? _localizer["Message sent. Please check your email."]
                : _localizer["We sent a code to the email address asociated with your account (if found). Please check your email."];

            // If the username provide is not an email address or phone number, tell the user "we sent you a code if you have an account"
            var userResponse = await _userStore.GetUserByUsernameAsync(model.Username);

            if (userResponse.HasError)
            {
                _logger.LogDebug("User not found");

                if (!usernameIsValidEmail)
                {
                    _logger.LogError("No valid email address found for user {0}", model.Username);
                    return(WebStatus.Success(defaultMessage)); // generic message prevent account enumeration
                }

                var result = await _messageService.SendAccountNotFoundMessageAsync(model.ApplicationId, model.Username);

                if (result.HasError)
                {
                    return(ServerError(result.Text));
                }
                // the fact that the user doesn't have an account is communicated privately via email
                await _eventNotificationService.NotifyEventAsync(model.Username, EventType.AccountNotFound);

                return(WebStatus.Success(defaultMessage)); // generic message prevent account enumeration
            }

            var user = userResponse.Result;

            _logger.LogDebug("User found");

            if (!EmailAddressChecker.EmailIsValid(user.Email))
            {
                _logger.LogError("No valid email address found for user {0}", model.Username);
                return(WebStatus.Success(defaultMessage)); // generic message prevent account enumeration
            }

            var oneTimeCodeResponse = await _oneTimeCodeService.GetOneTimeCodeAsync(
                user.Email,
                TimeSpan.FromMinutes(_options.OneTimeCodeValidityMinutes),
                model.NextUrl);

            switch (oneTimeCodeResponse.Status.StatusCode)
            {
            case GetOneTimeCodeStatusCode.Success:
                var status = await _messageService.SendOneTimeCodeAndLinkMessageAsync(model.ApplicationId,
                                                                                      model.Username, oneTimeCodeResponse.Result.ShortCode, oneTimeCodeResponse.Result.LongCode);

                await _eventNotificationService.NotifyEventAsync(model.Username, EventType.RequestOneTimeCode);

                if (status.IsOk)
                {
                    status = Status.Success(defaultMessage);
                }
                SetNonce(oneTimeCodeResponse.Result.ClientNonce);
                return(new WebStatus(status));

            case GetOneTimeCodeStatusCode.TooManyRequests:
                return(WebStatus.Error(_localizer["Please wait a few minutes before requesting a new code."], HttpStatusCode.TooManyRequests));

            case GetOneTimeCodeStatusCode.ServiceFailure:
            default:
                return(ServerError(_localizer["Hmm. Something went wrong. Please try again."]));
            }
        }