The account lists carry timestamps, so they waited for the device timezone by rendering once in UTC and rebuilding themselves a moment later — long enough to replace a button under the first click. The page now waits for the zone the way Today waits for the date. The sign-in step likewise lets a preceding sign-out's redirect land before it fills the form, which is what a CI run caught and three local runs had not. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2.7 KiB
Invitation and sign-in UX
Superseded by auth-flow-refresh.md, which rebuilt both flows in 0.1.111. This document records the state before that package.
Administrators enter the recipient address before creating an invitation. The resulting single-use, seven-day invitation offers copy and direct email actions. A successful local mail submission disables the send button; a failed submission leaves the same link available for retry or manual sharing. Submission confirmation does not promise mailbox delivery.
The email address is URL-encoded in the invitation fragment, alongside the token. Neither value reaches HTTP access logs through this URL. Opening the link removes the fragment from browser history and prefills the address. Existing token-only invitation links remain supported. The address is a convenience, not a recipient binding: the existing rule that anyone possessing the unused link can register remains unchanged. Actual mailbox ownership still requires a separate email code or login link.
Sign-in shows one active step: request a code, then enter it with the address already filled in. “I already have a code” opens the second step independently on another device. Setup and manually entered invitation credentials are under a collapsed disclosure. Guest access remains a secondary action. A failed code attempt keeps the address and the code step.
For two hours, the same HTTP session retains the pending invitation/setup context so requesting a replacement code does not silently lose the right to register. Changing the address drops that context; successful sign-in invalidates the session. No schema or data migration is involved.
Validation covers encoded invitation addresses and history removal, both language email templates with captured local transport, single-step rendering and escaped remembered addresses, retry context and wrong-code handling. Browser acceptance creates an invitation with a recipient, captures its email, opens the link signed out, checks automatic address transfer and completes the new account login. No real test email is sent.
Verification on 2026-09-10
- Full JVM/Chromium run: 239 reported cases, 197 executed, 42 filtered/skipped, zero failures/errors. All 20 Chromium scenarios passed.
- After shortening the code-step introduction, controller tests and Firefox scenarios WJ-041/WJ-042 passed (2 scenarios, 11 steps), including the captured clipboard handoff and captured invitation email.
- Frontend JavaScript test files passed. Screenshots reviewed at 360 and 1280 CSS pixels; the compact code step was rechecked in Firefox at 360 pixels.
- Real invitation delivery is user-invoked; validation sent no external messages.