stack/apps/e2e/tests/backend/endpoints/api/v1
BilalG1 2f719903b1
Some checks failed
all-good: Did all the other checks pass? / all-good (push) Has been cancelled
Ensure Prisma migrations are in sync with the schema / check_prisma_migrations (22.x) (push) Has been cancelled
DB migration compat / Check if migrations changed (push) Has been cancelled
Docker Server Build and Push / Docker Build and Push Server (push) Has been cancelled
Docker Server Build and Run / docker (push) Has been cancelled
Runs E2E API Tests (Local Emulator) / E2E Tests (Local Emulator, Node ${{ matrix.node-version }}) (22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (mock, 22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (prod, 22.x) (push) Has been cancelled
Runs E2E API Tests with custom port prefix / build (22.x) (push) Has been cancelled
Runs E2E Fallback Tests / E2E Fallback Tests (Node ${{ matrix.node-version }}) (22.x) (push) Has been cancelled
Lint & build / lint_and_build (24) (push) Has been cancelled
TOC Generator / TOC Generator (push) Has been cancelled
DB migration compat / Back-compat — Current branch migrations with ${{ needs.check-migrations-changed.outputs.base_branch }} branch code (push) Has been cancelled
DB migration compat / Forward-compat — Current branch code with ${{ needs.check-migrations-changed.outputs.base_branch }} branch migrations (push) Has been cancelled
DB migration compat / No migration changes (skipped) (push) Has been cancelled
Redesign Email Server settings + managed domain flow (#1373)
## Summary

Rewrites the **Email Server** section of the project email settings page
and the managed-domain setup flow. Replaces the dropdown +
conditional-fields layout with a visual four-card picker, a clearer
unsaved-state model, a stepper dialog for managed-domain onboarding, and
a consistent tracked-domains list. Also fixes two data-correctness bugs
in the managed-domain backend.

## Walkthrough (2×, dead-frames trimmed)


![walkthrough](https://raw.githubusercontent.com/stack-auth/stack-auth/pr-assets-email-ui/pr-assets-walkthrough.gif)

## Before

The saved state was a minimal dropdown, but choosing Custom SMTP /
Resend revealed a long conditional form with a hidden gear toggle for
server config, no clear "what is saved" signal, and a separate dialog
pattern for managed domains.

| Saved (Managed) | Custom SMTP selected |
|---|---|
|
![before-managed](https://raw.githubusercontent.com/stack-auth/stack-auth/pr-assets-email-ui/pr-assets-01-before-shared.png)
|
![before-smtp](https://raw.githubusercontent.com/stack-auth/stack-auth/pr-assets-email-ui/pr-assets-02-before-smtp.png)
|

## After — Provider cards

Four visual cards (Stack Shared, Managed Domain, Resend, Custom SMTP)
with updated copy. The saved provider shows a green **Current** pill;
the card the user is previewing shows an amber dashed **Draft** pill. An
amber unsaved-changes banner appears between the picker and the form
when state diverges from saved, so it is unambiguous that a click is not
yet committed.

| Saved state | Previewing a different provider |
|---|---|
|
![after-saved](https://raw.githubusercontent.com/stack-auth/stack-auth/pr-assets-email-ui/pr-assets-03-after-saved.png)
|
![after-draft](https://raw.githubusercontent.com/stack-auth/stack-auth/pr-assets-email-ui/pr-assets-04-after-draft.png)
|

Copy changes:
- **Stack Shared** — "Only default emails — no custom templates, themes,
or sender identity." (was: "Shared (noreply@stackframe.co)")
- **Managed Domain** — "Bring your own domain. You add DNS records; we
handle signing & delivery." (was: "Managed (via managed domain setup)")
- **Resend** uses the official Resend brand mark (light/dark variants in
`apps/dashboard/public/assets/`)

## After — Managed domain list + stepper dialog

Selecting **Managed Domain** immediately shows the tracked-domain list
with an **Add domain** button. Each row reflects real status (Active /
Verified / Waiting for DNS / Verifying / Failed). Exactly one domain can
be **Active** — the one matching the saved email config; every other
verified/applied domain shows a **Use this domain** button so switching
is always possible.

Adding a domain opens a 3-stage dialog with a horizontal stepper (Verify
is right-aligned for the final step). Stage 2 replaces the old bare
NS-list with a proper **Type / Name / Content** DNS records table with
per-row copy buttons.

| Tracked domains list | DNS records table |
|---|---|
|
![after-list](https://raw.githubusercontent.com/stack-auth/stack-auth/pr-assets-email-ui/pr-assets-05-after-managed-list.png)
|
![after-dns-table](https://raw.githubusercontent.com/stack-auth/stack-auth/pr-assets-email-ui/pr-assets-06-after-dns-table.png)
|

## Bug fixes

- **Backend: applying a managed domain did not demote previously-applied
ones.** Multiple rows could end up with status `APPLIED` even though
only one could be in the saved config. New helper
`demoteOtherAppliedManagedEmailDomains({ tenancyId, keepId })` runs
inside `applyManagedEmailProvider` to demote all other applied rows in
the tenancy back to `VERIFIED` before marking the new one.
- **Frontend: "Use this domain" only appeared for `status ===
verified`.** A domain that had been applied then replaced could never be
re-applied from the UI. Button now appears for any `verified` or
`applied` row that is not currently in use; the **Active** label is
derived from config match instead of DB status.
- **Dev mock onboarding now mirrors production timing.**
`shouldUseMockManagedEmailOnboarding()` used to insert domains as
`verified` synchronously. Now the domain is created as
`pending_verification`, and a fire-and-forget `runAsynchronously(() =>
wait(1000))` updates it to `verified` — mirroring the real Resend
webhook flow so the UI states (pending → verifying → verified) are
exercised in local dev.

## Test plan
- [ ] Cards: clicking each card shows `Draft` pill + amber banner;
Discard restores; Save commits and flips `Current` to the new card
- [ ] Managed: Add domain → stage 1 input → stage 2 DNS table + copy →
Check verification flips to stage 3 → Use this domain sets it Active and
demotes the previously-active domain in the list
- [ ] Managed: clicking **Use this domain** on a non-active verified row
makes it Active and the previously-active row back to Verified
- [ ] Shared / Resend / SMTP: existing save + test-email flows still
work (logic preserved verbatim)
- [ ] `pnpm typecheck` (dashboard + backend) and `pnpm lint` pass

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Redesigned email domain setup flow with multi-step verification dialog
  * Added copy-to-clipboard for DNS records
* Enhanced provider selection interface with improved visual
presentation
* Onboarding now shows initial "pending verification" state and
completes verification asynchronously

* **Bug Fixes**
* Ensures only one managed domain becomes active when applying a domain
  * Improved error handling for email configuration saves

* **Tests**
  * Updated end-to-end tests to reflect async verification timing
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-24 13:35:03 -07:00
..
__snapshots__ Fix ClickHouse OOM in MAU query + optimize /internal/metrics route (#1344) 2026-04-19 22:57:46 -07:00
auth fix: refresh-token P2025 race with concurrent sign-out (#1372) 2026-04-24 18:44:39 +00:00
contact-channels Sign up rules (#1138) 2026-02-03 11:08:24 -08:00
emails More lenient email processing pause 2026-04-12 15:37:33 -07:00
integrations [codex] Fix Neon malformed Basic auth validation (#1381) 2026-04-24 11:59:18 -07:00
internal Redesign Email Server settings + managed domain flow (#1373) 2026-04-24 13:35:03 -07:00
payments Payments bulldozer txn rework (#1315) 2026-04-17 22:11:21 +00:00
ai-query.test.ts Overview revamp (#1238) 2026-04-15 09:36:00 -07:00
analytics-config.test.ts Queries view (#1145) 2026-02-16 11:39:21 -08:00
analytics-events-batch.test.ts fix clickhouse surrogate pair bug (#1270) 2026-03-23 10:09:04 -07:00
analytics-events.test.ts clickhouse user sync (#1159) 2026-02-12 16:52:20 -08:00
analytics-query.test.ts Classify ClickHouse NO_COMMON_TYPE (386) as unsafe (#1380) 2026-04-24 12:07:16 -07:00
api-keys.test.ts Email outbox backend (#1030) 2025-12-12 10:26:38 -08:00
auth-flows.test.ts Fix tests 2025-07-16 11:42:25 -07:00
check-feature-support.test.ts More backend endpoint implementations (#126) 2024-07-13 22:04:53 -07:00
connected-accounts.test.ts More connected accounts (#1165) 2026-02-18 15:19:35 -08:00
data-vault.test.ts Speed up tests (#1063) 2025-12-28 11:25:04 -08:00
email-themes.test.ts [Refactor][Feat][Fix] Rework Email Section With New Sent Page, Better Drafts Page, and Settings Page (#1221) 2026-03-11 12:01:36 -07:00
external-db-sync-advanced.test.ts Turnstile integration for fraud protection (#1239) 2026-03-20 21:26:45 +00:00
external-db-sync-basics.test.ts Sync engine should ignore missing tenancies 2026-04-09 23:31:21 -07:00
external-db-sync-high-volume.test.ts Turnstile integration for fraud protection (#1239) 2026-03-20 21:26:45 +00:00
external-db-sync-race.test.ts Turnstile integration for fraud protection (#1239) 2026-03-20 21:26:45 +00:00
external-db-sync-utils.ts clickhouse new syncs and verify-data (#1304) 2026-04-08 14:43:22 -07:00
index.test.ts "Require publishable client key" toggle (#1158) 2026-02-19 10:23:16 -08:00
internal-metrics.test.ts Overview revamp (#1238) 2026-04-15 09:36:00 -07:00
notification-preferences.test.ts Speed up tests (#1063) 2025-12-28 11:25:04 -08:00
oauth-providers.test.ts Fix OAuth provider disablement 2026-02-24 12:43:41 -08:00
project-permission-definitions.test.ts Config DB migration step 2 (#629) 2025-04-29 14:52:45 -07:00
project-permissions.test.ts Add onboarding status to Project model and implement related database… (#1246) 2026-03-13 12:00:40 -07:00
projects.test.ts Add onboarding status to Project model and implement related database… (#1246) 2026-03-13 12:00:40 -07:00
render-email.test.ts [Refactor] [Fix] Email Rendering Pipeline Refactor, Error Handling, and Bug Fixes (#1140) 2026-02-02 17:35:51 -08:00
restricted-users.test.ts Sign up rules (#1138) 2026-02-03 11:08:24 -08:00
risk-scores.test.ts private files n sm build shit (#1276) 2026-03-23 12:31:36 -07:00
send-email.test.ts Email outbox backend (#1030) 2025-12-12 10:26:38 -08:00
session-replays.test.ts analytics replay filters (#1213) 2026-02-24 13:00:45 -08:00
stripe-webhooks.test.ts fix product route access (#1134) 2026-01-27 18:30:14 +00:00
team-invitations.test.ts Payments bulldozer txn rework (#1315) 2026-04-17 22:11:21 +00:00
team-member-profiles.test.ts Speed up tests (#1063) 2025-12-28 11:25:04 -08:00
team-memberships.test.ts Turnstile integration for fraud protection (#1239) 2026-03-20 21:26:45 +00:00
team-permission-definitions.test.ts Fix error where deleting a team creator default permission would make the dashboard crash 2025-08-11 17:42:54 -07:00
team-permissions.test.ts Add onboarding status to Project model and implement related database… (#1246) 2026-03-13 12:00:40 -07:00
teams.test.ts Speed up tests (#1063) 2025-12-28 11:25:04 -08:00
token-refresh-events.test.ts Reduce number of token refresh events 2026-01-28 14:56:11 -08:00
unsubscribe-link.test.ts Emails redesign (#1076) 2026-02-16 14:57:17 -08:00
users-primary-email.test.ts Onboarding app & restricted users (#1069) 2026-01-11 17:22:14 -08:00
users.test.ts Add server-side flags for anonymous users 2026-04-03 10:43:34 -07:00