37 changed files with 333 additions and 271 deletions
@ -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<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpAccountApplicationContractsModule>(); |
|||
}); |
|||
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Get<AccountResource>() |
|||
.AddVirtualJson("/LINGYUN/Abp/Account/Localization/Resources"); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -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; } |
|||
} |
|||
@ -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; } |
|||
} |
|||
@ -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" |
|||
} |
|||
} |
|||
@ -1,15 +0,0 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"SendRepeatSmsVerifyCode": "手机验证码不能在 {0} 分钟内重复发送!", |
|||
"DuplicatePhoneNumber": "手机号已经存在!", |
|||
"PhoneNumberNotRegisterd": "手机号码未注册!", |
|||
"InvalidSmsVerifyCode": "手机验证码无效或已经过期!", |
|||
"RequiredEmailAddress": "邮件地址必须输入", |
|||
"InvalidPhoneNumber": "手机号无效", |
|||
"DuplicateWeChat": "微信号已经注册过!", |
|||
"DisplayName:SmsVerifyCode": "短信验证码", |
|||
"DisplayName:EmailVerifyCode": "邮件验证码", |
|||
"DisplayName:WeChatCode": "微信登录凭证" |
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -1,18 +1,25 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.props" /> |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
<Import Project="..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Localization" Version="4.4.0" /> |
|||
</ItemGroup> |
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\identity\LINGYUN.Abp.Identity.Domain.Shared\LINGYUN.Abp.Identity.Domain.Shared.csproj" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<None Remove="LINGYUN\Abp\Account\Emailing\Templates\*.tpl" /> |
|||
<None Remove="LINGYUN\Abp\Account\Localization\Resources\*.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="LINGYUN\Abp\Account\Emailing\Templates\*.tpl" /> |
|||
<EmbeddedResource Include="LINGYUN\Abp\Account\Localization\Resources\*.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Emailing" Version="$(VoloAbpPackageVersion)" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
|
|||
@ -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; } |
|||
} |
|||
} |
|||
@ -1,16 +0,0 @@ |
|||
namespace LINGYUN.Abp.Account |
|||
{ |
|||
/// <summary>
|
|||
/// 定义账户系统Url
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 定义在领域共享层,可以方便其他应用程序调用
|
|||
/// </remarks>
|
|||
public static class AccountUrlNames |
|||
{ |
|||
/// <summary>
|
|||
/// 邮件登录验证地址
|
|||
/// </summary>
|
|||
public static string MailLoginVerify { get; set; } = ""; |
|||
} |
|||
} |
|||
@ -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<AbpAccountResource> StringLocalizer { get; } |
|||
|
|||
public AccountEmailVerifySender( |
|||
IEmailSender emailSender, |
|||
ITemplateRenderer templateRenderer, |
|||
IStringLocalizer<AbpAccountResource> 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 |
|||
); |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.Account.Emailing; |
|||
|
|||
public interface IAccountEmailVerifySender |
|||
{ |
|||
Task SendMailLoginVerifyCodeAsync( |
|||
string code, |
|||
string userName, |
|||
string emailAddress); |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace LINGYUN.Abp.Account.Localization; |
|||
|
|||
[LocalizationResourceName("AbpAccountResource")] |
|||
public class AbpAccountResource |
|||
{ |
|||
} |
|||
@ -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}<br/><p>Your email security verification code is as follows. Please enter the verification code to proceed to the next step.</p><p>If not operated by you, please ignore this email.</p>", |
|||
"MailSecurityVerifyRemarks": "<p>(If it is not in the form of a link, copy the address to the browser address bar for further access)</p><p>Thank you for your visit and have a good time!</p>", |
|||
"ClickToValidation": "Click link verification" |
|||
} |
|||
} |
|||
@ -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": "您好<br/><p>您此次邮件安全验证码如下,请输入验证码进行下一步操作。</p><p>如非你本人操作,请忽略此邮件。</p>", |
|||
"MailSecurityVerifyRemarks": "此邮件为系统所发,请勿直接回复。", |
|||
"ClickToValidation": "点击进行验证" |
|||
} |
|||
} |
|||
@ -1,9 +0,0 @@ |
|||
namespace LINGYUN.Abp.Account |
|||
{ |
|||
public enum PhoneNumberVerifyType : sbyte |
|||
{ |
|||
Register = 0, |
|||
Signin = 10, |
|||
ResetPassword = 20 |
|||
} |
|||
} |
|||
@ -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<AccountResource> 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; |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
@ -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}<br/><p>Your email security verification code is as follows. Please enter the verification code to proceed to the next step.</p><p>If not operated by you, please ignore this email.</p>", |
|||
"MailSecurityVerifyRemarks": "<p>(If it is not in the form of a link, copy the address to the browser address bar for further access)</p><p>Thank you for your visit and have a good time!</p>", |
|||
"ClickToValidation": "Click link verification" |
|||
} |
|||
} |
|||
@ -1,18 +1,5 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"TwoFactor": "双因素身份验证", |
|||
"SelectedProvider": "选择验证方式", |
|||
"SendVerifyCode": "发送验证码", |
|||
"VerifyCode": "验证码", |
|||
"VerifyAuthenticatorCode": "验证身份代码", |
|||
"RememberBrowser": "在浏览器中记住我", |
|||
"TwoFactorAuthenticationInvaidUser": "认证失败,您的会话已失效,请程序登录!", |
|||
"InvaidGenerateTwoFactorToken": "验证码生成失败,请联系管理员!", |
|||
"TextTemplate:Abp.Account.MailSecurityVerifyLink": "邮件安全验证模板", |
|||
"MailSecurityVerify": "邮件安全验证", |
|||
"VerifyMyEmailAddress": "您好<br/><p>您此次邮件安全验证码如下,请输入验证码进行下一步操作。</p><p>如非你本人操作,请忽略此邮件。</p>", |
|||
"MailSecurityVerifyRemarks": "此邮件为系统所发,请勿直接回复。", |
|||
"ClickToValidation": "点击进行验证" |
|||
} |
|||
} |
|||
Loading…
Reference in new issue