Skip to content

feat: capture development email in MailHog via the Aspire sample (#73)#75

Merged
andregoepel merged 1 commit into
mainfrom
feature/aspire-mailhog
Jul 5, 2026
Merged

feat: capture development email in MailHog via the Aspire sample (#73)#75
andregoepel merged 1 commit into
mainfrom
feature/aspire-mailhog

Conversation

@andregoepel

Copy link
Copy Markdown
Owner

Closes #73.

What

  • AppHost: adds a MailHog container — SMTP on 1025, web UI on 8025 (open it from the Aspire dashboard to read captured mail). The web app WaitFors it.
  • Pre-configured email: the AppHost sets the web app's EmailSender__* config to send through MailHog. Because these come from configuration, not the database, email keeps working after a database reset with zero manual setup on the Email Settings page (the MailService uses the EmailSender section as its bootstrap when no DB record exists).
  • SmtpEmailSender auth guard: MailHog accepts mail without authentication and doesn't advertise AUTH, and MailKit throws if AuthenticateAsync is called against such a server. The sender now authenticates only when the server advertises it and a username is configured — so MailHog works, and so do other no-auth relays. Real servers that advertise AUTH behave exactly as before.

Why config, not DB seeding

The issue asks that email survive a database reset without re-setup. Configuration is independent of the (persistent-volume) database, so a wipe/reset can't remove it and there's no re-seed-on-startup logic to maintain. The Email Settings page shows these as the "from configuration" baseline, and an admin can still save DB overrides on top.

Verification

  • dotnet build -c Release — 0 errors (AppHost compiles against Aspire 13.4.6; SmtpCapabilities guard compiles).
  • dotnet test -c Release — 89/89.
  • I did not run the full Aspire end-to-end here (needs Docker + the setup/login flow + sending a test mail to view it in the MailHog UI). The auth guard is correct whether or not MailHog advertises AUTH, and the container/endpoint wiring is standard Aspire; please give it a spin to confirm mail lands in the MailHog UI.

Note

MailHog SMTP/UI use fixed host ports 1025/8025 for a stable local URL. If either conflicts on your machine, tell me and I'll switch to Aspire-assigned dynamic ports (wiring the SMTP endpoint into EmailSender__Server/Port via endpoint references).

Add a MailHog container to the AppHost (SMTP on 1025, web UI on 8025) and
pre-configure the web app's EmailSender section to send through it. The
settings come from configuration, not the database, so email keeps working
after a database reset with no manual setup on the Email Settings page.

MailHog accepts mail without authentication and does not advertise AUTH, and
MailKit throws if AuthenticateAsync is called against such a server. Guard the
call in SmtpEmailSender: only authenticate when the server advertises it and a
username is configured. This also makes the foundation work with other no-auth
relays.

Closes #73
@andregoepel
andregoepel merged commit 80016f0 into main Jul 5, 2026
3 checks passed
@andregoepel
andregoepel deleted the feature/aspire-mailhog branch July 5, 2026 07:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add MailHog to the Aspire sample and pre-configure email for development

1 participant