Add email verification for user accounts

Every account created after the first must confirm a 24-hour link
(Lib\Mailer::sendMail(), log-file or MailJet) before AdminAuth::attempt()
allows login, folded into the same generic pass/fail as a disabled account
or wrong password. First user and pre-migration rows are grandfathered;
create-admin-user.php also auto-verifies for lockout recovery.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
code
2026-07-15 19:23:20 +00:00
parent c0455241ea
commit e699027b4b
13 changed files with 396 additions and 41 deletions
+8 -3
View File
@@ -65,10 +65,15 @@ if (strlen($password) < 8) {
// Always role 'admin', as the script name says — /admin/users is the
// place to create registered users; this exists for first-user setup and
// lockout recovery, both of which need an admin.
// lockout recovery, both of which need an admin. Auto-verified for the
// same reason /admin/users auto-verifies the very first user: an admin
// created this way has nobody else to have vouched for them, and lockout
// recovery in particular can't depend on a mail transport being
// configured (see /admin/docs/admin-auth's email verification section).
$now = gmdate('Y-m-d\TH:i:s\Z');
Db::query(
"INSERT INTO users (username, email, password_hash, role, user_group, is_disabled, created_at) VALUES (?, ?, ?, 'admin', '', 0, ?)",
[$username, $email, password_hash($password, PASSWORD_DEFAULT), gmdate('Y-m-d\TH:i:s\Z')]
"INSERT INTO users (username, email, password_hash, role, user_group, is_disabled, created_at, verified_at) VALUES (?, ?, ?, 'admin', '', 0, ?, ?)",
[$username, $email, password_hash($password, PASSWORD_DEFAULT), $now, $now]
);
echo "User '{$username}' created.\n";