fix(auth): app passwords now sign in SMTP, IMAP and POP3
The webmail creates app passwords (shown once, stored hashed, with scopes) but the protocol servers only compared a login against mailboxes.password_hash, so an app password was always refused with 535 / authentication failed. They exist because mail clients cannot do a second factor. - port.MailboxAuth carries the mailbox's app passwords (newest 20) with their scopes; the Postgres repository loads them and stamps last_used_at on use - verifyCredential accepts the mailbox password or an app password that holds the scope of the protocol; SMTP, IMAP and POP3 use it. ManageSieve keeps the mailbox password only, as no default scope covers it - a malformed app password hash is skipped instead of failing the login; a malformed mailbox hash still surfaces as the server-side error it was Tests: unit cases for scopes and malformed hashes, the three entry points, repository tests against Postgres, and an end-to-end test on the real submission server that fails with 535 without the fix and passes with it. Full `go test ./...` with TEST_DATABASE_URL, go vet and lang-lint are clean.
This commit is contained in:
1 parent
8e7c0abd0a
commit
110a240cd9
10 files changed
+599
-5
No files matched your search
@@ -93,6 +93,23 @@ make reset-password EMAIL=… PASSWORD='…' # recovers a lockout, ends its se
|
||||
make reset-mfa EMAIL=… # clears every second factor
|
||||
```
|
||||
|
||||
### App passwords for mail clients
|
||||
|
||||
A mail client cannot answer a second factor, so an account signs a client in
|
||||
with an **app password**: create one in the webmail (Settings, app passwords),
|
||||
copy it once, and give it to the client as the account password. It is shown a
|
||||
single time and stored only as an Argon2id hash.
|
||||
|
||||
An app password works for SMTP submission, IMAP and POP3, as its `scopes`
|
||||
column allows (the default is all three). A scope limits it: an app password
|
||||
with only `imap` can read mail and cannot send. ManageSieve takes the mailbox
|
||||
password only. The mailbox password keeps working everywhere, and a login with
|
||||
an app password stamps its `last_used_at`, which the settings screen shows.
|
||||
|
||||
Until this was wired in, the protocols compared every password only against the
|
||||
mailbox password, so an app password was created, shown and then refused by
|
||||
SMTP, IMAP and POP3 with `535 Authentication credentials invalid`.
|
||||
|
||||
An account locks itself for 15 minutes after 5 failed passwords. That is the
|
||||
lockout working, not a fault; `reset-password` clears it.
|
||||
|
||||
|
||||
Reference in new issue
Block a user