# User Authentication Flow — Resend Confirmation Email ```mermaid sequenceDiagram actor User participant API as API Controller participant Mediator as MediatR pipeline
(ValidationBehavior) box rgb(241,243,234) Handler Layer participant ResendHandler as ResendConfirmationEmailHandler participant UserMgr as UserManager(ApplicationUser) participant TokenSvc as TokenService end box rgb(235,236,227) Infrastructure Layer participant SMTP as Email Provider participant Template as Template Provider end box rgb(219,238,221) Repository / Cross-slice participant UserStore as DapperUserStore
(IUserStore/IUserPasswordStore/IUserEmailStore) participant EmailDispatcher as EmailDispatcher
(Features.Emails) end participant DB as SQL Server Note over UserMgr: ASP.NET Core Identity's UserManager replaces the deleted AuthRepository — handlers delegate to UserManager, which calls DapperUserStore (persistence) and Argon2PasswordHasher. User->>API: POST /api/auth/confirm/resend?userId={id} (requires Bearer access token) activate API API->>Mediator: Send(ResendConfirmationEmailCommand(userId)) activate Mediator Mediator->>ResendHandler: Handle(command) activate ResendHandler ResendHandler->>UserMgr: FindByIdAsync(userId) activate UserMgr UserMgr->>UserStore: FindByIdAsync(userId) activate UserStore UserStore->>DB: SELECT ... FROM UserAccount WHERE UserAccountID = @Id activate DB DB-->>UserStore: row or null deactivate DB UserStore-->>UserMgr: ApplicationUser or null deactivate UserStore UserMgr-->>ResendHandler: ApplicationUser or null deactivate UserMgr alt User not found ResendHandler->>ResendHandler: return silently (prevents user enumeration) else User found ResendHandler->>UserMgr: IsEmailConfirmedAsync(user) UserMgr-->>ResendHandler: bool alt Already confirmed ResendHandler->>ResendHandler: return silently (no-op) else Not yet confirmed ResendHandler->>TokenSvc: GenerateConfirmationToken(user) activate TokenSvc TokenSvc-->>ResendHandler: confirmation token deactivate TokenSvc ResendHandler->>Mediator: Send(SendResendConfirmationEmailCommand) activate Mediator Mediator->>EmailDispatcher: SendResendConfirmationEmailAsync(firstName, email, confirmationToken) activate EmailDispatcher EmailDispatcher->>Template: Render email (same Razor pipeline as registration) EmailDispatcher->>SMTP: SendAsync(email, subject, body) deactivate EmailDispatcher deactivate Mediator end end ResendHandler-->>Mediator: (void) deactivate ResendHandler Mediator-->>API: (void) deactivate Mediator API->>User: 200 OK {message: "confirmation email has been resent"} Note right of API: Always 200 OK regardless of outcome above — same user-enumeration precaution as a not-found user or an already-confirmed account deactivate API ```