Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
a5bd68c
Fix. React. Scanner tab: temporary fetching scanner content implemented.
Glomberg Aug 20, 2026
7b51cec
Fix. React. Scanner tab refactoring #1.
Glomberg Aug 24, 2026
68a70e1
Udp.Code.Incorrect logs
datorik Aug 24, 2026
04e0b26
Merge remote-tracking branch 'origin/Upd-Scanner-Frontend-controller-…
Glomberg Aug 24, 2026
6da3383
Merge remote-tracking branch 'origin/Upd-Scanner-Frontend-controller-…
Glomberg Aug 24, 2026
ddee32e
Fix. React. Scanner tab refactoring #2.
Glomberg Aug 24, 2026
98e076a
Merge remote-tracking branch 'origin/Upd-Scanner-Frontend-controller-…
Glomberg Aug 24, 2026
22e0f7c
Fix. React. Scanner tab refactoring - Scan info block under developin…
Glomberg Aug 24, 2026
0dd4fcd
Fix. React. Scanner tab refactoring - old fetch fixed.
Glomberg Aug 24, 2026
1f39e43
Fix. React. Scanner tab refactoring - Scan info block under developin…
Glomberg Aug 24, 2026
f348d9b
Fix. React. Scanner tab refactoring - Last scan hint.
Glomberg Aug 24, 2026
68ce906
Fix. React. Scanner tab refactoring - Scan logs link.
Glomberg Aug 24, 2026
904eac1
Fix. React. Scanner tab refactoring - Export to PDF link.
Glomberg Aug 24, 2026
78db5e2
Fix. React. Scanner tab refactoring - Backups tab link.
Glomberg Aug 24, 2026
d0e7bc5
Fix. React. Scanner tab refactoring - Start scan button #1.
Glomberg Aug 24, 2026
16875ce
Fix. React. Scanner tab refactoring - Start scan button #2.
Glomberg Aug 24, 2026
90160d6
Merge branch 'Upd-Scanner-Frontend-controller-removed-VI' into Upd-Re…
Glomberg Sep 2, 2026
42710b0
Merge branch 'Upd-Scanner-Frontend-controller-removed-VI' into Upd-Re…
Glomberg Sep 2, 2026
bc452c7
Upd. React. Scanner - last scan info component implemented.
Glomberg Sep 2, 2026
4aed430
Upd. React. Scanner - scan stages render rebuilt.
Glomberg Sep 3, 2026
7a67636
Upd. React. Scanner - start scan button fixed.
Glomberg Sep 3, 2026
8d45e85
Upd. React. Scanner - progress bar fixed.
Glomberg Sep 3, 2026
60ee117
Upd. React. Scanner - progress bar fixed #2.
Glomberg Sep 3, 2026
cf2c6e7
Upd. React. Scanner - stages list fixed.
Glomberg Sep 3, 2026
f11e679
Upd. React. Scanner - scan log fixed.
Glomberg Sep 3, 2026
c357e3b
Fix. Code. ES-Lint notice fixed.
Glomberg Sep 3, 2026
cff460c
Fix. Code. Code style and psalm notice fixed.
Glomberg Sep 3, 2026
4e270cb
Udp.Code. Unify FW logs
datorik Sep 3, 2026
2d3fa47
Udp.Code. Unify FW logs
datorik Sep 3, 2026
723506e
Upd. Settings. Improve admins counter on settings page. (#728)
svfcode Sep 6, 2026
e97e777
Udp.Code.Incorrect logs
datorik Sep 6, 2026
90b77df
Fix. Code. Copilot suggestion approved.
Glomberg Sep 7, 2026
0a75c0d
Fix. Code. Copilot suggestion approved.
Glomberg Sep 7, 2026
881a9ef
Fix. Code. Copilot suggestion approved.
Glomberg Sep 7, 2026
19befdf
Fix. Code. Copilot suggestion approved.
Glomberg Sep 7, 2026
909409d
Udp.Code. Unify FW log
alexander-b-clean Sep 7, 2026
13aa02a
New.Code.Server Requirements
datorik Sep 8, 2026
cc66c9d
Initialize warnings array in checkRequirements method
alexander-b-clean Sep 8, 2026
2802943
New.Code.Server Requirements. Psalm fix
datorik Sep 8, 2026
84d74ed
fix psalm
svfcode Sep 9, 2026
3866dd3
fix psalm
svfcode Sep 9, 2026
e39d547
Merge pull request #729 from CleanTalk/incorrect-logs.ab
alexandergull Sep 9, 2026
d64da3e
Upd. VulnerabilityAlarmService. Added current vulnerable module versi…
alexandergull Sep 9, 2026
bc6ffe3
Upd. VulnerabilityAlarmService. Fix after live tests.
alexandergull Sep 9, 2026
dc29d62
Fix. Sync. Resume cooldown extended form PSC cache warm. https://app.…
alexandergull Sep 10, 2026
ed988ec
Merge pull request #731 from CleanTalk/system-requirements-2.ab
alexandergull Sep 10, 2026
e13eb20
CP. Code. Fixed source.
alexandergull Sep 10, 2026
2ad874b
CP. Code. Fixed duplicate keys extraction.
alexandergull Sep 10, 2026
1504d38
CP. Code. Fixed docblock.
alexandergull Sep 10, 2026
aee660a
Merge remote-tracking branch 'origin/vuln_report_send_fix.ag' into vu…
alexandergull Sep 10, 2026
6226e8d
Merge pull request #732 from CleanTalk/vuln_report_send_fix.ag
alexandergull Sep 10, 2026
239dc69
Fix. Code. Fixed compatibility with php8.5. (#734)
svedge Sep 11, 2026
810b7a6
New. Code. Auto tests banners. (#733)
Glomberg Sep 14, 2026
198938c
Merge remote-tracking branch 'origin/dev' into Upd-React-Refactoring-…
Glomberg Sep 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 110 additions & 0 deletions .github/workflows/frontendBannersTests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
name: Testing Banners on admin side (frontend)

on:
push: # on push to each of these branches
branches:
- dev
- fix
- master
pull_request:
branches:
- dev
- master

jobs:
test:
runs-on: ubuntu-latest
services:
wordpress:
image: wordpress:latest
ports:
- 8080:80
env:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
- ./:/var/www/html/wp-content/plugins/security-malware-firewall
- ./mu-plugins:/var/www/html/wp-content/mu-plugins
db:
image: mysql:5.7
ports:
- "3306:3306"
env:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Wait for database to be ready
run: |
echo "Waiting for MySQL to be ready..."
for i in {1..30}; do
if docker exec $(docker ps -qf "ancestor=mysql:5.7") mysqladmin ping -ppassword --silent; then
echo "MySQL is ready!"
exit 0
fi
echo "Attempt $i/30: MySQL not ready yet..."
sleep 5
done
echo "MySQL connection timed out!"
exit 1

- name: Install WordPress using wp-cli
run: |
WP_CONTAINER_ID=$(docker ps -qf "ancestor=wordpress:latest")
DB_CONTAINER_ID=$(docker ps -qf "ancestor=mysql:5.7")

# Install WordPress using wp-cli
docker run --rm \
--volumes-from $WP_CONTAINER_ID \
--network container:$WP_CONTAINER_ID \
-e WORDPRESS_DB_HOST=$DB_CONTAINER_ID \
-e WORDPRESS_DB_USER=wordpress \
-e WORDPRESS_DB_PASSWORD=wordpress \
-e WORDPRESS_DB_NAME=wordpress \
wordpress:cli wp core install \
--url="http://localhost:8080" \
--title="Test Site" \
--admin_user="admin" \
--admin_password="password" \
--admin_email="admin@example.com" \
--skip-email

- name: Install and activate plugin
run: |
WP_CONTAINER_ID=$(docker ps -qf "ancestor=wordpress:latest")
DB_CONTAINER_ID=$(docker ps -qf "ancestor=mysql:5.7")

# Activate the plugin using wp-cli
docker run --rm \
--volumes-from $WP_CONTAINER_ID \
--network container:$WP_CONTAINER_ID \
-e WORDPRESS_DB_HOST=$DB_CONTAINER_ID \
-e WORDPRESS_DB_USER=wordpress \
-e WORDPRESS_DB_PASSWORD=wordpress \
-e WORDPRESS_DB_NAME=wordpress \
wordpress:cli wp plugin activate security-malware-firewall

- name: Set DB_HOST
run: echo "DB_HOST=$(docker ps -qf "ancestor=mysql:5.7")" >> $GITHUB_ENV

- name: Run Banners tests
uses: CleanTalk/e2e-tests-banners@spbct

- name: Matrix notify
if: failure()
uses: Glomberg/matrix-messenger-action@master
with:
server: ${{ secrets.MATRIX_SERVER }}
to: ${{ secrets.MATRIX_EXTERNSION_ROOM }}
token: ${{ secrets.MATRIX_USER_TOKEN }}
message: |
<a href="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}">SPBCT: Banners tests</a> failed ⛔!
Please, check the workflow, <strong>${{ github.actor }}</strong>

15 changes: 10 additions & 5 deletions inc/spbc-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,19 @@
use CleantalkSP\SpbctWP\DTO\ReactDataDTO;
use CleantalkSP\SpbctWP\Escape;
use CleantalkSP\SpbctWP\Scanner\DBTrigger\DBTriggerService;
use CleantalkSP\SpbctWP\Scanner\View\View;
use CleantalkSP\SpbctWP\Settings\SettingsGeneralReact;
use CleantalkSP\SpbctWP\ServerRequirementsChecker\View as ServerRequirementsView;
use CleantalkSP\SpbctWP\SpbcDevLogger;
use CleantalkSP\SpbctWP\VulnerabilityAlarm\Dto\PluginReport;
use CleantalkSP\SpbctWP\Firewall\View as FirewallView;
use CleantalkSP\SpbctWP\VulnerabilityAlarm\Dto\ThemeReport;
use CleantalkSP\SpbctWP\VulnerabilityAlarm\VulnerabilityAlarmService;
use CleantalkSP\Variables\Post;
use CleantalkSP\Variables\Server;
use CleantalkSP\SpbctWP\LinkConstructor;
use CleantalkSP\SpbctWP\ListTable;
use CleantalkSP\SpbctWP\Scanner\Cure;
use CleantalkSP\SpbctWP\Scanner\OSCron\Storages\OsCronTasksStorage;
use CleantalkSP\SpbctWP\Scanner\ScannerQueue;
use CleantalkSP\SpbctWP\SpbcEnqueue;
use CleantalkSP\SpbctWP\Variables\Cookie;
use CleantalkSP\SpbctWP\VulnerabilityAlarm\PscCertifiedPluginsController;
use CleantalkSP\SpbctWP\VulnerabilityAlarm\VulnerabilityAlarm;
Expand Down Expand Up @@ -95,9 +94,9 @@ function spbc_admin_init()
add_action('wp_ajax_spbc_scanner_save_to_pdf', array(ScannerAjaxEndpoints::class, 'downloadPDFReport'));
add_action('wp_ajax_spbc_scanner_get_pdf_file_name', array(ScannerAjaxEndpoints::class, 'getPDFReportFileName'));
add_action('wp_ajax_spbc_scanner_clear', array(ScannerAjaxEndpoints::class, 'clearScannerResults')); // Debug. Clear the table
add_action('wp_ajax_spbc_scanner__start', 'spbc_scanner__launch');
add_action('wp_ajax_spbc_scanner__start', 'spbc_scanner__start');
add_action('wp_ajax_spbc_scanner__getScannerStatus', 'spbc_scanner__getScannerStatus');
add_action('wp_ajax_spbc_scanner__last_scan_info', 'spbc_scanner__last_scan_info');
add_action('wp_ajax_spbc_scanner__last_scan_info', array(ScannerAjaxEndpoints::class, 'getLastScanInfo'));

// Scanner buttons
add_action('wp_ajax_spbc_scanner_file_send', array(ScannerAjaxEndpoints::class, 'sendFileForAnalysis'));
Expand Down Expand Up @@ -242,9 +241,15 @@ function spbct_get_tab_data()
case 'security_certified':
PscCertifiedPluginsController::ajaxRenderTab();
break;
case 'system_requirements':
wp_send_json(ServerRequirementsView::getReactData($data));
// no break
case 'spbct_settings_overview':
wp_send_json(spbc_field_options_overview_traffic_light());
// no break
case 'scanner':
wp_send_json(View::getReactData());
// no break
default:
wp_send_json_error('Unknown tab');
// no break
Expand Down
60 changes: 54 additions & 6 deletions inc/spbc-scanner.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,29 @@

// Prevent direct call
use CleantalkSP\SpbctWP\Cron;
use CleantalkSP\SpbctWP\Transaction;
use CleantalkSP\SpbctWP\Scanner\ScanningStagesModule\ScanningStagesStorage;

if ( ! defined('ABSPATH') ) {
die('Not allowed!');
}

/**
* Ajax wrapper function for launchBackground
*
* @return bool|string|string[]
*/
function spbc_scanner__start()
{
if ( ! spbc_check_ajax_referer('spbc_secret_nonce', 'security', false) ) {
wp_send_json(array('error' => 'Nonce had been changed. Please, restart the scan.'));
}
return spbc_scanner__launch();
}

/**
* Cron|RemoteCall wrapper function for launchBackground
*
* @return bool|string|string[]|void
* @return bool|string|string[]
*/
function spbc_scanner__launch()
{
Expand Down Expand Up @@ -77,6 +90,8 @@ function spbc_scanner__isScannerIsInProgress()

function spbc_scanner__getScannerStatus()
{
global $spbc;

if ( ! spbc_check_ajax_referer('spbc_secret_nonce', 'security', false) ) {
wp_send_json(array('error' => 'Nonce had been changed. Please, restart the scan.'));
}
Expand All @@ -86,26 +101,59 @@ function spbc_scanner__getScannerStatus()
$current_cron_task = Cron::getTask('background_scan');
if ( $current_cron_task && isset($current_cron_task['params']['stage'], $current_cron_task['params']['offset']) ) {
$current_stage = $current_cron_task['params']['stage'];
$current_offset = $current_cron_task['params']['offset'];
$current_offset = (int) $current_cron_task['params']['offset'];
$current_stage_class = null;
$completed_stages = [];
foreach ($stages as $stage_key => $stage) {
// Convert $stageKey like CleantalkSP\SpbctWP\Scanner\ScanningStagesModule\Stages\GetCmsHashes into get_cms_hashes
foreach ($stages as $stage_key => $_stage) {
// Convert $stage_key like CleantalkSP\SpbctWP\Scanner\ScanningStagesModule\Stages\GetCmsHashes into get_cms_hashes
$stage_class_name = explode('\\', $stage_key);
$stage_class_name = end($stage_class_name);
$stage_name = strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $stage_class_name));
if ($stage_name === $current_stage) {
$current_stage_class = $stage_key;
break;
}
$completed_stages[] = [
'stage' => $stage_name,
'status' => 'completed',
];
}

// Per-stage progress (0-100%), specific only to the currently running stage.
// The overall scan progress is already visualized via the completed/current stages
// list, so this percentage is intentionally scoped to "how far is the current stage".
$current_stage_total = null;
if ($current_stage === 'file_system_analysis') {
// The total files count is discovered on the stage's first iteration and stored
// globally (spbc_scanner-side), not on the stage's own data object.
$current_stage_total = isset($spbc->data['scanner']['files_total'])
? (int) $spbc->data['scanner']['files_total']
: null;
} elseif ($current_stage_class !== null) {
$stages_storage = new ScanningStagesStorage();
$stages_storage->converter->loadCollection();
$stage_data_obj = $stages_storage->getStage($current_stage_class);
if ( ! empty($stage_data_obj->total_count_files_for_analysis) ) {
// signature_analysis, heuristic_analysis, binary_analysis
$current_stage_total = (int) $stage_data_obj->total_count_files_for_analysis;
} elseif ( ! empty($stage_data_obj->total) ) {
// outbound_links, frontend_analysis
$current_stage_total = (int) $stage_data_obj->total;
}
}

$current_stage_percent = null;
if ($current_stage_total !== null && $current_stage_total > 0) {
$current_stage_percent = min(100, (int) round($current_offset / $current_stage_total * 100));
}

wp_send_json_success(array(
'status' => 'in_progress',
'current_stage' => [
'stage' => $current_stage,
'offset' => $current_offset,
'total' => $current_stage_total,
'percent' => $current_stage_percent,
'status' => 'in_progress',
],
'completed_stages' => $completed_stages,
Expand All @@ -116,4 +164,4 @@ function spbc_scanner__getScannerStatus()
wp_send_json_success(array(
'status' => 'end',
));
}
}
Loading
Loading