68 changed files with 810 additions and 387 deletions
@ -1,11 +1,27 @@ |
|||
using Volo.Abp.Modularity; |
|||
|
|||
using Volo.Abp.Account.Localization; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace LINGYUN.Abp.Account |
|||
{ |
|||
[DependsOn( |
|||
typeof(Volo.Abp.Account.AbpAccountApplicationContractsModule), |
|||
typeof(AbpAccountDomainSharedModule))] |
|||
typeof(Volo.Abp.Account.AbpAccountApplicationContractsModule))] |
|||
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,13 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace LINGYUN.Abp.Account; |
|||
|
|||
public class ConfirmEmailInput |
|||
{ |
|||
[Required] |
|||
public Guid UserId { get; set; } |
|||
|
|||
[Required] |
|||
public string ConfirmToken { get; set; } |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Abp.Account; |
|||
|
|||
public class SendEmailConfirmCodeDto |
|||
{ |
|||
[Required] |
|||
[EmailAddress] |
|||
[Display(Name = "EmailAddress")] |
|||
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxEmailLength))] |
|||
public string Email { get; set; } |
|||
|
|||
[Required] |
|||
public string AppName { get; set; } |
|||
|
|||
public string ReturnUrl { get; set; } |
|||
|
|||
public string ReturnUrlHash { get; set; } |
|||
} |
|||
@ -1,16 +1,31 @@ |
|||
using LINGYUN.Abp.Identity; |
|||
using LINGYUN.Abp.Account.Templates; |
|||
using LINGYUN.Abp.Identity; |
|||
using LINGYUN.Abp.WeChat.MiniProgram; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
using Volo.Abp.UI.Navigation.Urls; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace LINGYUN.Abp.Account |
|||
{ |
|||
[DependsOn( |
|||
typeof(Volo.Abp.Account.AbpAccountApplicationModule), |
|||
typeof(AbpAccountApplicationContractsModule), |
|||
typeof(AbpAccountTemplatesModule), |
|||
typeof(AbpIdentityDomainModule), |
|||
typeof(AbpWeChatMiniProgramModule))] |
|||
public class AbpAccountApplicationModule : AbpModule |
|||
{ |
|||
|
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpAccountApplicationModule>(); |
|||
}); |
|||
|
|||
Configure<AppUrlOptions>(options => |
|||
{ |
|||
options.Applications["MVC"].Urls[AccountUrlNames.EmailConfirm] = "Account/EmailConfirm"; |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,32 @@ |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Sms; |
|||
|
|||
namespace LINGYUN.Abp.Account; |
|||
|
|||
public class AccountSmsSecurityCodeSender : IAccountSmsSecurityCodeSender, ITransientDependency |
|||
{ |
|||
protected ISmsSender SmsSender { get; } |
|||
|
|||
public AccountSmsSecurityCodeSender(ISmsSender smsSender) |
|||
{ |
|||
SmsSender = smsSender; |
|||
} |
|||
|
|||
public async virtual Task SendSmsCodeAsync( |
|||
string phone, |
|||
string token, |
|||
string template, |
|||
CancellationToken cancellation = default) |
|||
{ |
|||
Check.NotNullOrWhiteSpace(template, nameof(template)); |
|||
|
|||
var smsMessage = new SmsMessage(phone, token); |
|||
smsMessage.Properties.Add("code", token); |
|||
smsMessage.Properties.Add("TemplateCode", template); |
|||
|
|||
await SmsSender.SendAsync(smsMessage); |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
namespace LINGYUN.Abp.Account; |
|||
|
|||
public static class AccountUrlNames |
|||
{ |
|||
public const string EmailConfirm = "Abp.Account.EmailConfirm"; |
|||
} |
|||
@ -0,0 +1,92 @@ |
|||
using LINGYUN.Abp.Account.Emailing.Templates; |
|||
using Microsoft.Extensions.Localization; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Diagnostics; |
|||
using System.Text.Encodings.Web; |
|||
using System.Threading.Tasks; |
|||
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 LINGYUN.Abp.Account.Emailing; |
|||
|
|||
[Dependency(ReplaceServices = true)] |
|||
[ExposeServices( |
|||
typeof(IAccountEmailConfirmSender), |
|||
typeof(IAccountEmailVerifySender), |
|||
typeof(IAccountEmailer), |
|||
typeof(AccountEmailSender))] |
|||
public class AccountEmailSender : |
|||
AccountEmailer, |
|||
IAccountEmailConfirmSender, |
|||
IAccountEmailVerifySender, |
|||
ITransientDependency |
|||
{ |
|||
public AccountEmailSender( |
|||
IEmailSender emailSender, |
|||
ITemplateRenderer templateRenderer, |
|||
IStringLocalizer<AccountResource> accountLocalizer, |
|||
IAppUrlProvider appUrlProvider, |
|||
ICurrentTenant currentTenant) |
|||
: base(emailSender, templateRenderer, accountLocalizer, appUrlProvider, currentTenant) |
|||
{ |
|||
} |
|||
|
|||
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 |
|||
); |
|||
} |
|||
|
|||
public async virtual Task SendEmailConfirmLinkAsync( |
|||
IdentityUser user, |
|||
string confirmToken, |
|||
string appName, |
|||
string returnUrl = null, |
|||
string returnUrlHash = null) |
|||
{ |
|||
Debug.Assert(CurrentTenant.Id == user.TenantId, "This method can only work for current tenant!"); |
|||
|
|||
var url = await AppUrlProvider.GetUrlAsync(appName, AccountUrlNames.EmailConfirm); |
|||
|
|||
var link = $"{url}?userId={user.Id}&{TenantResolverConsts.DefaultTenantKey}={user.TenantId}&confirmToken={UrlEncoder.Default.Encode(confirmToken)}"; |
|||
|
|||
if (!returnUrl.IsNullOrEmpty()) |
|||
{ |
|||
link += "&returnUrl=" + NormalizeReturnUrl(returnUrl); |
|||
} |
|||
|
|||
if (!returnUrlHash.IsNullOrEmpty()) |
|||
{ |
|||
link += "&returnUrlHash=" + returnUrlHash; |
|||
} |
|||
|
|||
var emailContent = await TemplateRenderer.RenderAsync( |
|||
AccountEmailTemplates.MailConfirmLink, |
|||
new { link = link } |
|||
); |
|||
|
|||
await EmailSender.SendAsync( |
|||
user.Email, |
|||
StringLocalizer["EmailConfirm"], |
|||
emailContent |
|||
); |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Identity; |
|||
|
|||
namespace LINGYUN.Abp.Account.Emailing; |
|||
|
|||
public interface IAccountEmailConfirmSender |
|||
{ |
|||
Task SendEmailConfirmLinkAsync( |
|||
IdentityUser user, |
|||
string confirmToken, |
|||
string appName, |
|||
string returnUrl = null, |
|||
string returnUrlHash = null |
|||
); |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.Account |
|||
{ |
|||
public interface IAccountSmsSecurityCodeSender |
|||
{ |
|||
Task SendSmsCodeAsync( |
|||
string phone, |
|||
string token, |
|||
string template, // 传递模板号
|
|||
CancellationToken cancellation = default); |
|||
} |
|||
} |
|||
@ -1,28 +0,0 @@ |
|||
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(AbpEmailingModule))] |
|||
public class AbpAccountDomainSharedModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpAccountDomainSharedModule>(); |
|||
}); |
|||
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Add<AbpAccountResource>("en") |
|||
.AddVirtualJson("/LINGYUN/Abp/Account/Localization/Resources"); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -1,44 +0,0 @@ |
|||
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 |
|||
); |
|||
} |
|||
} |
|||
@ -1,22 +0,0 @@ |
|||
using LINGYUN.Abp.Account.Localization; |
|||
using Volo.Abp.Emailing.Templates; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.TextTemplating; |
|||
|
|||
namespace LY.MicroService.IdentityServer.Emailing.Templates; |
|||
|
|||
public class AccountEmailTemplateDefinitionProvider : TemplateDefinitionProvider |
|||
{ |
|||
public override void Define(ITemplateDefinitionContext context) |
|||
{ |
|||
context.Add( |
|||
new TemplateDefinition( |
|||
AccountEmailTemplates.MailSecurityVerifyLink, |
|||
displayName: LocalizableString.Create<AbpAccountResource>( |
|||
$"TextTemplate:{AccountEmailTemplates.MailSecurityVerifyLink}"), |
|||
layout: StandardEmailTemplates.Layout, |
|||
localizationResource: typeof(AbpAccountResource) |
|||
).WithVirtualFilePath("/LINGYUN/Abp/Account/Emailing/Templates/MailSecurityVerify.tpl", true) |
|||
); |
|||
} |
|||
} |
|||
@ -1,8 +0,0 @@ |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace LINGYUN.Abp.Account.Localization; |
|||
|
|||
[LocalizationResourceName("AbpAccountResource")] |
|||
public class AbpAccountResource |
|||
{ |
|||
} |
|||
@ -1,3 +0,0 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -1,18 +0,0 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Identity.Domain" Version="4.4.0" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<Folder Include="Microsoft\AspNetCore\Identity\" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -1,9 +0,0 @@ |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Account |
|||
{ |
|||
[DependsOn(typeof(AbpAccountDomainSharedModule))] |
|||
public class AbpAccountDomainModule : AbpModule |
|||
{ |
|||
} |
|||
} |
|||
@ -1,16 +0,0 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Identity; |
|||
|
|||
namespace LINGYUN.Abp.Account |
|||
{ |
|||
public interface IIdentityUserRepository : IReadOnlyRepository<IdentityUser, Guid> |
|||
{ |
|||
Task<bool> PhoneNumberHasRegistedAsync(string phoneNumber); |
|||
|
|||
Task<IdentityUser> FindByPhoneNumberAsync(string phoneNumber); |
|||
|
|||
Task<Guid?> GetIdByPhoneNumberAsync(string phoneNumber); |
|||
} |
|||
} |
|||
@ -1,25 +1,29 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<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> |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<None Remove="LINGYUN\Abp\Account\Emailing\Templates\*.tpl" /> |
|||
<None Remove="LINGYUN\Abp\Account\Templates\Localization\Resources\*.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="LINGYUN\Abp\Account\Emailing\Templates\*.tpl" /> |
|||
<EmbeddedResource Include="LINGYUN\Abp\Account\Templates\Localization\Resources\*.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Emailing" Version="$(VoloAbpPackageVersion)" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.Abp.Account.Application.Contracts\LINGYUN.Abp.Account.Application.Contracts.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -1,7 +1,11 @@ |
|||
namespace LY.MicroService.IdentityServer.Emailing.Templates; |
|||
namespace LINGYUN.Abp.Account.Emailing.Templates; |
|||
|
|||
public static class AccountEmailTemplates |
|||
{ |
|||
/// <summary>
|
|||
/// 邮件地址确认
|
|||
/// </summary>
|
|||
public const string MailConfirmLink = "Abp.Account.MailConfirmLink"; |
|||
/// <summary>
|
|||
/// 邮件安全验证
|
|||
/// </summary>
|
|||
@ -0,0 +1,32 @@ |
|||
using Volo.Abp.Account.Localization; |
|||
using Volo.Abp.Emailing.Templates; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.TextTemplating; |
|||
|
|||
namespace LINGYUN.Abp.Account.Emailing.Templates; |
|||
|
|||
public class AccountTemplateDefinitionProvider : TemplateDefinitionProvider |
|||
{ |
|||
public override void Define(ITemplateDefinitionContext context) |
|||
{ |
|||
context.Add( |
|||
new TemplateDefinition( |
|||
AccountEmailTemplates.MailSecurityVerifyLink, |
|||
displayName: L($"TextTemplate:{AccountEmailTemplates.MailSecurityVerifyLink}"), |
|||
layout: StandardEmailTemplates.Layout, |
|||
localizationResource: typeof(AccountResource) |
|||
).WithVirtualFilePath("/LINGYUN/Abp/Account/Emailing/Templates/MailSecurityVerify.tpl", true), |
|||
new TemplateDefinition( |
|||
AccountEmailTemplates.MailConfirmLink, |
|||
displayName: L($"TextTemplate:{AccountEmailTemplates.MailConfirmLink}"), |
|||
layout: StandardEmailTemplates.Layout, |
|||
localizationResource: typeof(AccountResource) |
|||
).WithVirtualFilePath("/LINGYUN/Abp/Account/Emailing/Templates/MailConfirm.tpl", true) |
|||
); |
|||
} |
|||
|
|||
private static ILocalizableString L(string name) |
|||
{ |
|||
return LocalizableString.Create<AccountResource>(name); |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
<h3>{{L "EmailConfirm"}}</h3> |
|||
|
|||
<p>{{L "EmailConfirmInfo"}}</p> |
|||
|
|||
<div> |
|||
<a href="{{model.link}}">{{L "ConfirmMyEmail"}}</a> |
|||
</div> |
|||
@ -0,0 +1,13 @@ |
|||
using Volo.Abp.Emailing; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Account.Templates |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpEmailingModule), |
|||
typeof(AbpAccountApplicationContractsModule))] |
|||
public class AbpAccountTemplatesModule : AbpModule |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"TextTemplate:Abp.Account.MailSecurityVerifyLink": "Mail security validation template", |
|||
"TextTemplate:Abp.Account.MailConfirmLink": "Mail confirm 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", |
|||
"Validation": "Validation", |
|||
"EmailConfirm": "Email confirm", |
|||
"EmailConfirmInfo": "We received an email confirmation request! If you initiated this request, please click the link below to confirm the email address.", |
|||
"ConfirmMyEmail": "Bind my email address", |
|||
"YourEmailIsSuccessfullyConfirm": "Your email address was bound successfully." |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"TextTemplate:Abp.Account.MailSecurityVerifyLink": "邮件验证模板", |
|||
"TextTemplate:Abp.Account.MailConfirmLink": "邮件确认模板", |
|||
"MailSecurityVerify": "邮件安全验证", |
|||
"VerifyMyEmailAddress": "您好<br/><p>您此次邮件安全验证码如下,请输入验证码进行下一步操作。</p><p>如非你本人操作,请忽略此邮件。</p>", |
|||
"MailSecurityVerifyRemarks": "此邮件为系统所发,请勿直接回复。", |
|||
"ClickToValidation": "点击进行验证", |
|||
"Validation": "验证", |
|||
"EmailConfirm": "邮件确认", |
|||
"EmailConfirmInfo": "我们收到了邮件确认请求!如果你发起了此请求,请单击以下链接以确认邮件地址.", |
|||
"ConfirmMyEmail": "绑定我的邮箱地址", |
|||
"YourEmailIsSuccessfullyConfirm": "您的邮件地址绑定成功." |
|||
} |
|||
} |
|||
@ -1,20 +0,0 @@ |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.Identity |
|||
{ |
|||
public interface IUserSecurityCodeSender |
|||
{ |
|||
Task SendPhoneConfirmedCodeAsync( |
|||
string phone, |
|||
string token, |
|||
string template, // 传递模板号
|
|||
CancellationToken cancellation = default); |
|||
|
|||
Task SendEmailConfirmedCodeAsync( |
|||
string userName, |
|||
string email, |
|||
string token, |
|||
CancellationToken cancellation = default); |
|||
} |
|||
} |
|||
@ -1,5 +0,0 @@ |
|||
<div style="position: absolute;"> |
|||
<span>{{L "EmailConfirmed" model.user}}</span> |
|||
<p style="display:block; padding:0 50px; width: 150px; height:48px; line-height:48px; color:#cc0000; font-size:26px; background:#9c9797; font-weight:bold;">{{model.code}}</p> |
|||
<span>{{L "EmailConfirmedRemarks"}}</span> |
|||
</div> |
|||
@ -1,26 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Emailing.Templates; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.TextTemplating; |
|||
using Volo.Abp.Identity.Localization; |
|||
|
|||
namespace LY.MicroService.IdentityServer.Emailing.Templates |
|||
{ |
|||
public class IdentityEmailTemplateDefinitionProvider : TemplateDefinitionProvider |
|||
{ |
|||
public override void Define(ITemplateDefinitionContext context) |
|||
{ |
|||
context.Add( |
|||
new TemplateDefinition( |
|||
IdentityEmailTemplates.EmailConfirmed, |
|||
displayName: LocalizableString.Create<IdentityResource>($"TextTemplate:{IdentityEmailTemplates.EmailConfirmed}"), |
|||
layout: StandardEmailTemplates.Layout, |
|||
localizationResource: typeof(IdentityResource) |
|||
).WithVirtualFilePath("/LINGYUN/Abp/IdentityServer4/Emailing/Templates/EmailConfirmed.tpl", true) |
|||
); |
|||
} |
|||
} |
|||
} |
|||
@ -1,7 +0,0 @@ |
|||
namespace LY.MicroService.IdentityServer.Emailing.Templates |
|||
{ |
|||
public static class IdentityEmailTemplates |
|||
{ |
|||
public const string EmailConfirmed = "Abp.Identity.EmailConfirmed"; |
|||
} |
|||
} |
|||
@ -1,65 +0,0 @@ |
|||
using LINGYUN.Abp.Identity; |
|||
using LY.MicroService.IdentityServer.Emailing.Templates; |
|||
using Microsoft.Extensions.Localization; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Emailing; |
|||
using Volo.Abp.Identity.Localization; |
|||
using Volo.Abp.Sms; |
|||
using Volo.Abp.TextTemplating; |
|||
|
|||
namespace LY.MicroService.IdentityServer; |
|||
|
|||
public class UserSecurityCodeSender : IUserSecurityCodeSender, ITransientDependency |
|||
{ |
|||
protected IEmailSender EmailSender { get; } |
|||
protected ITemplateRenderer TemplateRenderer { get; } |
|||
protected IStringLocalizer<IdentityResource> Localizer { get; } |
|||
|
|||
protected ISmsSender SmsSender { get; } |
|||
|
|||
public UserSecurityCodeSender( |
|||
ISmsSender smsSender, |
|||
IEmailSender emailSender, |
|||
ITemplateRenderer templateRenderer, |
|||
IStringLocalizer<IdentityResource> localizer) |
|||
{ |
|||
SmsSender = smsSender; |
|||
EmailSender = emailSender; |
|||
TemplateRenderer = templateRenderer; |
|||
Localizer = localizer; |
|||
} |
|||
|
|||
public virtual async Task SendEmailConfirmedCodeAsync( |
|||
string userName, |
|||
string email, |
|||
string token, |
|||
CancellationToken cancellation = default) |
|||
{ |
|||
var emailContent = await TemplateRenderer.RenderAsync( |
|||
IdentityEmailTemplates.EmailConfirmed, |
|||
new { user = userName, code = token }); |
|||
|
|||
await EmailSender.SendAsync( |
|||
email, |
|||
Localizer["EmailConfirmed"], |
|||
emailContent); |
|||
} |
|||
|
|||
public virtual async Task SendPhoneConfirmedCodeAsync( |
|||
string phone, |
|||
string token, |
|||
string template, |
|||
CancellationToken cancellation = default) |
|||
{ |
|||
Check.NotNullOrWhiteSpace(template, nameof(template)); |
|||
|
|||
var smsMessage = new SmsMessage(phone, token); |
|||
smsMessage.Properties.Add("code", token); |
|||
smsMessage.Properties.Add("TemplateCode", template); |
|||
|
|||
await SmsSender.SendAsync(smsMessage); |
|||
} |
|||
} |
|||
@ -0,0 +1,56 @@ |
|||
@using Volo.Abp.Account.Localization |
|||
@using Volo.Abp.Users |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Theming |
|||
@using Volo.Abp.Identity.Settings |
|||
@using Volo.Abp.Settings |
|||
@inject IHtmlLocalizer<AccountResource> L |
|||
@inject ICurrentUser CurrentUser |
|||
@inject ISettingProvider SettingManager |
|||
@inject IThemeManager ThemeManager |
|||
@model Volo.Abp.Account.Web.Pages.Account.Components.ProfileManagementGroup.PersonalInfo.AccountProfilePersonalInfoManagementGroupViewComponent.PersonalInfoModel |
|||
@{ |
|||
var isUserNameUpdateEnabled = string.Equals(await SettingManager.GetOrNullAsync(IdentitySettingNames.User.IsUserNameUpdateEnabled), "true", |
|||
StringComparison.OrdinalIgnoreCase); |
|||
|
|||
var isEmailUpdateEnabled = string.Equals(await SettingManager.GetOrNullAsync(IdentitySettingNames.User.IsEmailUpdateEnabled), "true", |
|||
StringComparison.OrdinalIgnoreCase); |
|||
} |
|||
|
|||
<h4>@L["PersonalSettings"]</h4><hr/> |
|||
<form method="post" id="PersonalSettingsForm"> |
|||
|
|||
<input asp-for="ConcurrencyStamp" /> |
|||
|
|||
<abp-input asp-for="UserName" readonly="!isUserNameUpdateEnabled"/> |
|||
|
|||
<abp-row> |
|||
<abp-column size-md="_6"> |
|||
<abp-input asp-for="Name"/> |
|||
</abp-column> |
|||
<abp-column size-md="_6"> |
|||
<abp-input asp-for="Surname"/> |
|||
</abp-column> |
|||
</abp-row> |
|||
|
|||
<abp-row> |
|||
<abp-column size-md="_9"> |
|||
<abp-input asp-for="Email" readonly="!isEmailUpdateEnabled"/> |
|||
</abp-column> |
|||
<abp-column size-md="_3"> |
|||
|
|||
@if (CurrentUser.EmailVerified) |
|||
{ |
|||
<abp-button button-type="Success" text="@L["Confirmed"].Value"/> |
|||
} |
|||
else |
|||
{ |
|||
<a href="/Account/SendEmailConfirm">@L["Validation"].Value</a> |
|||
} |
|||
</abp-column> |
|||
</abp-row> |
|||
|
|||
<abp-input asp-for="PhoneNumber"/> |
|||
|
|||
<abp-button type="submit" button-type="Primary" text="@L["Submit"].Value"/> |
|||
</form> |
|||
@ -0,0 +1,28 @@ |
|||
(function ($) { |
|||
$(function () { |
|||
var l = abp.localization.getResource("AbpAccount"); |
|||
|
|||
$('#PersonalSettingsForm').submit(function (e) { |
|||
e.preventDefault(); |
|||
|
|||
if (!$('#PersonalSettingsForm').valid()) { |
|||
return false; |
|||
} |
|||
|
|||
var input = $('#PersonalSettingsForm').serializeFormToObject(); |
|||
|
|||
volo.abp.account.profile.update(input).then(function (result) { |
|||
abp.notify.success(l('PersonalSettingsSaved')); |
|||
updateConcurrencyStamp(); |
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
abp.event.on('passwordChanged', updateConcurrencyStamp); |
|||
|
|||
function updateConcurrencyStamp(){ |
|||
volo.abp.account.profile.get().then(function(profile){ |
|||
$("#ConcurrencyStamp").val(profile.concurrencyStamp); |
|||
}); |
|||
} |
|||
})(jQuery); |
|||
@ -0,0 +1,17 @@ |
|||
@page |
|||
@inject IHtmlLocalizer<AccountResource> L |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using Volo.Abp.Account.Localization |
|||
@model LY.MicroService.IdentityServer.Pages.Account.EmailConfirmModel |
|||
@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout |
|||
<div class="card mt-3 shadow-sm rounded"> |
|||
<div class="card-body p-5"> |
|||
<h4>@L["EmailConfirm"]</h4> |
|||
<form method="post"> |
|||
<abp-input asp-for="UserId"/> |
|||
<abp-input asp-for="ConfirmToken"/> |
|||
<a abp-button="Secondary" asp-page="./Login">@L["Cancel"]</a> |
|||
<abp-button type="submit" button-type="Primary" text="@L["Submit"].Value"/> |
|||
</form> |
|||
</div> |
|||
</div> |
|||
@ -0,0 +1,75 @@ |
|||
using LINGYUN.Abp.Account; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Account.Localization; |
|||
using Volo.Abp.Account.Web.Pages.Account; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LY.MicroService.IdentityServer.Pages.Account |
|||
{ |
|||
public class EmailConfirmModel : AccountPageModel |
|||
{ |
|||
[Required] |
|||
[HiddenInput] |
|||
[BindProperty(SupportsGet = true)] |
|||
public Guid UserId { get; set; } |
|||
|
|||
[Required] |
|||
[HiddenInput] |
|||
[BindProperty(SupportsGet = true)] |
|||
public string ConfirmToken { get; set; } |
|||
|
|||
[HiddenInput] |
|||
[BindProperty(SupportsGet = true)] |
|||
public string ReturnUrl { get; set; } |
|||
|
|||
[HiddenInput] |
|||
[BindProperty(SupportsGet = true)] |
|||
public string ReturnUrlHash { get; set; } |
|||
|
|||
public IMyProfileAppService MyProfileAppService { get; set; } |
|||
|
|||
public EmailConfirmModel() |
|||
{ |
|||
LocalizationResourceType = typeof(AccountResource); |
|||
} |
|||
|
|||
public async virtual Task<IActionResult> OnPostAsync() |
|||
{ |
|||
try |
|||
{ |
|||
ValidateModel(); |
|||
|
|||
await MyProfileAppService.ConfirmEmailAsync( |
|||
new ConfirmEmailInput |
|||
{ |
|||
UserId = UserId, |
|||
ConfirmToken = ConfirmToken, |
|||
}); |
|||
} |
|||
catch (AbpIdentityResultException e) |
|||
{ |
|||
if (!string.IsNullOrWhiteSpace(e.Message)) |
|||
{ |
|||
Alerts.Warning(GetLocalizeExceptionMessage(e)); |
|||
return Page(); |
|||
} |
|||
|
|||
throw; |
|||
} |
|||
catch (AbpValidationException) |
|||
{ |
|||
return Page(); |
|||
} |
|||
|
|||
return RedirectToPage("./ConfirmEmailConfirmation", new |
|||
{ |
|||
returnUrl = ReturnUrl, |
|||
returnUrlHash = ReturnUrlHash |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
@page |
|||
@model LY.MicroService.IdentityServer.Pages.Account.EmailConfirmConfirmationModel |
|||
@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using Volo.Abp.Account.Localization |
|||
@inject IHtmlLocalizer<AccountResource> L |
|||
<div class="card mt-3 shadow-sm rounded"> |
|||
<div class="card-body p-5"> |
|||
<h4>@L["EmailConfirm"]</h4> |
|||
<p>@L["YourEmailIsSuccessfullyConfirm"]</p> |
|||
<a abp-button="Primary" href="@Url.Content(Model.ReturnUrl)">@L["GoToTheApplication"]</a> |
|||
</div> |
|||
</div> |
|||
@ -0,0 +1,23 @@ |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Account.Web.Pages.Account; |
|||
|
|||
namespace LY.MicroService.IdentityServer.Pages.Account; |
|||
|
|||
[AllowAnonymous] |
|||
public class EmailConfirmConfirmationModel : AccountPageModel |
|||
{ |
|||
[BindProperty(SupportsGet = true)] |
|||
public string ReturnUrl { get; set; } |
|||
|
|||
[BindProperty(SupportsGet = true)] |
|||
public string ReturnUrlHash { get; set; } |
|||
|
|||
public virtual Task<IActionResult> OnGetAsync() |
|||
{ |
|||
ReturnUrl = GetRedirectUrl(ReturnUrl, ReturnUrlHash); |
|||
|
|||
return Task.FromResult<IActionResult>(Page()); |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
@page |
|||
@inject IHtmlLocalizer<AccountResource> L |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using Volo.Abp.Account.Localization |
|||
@model LY.MicroService.IdentityServer.Pages.Account.SendEmailConfirmModel |
|||
@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout |
|||
<div class="card mt-3 shadow-sm rounded"> |
|||
<div class="card-body p-5"> |
|||
<h4>@L["EmailConfirm"]</h4> |
|||
<form method="post"> |
|||
<abp-input asp-for="Email" readonly="true" /> |
|||
<a abp-button="Secondary" asp-page="./Login">@L["Cancel"]</a> |
|||
<abp-button type="submit" button-type="Primary" text="@L["ClickToValidation"].Value"/> |
|||
</form> |
|||
</div> |
|||
</div> |
|||
@ -0,0 +1,75 @@ |
|||
using LINGYUN.Abp.Account; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Account.Localization; |
|||
using Volo.Abp.Account.Web.Pages.Account; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LY.MicroService.IdentityServer.Pages.Account |
|||
{ |
|||
public class SendEmailConfirmModel : AccountPageModel |
|||
{ |
|||
[BindProperty(SupportsGet = true)] |
|||
public string Email { get; set; } |
|||
|
|||
[HiddenInput] |
|||
[BindProperty(SupportsGet = true)] |
|||
public string ReturnUrl { get; set; } |
|||
|
|||
[HiddenInput] |
|||
[BindProperty(SupportsGet = true)] |
|||
public string ReturnUrlHash { get; set; } |
|||
|
|||
public IMyProfileAppService MyProfileAppService { get; set; } |
|||
|
|||
public SendEmailConfirmModel() |
|||
{ |
|||
LocalizationResourceType = typeof(AccountResource); |
|||
} |
|||
|
|||
public virtual Task<IActionResult> OnGetAsync() |
|||
{ |
|||
Email = CurrentUser.Email; |
|||
|
|||
return Task.FromResult<IActionResult>(Page()); |
|||
} |
|||
|
|||
public async virtual Task<IActionResult> OnPostAsync() |
|||
{ |
|||
try |
|||
{ |
|||
ValidateModel(); |
|||
|
|||
await MyProfileAppService.SendEmailConfirmLinkAsync( |
|||
new SendEmailConfirmCodeDto |
|||
{ |
|||
Email = Email, |
|||
AppName = "MVC", |
|||
ReturnUrl = ReturnUrl, |
|||
ReturnUrlHash = ReturnUrlHash |
|||
}); |
|||
} |
|||
catch (AbpIdentityResultException e) |
|||
{ |
|||
if (!string.IsNullOrWhiteSpace(e.Message)) |
|||
{ |
|||
Alerts.Warning(GetLocalizeExceptionMessage(e)); |
|||
return Page(); |
|||
} |
|||
|
|||
throw; |
|||
} |
|||
catch (AbpValidationException) |
|||
{ |
|||
return Page(); |
|||
} |
|||
|
|||
return RedirectToPage("~/Account/Manage", new |
|||
{ |
|||
returnUrl = ReturnUrl |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue