hi
Once you can reproduce the problem locally, feel free to share it, I will fix it immediately
Thanks.
hi
The FAQ page will be available in ABP 10.0.
You can now use an MVC page to manage it.
Thanks.
hi
Remote debug will be hard.
Can you test your case in a new template project?
Thanks.
You can try the latest version:
Add a 2FA.cshtml
in your Pages
folder. Also, make it an embedded file.
Send an email to liming.ma@volosoft.com. I will share the 2FA.cshtml
content.
<ItemGroup>
<Content Remove="Pages\2FA.cshtml" />
<EmbeddedResource Include="Pages\2FA.cshtml" />
</ItemGroup>
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<ProfileManagementPageOptions>(options =>
{
options.Contributors.RemoveAll(x => x is AccountProfileManagementPageContributor);
options.Contributors.Add(new MyAccountProfileManagementPageContributor());
});
}
```cs System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Volo.Abp.Account;
using Volo.Abp.Account.Localization;
using Volo.Abp.Account.Public.Web.Pages.Account.Components.ProfileManagementGroup.TwoFactor;
using Volo.Abp.Account.Public.Web.ProfileManagement;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Identity;
using Volo.Abp.Identity.Settings;
using Volo.Abp.Security.Claims;
using Volo.Abp.Settings;
using Volo.Abp.Threading;
using IdentityUser = Volo.Abp.Identity.IdentityUser;
namespace MyCompanyName.MyProjectName.Web;
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(AccountProfileTwoFactorManagementGroupViewComponent))]
public class MyAccountProfileTwoFactorManagementGroupViewComponent : AccountProfileTwoFactorManagementGroupViewComponent
{
public MyAccountProfileTwoFactorManagementGroupViewComponent(
IProfileAppService profileAppService,
IAccountAppService accountAppService,
IdentityProTwoFactorManager identityProTwoFactorManager)
: base(profileAppService, accountAppService, identityProTwoFactorManager)
{
}
public override async Task<IViewComponentResult> InvokeAsync()
{
var authenticatorInfo = await AccountAppService.GetAuthenticatorInfoAsync();
var model = new ChangeTwoFactorModel
{
TwoFactorForcedEnabled = await IdentityProTwoFactorManager.IsForcedEnableAsync(),
TwoFactorEnabled = await ProfileAppService.GetTwoFactorEnabledAsync(),
HasAuthenticator = await AccountAppService.HasAuthenticatorAsync(),
SharedKey = authenticatorInfo.Key,
AuthenticatorUri = authenticatorInfo.Uri
};
return View("~/Pages/2FA.cshtml", model);
}
}
public class MyAccountProfileManagementPageContributor : IProfileManagementPageContributor
{
public async Task ConfigureAsync(ProfileManagementPageCreationContext context)
{
await new AccountProfileManagementPageContributor().ConfigureAsync(context);
var identityTwoFactorManager = context.ServiceProvider.GetRequiredService<IdentityProTwoFactorManager>();
var settingProvider = context.ServiceProvider.GetRequiredService<ISettingProvider>();
if (!await identityTwoFactorManager.IsForcedDisableAsync() &&
await settingProvider.GetAsync<bool>(IdentityProSettingNames.TwoFactor.UsersCanChange))
{
var l = context.ServiceProvider.GetRequiredService<IStringLocalizer<AccountResource>>();
context.Groups.Add(
new ProfileManagementPageGroup(
"Volo-Abp-Account-TwoFactor",
l["ProfileTab:TwoFactor"],
typeof(AccountProfileTwoFactorManagementGroupViewComponent)
)
);
}
}
}
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IdentityUserManager))]
public class MyIdentityUserManager : IdentityUserManager
{
public MyIdentityUserManager(IdentityUserStore store,
IIdentityRoleRepository roleRepository,
IIdentityUserRepository userRepository,
IOptions<IdentityOptions> optionsAccessor,
IPasswordHasher<IdentityUser> passwordHasher,
IEnumerable<IUserValidator<IdentityUser>> userValidators,
IEnumerable<IPasswordValidator<IdentityUser>> passwordValidators,
ILookupNormalizer keyNormalizer,
IdentityErrorDescriber errors,
IServiceProvider services,
ILogger<IdentityUserManager> logger,
ICancellationTokenProvider cancellationTokenProvider,
IOrganizationUnitRepository organizationUnitRepository,
ISettingProvider settingProvider,
IDistributedEventBus distributedEventBus,
IIdentityLinkUserRepository identityLinkUserRepository,
IDistributedCache<AbpDynamicClaimCacheItem> dynamicClaimCache)
: base(store, roleRepository, userRepository, optionsAccessor, passwordHasher, userValidators,
passwordValidators, keyNormalizer, errors, services, logger, cancellationTokenProvider,
organizationUnitRepository, settingProvider, distributedEventBus, identityLinkUserRepository,
dynamicClaimCache)
{
}
public override async Task<IList<string>> GetValidTwoFactorProvidersAsync(IdentityUser user)
{
var providers = await base.GetValidTwoFactorProvidersAsync(user);
providers.RemoveAll(x => x == TokenOptions.DefaultEmailProvider || x == TokenOptions.DefaultPhoneProvider);
return providers;
}
}
hi
Add the code below to your Blazor project will fix it.
var valueValidatorFactoryOptions = context.Services.ExecutePreConfiguredActions<ValueValidatorFactoryOptions>();
Configure<JsonOptions>(options =>
{
options.JsonSerializerOptions.Converters.AddIfNotContains(new StringValueTypeJsonConverter(valueValidatorFactoryOptions));
});