With a domain mapped to its own Stalwart (#238), two requests still went to STALWART_URL:
/api/account/* (password, app passwords, 2FA) re-fetched the upstream session without upstreamFor(). Once the five-minute session cache expired, a mapped account's credential calls reached the default server, which either rejects the password or has a different account with the same name.
The locale lookup resolved Stalwart's apiUrl against the default server instead of session.baseUrl.
Both now go to the server that issued the session. Found while scoping in-app administration, which would have inherited the same routing.
Testing
New test in accountinfo.test.ts: every account-info request goes to the session's server. It fails without the upstream.ts change and passes with it.
npm run typecheck -w server and npm test -w server: 169/169 pass.
## Summary
With a domain mapped to its own Stalwart (#238), two requests still went to `STALWART_URL`:
- **`/api/account/*`** (password, app passwords, 2FA) re-fetched the upstream session without `upstreamFor()`. Once the five-minute session cache expired, a mapped account's credential calls reached the default server, which either rejects the password or has a different account with the same name.
- **The locale lookup** resolved Stalwart's `apiUrl` against the default server instead of `session.baseUrl`.
Both now go to the server that issued the session. Found while scoping in-app administration, which would have inherited the same routing.
## Testing
- New test in `accountinfo.test.ts`: every account-info request goes to the session's server. It fails without the `upstream.ts` change and passes with it.
- `npm run typecheck -w server` and `npm test -w server`: 169/169 pass.
## Translations
No user-visible strings added or changed.
**Merged** 2026-09-13 as coffey-labs/ihasmail@5f5672fed378
<sub>Rebuilt from: git history, session transcript.</sub>
This repo is archived. You cannot comment on issues.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
With a domain mapped to its own Stalwart (#238), two requests still went to
STALWART_URL:/api/account/*(password, app passwords, 2FA) re-fetched the upstream session withoutupstreamFor(). Once the five-minute session cache expired, a mapped account's credential calls reached the default server, which either rejects the password or has a different account with the same name.apiUrlagainst the default server instead ofsession.baseUrl.Both now go to the server that issued the session. Found while scoping in-app administration, which would have inherited the same routing.
Testing
accountinfo.test.ts: every account-info request goes to the session's server. It fails without theupstream.tschange and passes with it.npm run typecheck -w serverandnpm test -w server: 169/169 pass.Translations
No user-visible strings added or changed.
Merged 2026-09-13 as coffey-labs/ihasmail@5f5672fed3
Rebuilt from: git history, session transcript.