using Domain.Entities; using Infrastructure.Email; using Infrastructure.Email.Templates.Rendering; namespace Service.Emails; /// /// Defines operations for sending account-related emails, such as registration and confirmation resend emails. /// public interface IEmailService { /// /// Sends a welcome email containing an account confirmation link to a newly registered user. /// /// The newly created user account to email. /// The confirmation token to embed in the confirmation link. /// A task that completes once the email has been sent. public Task SendRegistrationEmailAsync( UserAccount createdUser, string confirmationToken ); /// /// Sends an email containing a fresh account confirmation link to a user who requested a resend. /// /// The user account to email. /// The confirmation token to embed in the confirmation link. /// A task that completes once the email has been sent. public Task SendResendConfirmationEmailAsync( UserAccount user, string confirmationToken ); } /// /// Default implementation of that renders email templates and dispatches /// them via an . /// /// Provider used to deliver the rendered emails. /// Provider used to render HTML email bodies from templates. public class EmailService( IEmailProvider emailProvider, IEmailTemplateProvider emailTemplateProvider ) : IEmailService { /// /// The base URL of the website, used to build confirmation links. Read from the /// WEBSITE_BASE_URL environment variable. /// /// /// Thrown at type initialization time when the WEBSITE_BASE_URL environment variable is not set. /// private static readonly string WebsiteBaseUrl = Environment.GetEnvironmentVariable("WEBSITE_BASE_URL") ?? throw new InvalidOperationException("WEBSITE_BASE_URL environment variable is not set"); /// /// Builds a confirmation link from the given token, renders the registration welcome email template, /// and sends it to the newly created user. /// /// The newly created user account to email. /// The confirmation token to embed in the confirmation link. /// A task that completes once the email has been sent. public async Task SendRegistrationEmailAsync( UserAccount createdUser, string confirmationToken ) { var confirmationLink = $"{WebsiteBaseUrl}/users/confirm?token={confirmationToken}"; var emailHtml = await emailTemplateProvider.RenderUserRegisteredEmailAsync( createdUser.FirstName, confirmationLink ); await emailProvider.SendAsync( createdUser.Email, "Welcome to The Biergarten App!", emailHtml, isHtml: true ); } /// /// Builds a confirmation link from the given token, renders the resend-confirmation email template, /// and sends it to the user. /// /// The user account to email. /// The confirmation token to embed in the confirmation link. /// A task that completes once the email has been sent. public async Task SendResendConfirmationEmailAsync( UserAccount user, string confirmationToken ) { var confirmationLink = $"{WebsiteBaseUrl}/users/confirm?token={confirmationToken}"; var emailHtml = await emailTemplateProvider.RenderResendConfirmationEmailAsync( user.FirstName, confirmationLink ); await emailProvider.SendAsync( user.Email, "Confirm Your Email - The Biergarten App", emailHtml, isHtml: true ); } }