diff --git a/aspnet-core/LINGYUN.MicroService.All.sln b/aspnet-core/LINGYUN.MicroService.All.sln index d95121a18..0d1e59be7 100644 --- a/aspnet-core/LINGYUN.MicroService.All.sln +++ b/aspnet-core/LINGYUN.MicroService.All.sln @@ -426,7 +426,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.TextTemplating. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.Common", "modules\common\LINGYUN.Abp.Notifications.Common\LINGYUN.Abp.Notifications.Common.csproj", "{0CE035CF-2D8A-4559-93EC-ADBEC4237C61}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.AspNetCore.Mvc.Localization", "modules\localization\LINGYUN.Abp.AspNetCore.Mvc.Localization\LINGYUN.Abp.AspNetCore.Mvc.Localization.csproj", "{995DB1CE-A2FC-4468-A521-4207FD587EC5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.Mvc.Localization", "modules\localization\LINGYUN.Abp.AspNetCore.Mvc.Localization\LINGYUN.Abp.AspNetCore.Mvc.Localization.csproj", "{995DB1CE-A2FC-4468-A521-4207FD587EC5}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Account.Domain.Shared", "modules\account\LINGYUN.Abp.Account.Domain.Shared\LINGYUN.Abp.Account.Domain.Shared.csproj", "{446852ED-D80C-450F-8383-6B1ADCA08A59}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -1110,6 +1112,10 @@ Global {995DB1CE-A2FC-4468-A521-4207FD587EC5}.Debug|Any CPU.Build.0 = Debug|Any CPU {995DB1CE-A2FC-4468-A521-4207FD587EC5}.Release|Any CPU.ActiveCfg = Release|Any CPU {995DB1CE-A2FC-4468-A521-4207FD587EC5}.Release|Any CPU.Build.0 = Release|Any CPU + {446852ED-D80C-450F-8383-6B1ADCA08A59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {446852ED-D80C-450F-8383-6B1ADCA08A59}.Debug|Any CPU.Build.0 = Debug|Any CPU + {446852ED-D80C-450F-8383-6B1ADCA08A59}.Release|Any CPU.ActiveCfg = Release|Any CPU + {446852ED-D80C-450F-8383-6B1ADCA08A59}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1319,6 +1325,7 @@ Global {A53FE09E-6B1C-46C0-9422-C313D14AE9E4} = {ABD89F39-62D9-439E-8662-BE4F36BFA04F} {0CE035CF-2D8A-4559-93EC-ADBEC4237C61} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E} {995DB1CE-A2FC-4468-A521-4207FD587EC5} = {90E88EAC-4291-4406-8D88-EFDF61B11292} + {446852ED-D80C-450F-8383-6B1ADCA08A59} = {9E72FEB9-A626-4312-892B-CDD043879758} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718} diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN.Abp.Account.Application.Contracts.csproj b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN.Abp.Account.Application.Contracts.csproj index 49d8645c9..95bc1f9ba 100644 --- a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN.Abp.Account.Application.Contracts.csproj +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN.Abp.Account.Application.Contracts.csproj @@ -9,17 +9,11 @@ - - - - - - - + - + diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/AbpAccountApplicationContractsModule.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/AbpAccountApplicationContractsModule.cs index 4cff95a7d..6044f4a04 100644 --- a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/AbpAccountApplicationContractsModule.cs +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/AbpAccountApplicationContractsModule.cs @@ -1,27 +1,11 @@ -using Volo.Abp.Account.Localization; -using Volo.Abp.Localization; -using Volo.Abp.Modularity; -using Volo.Abp.VirtualFileSystem; +using Volo.Abp.Modularity; namespace LINGYUN.Abp.Account { [DependsOn( - typeof(Volo.Abp.Account.AbpAccountApplicationContractsModule))] + typeof(Volo.Abp.Account.AbpAccountApplicationContractsModule), + typeof(AbpAccountDomainSharedModule))] public class AbpAccountApplicationContractsModule : AbpModule { - public override void ConfigureServices(ServiceConfigurationContext context) - { - Configure(options => - { - options.FileSets.AddEmbedded(); - }); - - Configure(options => - { - options.Resources - .Get() - .AddVirtualJson("/LINGYUN/Abp/Account/Localization/Resources"); - }); - } } } diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Dto/GetTwoFactorProvidersInput.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Dto/GetTwoFactorProvidersInput.cs new file mode 100644 index 000000000..2e65ad104 --- /dev/null +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Dto/GetTwoFactorProvidersInput.cs @@ -0,0 +1,10 @@ +using Volo.Abp.Identity; +using Volo.Abp.Validation; + +namespace LINGYUN.Abp.Account; + +public class GetTwoFactorProvidersInput +{ + [DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxUserNameLength))] + public string UserName { get; set; } +} diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Dto/SendEmailSigninCodeDto.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Dto/SendEmailSigninCodeDto.cs new file mode 100644 index 000000000..b005c0d9c --- /dev/null +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Dto/SendEmailSigninCodeDto.cs @@ -0,0 +1,13 @@ +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Identity; +using Volo.Abp.Validation; + +namespace LINGYUN.Abp.Account; +public class SendEmailSigninCodeDto +{ + [Required] + [EmailAddress] + [Display(Name = "EmailAddress")] + [DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxEmailLength))] + public string EmailAddress { get; set; } +} diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/IAccountAppService.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/IAccountAppService.cs index 09490c334..102c0cf32 100644 --- a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/IAccountAppService.cs +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/IAccountAppService.cs @@ -1,4 +1,6 @@ using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; namespace LINGYUN.Abp.Account @@ -35,11 +37,23 @@ namespace LINGYUN.Abp.Account /// /// Task SendPhoneSigninCodeAsync(SendPhoneSigninCodeDto input); + /// + /// 发送邮件登录验证码 + /// + /// + /// + Task SendEmailSigninCodeAsync(SendEmailSigninCodeDto input); /// /// 发送手机重置密码验证码短信 /// /// /// Task SendPhoneResetPasswordCodeAsync(SendPhoneResetPasswordCodeDto input); + /// + /// 获取用户二次认证提供者列表 + /// + /// + /// + Task> GetTwoFactorProvidersAsync(GetTwoFactorProvidersInput input); } } diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Localization/Resources/en.json b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Localization/Resources/en.json deleted file mode 100644 index 4027f88bd..000000000 --- a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Localization/Resources/en.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "culture": "en", - "texts": { - "SendRepeatSmsVerifyCode": "Phone verification code cannot be sent repeatedly within {0} minutes!", - "DuplicatePhoneNumber": "The phone number already exists!", - "PhoneNumberNotRegisterd": "The registered mobile phone number is not registered!", - "InvalidSmsVerifyCode": "The phone verification code is invalid or expired!", - "RequiredEmailAddress": "Email address required", - "InvalidPhoneNumber": "Invalid phone number", - "DuplicateWeChat": "The wechat has been registered!", - "DisplayName:SmsVerifyCode": "SMS verification code", - "DisplayName:EmailVerifyCode": "Mail verification code", - "DisplayName:WeChatCode": "Wechat login code" - } -} \ No newline at end of file diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Localization/Resources/zh-Hans.json b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Localization/Resources/zh-Hans.json deleted file mode 100644 index 61f172530..000000000 --- a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Localization/Resources/zh-Hans.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "culture": "zh-Hans", - "texts": { - "SendRepeatSmsVerifyCode": "手机验证码不能在 {0} 分钟内重复发送!", - "DuplicatePhoneNumber": "手机号已经存在!", - "PhoneNumberNotRegisterd": "手机号码未注册!", - "InvalidSmsVerifyCode": "手机验证码无效或已经过期!", - "RequiredEmailAddress": "邮件地址必须输入", - "InvalidPhoneNumber": "手机号无效", - "DuplicateWeChat": "微信号已经注册过!", - "DisplayName:SmsVerifyCode": "短信验证码", - "DisplayName:EmailVerifyCode": "邮件验证码", - "DisplayName:WeChatCode": "微信登录凭证" - } -} \ No newline at end of file diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AccountAppService.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AccountAppService.cs index 5b0483eff..7767e4421 100644 --- a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AccountAppService.cs +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AccountAppService.cs @@ -1,4 +1,5 @@ -using LINGYUN.Abp.Identity; +using LINGYUN.Abp.Account.Emailing; +using LINGYUN.Abp.Identity; using LINGYUN.Abp.Identity.Security; using LINGYUN.Abp.Identity.Settings; using LINGYUN.Abp.WeChat; @@ -10,10 +11,12 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using System; using System.ComponentModel.DataAnnotations; +using System.Linq; using System.Text; using System.Threading.Tasks; using Volo.Abp; using Volo.Abp.Account; +using Volo.Abp.Application.Dtos; using Volo.Abp.Caching; using Volo.Abp.Clients; using Volo.Abp.Identity; @@ -304,6 +307,40 @@ namespace LINGYUN.Abp.Account }); } + public async virtual Task SendEmailSigninCodeAsync(SendEmailSigninCodeDto input) + { + var sender = LazyServiceProvider.LazyGetRequiredService(); + + var user = await UserManager.FindByEmailAsync(input.EmailAddress); + + if (user == null) + { + throw new UserFriendlyException(L["UserNotRegisterd"]); + } + if (!user.EmailConfirmed) + { + throw new UserFriendlyException(L["UserEmailNotConfirmed"]); + } + + var code = await UserManager.GenerateTwoFactorTokenAsync(user, TokenOptions.DefaultEmailProvider); + + await sender.SendMailLoginVerifyCodeAsync(code, user.UserName, user.Email); + } + + public async virtual Task> GetTwoFactorProvidersAsync(GetTwoFactorProvidersInput input) + { + var user = await UserManager.FindByNameAsync(input.UserName); + + if (user == null) + { + throw new UserFriendlyException(L["UserNotRegisterd"]); + } + + var userFactors = await UserManager.GetValidTwoFactorProvidersAsync(user); + return new ListResultDto( + userFactors.Select(key => new NameValue(L[$"TwoFactor:{key}"].Value, key)).ToList()); + } + protected virtual async Task GetUserByPhoneNumberAsync(string phoneNumber, bool isConfirmed = true) { var user = await UserRepository.FindByPhoneNumberAsync(phoneNumber, isConfirmed, true); diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/MyClaimAppService.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/MyClaimAppService.cs index 1e9f06897..a07a782fe 100644 --- a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/MyClaimAppService.cs +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/MyClaimAppService.cs @@ -1,4 +1,5 @@ using LINGYUN.Abp.Identity; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using System.Collections.Generic; using System.Security.Claims; @@ -6,6 +7,7 @@ using System.Threading.Tasks; namespace LINGYUN.Abp.Account { + [Authorize] public class MyClaimAppService : AccountApplicationServiceBase, IMyClaimAppService { public MyClaimAppService() diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/FodyWeavers.xsd b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/FodyWeavers.xsd new file mode 100644 index 000000000..11da52550 --- /dev/null +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN.Abp.Account.Domain.Shared.csproj b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN.Abp.Account.Domain.Shared.csproj index 9209be4eb..f5931fa38 100644 --- a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN.Abp.Account.Domain.Shared.csproj +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN.Abp.Account.Domain.Shared.csproj @@ -1,18 +1,25 @@ - - - + - - netstandard2.0 - - + + - - - + + netstandard2.0 + + - - - + + + + + + + + + + + + + diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/AbpAccountDomainSharedModule.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/AbpAccountDomainSharedModule.cs index cda7cd239..ec56918ac 100644 --- a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/AbpAccountDomainSharedModule.cs +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/AbpAccountDomainSharedModule.cs @@ -1,11 +1,13 @@ -using Volo.Abp.Account.Localization; +using LINGYUN.Abp.Account.Localization; +using Volo.Abp.Emailing; using Volo.Abp.Localization; using Volo.Abp.Modularity; using Volo.Abp.VirtualFileSystem; namespace LINGYUN.Abp.Account { - [DependsOn(typeof(AbpLocalizationModule))] + [DependsOn( + typeof(AbpEmailingModule))] public class AbpAccountDomainSharedModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) @@ -18,7 +20,7 @@ namespace LINGYUN.Abp.Account Configure(options => { options.Resources - .Add("zh-Hans") + .Add("en") .AddVirtualJson("/LINGYUN/Abp/Account/Localization/Resources"); }); } diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/AccountRegisterVerifyCacheItem.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/AccountRegisterVerifyCacheItem.cs deleted file mode 100644 index ea74bbe66..000000000 --- a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/AccountRegisterVerifyCacheItem.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace LINGYUN.Abp.Account -{ - public class AccountRegisterVerifyCacheItem - { - public string PhoneNumber { get; set; } - public string VerifyCode { get; set; } - public string VerifyToken { get; set; } - } -} diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/AccountUrlNames.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/AccountUrlNames.cs deleted file mode 100644 index 3541c5868..000000000 --- a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/AccountUrlNames.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace LINGYUN.Abp.Account -{ - /// - /// 定义账户系统Url - /// - /// - /// 定义在领域共享层,可以方便其他应用程序调用 - /// - public static class AccountUrlNames - { - /// - /// 邮件登录验证地址 - /// - public static string MailLoginVerify { get; set; } = ""; - } -} diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Emailing/AccountEmailVerifySender.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Emailing/AccountEmailVerifySender.cs new file mode 100644 index 000000000..4d959f55b --- /dev/null +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Emailing/AccountEmailVerifySender.cs @@ -0,0 +1,44 @@ +using LINGYUN.Abp.Account.Localization; +using LY.MicroService.IdentityServer.Emailing.Templates; +using Microsoft.Extensions.Localization; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Emailing; +using Volo.Abp.TextTemplating; + +namespace LINGYUN.Abp.Account.Emailing; + +public class AccountEmailVerifySender : IAccountEmailVerifySender, ITransientDependency +{ + protected IEmailSender EmailSender { get; } + protected ITemplateRenderer TemplateRenderer { get; } + + protected IStringLocalizer StringLocalizer { get; } + + public AccountEmailVerifySender( + IEmailSender emailSender, + ITemplateRenderer templateRenderer, + IStringLocalizer stringLocalizer) + { + EmailSender = emailSender; + TemplateRenderer = templateRenderer; + StringLocalizer = stringLocalizer; + } + + public async virtual Task SendMailLoginVerifyCodeAsync( + string code, + string userName, + string emailAddress) + { + var emailContent = await TemplateRenderer.RenderAsync( + AccountEmailTemplates.MailSecurityVerifyLink, + new { code = code, user = userName } + ); + + await EmailSender.SendAsync( + emailAddress, + StringLocalizer["MailSecurityVerify"], + emailContent + ); + } +} diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Emailing/IAccountEmailVerifySender.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Emailing/IAccountEmailVerifySender.cs new file mode 100644 index 000000000..55eb373c0 --- /dev/null +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Emailing/IAccountEmailVerifySender.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; + +namespace LINGYUN.Abp.Account.Emailing; + +public interface IAccountEmailVerifySender +{ + Task SendMailLoginVerifyCodeAsync( + string code, + string userName, + string emailAddress); +} diff --git a/aspnet-core/services/LY.MicroService.identityServer/Emailing/Templates/AccountEmailTemplateDefinitionProvider.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Emailing/Templates/AccountEmailTemplateDefinitionProvider.cs similarity index 56% rename from aspnet-core/services/LY.MicroService.identityServer/Emailing/Templates/AccountEmailTemplateDefinitionProvider.cs rename to aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Emailing/Templates/AccountEmailTemplateDefinitionProvider.cs index 3256e18fd..4e3f2a87a 100644 --- a/aspnet-core/services/LY.MicroService.identityServer/Emailing/Templates/AccountEmailTemplateDefinitionProvider.cs +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Emailing/Templates/AccountEmailTemplateDefinitionProvider.cs @@ -1,4 +1,4 @@ -using Volo.Abp.Account.Localization; +using LINGYUN.Abp.Account.Localization; using Volo.Abp.Emailing.Templates; using Volo.Abp.Localization; using Volo.Abp.TextTemplating; @@ -12,10 +12,11 @@ public class AccountEmailTemplateDefinitionProvider : TemplateDefinitionProvider context.Add( new TemplateDefinition( AccountEmailTemplates.MailSecurityVerifyLink, - displayName: LocalizableString.Create($"TextTemplate:{AccountEmailTemplates.MailSecurityVerifyLink}"), + displayName: LocalizableString.Create( + $"TextTemplate:{AccountEmailTemplates.MailSecurityVerifyLink}"), layout: StandardEmailTemplates.Layout, - localizationResource: typeof(AccountResource) - ).WithVirtualFilePath("/Emailing/Templates/MailSecurityVerify.tpl", true) + localizationResource: typeof(AbpAccountResource) + ).WithVirtualFilePath("/LINGYUN/Abp/Account/Emailing/Templates/MailSecurityVerify.tpl", true) ); } } diff --git a/aspnet-core/services/LY.MicroService.identityServer/Emailing/Templates/AccountEmailTemplates.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Emailing/Templates/AccountEmailTemplates.cs similarity index 100% rename from aspnet-core/services/LY.MicroService.identityServer/Emailing/Templates/AccountEmailTemplates.cs rename to aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Emailing/Templates/AccountEmailTemplates.cs diff --git a/aspnet-core/services/LY.MicroService.identityServer/Emailing/Templates/MailSecurityVerify.tpl b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Emailing/Templates/MailSecurityVerify.tpl similarity index 100% rename from aspnet-core/services/LY.MicroService.identityServer/Emailing/Templates/MailSecurityVerify.tpl rename to aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Emailing/Templates/MailSecurityVerify.tpl diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Localization/AbpAccountResource.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Localization/AbpAccountResource.cs new file mode 100644 index 000000000..ebc24bbb6 --- /dev/null +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Localization/AbpAccountResource.cs @@ -0,0 +1,8 @@ +using Volo.Abp.Localization; + +namespace LINGYUN.Abp.Account.Localization; + +[LocalizationResourceName("AbpAccountResource")] +public class AbpAccountResource +{ +} diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Localization/Resources/en.json b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Localization/Resources/en.json new file mode 100644 index 000000000..bc21bd865 --- /dev/null +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Localization/Resources/en.json @@ -0,0 +1,33 @@ +{ + "culture": "en", + "texts": { + "UserNotRegisterd": "The user account is not registered!", + "UserEmailNotConfirmed": "The user's email address is not confirmed!", + "SendRepeatSmsVerifyCode": "Phone verification code cannot be sent repeatedly within {0} minutes!", + "DuplicatePhoneNumber": "The phone number already exists!", + "PhoneNumberNotRegisterd": "The registered mobile phone number is not registered!", + "InvalidSmsVerifyCode": "The phone verification code is invalid or expired!", + "RequiredEmailAddress": "Email address required", + "InvalidPhoneNumber": "Invalid phone number", + "DuplicateWeChat": "The wechat has been registered!", + "DisplayName:SmsVerifyCode": "SMS verification code", + "DisplayName:EmailVerifyCode": "Mail verification code", + "DisplayName:WeChatCode": "Wechat login code", + "TwoFactor": "Two factor authentication", + "TwoFactor:Email": "Email", + "TwoFactor:Phone": "Phone", + "TwoFactor:Authenticator": "Authenticator", + "SelectedProvider": "Select validation mode", + "SendVerifyCode": "Send verification code", + "VerifyCode": "Verification code", + "VerifyAuthenticatorCode": "Authentication code", + "RememberBrowser": "Remember me in the browser", + "TwoFactorAuthenticationInvaidUser": "Authentication failed. Your session is invalid. Please re login try again!", + "InvaidGenerateTwoFactorToken": "Verification code generation failed. Please contact your administrator!", + "TextTemplate:Abp.Account.MailSecurityVerifyLink": "Mail security validation template", + "MailSecurityVerify": "Mail security verification", + "VerifyMyEmailAddress": "Hello {0}

Your email security verification code is as follows. Please enter the verification code to proceed to the next step.

If not operated by you, please ignore this email.

", + "MailSecurityVerifyRemarks": "

(If it is not in the form of a link, copy the address to the browser address bar for further access)

Thank you for your visit and have a good time!

", + "ClickToValidation": "Click link verification" + } +} \ No newline at end of file diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Localization/Resources/zh-Hans.json b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Localization/Resources/zh-Hans.json new file mode 100644 index 000000000..e9650ceeb --- /dev/null +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Localization/Resources/zh-Hans.json @@ -0,0 +1,33 @@ +{ + "culture": "zh-Hans", + "texts": { + "UserNotRegisterd": "用户账号未注册!", + "UserEmailNotConfirmed": "用户邮件地址未确认!", + "SendRepeatSmsVerifyCode": "手机验证码不能在 {0} 分钟内重复发送!", + "DuplicatePhoneNumber": "手机号已经存在!", + "PhoneNumberNotRegisterd": "手机号码未注册!", + "InvalidSmsVerifyCode": "手机验证码无效或已经过期!", + "RequiredEmailAddress": "邮件地址必须输入", + "InvalidPhoneNumber": "手机号无效", + "DuplicateWeChat": "微信号已经注册过!", + "DisplayName:SmsVerifyCode": "短信验证码", + "DisplayName:EmailVerifyCode": "邮件验证码", + "DisplayName:WeChatCode": "微信登录凭证", + "TwoFactor": "双因素身份验证", + "TwoFactor:Email": "邮箱验证", + "TwoFactor:Phone": "手机验证", + "TwoFactor:Authenticator": "验证码验证", + "SelectedProvider": "选择验证方式", + "SendVerifyCode": "发送验证码", + "VerifyCode": "验证码", + "VerifyAuthenticatorCode": "验证身份代码", + "RememberBrowser": "在浏览器中记住我", + "TwoFactorAuthenticationInvaidUser": "认证失败,您的会话已失效,请程序登录!", + "InvaidGenerateTwoFactorToken": "验证码生成失败,请联系管理员!", + "TextTemplate:Abp.Account.MailSecurityVerifyLink": "邮件安全验证模板", + "MailSecurityVerify": "邮件安全验证", + "VerifyMyEmailAddress": "您好

您此次邮件安全验证码如下,请输入验证码进行下一步操作。

如非你本人操作,请忽略此邮件。

", + "MailSecurityVerifyRemarks": "此邮件为系统所发,请勿直接回复。", + "ClickToValidation": "点击进行验证" + } +} \ No newline at end of file diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/PhoneNumberVerifyType.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/PhoneNumberVerifyType.cs deleted file mode 100644 index 4c01f3b55..000000000 --- a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/PhoneNumberVerifyType.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace LINGYUN.Abp.Account -{ - public enum PhoneNumberVerifyType : sbyte - { - Register = 0, - Signin = 10, - ResetPassword = 20 - } -} diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.HttpApi/LINGYUN/Abp/Account/AbpAccountHttpApiModule.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.HttpApi/LINGYUN/Abp/Account/AbpAccountHttpApiModule.cs index 66ae75ed2..78771e56b 100644 --- a/aspnet-core/modules/account/LINGYUN.Abp.Account.HttpApi/LINGYUN/Abp/Account/AbpAccountHttpApiModule.cs +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.HttpApi/LINGYUN/Abp/Account/AbpAccountHttpApiModule.cs @@ -1,6 +1,8 @@ -using Microsoft.Extensions.DependencyInjection; +using LINGYUN.Abp.Account.Localization; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Account.Localization; using Volo.Abp.AspNetCore.Mvc.Localization; +using Volo.Abp.Localization; using Volo.Abp.Modularity; namespace LINGYUN.Abp.Account @@ -24,5 +26,15 @@ namespace LINGYUN.Abp.Account mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpAccountHttpApiModule).Assembly); }); } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.Resources + .Get() + .AddBaseTypes(typeof(AbpAccountResource)); + }); + } } } diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.HttpApi/LINGYUN/Abp/Account/AccountController.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.HttpApi/LINGYUN/Abp/Account/AccountController.cs index 03d051e3f..7ae3ef60f 100644 --- a/aspnet-core/modules/account/LINGYUN.Abp.Account.HttpApi/LINGYUN/Abp/Account/AccountController.cs +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.HttpApi/LINGYUN/Abp/Account/AccountController.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using Volo.Abp; using Volo.Abp.Account; +using Volo.Abp.Application.Dtos; using Volo.Abp.AspNetCore.Mvc; namespace LINGYUN.Abp.Account @@ -46,6 +47,13 @@ namespace LINGYUN.Abp.Account await AccountAppService.SendPhoneSigninCodeAsync(input); } + [HttpPost] + [Route("email/send-signin-code")] + public async virtual Task SendEmailSigninCodeAsync(SendEmailSigninCodeDto input) + { + await AccountAppService.SendEmailSigninCodeAsync(input); + } + [HttpPost] [Route("phone/send-register-code")] public async virtual Task SendPhoneRegisterCodeAsync(SendPhoneRegisterCodeDto input) @@ -59,5 +67,12 @@ namespace LINGYUN.Abp.Account { await AccountAppService.SendPhoneResetPasswordCodeAsync(input); } + + [HttpGet] + [Route("two-factor-providers")] + public async virtual Task> GetTwoFactorProvidersAsync(GetTwoFactorProvidersInput input) + { + return await AccountAppService.GetTwoFactorProvidersAsync(input); + } } } diff --git a/aspnet-core/services/LY.MicroService.identityServer/Emailing/AccountEmailVerifySender.cs b/aspnet-core/services/LY.MicroService.identityServer/Emailing/AccountEmailVerifySender.cs deleted file mode 100644 index 63b2ee0d0..000000000 --- a/aspnet-core/services/LY.MicroService.identityServer/Emailing/AccountEmailVerifySender.cs +++ /dev/null @@ -1,104 +0,0 @@ -using LY.MicroService.IdentityServer.Emailing.Templates; -using Microsoft.Extensions.Localization; -using System; -using System.Diagnostics; -using System.Threading.Tasks; -using System.Web; -using Volo.Abp.Account.Emailing; -using Volo.Abp.Account.Localization; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Emailing; -using Volo.Abp.Identity; -using Volo.Abp.MultiTenancy; -using Volo.Abp.TextTemplating; -using Volo.Abp.UI.Navigation.Urls; - -namespace LY.MicroService.IdentityServer.Emailing; - -[Dependency(ReplaceServices = true)] -[ExposeServices( - typeof(IAccountEmailer), - typeof(AccountEmailer), - typeof(IAccountEmailVerifySender), - typeof(AccountEmailVerifySender))] -public class AccountEmailVerifySender : AccountEmailer, IAccountEmailVerifySender, ITransientDependency -{ - public AccountEmailVerifySender( - IEmailSender emailSender, - ITemplateRenderer templateRenderer, - IStringLocalizer stringLocalizer, - IAppUrlProvider appUrlProvider, - ICurrentTenant currentTenant) - : base(emailSender, templateRenderer, stringLocalizer, appUrlProvider, currentTenant) - { - } - - public virtual async Task SendMailLoginVerifyLinkAsync( - IdentityUser user, - string code, - string appName, - string provider, - bool rememberMe = false, - string returnUrl = null, - string returnUrlHash = null) - { - Debug.Assert(CurrentTenant.Id == user.TenantId, "This method can only work for current tenant!"); - - // TODO: 需要生成快捷链接 - //var url = await AppUrlProvider.GetUrlAsync(appName, AccountUrlNames.MailLoginVerify); - - //var link = $"{url}?provider={provider}&rememberMe={rememberMe}&resetToken={UrlEncoder.Default.Encode(code)}"; - - //if (!returnUrl.IsNullOrEmpty()) - //{ - // link += "&returnUrl=" + NormalizeReturnUrl(returnUrl); - //} - - //if (!returnUrlHash.IsNullOrEmpty()) - //{ - // link += "&returnUrlHash=" + returnUrlHash; - //} - - var emailContent = await TemplateRenderer.RenderAsync( - AccountEmailTemplates.MailSecurityVerifyLink, - new { code = code, user = user.UserName } - ); - - await EmailSender.SendAsync( - user.Email, - StringLocalizer["MailSecurityVerify"], - emailContent - ); - } - - protected override string NormalizeReturnUrl(string returnUrl) - { - if (returnUrl.IsNullOrEmpty()) - { - return returnUrl; - } - - //Handling openid connect login - if (returnUrl.StartsWith("/connect/authorize/callback", StringComparison.OrdinalIgnoreCase)) - { - if (returnUrl.Contains("?")) - { - var queryPart = returnUrl.Split('?')[1]; - var queryParameters = queryPart.Split('&'); - foreach (var queryParameter in queryParameters) - { - if (queryParameter.Contains("=")) - { - var queryParam = queryParameter.Split('='); - if (queryParam[0] == "redirect_uri") - { - return HttpUtility.UrlDecode(queryParam[1]); - } - } - } - } - } - - return returnUrl; - } -} diff --git a/aspnet-core/services/LY.MicroService.identityServer/Emailing/IAccountEmailVerifySender.cs b/aspnet-core/services/LY.MicroService.identityServer/Emailing/IAccountEmailVerifySender.cs deleted file mode 100644 index ad52a8824..000000000 --- a/aspnet-core/services/LY.MicroService.identityServer/Emailing/IAccountEmailVerifySender.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading.Tasks; -using Volo.Abp.Account.Emailing; -using Volo.Abp.Identity; - -namespace LY.MicroService.IdentityServer.Emailing; - -public interface IAccountEmailVerifySender : IAccountEmailer -{ - Task SendMailLoginVerifyLinkAsync( - IdentityUser user, - string code, - string appName, - string provider, - bool rememberMe = false, - string returnUrl = null, - string returnUrlHash = null); -} diff --git a/aspnet-core/services/LY.MicroService.identityServer/IdentityServerModule.Configure.cs b/aspnet-core/services/LY.MicroService.identityServer/IdentityServerModule.Configure.cs index 218fd02ee..dd693f9e5 100644 --- a/aspnet-core/services/LY.MicroService.identityServer/IdentityServerModule.Configure.cs +++ b/aspnet-core/services/LY.MicroService.identityServer/IdentityServerModule.Configure.cs @@ -1,4 +1,5 @@ using DotNetCore.CAP; +using LINGYUN.Abp.Account.Localization; using LINGYUN.Abp.IdentityServer.IdentityResources; using LINGYUN.Abp.Localization.CultureMap; using LINGYUN.Abp.Serilog.Enrichers.Application; @@ -179,6 +180,7 @@ public partial class IdentityServerModule options.Resources .Get() + .AddBaseTypes(typeof(AbpAccountResource)) .AddVirtualJson("/Localization/Resources"); }); diff --git a/aspnet-core/services/LY.MicroService.identityServer/IdentityServerModule.cs b/aspnet-core/services/LY.MicroService.identityServer/IdentityServerModule.cs index 262f777e7..04e632358 100644 --- a/aspnet-core/services/LY.MicroService.identityServer/IdentityServerModule.cs +++ b/aspnet-core/services/LY.MicroService.identityServer/IdentityServerModule.cs @@ -1,4 +1,5 @@ using DotNetCore.CAP; +using LINGYUN.Abp.Account; using LINGYUN.Abp.AspNetCore.HttpOverrides; using LINGYUN.Abp.AuditLogging.Elasticsearch; using LINGYUN.Abp.Data.DbMigrator; @@ -44,6 +45,7 @@ namespace LY.MicroService.IdentityServer; typeof(AbpAspNetCoreSerilogModule), typeof(AbpAccountWebIdentityServerModule), typeof(AbpAccountApplicationModule), + typeof(AbpAccountDomainSharedModule), typeof(AbpAspNetCoreMvcUiBasicThemeModule), typeof(AbpAutofacModule), typeof(AbpCachingStackExchangeRedisModule), diff --git a/aspnet-core/services/LY.MicroService.identityServer/LY.MicroService.IdentityServer.csproj b/aspnet-core/services/LY.MicroService.identityServer/LY.MicroService.IdentityServer.csproj index d8d3b7410..4617d0424 100644 --- a/aspnet-core/services/LY.MicroService.identityServer/LY.MicroService.IdentityServer.csproj +++ b/aspnet-core/services/LY.MicroService.identityServer/LY.MicroService.IdentityServer.csproj @@ -7,7 +7,6 @@ - @@ -46,6 +45,7 @@ + diff --git a/aspnet-core/services/LY.MicroService.identityServer/Localization/Resources/en.json b/aspnet-core/services/LY.MicroService.identityServer/Localization/Resources/en.json index 7291dc84a..a9c8dcc3f 100644 --- a/aspnet-core/services/LY.MicroService.identityServer/Localization/Resources/en.json +++ b/aspnet-core/services/LY.MicroService.identityServer/Localization/Resources/en.json @@ -1,18 +1,5 @@ { "culture": "en", "texts": { - "TwoFactor": "Two factor authentication", - "SelectedProvider": "Select validation mode", - "SendVerifyCode": "Send verification code", - "VerifyCode": "Verification code", - "VerifyAuthenticatorCode": "Authentication code", - "RememberBrowser": "Remember me in the browser", - "TwoFactorAuthenticationInvaidUser": "Authentication failed. Your session is invalid. Please re login try again!", - "InvaidGenerateTwoFactorToken": "Verification code generation failed. Please contact your administrator!", - "TextTemplate:Abp.Account.MailSecurityVerifyLink": "Mail security validation template", - "MailSecurityVerify": "Mail security verification", - "VerifyMyEmailAddress": "Hello {0}

Your email security verification code is as follows. Please enter the verification code to proceed to the next step.

If not operated by you, please ignore this email.

", - "MailSecurityVerifyRemarks": "

(If it is not in the form of a link, copy the address to the browser address bar for further access)

Thank you for your visit and have a good time!

", - "ClickToValidation": "Click link verification" } } \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.identityServer/Localization/Resources/zh-Hans.json b/aspnet-core/services/LY.MicroService.identityServer/Localization/Resources/zh-Hans.json index 0396e0bde..2bdcf10ac 100644 --- a/aspnet-core/services/LY.MicroService.identityServer/Localization/Resources/zh-Hans.json +++ b/aspnet-core/services/LY.MicroService.identityServer/Localization/Resources/zh-Hans.json @@ -1,18 +1,5 @@ { "culture": "zh-Hans", "texts": { - "TwoFactor": "双因素身份验证", - "SelectedProvider": "选择验证方式", - "SendVerifyCode": "发送验证码", - "VerifyCode": "验证码", - "VerifyAuthenticatorCode": "验证身份代码", - "RememberBrowser": "在浏览器中记住我", - "TwoFactorAuthenticationInvaidUser": "认证失败,您的会话已失效,请程序登录!", - "InvaidGenerateTwoFactorToken": "验证码生成失败,请联系管理员!", - "TextTemplate:Abp.Account.MailSecurityVerifyLink": "邮件安全验证模板", - "MailSecurityVerify": "邮件安全验证", - "VerifyMyEmailAddress": "您好

您此次邮件安全验证码如下,请输入验证码进行下一步操作。

如非你本人操作,请忽略此邮件。

", - "MailSecurityVerifyRemarks": "此邮件为系统所发,请勿直接回复。", - "ClickToValidation": "点击进行验证" } } \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.identityServer/Pages/Account/SendCode.cshtml b/aspnet-core/services/LY.MicroService.identityServer/Pages/Account/SendCode.cshtml index 7dd20f502..96de45e7a 100644 --- a/aspnet-core/services/LY.MicroService.identityServer/Pages/Account/SendCode.cshtml +++ b/aspnet-core/services/LY.MicroService.identityServer/Pages/Account/SendCode.cshtml @@ -14,7 +14,12 @@
- @L["SendVerifyCode"] +
+ @L["SendVerifyCode"] +
+ + @L["Login"] + diff --git a/aspnet-core/services/LY.MicroService.identityServer/Pages/Account/SendCode.cshtml.cs b/aspnet-core/services/LY.MicroService.identityServer/Pages/Account/SendCode.cshtml.cs index df01aebff..9434bc02c 100644 --- a/aspnet-core/services/LY.MicroService.identityServer/Pages/Account/SendCode.cshtml.cs +++ b/aspnet-core/services/LY.MicroService.identityServer/Pages/Account/SendCode.cshtml.cs @@ -1,4 +1,4 @@ -using LY.MicroService.IdentityServer.Emailing; +using LINGYUN.Abp.Account.Emailing; using LINGYUN.Abp.Identity.Settings; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; @@ -9,7 +9,7 @@ using Volo.Abp; using Volo.Abp.Account.Localization; using Volo.Abp.Account.Web.Pages.Account; using Volo.Abp.Sms; - + namespace LY.MicroService.IdentityServer.Pages.Account { public class SendCodeModel : AccountPageModel @@ -91,12 +91,11 @@ namespace LY.MicroService.IdentityServer.Pages.Account if (Input.SelectedProvider == "Email") { - var appName = "MVC"; // TODO: Abpܵ˼䶯 await AccountEmailVerifySender - .SendMailLoginVerifyLinkAsync( - user, code, appName, - Input.SelectedProvider, - RememberMe, ReturnUrl, ReturnUrlHash); + .SendMailLoginVerifyCodeAsync( + code, + user.UserName, + user.Email); } else if (Input.SelectedProvider == "Phone") { diff --git a/aspnet-core/services/LY.MicroService.identityServer/Pages/Account/VerifyAuthenticatorCode.cshtml b/aspnet-core/services/LY.MicroService.identityServer/Pages/Account/VerifyAuthenticatorCode.cshtml index 153ec9d9c..9a9b65122 100644 --- a/aspnet-core/services/LY.MicroService.identityServer/Pages/Account/VerifyAuthenticatorCode.cshtml +++ b/aspnet-core/services/LY.MicroService.identityServer/Pages/Account/VerifyAuthenticatorCode.cshtml @@ -18,6 +18,9 @@ @L["VerifyAuthenticatorCode"] + + @L["Login"] + \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.identityServer/Pages/Account/VerifyCode.cshtml b/aspnet-core/services/LY.MicroService.identityServer/Pages/Account/VerifyCode.cshtml index 19a006403..eb198aca4 100644 --- a/aspnet-core/services/LY.MicroService.identityServer/Pages/Account/VerifyCode.cshtml +++ b/aspnet-core/services/LY.MicroService.identityServer/Pages/Account/VerifyCode.cshtml @@ -18,7 +18,12 @@ - @L["VerifyAuthenticatorCode"] +
+ @L["VerifyAuthenticatorCode"] +
+ + @L["SendVerifyCode"] +