docs: file two host-app issues found during the S/MIME spike
1. A 401 from ANY login step is reported as wrong password. auth-store.ts:61 classifies any error whose message merely contains the substring 401 as invalid_credentials, and it is fed by a catch-all around the entire login sequence. Reproduced with admin@sandbox.vnc.de, a Stalwart administrative principal with no mailbox: POST /api/auth/session returns 200 (the password IS correct), then the JMAP session fetch returns 401 and the UI claims the password is wrong. Verified directly: bernd.rodler gets 200 with a mail capability, admin gets 401. Cost several minutes re-typing a password that was never wrong. An admin-only principal, a disabled mailbox and a revoked mail permission are all indistinguishable from a typo. 2. Page reload signs you out unless stay-signed-in is ticked, which also silently prevents plugin activation and therefore looks like a plugin bug. SESSION_SECRET is intact, so not a key rotation. Neither blocks P1; both deliberately not chased during the spike. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
a9af816012
commit
fe77e9f52b
@@ -0,0 +1,55 @@
|
|||||||
|
# VNCmail+ — known issues (host app, not the S/MIME plugin)
|
||||||
|
|
||||||
|
Filed during the S/MIME spike, 2026-08-04. Neither blocks P1.
|
||||||
|
|
||||||
|
## 1. A 401 from any login step is reported as "wrong password"
|
||||||
|
|
||||||
|
`stores/auth-store.ts:61`
|
||||||
|
|
||||||
|
```ts
|
||||||
|
{ key: 'invalid_credentials', matches: ['Invalid username or password', '401', 'Unauthorized'] },
|
||||||
|
```
|
||||||
|
|
||||||
|
`classifyLoginError` is fed by a catch-all wrapped around the *entire* login
|
||||||
|
sequence (`auth-store.ts:767`), so any error whose message merely *contains*
|
||||||
|
`401` becomes "Invalid username or password" — including a 401 raised well
|
||||||
|
after the credential check already succeeded.
|
||||||
|
|
||||||
|
**Reproduced:** `admin@sandbox.vnc.de` is a Stalwart *administrative principal*
|
||||||
|
with no mailbox. `POST /api/auth/session` returns `200 {"ok":true}` — the
|
||||||
|
password is genuinely correct — but the follow-up JMAP session fetch returns
|
||||||
|
`401 Unauthorized` ("You have to authenticate first."), and the UI reports a
|
||||||
|
wrong password. Verified side by side against `GET /.well-known/jmap` with
|
||||||
|
Basic auth:
|
||||||
|
|
||||||
|
| Account | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bernd.rodler@sandbox.vnc.de` | `200` · 1 account · mail capability present |
|
||||||
|
| `admin@sandbox.vnc.de` | `401 Unauthorized` |
|
||||||
|
|
||||||
|
**Cost observed:** several minutes lost re-typing a password that was never wrong.
|
||||||
|
|
||||||
|
**Impact:** an admin-only principal, a disabled mailbox, and a revoked mail
|
||||||
|
permission are all indistinguishable from a typo. Users retry credentials
|
||||||
|
indefinitely and support chases the wrong cause.
|
||||||
|
|
||||||
|
**Fix direction:** distinguish a 401 from the credential check from a 401 raised
|
||||||
|
by a later step, and give the latter its own message (e.g. "This account has no
|
||||||
|
mailbox"). Matching on the bare substring `401` anywhere in an error message is
|
||||||
|
too broad regardless — it will also catch a 401 from an unrelated downstream
|
||||||
|
call, and any error text that happens to contain those digits.
|
||||||
|
|
||||||
|
## 2. Page reload signs you out unless "stay signed in" is ticked
|
||||||
|
|
||||||
|
Reloading `localhost:3100` without `rememberMe` produces *"Ihre Sitzung ist
|
||||||
|
abgelaufen"*. During the spike this also silently prevented plugin activation
|
||||||
|
(the sandbox loader only runs after a successful boot), which presented as a
|
||||||
|
plugin fault rather than a session fault — it cost two debugging cycles before
|
||||||
|
the real cause was clear.
|
||||||
|
|
||||||
|
`.env.local` `SESSION_SECRET` is intact, so this is not a signing-key rotation.
|
||||||
|
This may be the same complaint raised earlier about sessions expiring too
|
||||||
|
quickly — if so, the 6-hour `jmap_stalwart_ctx` `maxAge` added in
|
||||||
|
`lib/stalwart/auth-context.ts` did not address the real cause.
|
||||||
|
|
||||||
|
Unknown size until diagnosed. Deliberately not chased during the spike.
|
||||||
Reference in New Issue
Block a user