Replace shared email commands with MediatR notifications (#280)

This commit is contained in:
Aaron Po
2026-09-05 22:37:00 -04:00
committed by GitHub
parent 4aa7ba5d9b
commit d958933250
24 changed files with 322 additions and 218 deletions

View File

@@ -3,17 +3,17 @@ using Domain.Exceptions;
using Features.Auth.Commands.Profile.CreateUserProfile;
using Features.Auth.Dtos;
using Features.Auth.Identity;
using Features.Auth.Notifications;
using Features.Auth.Services;
using MediatR;
using Microsoft.AspNetCore.Identity;
using Shared.Application.Emails;
namespace Features.Auth.Commands.Authentication.RegisterUser;
/// <summary>
/// Handles <see cref="RegisterUserCommand" />: creates the user via <see cref="UserManager{TUser}" />
/// (which validates uniqueness and hashes the password), issues access/refresh/confirmation tokens, and
/// attempts to send the registration confirmation email via Features.Emails.
/// publishes <see cref="UserRegisteredNotification" /> for Features.Emails to send the confirmation email.
/// </summary>
public class RegisterUserHandler(
UserManager<ApplicationUser> userManager,
@@ -60,31 +60,19 @@ public class RegisterUserHandler(
user.Id,
user.UserName,
string.Empty,
string.Empty,
false
string.Empty
);
bool emailSent = false;
try
{
await mediator.Send(
new SendRegistrationEmailCommand(user.FirstName, user.Email, confirmationToken),
cancellationToken
);
emailSent = true;
}
catch (Exception ex)
{
await Console.Error.WriteLineAsync(ex.Message);
Console.WriteLine("Could not send email.");
}
await mediator.Publish(
new UserRegisteredNotification(user.Id, request.FirstName, user.Email, confirmationToken),
cancellationToken
);
return new RegistrationPayload(
user.Id,
user.UserName,
refreshToken,
accessToken,
emailSent
accessToken
);
}
}

View File

@@ -1,14 +1,14 @@
using Features.Auth.Identity;
using Features.Auth.Notifications;
using Features.Auth.Services;
using MediatR;
using Microsoft.AspNetCore.Identity;
using Shared.Application.Emails;
namespace Features.Auth.Commands.Authentication.ResendConfirmationEmail;
/// <summary>
/// Handles <see cref="ResendConfirmationEmailCommand" /> by generating a fresh confirmation token and
/// sending it via Features.Emails.
/// publishing <see cref="ConfirmationEmailResendRequestedNotification" /> for Features.Emails to send it.
/// </summary>
/// <remarks>
/// Returns silently without sending an email if the user does not exist (to prevent user enumeration)
@@ -33,8 +33,13 @@ public class ResendConfirmationEmailHandler(
return; // Already confirmed, no-op
string confirmationToken = tokenService.GenerateConfirmationToken(user.Id, user.UserName);
await mediator.Send(
new SendResendConfirmationEmailCommand(user.FirstName, user.Email, confirmationToken),
await mediator.Publish(
new ConfirmationEmailResendRequestedNotification(
user.Id,
user.FirstName,
user.Email,
confirmationToken
),
cancellationToken
);
}