diff --git a/README.md b/README.md index a45b07a..3131a0f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ Anti-spam plugin for Joomla 3.X.-4.x ============ -Version 3.2.4 +Version 3.2.5 ======= ## Simple antispam test @@ -22,4 +22,4 @@ Example how to use plugin to filter spam bots at any Joomla form. ## Requirements -* CleanTalk account https://cleantalk.org/register?product=anti-spam \ No newline at end of file +* CleanTalk account https://cleantalk.org/register?product=anti-spam diff --git a/cleantalkantispam.php b/cleantalkantispam.php index b369535..7f4dfc7 100644 --- a/cleantalkantispam.php +++ b/cleantalkantispam.php @@ -3,7 +3,7 @@ /** * CleanTalk joomla plugin * - * @version 3.2.4 + * @version 3.2.5 * @package Cleantalk * @subpackage Joomla * @author CleanTalk (welcome@cleantalk.org) @@ -48,6 +48,7 @@ use Cleantalk\Common\Cleaner\Sanitize; use Cleantalk\Common\Mloader\Mloader; +use Cleantalk\Common\Variables\Cookie; use Cleantalk\Common\Variables\Server; use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; @@ -64,6 +65,7 @@ define('APBCT_SELECT_LIMIT', 5000); // Select limit for logs. define('APBCT_WRITE_LIMIT', 5000); // Write limit for firewall data. define('APBCT_DIR_PATH', __DIR__); +define('APBCT_CRON_HANDLER__SFW_UPDATE', 'plgSystemCleantalkantispam::apbct_sfw_update'); //define('APBCT_EXCLUSION_STRICT_MODE', true); class plgSystemCleantalkantispam extends JPlugin @@ -72,7 +74,7 @@ class plgSystemCleantalkantispam extends JPlugin * Plugin version string for server * @since 1.0 */ - const ENGINE = 'joomla34-324'; + const ENGINE = 'joomla34-325'; /** * Flag marked JComments form initialization. @@ -489,9 +491,31 @@ public function onExtensionAfterSave($name, $data) $new_config = json_decode($data->params, true); $access_key = trim($new_config['apikey']); + $cron_class = Mloader::get('Cron'); + $cron = new $cron_class(); + if (isset($new_config['ct_sfw_enable'])) { - self::apbct_sfw_update($access_key); - self::apbct_sfw_send_logs($access_key); + if ($new_config['ct_sfw_enable'] == 1) { + //update tasks + /** @var \Cleantalk\Common\Cron\Cron $cron */ + $cron->updateTask( 'sfw_update', '\plgSystemCleantalkantispam::apbct_sfw_update', 86400, time() + 60 ); + $cron->updateTask( 'sfw_send_logs', '\plgSystemCleantalkantispam::apbct_sfw_send_logs', 3600 ); + // run update itself + $update_result = self::apbct_sfw_update($access_key); + self::apbct_sfw_send_logs($access_key); + } else { + //remove tasks + $cron->removeTask( 'sfw_update'); + $cron->removeTask( 'sfw_send_logs'); + $cron->removeTask( 'sfw_update_checker'); + //remove fwstats + $firewall = new \Cleantalk\Common\Firewall\Firewall( + $access_key, + APBCT_TBL_FIREWALL_LOG + ); + $empty_stats = new \Cleantalk\Common\Firewall\FwStats(); + $firewall::saveFwStats($empty_stats); + } } $this->ctSendFeedback($access_key, '0:' . self::ENGINE); @@ -527,7 +551,8 @@ private function exceptionList() ($option_cmd == 'com_virtuemart' && $task_cmd == 'cart') || ($option_cmd == 'com_rsform' && $task_cmd == 'ajaxValidate') || // RSFrom ajax validation on multipage form ($option_cmd == 'com_virtuemart' && !empty($ctask_cmd) && ($ctask_cmd !== 'savebtaddress' || empty($post_field_stage) || $post_field_stage !== 'final')) || - $option_cmd === 'com_civicrm' + $option_cmd === 'com_civicrm' || + ($option_cmd === 'com_jshopping' && $task_cmd === 'loginsave') ) return true; @@ -870,38 +895,37 @@ public function onAfterRoute() } } - if ($_SERVER['REQUEST_METHOD'] == 'GET') - { - if ($this->params->get('ct_check_search')) - { - if ( $option_cmd === 'com_search' && isset($_GET['searchword']) && $_GET['searchword'] !== '' ) // Search form + + // Search form + if ($_SERVER['REQUEST_METHOD'] == 'GET' && $this->params->get('ct_check_search')) { + if ($option_cmd === 'com_search' && isset($_GET['searchword']) && $_GET['searchword'] !== '' || + $option_cmd === 'com_finder' && isset($_GET['q']) && $_GET['q'] !== '' + ) { + $post_info['comment_type'] = 'site_search_joomla34'; + $sender_email = JFactory::getUser()->email; + $sender_nickname = JFactory::getUser()->username; + $message = isset($_GET['searchword']) ? trim($_GET['searchword']) : trim($_GET['q']); + $ctResponse = $this->ctSendRequest( + 'check_message', + array( + 'sender_nickname' => $sender_nickname, + 'sender_email' => $sender_email, + 'message' => trim(preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $message)), + 'post_info' => json_encode($post_info), + ) + ); + if ($ctResponse) { - $post_info['comment_type'] = 'site_search_joomla34'; - $sender_email = JFactory::getUser()->email; - $sender_nickname = JFactory::getUser()->username; - $message = trim($_GET['searchword']); - $ctResponse = $this->ctSendRequest( - 'check_message', - array( - 'sender_nickname' => $sender_nickname, - 'sender_email' => $sender_email, - 'message' => trim(preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $message)), - 'post_info' => json_encode($post_info), - ) - ); - if ($ctResponse) + if (!empty($ctResponse) && is_array($ctResponse)) { - if (!empty($ctResponse) && is_array($ctResponse)) + if ($ctResponse['errno'] != 0) + $this->sendAdminEmail("CleanTalk. Can't verify search form!", $ctResponse['comment']); + else { - if ($ctResponse['errno'] != 0) - $this->sendAdminEmail("CleanTalk. Can't verify search form!", $ctResponse['comment']); - else + if ($ctResponse['allow'] == 0) { - if ($ctResponse['allow'] == 0) - { - $this->doBlockPage($ctResponse['comment']); + $this->doBlockPage($ctResponse['comment']); - } } } } @@ -1123,12 +1147,19 @@ public function onAfterRoute() if( ! isset( $post_info['comment_type'] ) ) $post_info['comment_type'] = 'feedback_general_contact_form'; + if (is_string($message)) { + $message = json_decode($message, true); + } + if (isset($message['ct_bot_detector_event_token'])) { + unset($message['ct_bot_detector_event_token']); + } + $ctResponse = $this->ctSendRequest( 'check_message', array( 'sender_nickname' => $sender_nickname, 'sender_email' => $sender_email, - 'message' => $message, + 'message' => json_encode($message), 'post_info' => json_encode($post_info), ) ); @@ -1185,7 +1216,8 @@ public function onAfterRoute() die(); } elseif ( $app->input->get('option') === 'com_sppagebuilder' && - !isset($app->input->get('form')['formId']) + !isset($app->input->get('form')['formId']) && + JFactory::getApplication()->input->get('option') === 'com_ajax' ) { $output['status'] = false; $output['content'] = '' . $ctResponse['comment'] . ''; @@ -2298,7 +2330,7 @@ private function ct_setcookie( $name, $value ) } else { // To cookies - setcookie($name, $value, 0, '/'); + Cookie::set($name, $value); } } @@ -2519,11 +2551,16 @@ private function apbct_run_cron() { /** @var \Cleantalk\Common\Cron\Cron $cron_class */ $cron_class = Mloader::get('Cron'); + $cron = new $cron_class(); + /** @var \Cleantalk\Common\RemoteCalls\RemoteCalls $rc_class */ $rc_class = Mloader::get('RemoteCalls'); - $cron = new $cron_class(); - if (!$this->params->get($cron->getCronOptionName())) { + /** @var \Cleantalk\Common\StorageHandler\StorageHandler $storage_handler_class */ + $storage_handler_class = Mloader::get('StorageHandler'); + $storage_handler_class = new $storage_handler_class(); + + if ( (int)$storage_handler_class->getSetting($cron->getCronOptionName()) === 0 ) { $cron->addTask( 'sfw_update', '\plgSystemCleantalkantispam::apbct_sfw_update', 86400, time() + 60 ); $cron->addTask( 'sfw_send_logs', '\plgSystemCleantalkantispam::apbct_sfw_send_logs', 3600 ); } diff --git a/cleantalkantispam.xml b/cleantalkantispam.xml index dd04d7a..e517dad 100644 --- a/cleantalkantispam.xml +++ b/cleantalkantispam.xml @@ -7,7 +7,7 @@ GNU/GPLv2 welcome@cleantalk.org cleantalk.org - 3.2.4 + 3.2.5 PLG_SYSTEM_CLEANTALKANTISPAM_DESCRIPTION updater.php diff --git a/js/ct-checkusers.js b/js/ct-checkusers.js index 76156f9..a303bfd 100644 --- a/js/ct-checkusers.js +++ b/js/ct-checkusers.js @@ -11,7 +11,8 @@ window.apbct = window.apbct || {}; totalUsers: 0, limit: 20, offset: 0, - improvedCheck: false + improvedCheck: false, + cleared: false }; apbct = apbct || {}; @@ -47,6 +48,9 @@ window.apbct = window.apbct || {}; usersChecker.setListeners = () => { $('#check_spam_users').click(() => { + if (scanInProgress || usersChecker.cleared) { + return; + } usersChecker.improvedCheck = $("#ct_impspamcheck_checkbox").is(":checked"); usersChecker.clearUserCheckerResults() @@ -132,6 +136,7 @@ window.apbct = window.apbct || {}; usersChecker.clearUserCheckerResults = () => { usersChecker.layoutClearById('spamusers_table'); const data = {action: 'usersChecker', route: 'clearResults'}; + usersChecker.cleared = true; return usersChecker.ajaxRequest(data); }; @@ -176,6 +181,7 @@ window.apbct = window.apbct || {}; response => { try { usersChecker.runUserCheckerSuccess(JSON.parse(response)); + usersChecker.cleared = false; } catch (error) { usersChecker.runUserCheckerError(error); } diff --git a/js/ct-functions.js b/js/ct-functions.js index 648e246..79d0364 100755 --- a/js/ct-functions.js +++ b/js/ct-functions.js @@ -276,6 +276,10 @@ function checkEasySocial(form) { } function ct_is_excluded_forms(form) { + if (form.onsubmit_prev && form.onsubmit_prev.toString().includes('validateRegistrationForm')) { + return true; + } + let value; for (let key in form.elements){ if (isNaN(+key)) { diff --git a/js/ct-settings.js b/js/ct-settings.js index eb910e7..3f9c4f7 100644 --- a/js/ct-settings.js +++ b/js/ct-settings.js @@ -194,7 +194,7 @@ jQuery(document).ready(function(){ .append("

") .append(""+ct_license_notice+""); - jQuery('#key_buttons_wrapper').closest('.control-label').css('width', 'auto').next().empty(); + jQuery('#key_buttons_wrapper').closest('.control-label').css('width', 'auto').next().empty(); } } @@ -357,7 +357,7 @@ jQuery(document).ready(function(){ } } - if (joomlaVersion() === '4') { + if (joomlaVersion() === '4' || joomlaVersion() === '5') { const apbctSettingsTabs = jQuery('#myTab button[role="tab"]'); jQuery.each(apbctSettingsTabs, function (index, tab) { let tabElement = jQuery(tab); diff --git a/lib/Cleantalk/Common/Cron/Cron.php b/lib/Cleantalk/Common/Cron/Cron.php index 616873a..f8e222d 100644 --- a/lib/Cleantalk/Common/Cron/Cron.php +++ b/lib/Cleantalk/Common/Cron/Cron.php @@ -64,7 +64,6 @@ public function __construct( } $this->tasks = $this->getTasks(); - if ( !empty($this->tasks) ) { $this->createId(); usleep(10000); // 10 ms @@ -124,7 +123,6 @@ public function getTasks() $storage_handler_class = Mloader::get('StorageHandler'); $storage_handler_class = new $storage_handler_class(); $tasks = $storage_handler_class->getSetting($this->cron_option_name); - return empty($tasks) ? array() : $tasks; } @@ -238,6 +236,9 @@ public function checkTasks() // No tasks to run if ( empty($this->tasks) || $storage_handler_class->getSetting('cleantalk_cron_pid') !== $this->id ) { + if ($this->debug) { + error_log(var_export('Wrong cleantalk_cron_pid or task list empty', true)); + } return false; } diff --git a/lib/Cleantalk/Common/Firewall/FirewallUpdater.php b/lib/Cleantalk/Common/Firewall/FirewallUpdater.php index 40d6278..6f1453e 100644 --- a/lib/Cleantalk/Common/Firewall/FirewallUpdater.php +++ b/lib/Cleantalk/Common/Firewall/FirewallUpdater.php @@ -131,7 +131,7 @@ private function updateInit($delay = 0) $this->fwStats->updating_last_start = time(); $fw_class::saveFwStats($this->fwStats); - if ( !empty($prepare_dir__result['error']) || !empty($test_rc_result['error']) ) { + if ( (defined('APBCT_SFW_DIRECT_UPDATE') && APBCT_SFW_DIRECT_UPDATE) || !empty($prepare_dir__result['error']) || !empty($test_rc_result['error']) ) { return $this->directUpdate(); } @@ -219,7 +219,7 @@ private function updateWorker($checker_work = false) } } - if ( isset($result['error'], $result['status']) && $result['status'] === 'FINISHED' ) { + if ( ( isset($result['error'], $result['status']) && $result['status'] === 'FINISHED' ) ) { $this->updateFallback(); $direct_upd_res = $this->directUpdate(); @@ -731,6 +731,7 @@ public static function endOfUpdate($_api_key, $is_first_updating = false) $cron->updateTask('sfw_update', $sfw_update_handler, $fw_stats->update_period); $cron->removeTask('sfw_update_checker'); + self::removeUpdDir($fw_stats->updating_folder); // Reset all FW stats diff --git a/lib/Cleantalk/Common/Helper/Helper.php b/lib/Cleantalk/Common/Helper/Helper.php index 1c9b28f..3454555 100644 --- a/lib/Cleantalk/Common/Helper/Helper.php +++ b/lib/Cleantalk/Common/Helper/Helper.php @@ -867,27 +867,32 @@ public static function removeNonUTF8($data) */ public static function toUTF8($obj, $data_codepage = null) { + if ( empty($obj) ) { + return $obj; + } // Array || object - if (is_array($obj) || is_object($obj)) { - foreach ($obj as $_key => &$val) { - $val = self::toUTF8($val, $data_codepage); - } - unset($val); - //String - } else { - if ( !preg_match('//u', $obj) ) { - if ( function_exists('mb_detect_encoding') ) { - $encoding = mb_detect_encoding($obj); - $encoding = $encoding ?: $data_codepage; - } else { - $encoding = $data_codepage; + if ($obj) { + if (is_array($obj) || is_object($obj)) { + foreach ($obj as $_key => &$val) { + $val = self::toUTF8($val, $data_codepage); } + unset($val); + //String + } else { + if ( !preg_match('//u', $obj) ) { + if ( function_exists('mb_detect_encoding') ) { + $encoding = mb_detect_encoding($obj); + $encoding = $encoding ?: $data_codepage; + } else { + $encoding = $data_codepage; + } - if ( $encoding ) { - if ( function_exists('mb_convert_encoding') ) { - $obj = mb_convert_encoding($obj, 'UTF-8', $encoding); - } elseif ( version_compare(phpversion(), '8.3', '<') ) { - $obj = @utf8_encode($obj); + if ( $encoding ) { + if ( function_exists('mb_convert_encoding') ) { + $obj = mb_convert_encoding($obj, 'UTF-8', $encoding); + } elseif ( version_compare(phpversion(), '8.3', '<') ) { + $obj = @utf8_encode($obj); + } } } } diff --git a/lib/Cleantalk/Common/Http/Request.php b/lib/Cleantalk/Common/Http/Request.php index b6587b7..47ef741 100644 --- a/lib/Cleantalk/Common/Http/Request.php +++ b/lib/Cleantalk/Common/Http/Request.php @@ -417,10 +417,10 @@ protected function appendOptionsObligatory() $this->options = array_replace( array( CURLOPT_URL => ! is_array($this->url) ? $this->url : null, - CURLOPT_TIMEOUT => 10, - CURLOPT_LOW_SPEED_TIME => 7, + CURLOPT_TIMEOUT => 75, + CURLOPT_LOW_SPEED_TIME => 25, CURLOPT_RETURNTRANSFER => true, - CURLOPT_CONNECTTIMEOUT => 5000, + CURLOPT_CONNECTTIMEOUT => 10000, CURLOPT_FORBID_REUSE => true, CURLOPT_USERAGENT => self::AGENT, CURLOPT_POST => true, diff --git a/lib/Cleantalk/Custom/Helper/Helper.php b/lib/Cleantalk/Custom/Helper/Helper.php index 693329b..e61e172 100644 --- a/lib/Cleantalk/Custom/Helper/Helper.php +++ b/lib/Cleantalk/Custom/Helper/Helper.php @@ -345,8 +345,8 @@ static public function get_fields_any($arr, $fields_exclusions = '', $message = // Removes whitespaces $value = !is_null($value) ? $value : ''; - $value = urldecode( trim( $value ) ); // Fully cleaned message $value_for_email = trim( $value ); // Removes shortcodes to do better spam filtration on server side. + $value = urldecode( trim( $value ) ); // Fully cleaned message // Email if ( ! $email && preg_match( "/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/", $value_for_email ) ) { diff --git a/plugin-updates.xml b/plugin-updates.xml index bcaebc7..3341a1f 100644 --- a/plugin-updates.xml +++ b/plugin-updates.xml @@ -6,9 +6,9 @@ cleantalkantispam plugin system - 3.2.4 + 3.2.5 - https://github.com/CleanTalk/joomla3.x-4.x-antispam/archive/3.2.4.zip + https://github.com/CleanTalk/joomla3.x-4.x-antispam/archive/3.2.5.zip stable @@ -17,4 +17,4 @@ site - \ No newline at end of file +