c7f1bdd630
register.php was a fully open signup form with no bot defenses — the likely source of the unconfirmed accounts piling up in admin/users.php. - Add an always-on honeypot field + timing trap to register.php: either tripping silently pretends success without creating an account, so a bot doesn't learn it was caught. No configuration needed. - Add optional Google reCAPTCHA v3 support (includes/recaptcha.php, recaptcha_enabled()/verify_recaptcha(), no Composer dependency — a raw file_get_contents() POST like mailer.php's SMTP socket approach). A failed check here shows a real, visible error instead of the silent honeypot path, since a legitimate low-score user deserves a retry. - Configure it through admin/settings.php's new "Bot Protection" section, mirroring the existing SMTP pattern exactly: recaptcha_enabled/ recaptcha_site_key/recaptcha_secret_key in site_settings, secret key masked the same way smtp_pass now is (blank submission keeps it unchanged). install.php seeds sane defaults so the feature stays off until explicitly configured — fully backward compatible. - Add cron/cleanup_unconfirmed.php: deletes accounts still unconfirmed after 3 days. CLI-only (refuses to run over HTTP, and cron/.htaccess denies web access to the directory as a second layer) since it's an unattended, irreversible deletion. Safe by construction — login.php already refuses login to unconfirmed accounts, so these rows can never own a session/novena_group/custom_prayer row. Not wired up automatically; README documents the Hostinger cron job to schedule it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
42 lines
1.3 KiB
PHP
42 lines
1.3 KiB
PHP
<?php
|
|
/**
|
|
* cron/cleanup_unconfirmed.php
|
|
* Deletes accounts that have sat unconfirmed for more than $days days.
|
|
*
|
|
* CLI-only — refuses to run if reached over HTTP, since this performs a
|
|
* real, irreversible deletion and has no business being web-accessible.
|
|
*
|
|
* Schedule this via your host's cron job feature, e.g. once daily:
|
|
* php /path/to/Rosary/cron/cleanup_unconfirmed.php
|
|
*
|
|
* Safe by construction: login.php refuses login to any account with
|
|
* email_confirmed = 0, so an unconfirmed account can never have created a
|
|
* session/novena_group/custom_prayer row — nothing here can orphan data.
|
|
*/
|
|
if (PHP_SAPI !== 'cli') {
|
|
http_response_code(403);
|
|
exit('This script may only be run from the command line.');
|
|
}
|
|
|
|
require_once __DIR__ . '/../config/db.php';
|
|
|
|
$days = 3;
|
|
$pdo = get_pdo();
|
|
|
|
$st = $pdo->prepare("
|
|
SELECT id, username, email, created_at
|
|
FROM users
|
|
WHERE email_confirmed = 0
|
|
AND created_at < (NOW() - INTERVAL ? DAY)
|
|
");
|
|
$st->execute([$days]);
|
|
$stale = $st->fetchAll();
|
|
|
|
$del = $pdo->prepare('DELETE FROM users WHERE id = ?');
|
|
foreach ($stale as $u) {
|
|
$del->execute([$u['id']]);
|
|
echo date('c') . " deleted unconfirmed user #{$u['id']} ({$u['username']}, {$u['email']}, registered {$u['created_at']})\n";
|
|
}
|
|
|
|
echo date('c') . ' — ' . count($stale) . " account(s) removed.\n";
|