mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-10-15 18:14:44 +00:00
98 lines
3.1 KiB
Plaintext
98 lines
3.1 KiB
Plaintext
@startuml resend-confirmation
|
|
!include ../../../pipeline/diagrams/biergarten-weizen-theme.puml
|
|
skinparam sequenceMessageAlign center
|
|
skinparam maxMessageSize 200
|
|
|
|
title User Authentication Flow - Resend Confirmation Email
|
|
|
|
actor User
|
|
participant "API\nController" as API
|
|
participant "MediatR pipeline\n(ValidationBehavior)" as Mediator
|
|
box "Handler Layer" #F1F3EA
|
|
participant "ResendConfirmationEmailHandler" as ResendHandler
|
|
participant "UserManager<ApplicationUser>" as UserMgr
|
|
participant "TokenService" as TokenSvc
|
|
end box
|
|
box "Infrastructure Layer" #EBECE3
|
|
participant "Email\nProvider" as SMTP
|
|
participant "Template\nProvider" as Template
|
|
end box
|
|
box "Repository / Cross-slice" #DBEEDD
|
|
participant "DapperUserStore\n(IUserStore/IUserPasswordStore/\nIUserEmailStore)" as UserStore
|
|
participant "EmailDispatcher\n(Features.Emails)" as EmailDispatcher
|
|
end box
|
|
database "SQL Server" as DB
|
|
|
|
note over UserMgr
|
|
ASP.NET Core Identity's UserManager<TUser>
|
|
replaces the deleted AuthRepository: handlers
|
|
no longer issue SQL or call Argon2 directly,
|
|
they delegate to UserManager, which in turn
|
|
calls DapperUserStore (persistence) and
|
|
Argon2PasswordHasher (IPasswordHasher<TUser>).
|
|
end note
|
|
|
|
User -> API: POST /api/auth/confirm/resend?userId=<id>\n(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 ...\nFROM dbo.UserAccount\nWHERE 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\n(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(\n firstName, email, confirmationToken)
|
|
activate EmailDispatcher
|
|
EmailDispatcher -> Template: Render email\n(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\n{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.
|
|
end note
|
|
deactivate API
|
|
|
|
@enduml
|