Move registration email delivery to email-first sign-in
Change the existing uncommitted user-administration implementation: operator action becomes Create user and persists a reusable pending account without invitation/outbox mail. Sign-in becomes email-first, then a session-bound password step for fully registered accounts or generic check-email registration step for pending accounts. Unknown/disabled addresses do not create accounts or send mail; no public self-registration. Existing single-use/expiring setup, Mailpit worker, authorization/audit and last-admin protections remain. Implementation constraints: preserve existing applied migration checksums using an explicit new migration; reuse anonymous sessions, CSRF/origin, password work/attempt budgets, invitation lifecycle/outbox. Bind selected email server-side; prevent email-step bypass or cross-account form tampering. Registration issuance must serialize/recheck account and session state, avoid repeated-email floods or invalidating already delivered links, and keep secrets out of audit/outbox/logs. Remove operator-triggered send/resend flow; retain revocation where useful. Existing uncommitted changes are related prior work; preserve them, do not commit or alter production. User additionally requested removal of explanatory subtitle/hint spam: remove redundant model/workflow copy from user list/create/detail/setup forms and keep labels, actionable errors and necessary warnings; put detailed explanations in docs. Acceptance: create user UI sends no mail; first sign-in email submission queues one expiring single-use setup email; repeat/concurrent requests are bounded, preserve current link and obey resend cooldown; established users enter password only after email step. Existing operator login and full second-operator grant/revoke/disable browser journeys work without JavaScript in both themes. Tests cover unknown/disabled/foreign realms, CSRF/origin, step binding and expiry/replay, issuance concurrency/rate limits, atomic rollback/audit exclusion, and migration compatibility. Pass format/Clippy/ordinary Rust/full synthetic gate and complete browser gate; update repository documentation. Verified milestone: email-first service/HTTP and silent creation are implemented; 69 Rust tests through the synthetic gate pass, including four new regressions for no-mail creation/only-POST issuance, session/nonce/expiry step binding, concurrent issuance/cooldown/stable resend links, rollback and disabled/foreign accounts. Registration mail requests use a service principal rather than falsely attributing unverified requests to the target account. Established-password login and the full create→email-first registration→Mailpit→own password→grant/revoke/disable journey pass all four theme/JS cases; new screenshots inspected and explanatory UI copy removed. A browser helper label selector was corrected after a reproduced timeout; retest passes. Preview matrix passed before that helper correction; full final gate rerun still pending. Migration compatibility: the interactive synthetic DB had applied 0005 before the later audit-actor adjustment. Restored 0005 byte-for-byte to its recorded checksum and moved the adjustment into new 0006, without editing DB migration metadata/resetting data. Dedicated helper migration then succeeds. Final docs and all gates now pass. README, docs/authentication.md, docs/user-administration.md and frontend/README.md describe silent creation, email/password/registration routes, cooldown, service-principal attribution, remaining enumeration tradeoff and local delivery. The user also requested consistent field layout: reason now uses the existing shared TextField component with unique IDs; dropdown labels are separate from controls. Browser checks verify labels above controls and unique IDs across repeated forms. Create/email/password/registration/detail screenshots were visually inspected in light/dark, including JavaScript off. Final verified validation: cargo fmt --check, strict workspace/all-target/all-feature Clippy, ordinary workspace/all-feature Rust tests, python3 dev/run.py test (69 Rust tests plus five tooling tests and asset checks/build), and python3 dev/run.py browser-test (eight preview matrix cases plus all four expanded operator journeys) pass. Raw setup URLs/password/key log exclusions also pass. Whitespace and private-metadata scans pass. The latest parallel feature review was user-aborted, so no completed final independent review or approval is claimed. Owned test processes were cleaned up; the user's active development server on 8800/Vite5173 was left alone. Changes remain uncommitted on the existing feature branch; no production changes.
Checklist
3 of 3 complete- Create pending accounts without email and implement serialized, rate-limited registration delivery at email-first sign-in with session-bound password steps.
- Verify two-step login, no-mail creation, registration cooldown/replay/concurrency, authorization and audit boundaries with synthetic regression tests.
- Update browser journeys and documentation; pass formatting, Clippy, full synthetic tests and light/dark JavaScript-on/off browser gates.