public async Task <ActionResult> SendCode(string code)
        {
            // 1. Retrieve user
            var authenticatedUser = await _authenticationService.GetAuthenticatedUser(this, Host.Constants.CookieNames.TwoFactorCookieName).ConfigureAwait(false);

            if (authenticatedUser == null || authenticatedUser.Identity == null || !authenticatedUser.Identity.IsAuthenticated)
            {
                throw new IdentityServerException(Core.Errors.ErrorCodes.UnhandledExceptionCode, Core.Errors.ErrorDescriptions.TwoFactorAuthenticationCannotBePerformed);
            }

            // 2. Return translated view.
            var resourceOwner = await _userActions.GetUser(authenticatedUser).ConfigureAwait(false);

            var service   = _twoFactorAuthenticationHandler.Get(resourceOwner.TwoFactorAuthentication);
            var viewModel = new CodeViewModel
            {
                AuthRequestCode = code,
                ClaimName       = service.RequiredClaim
            };
            var claim = resourceOwner.Claims.FirstOrDefault(c => c.Type == service.RequiredClaim);

            if (claim != null)
            {
                viewModel.ClaimValue = claim.Value;
            }

            ViewBag.IsAuthenticated = false;
            await TranslateView(DefaultLanguage).ConfigureAwait(false);

            return(View(viewModel));
        }
        public async Task <string> ExecuteAsync(string subject)
        {
            if (string.IsNullOrWhiteSpace(subject))
            {
                throw new ArgumentNullException(nameof(subject));
            }

            var resourceOwner = await _resourceOwnerRepository.GetAsync(subject);

            if (resourceOwner == null)
            {
                throw new IdentityServerException(ErrorCodes.UnhandledExceptionCode, ErrorDescriptions.TheRoDoesntExist);
            }

            if (string.IsNullOrWhiteSpace(resourceOwner.TwoFactorAuthentication))
            {
                throw new IdentityServerException(
                          ErrorCodes.UnhandledExceptionCode,
                          ErrorDescriptions.TwoFactorAuthenticationIsNotEnabled);
            }

            var confirmationCode = new ConfirmationCode
            {
                Value     = await GetCode(),
                IssueAt   = DateTime.UtcNow,
                ExpiresIn = 300
            };

            var service = _twoFactorAuthenticationHandler.Get(resourceOwner.TwoFactorAuthentication);

            if (!resourceOwner.Claims.Any(c => c.Type == service.RequiredClaim))
            {
                throw new ClaimRequiredException(service.RequiredClaim);
            }

            if (!await _confirmationCodeStore.Add(confirmationCode))
            {
                throw new IdentityServerException(ErrorCodes.UnhandledExceptionCode, ErrorDescriptions.TheConfirmationCodeCannotBeSaved);
            }

            await _twoFactorAuthenticationHandler.SendCode(confirmationCode.Value, resourceOwner.TwoFactorAuthentication, resourceOwner);

            return(confirmationCode.Value);
        }
        public async Task <Option <string> > Send(string subject, CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(subject))
            {
                _logger.LogError(Strings.TheSubjectCannotBeRetrieved);
                return(new Option <string> .Error(
                           new ErrorDetails
                {
                    Title = ErrorCodes.UnhandledExceptionCode,
                    Detail = Strings.TheSubjectCannotBeRetrieved,
                    Status = HttpStatusCode.NotFound
                }));
            }

            var resourceOwner = await _resourceOwnerRepository.Get(subject, cancellationToken).ConfigureAwait(false);

            if (resourceOwner == null)
            {
                _logger.LogError(Strings.TheRoDoesntExist);
                return(new Option <string> .Error(
                           new ErrorDetails
                {
                    Title = ErrorCodes.UnhandledExceptionCode,
                    Detail = Strings.TheRoDoesntExist,
                    Status = HttpStatusCode.NotFound
                }));
            }

            if (string.IsNullOrWhiteSpace(resourceOwner.TwoFactorAuthentication))
            {
                _logger.LogError(Strings.TwoFactorAuthenticationIsNotEnabled);
                return(new Option <string> .Error(
                           new ErrorDetails
                {
                    Title = ErrorCodes.UnhandledExceptionCode,
                    Detail = Strings.TwoFactorAuthenticationIsNotEnabled,
                    Status = HttpStatusCode.NotFound
                }));
            }

            var confirmationCode = new ConfirmationCode
            {
                Value     = await GetCode(subject, cancellationToken).ConfigureAwait(false),
                IssueAt   = DateTimeOffset.UtcNow,
                ExpiresIn = 300
            };

            var service = _twoFactorAuthenticationHandler.Get(resourceOwner.TwoFactorAuthentication) !;

            if (resourceOwner.Claims.All(c => c.Type != service.RequiredClaim))
            {
                throw new ClaimRequiredException(service.RequiredClaim);
            }

            if (!await _confirmationCodeStore.Add(confirmationCode, cancellationToken).ConfigureAwait(false))
            {
                _logger.LogError(Strings.TheConfirmationCodeCannotBeSaved);
                return(new Option <string> .Error(
                           new ErrorDetails
                {
                    Title = ErrorCodes.UnhandledExceptionCode,
                    Detail = Strings.TheConfirmationCodeCannotBeSaved,
                    Status = HttpStatusCode.InternalServerError
                }));
            }

            await _twoFactorAuthenticationHandler.SendCode(confirmationCode.Value, resourceOwner.TwoFactorAuthentication, resourceOwner).ConfigureAwait(false);

            return(new Option <string> .Result(confirmationCode.Value));
        }