From 8f3b0a86adb0db521df6ea580aa88c272a5e2930 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 4 Nov 2026 07:44:17 +0000 Subject: [PATCH] Unsaved settings: purge after 4 weeks, log errors, common usernames The plugin runs with built-in defaults until an administrator saves the settings, and these are meant to be what the settings page shows (see DefaultSettings). Three were not: - deleteOld: the plugin purged failed logins after 4 weeks, the settings page showed 0 - so the first save of the settings switched purging off, contrary to the changelog. The page says 4 weeks now (com_bfstop). - logLevel: the plugin didn't log at all, the page showed "errors". - riskCommonUsernames: the page listed admin, administrator, root, test and webmaster, the plugin used an empty list (no risk points, and such names were stored as a hash when they aren't an account). They are in DefaultSettings now, which testUnsavedSettingsAreWhatTheSettings PageShows compares with the settings form. DatabaseHelper::$DEFAULT_PURGE_WEEKS is replaced by DefaultSettings['deleteOld']. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AFJFMMUpch4LGexEiXN8Nc --- src/Extension/Bfstop.php | 11 +++++++++-- src/Helper/DatabaseHelper.php | 4 ---- src/Helper/RiskHelper.php | 3 ++- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Extension/Bfstop.php b/src/Extension/Bfstop.php index 0a0d068..89a603c 100644 --- a/src/Extension/Bfstop.php +++ b/src/Extension/Bfstop.php @@ -47,6 +47,13 @@ class Bfstop extends CMSPlugin implements SubscriberInterface 'adaptiveDelayMax' => 0, 'adaptiveDelayThresholdMin' => 50, 'adaptiveDelayThresholdMax' => 200, + // failed logins are purged after this many weeks unless the + // administrator chose another time (0 = never). Keeping them for ever + // is not needed to protect anything, and they are personal data + // (addresses, usernames) + 'deleteOld' => 4, + 'logLevel' => 8, // Log::ERROR + 'riskCommonUsernames' => "admin\nadministrator\nroot\ntest\nwebmaster", ); private LoggerHelper $logger; @@ -390,7 +397,7 @@ private function accountThrottleDelay($logEntry) private function init() { - $this->logger = new LoggerHelper($this->getIntParam('logLevel', LoggerHelper::Disabled), + $this->logger = new LoggerHelper($this->getIntParam('logLevel', self::DefaultSettings['logLevel']), LoggerHelper::maxBytesFromMegabytes($this->getIntParam('logMaxSize', LoggerHelper::DefaultMaxSizeMB))); $this->mydb = new DatabaseHelper($this->logger); $this->notifier = new NotifierHelper($this->logger, $this->mydb, @@ -794,7 +801,7 @@ public function onAfterInitialise($event) $now = time(); if ($now > ($lastPurge + $purgeInterval)) { - $purgeAge = $this->getIntParam('deleteOld', DatabaseHelper::$DEFAULT_PURGE_WEEKS); + $purgeAge = $this->getIntParam('deleteOld', self::DefaultSettings['deleteOld']); if ($purgeAge > 0) { $this->mydb->purgeOldEntries($purgeAge); diff --git a/src/Helper/DatabaseHelper.php b/src/Helper/DatabaseHelper.php index 3f75079..cb75441 100644 --- a/src/Helper/DatabaseHelper.php +++ b/src/Helper/DatabaseHelper.php @@ -28,10 +28,6 @@ class DatabaseHelper // TokenunblockModel::TokenValidDays must stay in sync with this public static $UNBLOCK_TOKEN_VALID_DAYS = 3; - // failed logins are purged after this many weeks unless the administrator - // chose another time (0 = never). Keeping them for ever is not needed to - // protect anything, and they are personal data (addresses, usernames) - public static $DEFAULT_PURGE_WEEKS = 4; // upper bound for the rows of the failed logins, however the purge age is // set: a visitor can add one for every request, from as many addresses as diff --git a/src/Helper/RiskHelper.php b/src/Helper/RiskHelper.php index 67c818e..ca11165 100644 --- a/src/Helper/RiskHelper.php +++ b/src/Helper/RiskHelper.php @@ -10,6 +10,7 @@ defined('_JEXEC') or die; +use Codeling\Plugin\System\Bfstop\Extension\Bfstop; use Joomla\CMS\Log\Log; use Joomla\Registry\Registry; @@ -58,7 +59,7 @@ private static function knownIpScore(DatabaseHelper $db, LoggerHelper $logger, R */ public static function isCommonUsername(Registry $params, $username) { - $list = (string) $params->get('riskCommonUsernames', ''); + $list = (string) $params->get('riskCommonUsernames', Bfstop::DefaultSettings['riskCommonUsernames']); $candidates = array_filter(array_map('trim', explode("\n", str_replace("\r", '', $list)))); foreach ($candidates as $candidate) {