- Shipped
- September 28, 2026 at 9:42 AM UTC
- Author
- Kamo
- Commit
- b8e6f4a
EmailService's DavAuthFilter posted Basic credentials to **************** a route that never existed (405), so since 2026-03-19 no phone (iOS, DAVx5) could add a Kamo calendar or address book (SP07 T37). POST /api/internal/dav/sign-in (unforwarded prefix; X-Internal-Auth against internal.auth.secret, constant-time, 503 when unset, 403 on a mismatch) checks the password the way SecurityController.login does, with the client's relayed X-Forwarded-Host / X-Forwarded-For / User-Agent, and mints no session: - access rules for the host, then for the chosen workspace; a host naming no organization; - the progressive lockout BEFORE the password is compared; a wrong password counts; - a custom domain names the workspace; on the platform host a named workspace (the web's ?org= hint) or the account's one enterable workspace, else CHOOSE_WORKSPACE (a calendar app cannot pick); - synthetic account, voided organization, unverified e-mail, soft-deleted / no longer employed / AI member, and a confirmed second factor (no app passwords exist) are refused; - recordSuccess only once every gate has passed. RepeatedWrongPasswords: a device replaying the same stale password is refused but charged one strike, not one per sync, so a forgotten phone cannot walk the office address up to the permanent block. The marker is a PBKDF2 derivation at the platform's password cost.
