Web flow (cPanel File Manager)
If you have file-system access to your portal install (through cPanel, FTP, or similar) but not a working SSH shell, use this flow:
data/ folder.
.reset-token.txt (note the leading dot — Apache treats this
as a hidden file and won't serve it on hosts that ship the default FilesMatch "^\."
directive).
https://<your-portal>/bin/reset-admin-password.php?token=<that-same-string>.
The page will list every admin and dealer account so you can pick the one to reset.
/login.php with a success flash.
data/.reset-token.txt with a fresh value.
SSH flow (no token required)
CLI access implies server-level trust, so the token file is not required when running from the shell.
# List every admin / dealer account:
php bin/reset-admin-password.php --list
# Reset a known account's password:
php bin/reset-admin-password.php --email admin@example.com \
--password '<new-strong-password>'
# Create a brand-new admin (use when no admins exist at all):
php bin/reset-admin-password.php --create-admin \
--email admin@example.com --name 'Admin' \
--password '<new-strong-password>'
What this does
- Hashes the new password with Argon2id and writes it directly into the users table.
- Clears the
must_change_passwordflag so you can log in immediately afterwards. - Resets the failed-login counter and clears any lockout on the account.
- Writes an
admin.password_reset_emergencyrow toaudit_logwith the IP and user-agent that performed the reset. - Web mode: deletes
data/.reset-token.txtimmediately so the URL can't be replayed.
Reset done but still can't log in?
Use the Login Diagnostic Inspector to see exactly which check is rejecting the
credentials — wrong password, account locked, IP rate-limited, account inactive, etc. It runs the
same gates Auth::login() runs, in read-only mode (it never increments the failure
counter or writes to audit_log on a probe).
data/, create .diagnose-token.txt with any random string.
https://<your-portal>/bin/diagnose-login.php?token=<that-same-string>.
user_exists,
password_verifies, user_not_locked, ip_rate_limit,
ip_blocked) reports pass/fail with detail so the failing one is obvious.
data/.diagnose-token.txt when you're done. (Unlike the reset tool, this one
does not auto-delete — diagnosing often needs more than one look.)
CLI alternative (no token required):
php bin/diagnose-login.php --email <e> --password <p>,
php bin/diagnose-login.php --recent-logins, or
php bin/diagnose-login.php --rate-limits.