From 591da6de5c09336243ad8bc91df54aaffda2ac17 Mon Sep 17 00:00:00 2001 From: Marcel Baumgartner Date: Thu, 13 Jul 2023 20:39:02 +0200 Subject: [PATCH] Implemented new mail system components --- Moonlight/App/Services/Mail/MailService.cs | 95 ++++++++++++++------- Moonlight/Shared/Views/Admin/Sys/Mail.razor | 51 ++++++++--- 2 files changed, 105 insertions(+), 41 deletions(-) diff --git a/Moonlight/App/Services/Mail/MailService.cs b/Moonlight/App/Services/Mail/MailService.cs index 23d425bf..f362b6d7 100644 --- a/Moonlight/App/Services/Mail/MailService.cs +++ b/Moonlight/App/Services/Mail/MailService.cs @@ -2,6 +2,7 @@ using Moonlight.App.Database.Entities; using Moonlight.App.Exceptions; using Moonlight.App.Helpers; +using Moonlight.App.Repositories; using SmtpClient = MailKit.Net.Smtp.SmtpClient; namespace Moonlight.App.Services.Mail; @@ -14,8 +15,14 @@ public class MailService private readonly int Port; private readonly bool Ssl; - public MailService(ConfigService configService) + private readonly Repository UserRepository; + + public MailService( + ConfigService configService, + Repository userRepository) { + UserRepository = userRepository; + var mailConfig = configService .Get() .Moonlight.Mail; @@ -26,29 +33,9 @@ public class MailService Port = mailConfig.Port; Ssl = mailConfig.Ssl; } - - public async Task SendMail( - User user, - string name, - Action> values - ) + + public Task SendMailRaw(User user, string html) { - if (!File.Exists(PathBuilder.File("storage", "resources", "mail", $"{name}.html"))) - { - Logger.Warn($"Mail template '{name}' not found. Make sure to place one in the resources folder"); - throw new DisplayException("Mail template not found"); - } - - var rawHtml = await File.ReadAllTextAsync(PathBuilder.File("storage", "resources", "mail", $"{name}.html")); - - var val = new Dictionary(); - values.Invoke(val); - - val.Add("FirstName", user.FirstName); - val.Add("LastName", user.LastName); - - var parsed = ParseMail(rawHtml, val); - Task.Run(async () => { try @@ -62,17 +49,15 @@ public class MailService var body = new BodyBuilder { - HtmlBody = parsed + HtmlBody = html }; mailMessage.Body = body.ToMessageBody(); - using (var smtpClient = new SmtpClient()) - { - await smtpClient.ConnectAsync(Server, Port, Ssl); - await smtpClient.AuthenticateAsync(Email, Password); - await smtpClient.SendAsync(mailMessage); - await smtpClient.DisconnectAsync(true); - } + using var smtpClient = new SmtpClient(); + await smtpClient.ConnectAsync(Server, Port, Ssl); + await smtpClient.AuthenticateAsync(Email, Password); + await smtpClient.SendAsync(mailMessage); + await smtpClient.DisconnectAsync(true); } catch (Exception e) { @@ -80,6 +65,54 @@ public class MailService Logger.Warn(e); } }); + + return Task.CompletedTask; + } + + public async Task SendMail(User user, string template, Action> values) + { + if (!File.Exists(PathBuilder.File("storage", "resources", "mail", $"{template}.html"))) + { + Logger.Warn($"Mail template '{template}' not found. Make sure to place one in the resources folder"); + throw new DisplayException("Mail template not found"); + } + + var rawHtml = await File.ReadAllTextAsync(PathBuilder.File("storage", "resources", "mail", $"{template}.html")); + + var val = new Dictionary(); + values.Invoke(val); + + val.Add("FirstName", user.FirstName); + val.Add("LastName", user.LastName); + + var parsed = ParseMail(rawHtml, val); + + await SendMailRaw(user, parsed); + } + + public async Task SendEmailToAll(string template, Action> values) + { + var users = UserRepository + .Get() + .ToArray(); + + foreach (var user in users) + { + await SendMail(user, template, values); + } + } + + public async Task SendEmailToAllAdmins(string template, Action> values) + { + var users = UserRepository + .Get() + .Where(x => x.Admin) + .ToArray(); + + foreach (var user in users) + { + await SendMail(user, template, values); + } } private string ParseMail(string html, Dictionary values) diff --git a/Moonlight/Shared/Views/Admin/Sys/Mail.razor b/Moonlight/Shared/Views/Admin/Sys/Mail.razor index 92e2e07b..538b65e8 100644 --- a/Moonlight/Shared/Views/Admin/Sys/Mail.razor +++ b/Moonlight/Shared/Views/Admin/Sys/Mail.razor @@ -5,17 +5,35 @@ @using Moonlight.App.Helpers.Files @using Moonlight.App.Helpers @using BlazorTable +@using Moonlight.App.Database.Entities @using Moonlight.App.Models.Misc @using Moonlight.App.Services @using Moonlight.App.Services.Interop +@using Moonlight.App.Services.Mail @inject SmartTranslateService SmartTranslateService @inject ToastService ToastService @inject AlertService AlertService +@inject MailService MailService +
+
+ + Actions + +
+
+ + +
+
+ @if (CurrentMailTemplate == null) { @@ -63,9 +81,9 @@ } else { - } @@ -74,12 +92,17 @@ @code { + [CascadingParameter] + public User User { get; set; } + private MailTemplate[] MailTemplateFiles; private FileAccess FileAccess; private LazyLoader LazyLoader; - + + #region Template Editor + private MailTemplate? CurrentMailTemplate; - private string CurrentMailTemplateContent; + private string CurrentMailTemplateContent = ""; private async Task Load(LazyLoader arg) { @@ -101,10 +124,10 @@ private async Task EditTemplate(MailTemplate mailTemplate) { CurrentMailTemplate = mailTemplate; - + CurrentMailTemplateContent = await FileAccess .Read(CurrentMailTemplate.File); - + await InvokeAsync(StateHasChanged); } @@ -135,15 +158,23 @@ SmartTranslateService.Translate("Enter the name of the new template"), "" ); - - if(string.IsNullOrEmpty(name)) + + if (string.IsNullOrEmpty(name)) return; await FileAccess.Write(new() { Name = name + ".html" }, ""); - + await LazyLoader.Reload(); } + + #endregion + + private async Task SendTestMail() + { + await MailService.SendMailRaw(User, "If you see this mail, your moonlight mail configuration is ready to use"); + await AlertService.Info(SmartTranslateService.Translate("A test mail has been sent to the email address of your account")); + } } \ No newline at end of file