private async Task OnTransactionComplete(UserSummary user, AddAuthorizedTaskCommand addAuthorizedTaskCommand)
 {
     await _messageAggregator.PublishAsync(new UserAccountRecoveryInitiatedMessage()
     {
         AuthorizedTaskId = addAuthorizedTaskCommand.OutputAuthorizedTaskId,
         UserAreaCode     = user.UserArea.UserAreaCode,
         UserId           = user.UserId,
         Token            = addAuthorizedTaskCommand.OutputToken
     });
 }
        private async Task <AuthorizedTask> GetAuthorizedTaskAsync(AddAuthorizedTaskCommand addAuthorizedTaskCommand)
        {
            using var app = _appFactory.Create();
            var dbContext = app.Services.GetRequiredService <CofoundryDbContext>();

            var authorizedTask = await dbContext
                                 .AuthorizedTasks
                                 .Include(t => t.IPAddress)
                                 .Where(t => t.AuthorizedTaskId == addAuthorizedTaskCommand.OutputAuthorizedTaskId)
                                 .SingleAsync();

            return(authorizedTask);
        }
        private async Task <string> SendNotificationAsync(
            AddAuthorizedTaskCommand addAuthorizedTaskCommand,
            UserSummary user
            )
        {
            var context             = _userMailTemplateBuilderContextFactory.CreateAccountRecoveryContext(user, addAuthorizedTaskCommand.OutputToken);
            var mailTemplateBuilder = _userMailTemplateBuilderFactory.Create(user.UserArea.UserAreaCode);
            var mailTemplate        = await mailTemplateBuilder.BuildAccountRecoveryTemplateAsync(context);

            // Null template means don't send a notification
            if (mailTemplate != null)
            {
                await _mailService.SendAsync(user.Email, mailTemplate);
            }

            return(context.Token);
        }
        /// <summary>
        /// Creates a valid <see cref="AddAuthorizedTaskCommand"/> using the <see cref="TestAuthorizedTaskType1"/>
        /// task type.
        /// </summary>
        /// <param name="userId">Id of the user to scope the task to.</param>
        /// <param name="authorizedTaskTypeCode">The <see cref="IAuthorizedTaskTypeDefinition.AuthorizedTaskTypeCode"/> to group tasks by.</param>
        /// <param name="configuration">Optional configuration action to customize the command.</param>
        public AddAuthorizedTaskCommand CreateAddCommand(
            int userId,
            Action <AddAuthorizedTaskCommand> configuration = null)
        {
            var command = new AddAuthorizedTaskCommand()
            {
                AuthorizedTaskTypeCode = TestAuthorizedTaskType1.Code,
                UserId = userId
            };

            if (configuration != null)
            {
                configuration(command);
            }

            return(command);
        }
        private async Task <AddAuthorizedTaskCommand> GenerateTokenAsync(
            UserSummary user,
            AccountRecoveryOptions options,
            IExecutionContext executionContext
            )
        {
            if (string.IsNullOrWhiteSpace(user.Email))
            {
                throw new InvalidOperationException($"Cannot reset the password because user {user.UserId} does not have an email address.");
            }

            var command = new AddAuthorizedTaskCommand()
            {
                AuthorizedTaskTypeCode = UserAccountRecoveryAuthorizedTaskType.Code,
                UserId      = user.UserId,
                ExpireAfter = options.ExpireAfter
            };

            // Authorized tasks supports rate limits without a time window, but password
            // resets require a quantity and a window to set a rate limit
            if (options.InitiationRateLimit != null && options.InitiationRateLimit.HasValidQuantityAndWindow())
            {
                command.RateLimit = options.InitiationRateLimit;
            }

            try
            {
                await _domainRepository
                .WithContext(executionContext)
                .ExecuteCommandAsync(command);
            }
            catch (ValidationErrorException ex)
            {
                if (ex.ErrorCode == AuthorizedTaskValidationErrors.Create.RateLimitExceeded.ErrorCode)
                {
                    // Use a more specific error message
                    UserValidationErrors.AccountRecovery.Initiation.RateLimitExceeded.Throw();
                }

                throw;
            }

            return(command);
        }
        private async Task <AddAuthorizedTaskCommand> GenerateTokenAsync(
            UserSummary user,
            AccountVerificationOptions options,
            IExecutionContext executionContext
            )
        {
            if (string.IsNullOrWhiteSpace(user.Email))
            {
                throw new InvalidOperationException($"Cannot verify the user account because user {user.UserId} does not have an email address.");
            }

            var command = new AddAuthorizedTaskCommand()
            {
                AuthorizedTaskTypeCode = UserAccountVerificationAuthorizedTaskType.Code,
                UserId      = user.UserId,
                RateLimit   = options.InitiationRateLimit,
                ExpireAfter = options.ExpireAfter,
                TaskData    = user.Email
            };

            try
            {
                await _domainRepository
                .WithContext(executionContext)
                .ExecuteCommandAsync(command);
            }
            catch (ValidationErrorException ex)
            {
                if (ex.ErrorCode == AuthorizedTaskValidationErrors.Create.RateLimitExceeded.ErrorCode)
                {
                    // Use a more specific error message
                    UserValidationErrors.AccountVerification.Initiation.RateLimitExceeded.Throw();
                }

                throw;
            }

            return(command);
        }
        public async Task <string> AddAsync(AddAuthorizedTaskCommand command)
        {
            await ExtendableContentRepository.ExecuteCommandAsync(command);

            return(command.OutputToken);
        }