public IAccountRecoveryTemplateBuilderContext CreateAccountRecoveryContext(UserSummary user, string token)
        {
            var definition       = _userAreaDefinitionRepository.GetRequiredByCode(user.UserArea.UserAreaCode);
            var options          = _userAreaDefinitionRepository.GetOptionsByCode(user.UserArea.UserAreaCode).AccountRecovery;
            var isCofoundryAdmin = definition is CofoundryAdminUserArea;

            var context = new AccountRecoveryTemplateBuilderContext()
            {
                User  = user,
                Token = token,
                DefaultTemplateFactory = AccountRecoveryTemplateFactory
            };

            // Can be null to allow a custom IDefaultMailTemplateBuilder implementation to the path explicitly
            if (options.RecoveryUrlBase != null)
            {
                context.RecoveryUrlPath = _authorizedTaskTokenUrlHelper.MakeUrl(options.RecoveryUrlBase, token);
            }

            return(context);
        }
        private async Task <AccountRecoveryMailTemplate> AccountRecoveryTemplateFactory(AccountRecoveryTemplateBuilderContext context)
        {
            if (context.RecoveryUrlPath == null || !Uri.IsWellFormedUriString(context.RecoveryUrlPath, UriKind.Relative))
            {
                // The RecoveryUrlPath setting isn't required in config because the feature may not be used, or may
                // be manually constructed in a custom IDefaultMailTemplateBuilder implementation. However it should be
                // supplied at this point for our default builder.
                var options = _userAreaDefinitionRepository.GetOptionsByCode(context.User.UserArea.UserAreaCode).AccountRecovery;
                if (string.IsNullOrEmpty(options.RecoveryUrlBase))
                {
                    throw new InvalidOperationException($"To use the account recovery feature you must configure the {nameof(AccountRecoveryOptions.RecoveryUrlBase)} setting by implementing {nameof(IUserAreaDefinition)}.{nameof(IUserAreaDefinition.ConfigureOptions)}.");
                }

                throw new InvalidOperationException($"{nameof(AccountRecoveryTemplateBuilderContext)}.{nameof(context.RecoveryUrlPath)} should be a valid relative uri.");
            }

            var template = new AccountRecoveryMailTemplate();

            template.RecoveryUrl = _siteUrlResolver.MakeAbsolute(context.RecoveryUrlPath);
            await _userMailTemplateInitializer.Initialize(context.User, template);

            return(template);
        }