From the user demo: registering from a personal invite link must show the invited email pre-filled and unchangeable.
Current main already renders the email read-only — but keyed off any invite row matching the token, valid or not. With open registration enabled, a stale token (expired / already accepted / revoked) showed the stale invite's address read-only while the submit handler took the open-registration branch and required a posted email that the locked field never submits (it has no name), dead-ending the form with "Please enter a valid email address."
RegistrationPage::render() now computes $inviteValid (Invite::isAcceptable()) once and the template locks the email exactly when the invite is redeemable; a stale token with open registration on falls back to the normal editable field. The server side was already safe — on submit a valid invite's stored address is always used, so a tampered client value is ignored; that behaviour is unchanged and now covered by rendering tests.
Tests
RegistrationPageTest::testValidInviteRendersEmailPrefilledAndLocked — read-only invited address, no editable name="email" input.
RegistrationPageTest::testStaleInviteWithOpenRegistrationShowsEditableEmail — editable field, stale address absent.
composer test — 367 tests pass; composer lint (PHPStan level 10) and composer cs clean.
Closes #78
## What & why
From the user demo: registering from a **personal invite link** must show the invited email pre-filled and unchangeable.
Current `main` already renders the email read-only — but keyed off *any* invite row matching the token, valid or not. With open registration enabled, a stale token (expired / already accepted / revoked) showed the stale invite's address read-only while the submit handler took the open-registration branch and required a posted `email` that the locked field never submits (it has no `name`), dead-ending the form with "Please enter a valid email address."
`RegistrationPage::render()` now computes `$inviteValid` (`Invite::isAcceptable()`) once and the template locks the email **exactly when the invite is redeemable**; a stale token with open registration on falls back to the normal editable field. The server side was already safe — on submit a valid invite's stored address is always used, so a tampered client value is ignored; that behaviour is unchanged and now covered by rendering tests.
## Tests
- `RegistrationPageTest::testValidInviteRendersEmailPrefilledAndLocked` — read-only invited address, no editable `name="email"` input.
- `RegistrationPageTest::testStaleInviteWithOpenRegistrationShowsEditableEmail` — editable field, stale address absent.
- `composer test` — 367 tests pass; `composer lint` (PHPStan level 10) and `composer cs` clean.
Docs updated: `docs/features/account-registration.md`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The register form keyed the read-only, prefilled email off any invite row
matching the token. A stale token (expired / accepted / revoked) with open
registration on therefore showed the stale invite's address read-only while
the submit handler took the open branch and required a posted email the
locked field never submits, dead-ending the form. The lock now applies
exactly when the invite is acceptable; otherwise the editable field renders.
Closes#78
Co-Authored-By: Claude Fable 5 <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #78
What & why
From the user demo: registering from a personal invite link must show the invited email pre-filled and unchangeable.
Current
mainalready renders the email read-only — but keyed off any invite row matching the token, valid or not. With open registration enabled, a stale token (expired / already accepted / revoked) showed the stale invite's address read-only while the submit handler took the open-registration branch and required a postedemailthat the locked field never submits (it has noname), dead-ending the form with "Please enter a valid email address."RegistrationPage::render()now computes$inviteValid(Invite::isAcceptable()) once and the template locks the email exactly when the invite is redeemable; a stale token with open registration on falls back to the normal editable field. The server side was already safe — on submit a valid invite's stored address is always used, so a tampered client value is ignored; that behaviour is unchanged and now covered by rendering tests.Tests
RegistrationPageTest::testValidInviteRendersEmailPrefilledAndLocked— read-only invited address, no editablename="email"input.RegistrationPageTest::testStaleInviteWithOpenRegistrationShowsEditableEmail— editable field, stale address absent.composer test— 367 tests pass;composer lint(PHPStan level 10) andcomposer csclean.Docs updated:
docs/features/account-registration.md.🤖 Generated with Claude Code