22 changed files with 403 additions and 166 deletions
@ -1,92 +0,0 @@ |
|||||
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={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,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
@ -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> |
||||
@ -0,0 +1,28 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0;net9.0</TargetFrameworks> |
||||
|
<AssemblyName>LINGYUN.Abp.Account.Emailing</AssemblyName> |
||||
|
<PackageId>LINGYUN.Abp.Account.Emailing</PackageId> |
||||
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
||||
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
||||
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<None Remove="LINGYUN\Abp\Account\Emailing\Templates\*.tpl" /> |
||||
|
<None Remove="LINGYUN\Abp\Account\Emailing\Localization\Resources\*.json" /> |
||||
|
<EmbeddedResource Include="LINGYUN\Abp\Account\Emailing\Templates\*.tpl" /> |
||||
|
<EmbeddedResource Include="LINGYUN\Abp\Account\Emailing\Localization\Resources\*.json" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Volo.Abp.Emailing" /> |
||||
|
<PackageReference Include="Volo.Abp.UI.Navigation" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,29 @@ |
|||||
|
using LINGYUN.Abp.Account.Emailing.Localization; |
||||
|
using Volo.Abp.Emailing; |
||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.Abp.Modularity; |
||||
|
using Volo.Abp.UI.Navigation; |
||||
|
using Volo.Abp.VirtualFileSystem; |
||||
|
|
||||
|
namespace LINGYUN.Abp.Account.Emailing; |
||||
|
|
||||
|
[DependsOn( |
||||
|
typeof(AbpEmailingModule), |
||||
|
typeof(AbpUiNavigationModule))] |
||||
|
public class AbpAccountEmailingModule : AbpModule |
||||
|
{ |
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
Configure<AbpVirtualFileSystemOptions>(options => |
||||
|
{ |
||||
|
options.FileSets.AddEmbedded<AbpAccountEmailingModule>(); |
||||
|
}); |
||||
|
|
||||
|
Configure<AbpLocalizationOptions>(options => |
||||
|
{ |
||||
|
options.Resources |
||||
|
.Add<AccountEmailingResource>("en") |
||||
|
.AddVirtualJson("/LINGYUN/Abp/Account/Emailing/Localization/Resources"); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,137 @@ |
|||||
|
using LINGYUN.Abp.Account.Emailing.Localization; |
||||
|
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 System.Web; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Emailing; |
||||
|
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(AccountEmailSender))] |
||||
|
public class AccountEmailSender : |
||||
|
IAccountEmailConfirmSender, |
||||
|
IAccountEmailVerifySender, |
||||
|
ITransientDependency |
||||
|
{ |
||||
|
protected ITemplateRenderer TemplateRenderer { get; } |
||||
|
protected IEmailSender EmailSender { get; } |
||||
|
protected IStringLocalizer<AccountEmailingResource> StringLocalizer { get; } |
||||
|
protected IAppUrlProvider AppUrlProvider { get; } |
||||
|
protected ICurrentTenant CurrentTenant { get; } |
||||
|
|
||||
|
public AccountEmailSender( |
||||
|
IEmailSender emailSender, |
||||
|
ICurrentTenant currentTenant, |
||||
|
IAppUrlProvider appUrlProvider, |
||||
|
ITemplateRenderer templateRenderer, |
||||
|
IStringLocalizer<AccountEmailingResource> accountLocalizer) |
||||
|
{ |
||||
|
EmailSender = emailSender; |
||||
|
CurrentTenant = currentTenant; |
||||
|
AppUrlProvider = appUrlProvider; |
||||
|
StringLocalizer = accountLocalizer; |
||||
|
TemplateRenderer = templateRenderer; |
||||
|
} |
||||
|
|
||||
|
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( |
||||
|
Guid userId, |
||||
|
string userEmail, |
||||
|
string confirmToken, |
||||
|
string appName, |
||||
|
string returnUrl = null, |
||||
|
string returnUrlHash = null, |
||||
|
Guid? userTenantId = null) |
||||
|
{ |
||||
|
Debug.Assert(CurrentTenant.Id == userTenantId, "This method can only work for current tenant!"); |
||||
|
|
||||
|
var url = await AppUrlProvider.GetUrlAsync(appName, AccountUrlNames.EmailConfirm); |
||||
|
|
||||
|
var link = $"{url}?userId={userId}&{TenantResolverConsts.DefaultTenantKey}={userTenantId}&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( |
||||
|
userEmail, |
||||
|
StringLocalizer["EmailConfirm"], |
||||
|
emailContent |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
protected virtual 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]); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (returnUrl.StartsWith("/connect/authorize?", StringComparison.OrdinalIgnoreCase)) |
||||
|
{ |
||||
|
return HttpUtility.UrlEncode(returnUrl); |
||||
|
} |
||||
|
|
||||
|
return returnUrl; |
||||
|
} |
||||
|
} |
||||
@ -1,7 +1,7 @@ |
|||||
namespace LINGYUN.Abp.Account; |
namespace LINGYUN.Abp.Account.Emailing; |
||||
|
|
||||
public static class AccountUrlNames |
public static class AccountUrlNames |
||||
{ |
{ |
||||
public const string EmailConfirm = "Abp.Account.EmailConfirm"; |
public const string EmailConfirm = "Abp.Account.EmailConfirm"; |
||||
public const string EmailVerifyLogin = "Abp.Account.EmailVerifyLogin"; |
public const string EmailVerifyLogin = "Abp.Account.EmailVerifyLogin"; |
||||
} |
} |
||||
@ -1,15 +1,17 @@ |
|||||
using System.Threading.Tasks; |
using System; |
||||
using Volo.Abp.Identity; |
using System.Threading.Tasks; |
||||
|
|
||||
namespace LINGYUN.Abp.Account.Emailing; |
namespace LINGYUN.Abp.Account.Emailing; |
||||
|
|
||||
public interface IAccountEmailConfirmSender |
public interface IAccountEmailConfirmSender |
||||
{ |
{ |
||||
Task SendEmailConfirmLinkAsync( |
Task SendEmailConfirmLinkAsync( |
||||
IdentityUser user, |
Guid userId, |
||||
string confirmToken, |
string userEmail, |
||||
string appName, |
string confirmToken, |
||||
string returnUrl = null, |
string appName, |
||||
string returnUrlHash = null |
string returnUrl = null, |
||||
); |
string returnUrlHash = null, |
||||
} |
Guid? userTenantId = null |
||||
|
); |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
using Volo.Abp.Localization; |
||||
|
|
||||
|
namespace LINGYUN.Abp.Account.Emailing.Localization; |
||||
|
|
||||
|
[LocalizationResourceName("AbpAccountEmailing")] |
||||
|
public class AccountEmailingResource |
||||
|
{ |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
namespace LINGYUN.Abp.Account.Emailing.Templates; |
||||
|
|
||||
|
public static class AccountEmailTemplates |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 邮件地址确认
|
||||
|
/// </summary>
|
||||
|
public const string MailConfirmLink = "Abp.Account.MailConfirmLink"; |
||||
|
/// <summary>
|
||||
|
/// 邮件安全验证
|
||||
|
/// </summary>
|
||||
|
public const string MailSecurityVerifyLink = "Abp.Account.MailSecurityVerifyLink"; |
||||
|
} |
||||
@ -0,0 +1,32 @@ |
|||||
|
using LINGYUN.Abp.Account.Emailing.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(AccountEmailingResource) |
||||
|
).WithVirtualFilePath("/LINGYUN/Abp/Account/Emailing/Templates/MailSecurityVerify.tpl", true), |
||||
|
new TemplateDefinition( |
||||
|
AccountEmailTemplates.MailConfirmLink, |
||||
|
displayName: L($"TextTemplate:{AccountEmailTemplates.MailConfirmLink}"), |
||||
|
layout: StandardEmailTemplates.Layout, |
||||
|
localizationResource: typeof(AccountEmailingResource) |
||||
|
).WithVirtualFilePath("/LINGYUN/Abp/Account/Emailing/Templates/MailConfirm.tpl", true) |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
private static ILocalizableString L(string name) |
||||
|
{ |
||||
|
return LocalizableString.Create<AccountEmailingResource>(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,5 @@ |
|||||
|
<div style="position: absolute;"> |
||||
|
<span>{{L "VerifyMyEmailAddress"}}{{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 "MailSecurityVerifyRemarks"}}</span> |
||||
|
</div> |
||||
@ -1,28 +1,28 @@ |
|||||
using Volo.Abp.Account.Localization; |
using Volo.Abp.Account.Localization; |
||||
using Volo.Abp.Emailing; |
using Volo.Abp.Emailing; |
||||
using Volo.Abp.Localization; |
using Volo.Abp.Localization; |
||||
using Volo.Abp.Modularity; |
using Volo.Abp.Modularity; |
||||
using Volo.Abp.VirtualFileSystem; |
using Volo.Abp.VirtualFileSystem; |
||||
|
|
||||
namespace LINGYUN.Abp.Account.Templates; |
namespace LINGYUN.Abp.Account.Emailing; |
||||
|
|
||||
[DependsOn( |
[DependsOn( |
||||
typeof(AbpEmailingModule), |
typeof(AbpEmailingModule), |
||||
typeof(AbpAccountApplicationContractsModule))] |
typeof(AbpAccountApplicationContractsModule))] |
||||
public class AbpAccountTemplatesModule : AbpModule |
public class AbpAccountEmailingModule : AbpModule |
||||
{ |
{ |
||||
public override void ConfigureServices(ServiceConfigurationContext context) |
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
{ |
{ |
||||
Configure<AbpVirtualFileSystemOptions>(options => |
Configure<AbpVirtualFileSystemOptions>(options => |
||||
{ |
{ |
||||
options.FileSets.AddEmbedded<AbpAccountTemplatesModule>(); |
options.FileSets.AddEmbedded<AbpAccountEmailingModule>(); |
||||
}); |
}); |
||||
|
|
||||
Configure<AbpLocalizationOptions>(options => |
Configure<AbpLocalizationOptions>(options => |
||||
{ |
{ |
||||
options.Resources |
options.Resources |
||||
.Get<AccountResource>() |
.Get<AccountResource>() |
||||
.AddVirtualJson("/LINGYUN/Abp/Account/Templates/Localization/Resources"); |
.AddVirtualJson("/LINGYUN/Abp/Account/Emailing/Localization/Resources"); |
||||
}); |
}); |
||||
} |
} |
||||
} |
} |
||||
@ -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,13 +1,13 @@ |
|||||
namespace LINGYUN.Abp.Account.Emailing.Templates; |
namespace LINGYUN.Abp.Account.Emailing.Templates; |
||||
|
|
||||
public static class AccountEmailTemplates |
public static class AccountEmailTemplates |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// 邮件地址确认
|
/// 邮件地址确认
|
||||
/// </summary>
|
/// </summary>
|
||||
public const string MailConfirmLink = "Abp.Account.MailConfirmLink"; |
public const string MailConfirmLink = "Abp.Account.MailConfirmLink"; |
||||
/// <summary>
|
/// <summary>
|
||||
/// 邮件安全验证
|
/// 邮件安全验证
|
||||
/// </summary>
|
/// </summary>
|
||||
public const string MailSecurityVerifyLink = "Abp.Account.MailSecurityVerifyLink"; |
public const string MailSecurityVerifyLink = "Abp.Account.MailSecurityVerifyLink"; |
||||
} |
} |
||||
|
|||||
Loading…
Reference in new issue