CluPilotCloud/app
nexxo 5b8c28595a Require a confirmed address before an account can use anything
Registration opened an account that could sign in immediately on an address
nobody had proved was theirs — and anybody can type a stranger's into a
registration form. Both halves were commented out: the Fortify feature and
MustVerifyEmail on the model.

`verified` sits on the whole portal group rather than on the pages that spend
money. An unconfirmed address is not a billing problem to be caught at
checkout; it is an account that may not belong to the person holding it, and
the servers, the users and the backups behind it are worth as much to whoever
typed the address as to whoever owns it.

The mail is a Mailable in this product's design rather than Laravel's
notification, which would arrive with the framework's logo, button and footer
as the first thing anybody ever receives from CluPilot. It also has to leave
through the SYSTEM mailbox like every other account mail, which the
notification path does not do on its own.

The link is signed and expires, and the address is part of what is signed — so
a link issued to a mistyped address stops working the moment the address is
corrected, rather than confirming an address nobody can read. Tests cover the
tampered link, the expired one, the corrected address, and one account trying
to confirm another.

The waiting page is ours (Fortify has views off) and offers the only two things
that move somebody forward: send it again, or sign out and register with the
address they meant. The resend is throttled, because otherwise it is a button
that makes the server send mail to an arbitrary address as fast as it can be
clicked. Somebody already confirmed is redirected away from it — the `verified`
middleware only guards the other direction.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-28 23:43:20 +02:00
..
Actions Refuse a portal login for an address that already belongs to an operator 2026-07-28 14:42:16 +02:00
Console Check users directly for the reverse operator-identity collision, not just customers 2026-07-28 15:36:29 +02:00
Exceptions Refuse a portal login for an address that already belongs to an operator 2026-07-28 14:42:16 +02:00
Http Show where an account is signed in, and let it sign the other places out 2026-07-28 23:38:17 +02:00
Listeners Recognise the devices an account signs in from, and warn about a new one 2026-07-28 23:28:34 +02:00
Livewire Require a confirmed address before an account can use anything 2026-07-28 23:43:20 +02:00
Mail Require a confirmed address before an account can use anything 2026-07-28 23:43:20 +02:00
Models Require a confirmed address before an account can use anything 2026-07-28 23:43:20 +02:00
Notifications Stop mailing the initial admin password, hold it in the panel until noted 2026-07-28 23:19:20 +02:00
Policies Move the console's identity out of the customer table 2026-07-28 10:31:43 +02:00
Providers Recognise the devices an account signs in from, and warn about a new one 2026-07-28 23:28:34 +02:00
Provisioning Stop mailing the initial admin password, hold it in the panel until noted 2026-07-28 23:19:20 +02:00
Services Show where an account is signed in, and let it sign the other places out 2026-07-28 23:38:17 +02:00
Support Move operator two-factor enrolment off admin.settings onto its own page 2026-07-28 15:11:20 +02:00