Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions Ateleris.NET.Shared/Extensions/EmailServiceExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,24 @@ public class StaticEmailTemplateProviderOptions
"Your Reset Code",
"Please use the following code to reset your password:",
"");

public EmailTemplate AccountApproved { get; set; } = new(
"Account Approved - {0}",
"Account Approved",
"Great news! Your account has been approved. You can now access the platform.",
"Access Platform");

public EmailTemplate AccountApprovedWithConfirmation { get; set; } = new(
"Account Approved - {0}",
"Account Approved - Please Confirm Your Email",
"Great news! Your account has been approved. However, before you can access the platform, you need to confirm your email address. Please click the button below to confirm your email and complete your account setup.",
"Confirm Email & Access Platform");

public EmailTemplate AccountCreatedByAdmin { get; set; } = new(
"Account Created - {0}",
"Welcome - Please Confirm Your Email",
"An administrator has created an account for you. Before you can access the platform, you need to confirm your email address. A temporary password has been provided separately by the administrator. You can change your password at any time using the 'Forgot Password' option on the login page.",
"Confirm Email & Access Platform");
}

public class StaticEmailTemplateProvider(StaticEmailTemplateProviderOptions options) : IEmailTemplateProvider
Expand All @@ -84,4 +102,22 @@ public Task<EmailTemplate> GetResetPasswordCodeTemplateAsync(string domain)
var template = _options.ResetPasswordCode with { Subject = string.Format(_options.ResetPasswordCode.Subject, domain) };
return Task.FromResult(template);
}

public Task<EmailTemplate> GetAccountApprovedTemplateAsync(string domain)
{
var template = _options.AccountApproved with { Subject = string.Format(_options.AccountApproved.Subject, domain) };
return Task.FromResult(template);
}

public Task<EmailTemplate> GetAccountApprovedWithConfirmationTemplateAsync(string domain)
{
var template = _options.AccountApprovedWithConfirmation with { Subject = string.Format(_options.AccountApprovedWithConfirmation.Subject, domain) };
return Task.FromResult(template);
}

public Task<EmailTemplate> GetAccountCreatedByAdminTemplateAsync(string domain)
{
var template = _options.AccountCreatedByAdmin with { Subject = string.Format(_options.AccountCreatedByAdmin.Subject, domain) };
return Task.FromResult(template);
}
}
9 changes: 7 additions & 2 deletions Ateleris.NET.Shared/Services/EmailTemplateRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public string RenderStandardEmail(string title, string message, string buttonUrl
{
var content = new StringBuilder();
content.Append(FormatElement(_options.TitleFormat, title));
content.Append(FormatElement(_options.ContentFormat, $"<p>{message}</p>"));
content.Append(FormatElement(_options.ContentFormat, $"<p>{ConvertNewlinesToHtml(message)}</p>"));

if (!string.IsNullOrEmpty(buttonUrl) && !string.IsNullOrEmpty(buttonText))
{
Expand All @@ -27,7 +27,7 @@ public string RenderCodeEmail(string title, string message, string code)
{
var content = new StringBuilder();
content.Append(FormatElement(_options.TitleFormat, title));
content.Append(FormatElement(_options.ContentFormat, $"<p>{message}</p>"));
content.Append(FormatElement(_options.ContentFormat, $"<p>{ConvertNewlinesToHtml(message)}</p>"));
content.Append(FormatElement(_options.CodeFormat, code));
content.Append(FormatElement(_options.FooterFormat, DateTime.Now.Year, _options.Domain));

Expand All @@ -43,6 +43,11 @@ private static string FormatElement(string format, params object[] args)
{
return string.Format(format, args);
}

private static string ConvertNewlinesToHtml(string text)
{
return text.Replace("\r\n", "<br>").Replace("\n", "<br>").Replace("\r", "<br>");
}
}

public class EmailTemplateOptions
Expand Down
3 changes: 3 additions & 0 deletions Ateleris.NET.Shared/Services/IEmailTemplateProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ public interface IEmailTemplateProvider
Task<EmailTemplate> GetConfirmAccountTemplateAsync(string domain);
Task<EmailTemplate> GetResetPasswordTemplateAsync(string domain);
Task<EmailTemplate> GetResetPasswordCodeTemplateAsync(string domain);
Task<EmailTemplate> GetAccountApprovedTemplateAsync(string domain);
Task<EmailTemplate> GetAccountApprovedWithConfirmationTemplateAsync(string domain);
Task<EmailTemplate> GetAccountCreatedByAdminTemplateAsync(string domain);
}

public record EmailTemplate(string Subject, string Title, string Message, string ButtonText);
48 changes: 48 additions & 0 deletions Ateleris.NET.Shared/Services/IdentityEmailSenderService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,54 @@ public async Task SendPasswordResetCodeAsync(TUser user, string email, string re
var content = new TextPart(MimeKit.Text.TextFormat.Html) { Text = emailContent };
await SendEmailAsync(email, template.Subject, content);
}

public async Task SendAccountApprovedAsync(TUser user, string email, string loginLink)
{
logger.LogTrace("Sending account approval notification to user {user}", user.UserName);

var template = await templateProvider.GetAccountApprovedTemplateAsync(_options.Domain);

var emailContent = templateRenderer.RenderStandardEmail(
template.Title,
template.Message,
loginLink,
template.ButtonText);

var content = new TextPart(MimeKit.Text.TextFormat.Html) { Text = emailContent };
await SendEmailAsync(email, template.Subject, content);
}

public async Task SendAccountApprovedWithConfirmationAsync(TUser user, string email, string confirmationLink)
{
logger.LogTrace("Sending account approval notification with email confirmation to user {user}", user.UserName);

var template = await templateProvider.GetAccountApprovedWithConfirmationTemplateAsync(_options.Domain);

var emailContent = templateRenderer.RenderStandardEmail(
template.Title,
template.Message,
confirmationLink,
template.ButtonText);

var content = new TextPart(MimeKit.Text.TextFormat.Html) { Text = emailContent };
await SendEmailAsync(email, template.Subject, content);
}

public async Task SendAccountCreatedByAdminAsync(TUser user, string email, string confirmationLink)
{
logger.LogTrace("Sending account created by admin notification to user {user}", user.UserName);

var template = await templateProvider.GetAccountCreatedByAdminTemplateAsync(_options.Domain);

var emailContent = templateRenderer.RenderStandardEmail(
template.Title,
template.Message,
confirmationLink,
template.ButtonText);

var content = new TextPart(MimeKit.Text.TextFormat.Html) { Text = emailContent };
await SendEmailAsync(email, template.Subject, content);
}
}

public class EmailOptions
Expand Down