diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Controllers/AuthenticatorAppController.cs b/src/OrchardCore.Modules/OrchardCore.Users/Controllers/AuthenticatorAppController.cs index c81ffa8bfe3..156626050eb 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Controllers/AuthenticatorAppController.cs +++ b/src/OrchardCore.Modules/OrchardCore.Users/Controllers/AuthenticatorAppController.cs @@ -103,7 +103,7 @@ public async Task Index(EnableAuthenticatorViewModel model) await Notifier.SuccessAsync(H["Your authenticator app has been verified."]); - return await RedirectToTwoFactorAsync(user); + return await RedirectToTwoFactorAsync(user,model.ReturnUrl); } public async Task Reset() diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Controllers/SmsAuthenticatorController.cs b/src/OrchardCore.Modules/OrchardCore.Users/Controllers/SmsAuthenticatorController.cs index c3b80673627..85dbc39e9f1 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Controllers/SmsAuthenticatorController.cs +++ b/src/OrchardCore.Modules/OrchardCore.Users/Controllers/SmsAuthenticatorController.cs @@ -140,10 +140,10 @@ public async Task IndexPost(RequestCodeSmsAuthenticatorViewModel await SetPendingPhoneNumberAsync(phoneNumber, user.UserName); - return RedirectToAction(nameof(ValidateCode)); + return RedirectToAction(nameof(ValidateCode),new { model.ReturnUrl }); } - public async Task ValidateCode() + public async Task ValidateCode(string returnUrl=null) { var user = await UserManager.GetUserAsync(User); if (user == null) @@ -159,7 +159,7 @@ public async Task ValidateCode() return RedirectToAction(nameof(Index)); } - + ViewData["ReturnUrl"] = returnUrl; var model = new EnableSmsAuthenticatorViewModel { PhoneNumber = pendingPhoneNumber, @@ -193,7 +193,7 @@ public async Task ValidateCode(EnableSmsAuthenticatorViewModel mo await Notifier.SuccessAsync(H["Your phone number has been confirmed."]); - return await RedirectToTwoFactorAsync(user); + return await RedirectToTwoFactorAsync(user,model.ReturnUrl); } await Notifier.ErrorAsync(H["Invalid verification code."]); diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Controllers/TwoFactorAuthenticationBaseController.cs b/src/OrchardCore.Modules/OrchardCore.Users/Controllers/TwoFactorAuthenticationBaseController.cs index d6774acbfdd..735698bd47e 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Controllers/TwoFactorAuthenticationBaseController.cs +++ b/src/OrchardCore.Modules/OrchardCore.Users/Controllers/TwoFactorAuthenticationBaseController.cs @@ -131,7 +131,7 @@ protected async Task RefreshTwoFactorClaimAsync(IUser user) } } - protected async Task RedirectToTwoFactorAsync(IUser user) + protected async Task RedirectToTwoFactorAsync(IUser user, string returnUrl=null) { if (await UserManager.CountRecoveryCodesAsync(user) == 0) { @@ -142,12 +142,13 @@ protected async Task RedirectToTwoFactorAsync(IUser user) await Notifier.WarningAsync(H["New recovery codes were generated."]); - return RedirectToAction(nameof(TwoFactorAuthenticationController.ShowRecoveryCodes), _twoFactorAuthenticationControllerName); + // 传递 returnUrl 参数 + return RedirectToAction(nameof(TwoFactorAuthenticationController.ShowRecoveryCodes), _twoFactorAuthenticationControllerName, new { returnUrl }); } + // 如果不需要生成新的恢复码,则直接重定向到 TwoFactorIndex return RedirectToTwoFactorIndex(); } - protected async Task> GetTwoFactorProvidersAsync(IUser user) { var providers = await UserManager.GetValidTwoFactorProvidersAsync(user); diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Controllers/TwoFactorAuthenticationController.cs b/src/OrchardCore.Modules/OrchardCore.Users/Controllers/TwoFactorAuthenticationController.cs index 06ae865c89c..169c49bf356 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Controllers/TwoFactorAuthenticationController.cs +++ b/src/OrchardCore.Modules/OrchardCore.Users/Controllers/TwoFactorAuthenticationController.cs @@ -213,7 +213,7 @@ public async Task LoginWithRecoveryCode(LoginWithRecoveryCodeView return View(model); } - public async Task Index() + public async Task Index(string returnUrl=null) { var user = await UserManager.GetUserAsync(User); if (user == null) @@ -223,18 +223,20 @@ public async Task Index() var providers = await GetTwoFactorProvidersAsync(user); var model = new TwoFactorAuthenticationViewModel(); - await PopulateModelAsync(user, providers, model); + + await PopulateModelAsync(user, providers, model,returnUrl); if (user is User u) { model.PreferredProvider = u.As().DefaultProvider; } - + ViewData["ReturnUrl"] = returnUrl; + //RedirectToLocal(returnUrl); return View(model); } [HttpPost] - public async Task Index(TwoFactorAuthenticationViewModel model) + public async Task Index(TwoFactorAuthenticationViewModel model, string returnUrl = null) { var user = await UserManager.GetUserAsync(User); if (user == null) @@ -257,14 +259,27 @@ public async Task Index(TwoFactorAuthenticationViewModel model) await Notifier.SuccessAsync(H["Preferences were updated successfully."]); - return RedirectToAction(nameof(Index)); + // 优先使用提供的 returnUrl,如果没有提供则重定向到 Index + if (!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl)) + { + return Redirect(returnUrl); + } + else + { + return RedirectToAction(nameof(Index)); + } + //return RedirectToAction(nameof(Index)); } await Notifier.ErrorAsync(H["Unable to update preferences."]); } await PopulateModelAsync(user, providers, model); - + // 如果有 returnUrl,将其传递给视图 + if (!string.IsNullOrEmpty(returnUrl)) + { + ViewData["ReturnUrl"] = returnUrl; + } return View(model); } @@ -328,7 +343,7 @@ public async Task GenerateRecoveryCodesPost() return RedirectToAction(nameof(ShowRecoveryCodes)); } - public async Task ShowRecoveryCodes() + public async Task ShowRecoveryCodes(string returnUrl=null) { var user = await UserManager.GetUserAsync(User); if (user == null) @@ -339,7 +354,10 @@ public async Task ShowRecoveryCodes() var userId = await UserManager.GetUserIdAsync(user); var recoveryCodes = await GetCachedRecoveryCodesAsync(userId); - + if(Url.IsLocalUrl(returnUrl)) + { + return Redirect(returnUrl); + } if (recoveryCodes == null || recoveryCodes.Length == 0) { return RedirectToAction(nameof(Index)); @@ -474,7 +492,7 @@ private static string GetProvider(IList providers, IUser user, string pr return defaultProvider; } - private async Task PopulateModelAsync(IUser user, IList providers, TwoFactorAuthenticationViewModel model) + private async Task PopulateModelAsync(IUser user, IList providers, TwoFactorAuthenticationViewModel model,string returnUrl="") { model.User = user; model.IsTwoFaEnabled = await UserManager.GetTwoFactorEnabledAsync(user); @@ -489,6 +507,7 @@ private async Task PopulateModelAsync(IUser user, IList providers, TwoFa { Provider = key, IsEnabled = providers.Contains(key), + ReturnUrl = returnUrl }; var shape = await _twoFactorDisplayManager.BuildDisplayAsync(method, this, "SummaryAdmin"); diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Drivers/TwoFactorMethodDisplayDriver.cs b/src/OrchardCore.Modules/OrchardCore.Users/Drivers/TwoFactorMethodDisplayDriver.cs index 27916138379..a93faf1b109 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Drivers/TwoFactorMethodDisplayDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Users/Drivers/TwoFactorMethodDisplayDriver.cs @@ -12,23 +12,27 @@ public override IDisplayResult Display(TwoFactorMethod model, BuildDisplayContex { return null; } - + // 从上下文中获取 returnUrl 参数 + var icon = Initialize($"TwoFactorMethod_{model.Provider}_Icon", vm => { vm.Provider = model.Provider; vm.IsEnabled = model.IsEnabled; + vm.ReturnUrl = model.ReturnUrl; // 传递 returnUrl 参数 }).Location("SummaryAdmin", "Icon"); var content = Initialize($"TwoFactorMethod_{model.Provider}_Content", vm => { vm.Provider = model.Provider; vm.IsEnabled = model.IsEnabled; + vm.ReturnUrl = model.ReturnUrl; // 传递 returnUrl 参数 }).Location("SummaryAdmin", "Content"); var actions = Initialize($"TwoFactorMethod_{model.Provider}_Actions", vm => { vm.Provider = model.Provider; vm.IsEnabled = model.IsEnabled; + vm.ReturnUrl = model.ReturnUrl; // 传递 returnUrl 参数 }).Location("SummaryAdmin", "Actions"); return Combine(icon, content, actions); diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Drivers/UserDisplayDriver.cs b/src/OrchardCore.Modules/OrchardCore.Users/Drivers/UserDisplayDriver.cs index ad0064b3699..ffb7381fd63 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Drivers/UserDisplayDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Users/Drivers/UserDisplayDriver.cs @@ -53,8 +53,7 @@ public override Task DisplayAsync(User user, BuildDisplayContext return CombineAsync( Initialize("UserFields", model => model.User = user).Location("SummaryAdmin", "Header:1"), Initialize("UserInfo", model => model.User = user).Location("DetailAdmin", "Content:5"), - Initialize("UserButtons", model => model.User = user).Location("SummaryAdmin", "Actions:1"), - Initialize("UserActionsMenu", model => model.User = user).Location("SummaryAdmin", "ActionsMenu:5") + Initialize("UserButtons", model => model.User = user).Location("SummaryAdmin", "Actions:1") ); } diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Extensions/ControllerExtensions.cs b/src/OrchardCore.Modules/OrchardCore.Users/Extensions/ControllerExtensions.cs index 6b368864bfc..c97ae90868c 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Extensions/ControllerExtensions.cs +++ b/src/OrchardCore.Modules/OrchardCore.Users/Extensions/ControllerExtensions.cs @@ -106,7 +106,7 @@ internal static async Task SendEmailConfirmationTokenAsync(this Controll }, protocol: controller.HttpContext.Request.Scheme); - await SendEmailAsync(controller, user.Email, subject, new ConfirmEmailViewModel + await SendEmailAsync(controller, user.Email, subject, new ConfirmEmailViewModel() { User = user, ConfirmEmailUrl = callbackUrl, diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Filters/TwoFactorAuthenticationAuthorizationFilter.cs b/src/OrchardCore.Modules/OrchardCore.Users/Filters/TwoFactorAuthenticationAuthorizationFilter.cs index c0543341d0a..9991acd89be 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Filters/TwoFactorAuthenticationAuthorizationFilter.cs +++ b/src/OrchardCore.Modules/OrchardCore.Users/Filters/TwoFactorAuthenticationAuthorizationFilter.cs @@ -1,3 +1,4 @@ +using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; @@ -31,7 +32,56 @@ public TwoFactorAuthenticationAuthorizationFilter( _userManager = userManager; _twoFactorHandlerCoordinator = twoFactorHandlerCoordinator; } + public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) + { + ArgumentNullException.ThrowIfNull(context); + + if (context.HttpContext?.User?.Identity?.IsAuthenticated == false || + context.HttpContext.Request.Path.Equals("/" + _userOptions.LogoffPath, StringComparison.OrdinalIgnoreCase) || + context.HttpContext.Request.Path.Equals("/" + _userOptions.TwoFactorAuthenticationPath, StringComparison.OrdinalIgnoreCase) || + context.HttpContext.Request.Path.Equals("/TwoFactor-Authenticator/", StringComparison.OrdinalIgnoreCase)) + { + await next(); + return; + } + + var routeValues = context.HttpContext.Request.RouteValues; + var areaName = routeValues["area"]?.ToString(); + + if (areaName != null && string.Equals(areaName, UserConstants.Features.Users, StringComparison.OrdinalIgnoreCase)) + { + var controllerName = routeValues["controller"]?.ToString(); + if (controllerName != null && _allowedControllerNames.Contains(controllerName, StringComparer.OrdinalIgnoreCase)) + { + await next(); + return; + } + } + + if (context.HttpContext.User.HasClaim(claim => claim.Type == UserConstants.TwoFactorAuthenticationClaimType)) + { + var user = await _userManager.GetUserAsync(context.HttpContext.User); + + if (user == null) + { + await next(); + return; + } + + if (await _twoFactorHandlerCoordinator.IsRequiredAsync(user)) + { + // 获取当前请求的 URL + var originalUrl = context.HttpContext.Request.GetEncodedUrl(); + // 构建带有 returnUrl 参数的重定向 URL + var redirectUrl = $"/{_userOptions.TwoFactorAuthenticationPath}?returnUrl={Uri.EscapeDataString(originalUrl)}"; + context.Result = new RedirectResult(redirectUrl); + return; + } + } + + await next(); + } public async Task OnAuthorizationAsync(AuthorizationFilterContext context) { ArgumentNullException.ThrowIfNull(context); @@ -68,7 +118,26 @@ public async Task OnAuthorizationAsync(AuthorizationFilterContext context) if (await _twoFactorHandlerCoordinator.IsRequiredAsync(user)) { - context.Result = new RedirectResult("~/" + _userOptions.TwoFactorAuthenticationPath); + // 获取当前访问的URL + var currentUrl = context.HttpContext.Request.GetEncodedUrl(); + var requestScheme = context.HttpContext.Request.Scheme; + var host = context.HttpContext.Request.Host; +// var currentUrl = $"{requestScheme}://{host}{context.HttpContext.Request.PathBase}{context.HttpContext.Request.Path}{context.HttpContext.Request.QueryString}"; + +// var returnUrl = currentUrl.StartsWith($"{requestScheme}://{host}") +// ? $"{context.HttpContext.Request.PathBase}{context.HttpContext.Request.Path}{context.HttpContext.Request.QueryString}" +// : currentUrl; + // 如果是同域名,只保留路径部分 + var returnUrl = currentUrl.StartsWith($"{requestScheme}://{host}") + ? $"{context.HttpContext.Request.Path}{context.HttpContext.Request.QueryString}" + : currentUrl; + + // 生成重定向URL + var redirectUrl = $"/{_userOptions.TwoFactorAuthenticationPath}?returnUrl={Uri.EscapeDataString(returnUrl)}"; + + context.Result = new RedirectResult(redirectUrl); + + // context.Result = new RedirectResult("~/" + _userOptions.TwoFactorAuthenticationPath); } } } diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Liquid/UserFilters.cs b/src/OrchardCore.Modules/OrchardCore.Users/Liquid/UserFilters.cs index b8ce03755cd..1e1d36564e9 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Liquid/UserFilters.cs +++ b/src/OrchardCore.Modules/OrchardCore.Users/Liquid/UserFilters.cs @@ -3,7 +3,6 @@ using Fluid.Values; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; using OrchardCore.Liquid; using OrchardCore.Security; using OrchardCore.Security.Permissions; @@ -47,10 +46,6 @@ public static ValueTask HasClaim(FluidValue input, FilterArguments a if (string.Equals(claimType, Permission.ClaimType, StringComparison.OrdinalIgnoreCase) && user.HasClaim(StandardClaims.SiteOwner.Type, StandardClaims.SiteOwner.Value)) { - var logger = context.Services.GetRequiredService>(); - - logger.LogWarning("The tenant is using the 'has_claim' Liquid filter for Permission claims '{ClaimName}', which will break in the next major release of OrchardCore; please use 'has_permission: \"{ClaimName}\"' instead.", claimName, claimName); - return BooleanValue.True; } } diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Models/TwoFactorMethod.cs b/src/OrchardCore.Modules/OrchardCore.Users/Models/TwoFactorMethod.cs index 842b3aa0e0c..d5cccbcd20c 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Models/TwoFactorMethod.cs +++ b/src/OrchardCore.Modules/OrchardCore.Users/Models/TwoFactorMethod.cs @@ -5,4 +5,5 @@ public class TwoFactorMethod public string Provider { get; set; } public bool IsEnabled { get; set; } + public string ReturnUrl { get; set; } } diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Startup.cs b/src/OrchardCore.Modules/OrchardCore.Users/Startup.cs index 92446e5da87..deb4b9e969a 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Startup.cs +++ b/src/OrchardCore.Modules/OrchardCore.Users/Startup.cs @@ -424,7 +424,6 @@ public override void ConfigureServices(IServiceCollection services) o.MemberAccessStrategy.Register(); }); - services.AddScoped, UserRegistrationAdminDisplayDriver>(); services.AddSiteDisplayDriver(); services.AddNavigationProvider(); diff --git a/src/OrchardCore.Modules/OrchardCore.Users/TwoFactorAuthenticationStartup.cs b/src/OrchardCore.Modules/OrchardCore.Users/TwoFactorAuthenticationStartup.cs index 5d17b78f2d8..20629391bb6 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/TwoFactorAuthenticationStartup.cs +++ b/src/OrchardCore.Modules/OrchardCore.Users/TwoFactorAuthenticationStartup.cs @@ -7,7 +7,6 @@ using OrchardCore.DisplayManagement.Handlers; using OrchardCore.Modules; using OrchardCore.Mvc.Core.Utilities; -using OrchardCore.Security.Permissions; using OrchardCore.Users.Controllers; using OrchardCore.Users.Drivers; using OrchardCore.Users.Endpoints.EmailAuthenticator; @@ -33,12 +32,10 @@ public override void ConfigureServices(IServiceCollection services) options.Filters.Add(); }); - services.AddScoped, UserTwoFactorDisplayDriver>(); services.AddScoped(); services.AddScoped, TwoFactorUserMenuDisplayDriver>(); services.AddSiteDisplayDriver(); services.AddScoped, TwoFactorMethodDisplayDriver>(); - services.AddPermissionProvider(); } public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider) diff --git a/src/OrchardCore.Modules/OrchardCore.Users/ViewModels/EnableSmsAuthenticatorViewModel.cs b/src/OrchardCore.Modules/OrchardCore.Users/ViewModels/EnableSmsAuthenticatorViewModel.cs index 1956b3959b9..6657d67b181 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/ViewModels/EnableSmsAuthenticatorViewModel.cs +++ b/src/OrchardCore.Modules/OrchardCore.Users/ViewModels/EnableSmsAuthenticatorViewModel.cs @@ -8,4 +8,5 @@ public class EnableSmsAuthenticatorViewModel public string Code { get; set; } public string PhoneNumber { get; set; } + public string ReturnUrl { get; set; } } diff --git a/src/OrchardCore.Modules/OrchardCore.Users/ViewModels/RequestCodeSmsAuthenticatorViewModel.cs b/src/OrchardCore.Modules/OrchardCore.Users/ViewModels/RequestCodeSmsAuthenticatorViewModel.cs index 5931f81695d..f21c3758ad1 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/ViewModels/RequestCodeSmsAuthenticatorViewModel.cs +++ b/src/OrchardCore.Modules/OrchardCore.Users/ViewModels/RequestCodeSmsAuthenticatorViewModel.cs @@ -8,4 +8,5 @@ public class RequestCodeSmsAuthenticatorViewModel [BindNever] public bool AllowChangingPhoneNumber { get; set; } + public string ReturnUrl { get; set; } } diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Views/Items/TwoFactorMethod.Authenticator.Actions.cshtml b/src/OrchardCore.Modules/OrchardCore.Users/Views/Items/TwoFactorMethod.Authenticator.Actions.cshtml index c84c6e2c49a..ab10148c778 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Views/Items/TwoFactorMethod.Authenticator.Actions.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Users/Views/Items/TwoFactorMethod.Authenticator.Actions.cshtml @@ -4,10 +4,10 @@ @if (Model.IsEnabled) { - @T["Set"] + @T["Set"] @T["Reset"] } else { - @T["Add"] + @T["Add"] } diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Views/SmsAuthenticator/ValidateCode.cshtml b/src/OrchardCore.Modules/OrchardCore.Users/Views/SmsAuthenticator/ValidateCode.cshtml index 69fded480f6..feb0601f590 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Views/SmsAuthenticator/ValidateCode.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Users/Views/SmsAuthenticator/ValidateCode.cshtml @@ -20,12 +20,13 @@ -
+
+
diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Views/SmsAuthenticatorValidation.cshtml b/src/OrchardCore.Modules/OrchardCore.Users/Views/SmsAuthenticatorValidation.cshtml index ea3faad2903..7ca4e83919f 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Views/SmsAuthenticatorValidation.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Users/Views/SmsAuthenticatorValidation.cshtml @@ -4,7 +4,7 @@
@T["Please click here to receive a one-time verification code via SMS."]
- +
SmsAuthenticatorValidation
diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Views/TemplateUserConfirmEmail.cshtml b/src/OrchardCore.Modules/OrchardCore.Users/Views/TemplateUserConfirmEmail.cshtml index 891c422f467..dbad46ccb69 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Views/TemplateUserConfirmEmail.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Users/Views/TemplateUserConfirmEmail.cshtml @@ -13,7 +13,7 @@ @T["Dear {0},", Model.User.UserName]

-

@T["Please click here to confirm your account.", Html.Raw(Model.ConfirmEmailUrl)]

+

@T["Please click here to confirm your account.", Model.ConfirmEmailUrl]

@T.Plural(totalMinutes, "Please be aware that this link will expire in {0} minute.", "Please be aware that this link will expire in {0} minutes.", totalMinutes)

diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Views/TwoFactorAuthentication/Index.cshtml b/src/OrchardCore.Modules/OrchardCore.Users/Views/TwoFactorAuthentication/Index.cshtml index 05f5d5bb50b..c3ae1eb8b07 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Views/TwoFactorAuthentication/Index.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Users/Views/TwoFactorAuthentication/Index.cshtml @@ -11,7 +11,7 @@ ViewLayout = "Layout__TwoFactor"; } - +TowFactorAuthentication @if (Model.AuthenticationMethods.Count == 0) {
@@ -59,7 +59,7 @@ } else if (!Model.IsTwoFaEnabled && Model.ValidTwoFactorProviders.Count > 0) { -
+
} @@ -99,7 +99,7 @@ {

@T["The current device has been saved during the two-factor authentication process."]

-
+
@@ -108,7 +108,7 @@ @if (Model.ValidTwoFactorProviders.Count > 1) { -
+
+ + +}