Version Description
Download this release
Release Info
Developer | paultgoodchild |
Plugin | Shield Security for WordPress |
Version | 11.1.0 |
Comparing to | |
See all releases |
Code changes from version 11.0.3 to 11.1.0
- cl.json +74 -2
- icwp-wpsf.php +1 -1
- plugin-spec.php +30 -8
- readme.txt +1 -1
- resources/css/plugin.css +57 -24
- resources/css/{mainwp-extension.css → shield/mainwp.css} +0 -0
- resources/images/bootstrap/arrow-down-up.svg +1 -1
- resources/images/bootstrap/award.svg +2 -2
- resources/images/bootstrap/binoculars.svg +2 -2
- resources/images/bootstrap/book-half.svg +2 -2
- resources/images/bootstrap/bug.svg +2 -2
- resources/images/bootstrap/chat-right-dots-fill.svg +2 -2
- resources/images/bootstrap/diagram-3.svg +1 -1
- resources/images/bootstrap/emoji-smile.svg +3 -4
- resources/images/bootstrap/graph-up.svg +2 -2
- resources/images/bootstrap/link-45deg.svg +3 -3
- resources/images/bootstrap/pencil-square.svg +2 -2
- resources/images/bootstrap/people.svg +2 -2
- resources/images/bootstrap/person-badge.svg +3 -3
- resources/images/bootstrap/person-lines-fill.svg +2 -2
- resources/images/bootstrap/plug-fill.svg +3 -0
- resources/images/bootstrap/puzzle-fill.svg +3 -0
- resources/images/bootstrap/search.svg +3 -0
- resources/images/bootstrap/shield-shaded.svg +2 -3
- resources/images/bootstrap/sliders.svg +1 -1
- resources/images/bootstrap/speedometer.svg +4 -0
- resources/images/bootstrap/stickies.svg +3 -4
- resources/images/bootstrap/sticky.svg +2 -3
- resources/images/bootstrap/stoplights.svg +3 -4
- resources/images/bootstrap/tools.svg +3 -0
- resources/js/global-plugin.js +33 -176
- resources/js/icwp-options.js +0 -70
- resources/js/plugin.js +28 -87
- resources/js/shield/mainwp-extension.js +0 -14
- resources/js/shield/navigation.js +61 -0
- resources/js/shield/options.js +304 -0
- resources/js/shield/scans.js +19 -22
- resources/js/shield/secadmin.js +118 -0
- resources/js/shield/tables.js +2 -2
- src/config/feature-admin_access_restriction.php +5 -5
- src/config/feature-audit_trail.php +15 -35
- src/config/feature-comments_filter.php +5 -8
- src/config/feature-events.php +1 -5
- src/config/feature-firewall.php +4 -1
- src/config/feature-hack_protect.php +49 -47
- src/config/feature-headers.php +1 -1
- src/config/feature-ips.php +1 -14
- src/config/feature-login_protect.php +1 -4
- src/config/feature-plugin.php +12 -14
- src/config/feature-sessions.php +1 -15
- src/config/feature-traffic.php +0 -10
- src/lib/src/Controller/Config/ConfigVO.php +0 -9
- src/lib/src/Controller/Controller.php +31 -59
- src/lib/src/Databases/AuditTrail/Handler.php +4 -8
- src/lib/src/Databases/Base/BaseQuery.php +1 -1
- src/lib/src/Databases/Base/Handler.php +19 -66
- src/lib/src/Databases/Base/Insert.php +2 -4
- src/lib/src/Databases/Base/Select.php +11 -7
- src/lib/src/Databases/Base/Update.php +1 -1
- src/lib/src/Databases/ChangeTracking/Handler.php +0 -24
- src/lib/src/Databases/Common/TableSchema.php +1 -30
- src/lib/src/Databases/Events/Handler.php +4 -4
- src/lib/src/Databases/Events/Select.php +4 -4
- src/lib/src/Databases/FileLocker/Handler.php +4 -4
- src/lib/src/Databases/IPs/Handler.php +2 -18
- src/lib/src/Databases/ScanQueue/Select.php +7 -11
- src/lib/src/Databases/Scanner/Select.php +5 -9
- src/lib/src/Databases/Session/Handler.php +4 -8
- src/lib/src/Databases/Traffic/Handler.php +4 -4
- src/lib/src/Modules/AuditTrail/Auditors/Base.php +3 -1
- src/lib/src/Modules/AuditTrail/Auditors/Emails.php +1 -1
- src/lib/src/Modules/AuditTrail/Auditors/Plugins.php +1 -1
- src/lib/src/Modules/AuditTrail/Auditors/Posts.php +1 -1
- src/lib/src/Modules/AuditTrail/Auditors/Themes.php +1 -1
- src/lib/src/Modules/AuditTrail/Auditors/Upgrades.php +43 -20
- src/lib/src/Modules/AuditTrail/Auditors/Users.php +1 -1
- src/lib/src/Modules/AuditTrail/Auditors/Wordpress.php +1 -1
- src/lib/src/Modules/AuditTrail/Lib/AuditWriter.php +17 -14
- src/lib/src/Modules/AuditTrail/ModCon.php +1 -2
- src/lib/src/Modules/AuditTrail/Processor.php +7 -7
- src/lib/src/Modules/AuditTrail/UI.php +0 -10
- src/lib/src/Modules/Base/AjaxHandler.php +1 -36
- src/lib/src/Modules/Base/Lib/Request/FormParams.php +48 -0
- src/lib/src/Modules/Base/ModCon.php +50 -84
- src/lib/src/Modules/Base/Options.php +1 -1
- src/lib/src/Modules/Base/Strings.php +5 -5
- src/lib/src/Modules/Base/UI.php +13 -11
- src/lib/src/Modules/BaseShield/ModCon.php +26 -20
- src/lib/src/Modules/BaseShield/UI.php +0 -7
- src/lib/src/Modules/CommentsFilter/Scan/Scanner.php +1 -0
- src/lib/src/Modules/Events/Consolidate/ConsolidateAllEvents.php +22 -22
- src/lib/src/Modules/Events/Lib/EventsListener.php +6 -6
- src/lib/src/Modules/Events/Lib/EventsService.php +7 -2
- src/lib/src/Modules/Events/Lib/Reports/KeyStats.php +20 -21
- src/lib/src/Modules/Events/Lib/StatsWriter.php +11 -5
- src/lib/src/Modules/Events/Strings.php +6 -0
- src/lib/src/Modules/Events/UI.php +113 -0
- src/lib/src/Modules/Firewall/Lib/Scan/CanScan.php +28 -0
- src/lib/src/Modules/Firewall/Lib/Scan/Checks/Base.php +38 -0
- src/lib/src/Modules/Firewall/Lib/Scan/Checks/ExeFiles.php +41 -0
- src/lib/src/Modules/Firewall/Lib/Scan/Checks/Standard.php +69 -0
- src/lib/src/Modules/Firewall/Lib/Scan/ParametersToScan.php +85 -0
- src/lib/src/Modules/Firewall/Lib/Scan/PerformScan.php +70 -0
- src/lib/src/Modules/Firewall/Options.php +2 -2
- src/lib/src/Modules/Firewall/Processor.php +19 -13
- src/lib/src/Modules/HackGuard/AjaxHandler.php +30 -12
- src/lib/src/Modules/HackGuard/Insights/OverviewCards.php +8 -8
- src/lib/src/Modules/HackGuard/Lib/FileLocker/File.php +15 -10
- src/lib/src/Modules/HackGuard/Lib/FileLocker/FileLockerController.php +30 -23
- src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/BaseOps.php +12 -12
- src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/CreateFileLocks.php +4 -4
- src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/DeleteFileLock.php +10 -14
- src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/LoadFileLocks.php +1 -1
- src/lib/src/Modules/HackGuard/Lib/Reports/FileLockerAlerts.php +1 -1
- src/lib/src/Modules/HackGuard/Lib/Reports/ScanAlerts.php +6 -1
- src/lib/src/Modules/HackGuard/ModCon.php +15 -14
- src/lib/src/Modules/HackGuard/Scan/Queue/Build/QueueBuilder.php +1 -1
- src/lib/src/Modules/HackGuard/Scan/Queue/IsScanEnqueued.php +4 -8
- src/lib/src/Modules/HackGuard/Scan/Queue/ScanInitiate.php +1 -1
- src/lib/src/Modules/HackGuard/Strings.php +12 -12
- src/lib/src/Modules/HackGuard/UI.php +32 -34
- src/lib/src/Modules/Headers/ModCon.php +0 -6
- src/lib/src/Modules/Headers/Strings.php +0 -1
- src/lib/src/Modules/IPs/AjaxHandler.php +5 -4
- src/lib/src/Modules/IPs/BotTrack/TrackLinkCheese.php +0 -15
- src/lib/src/Modules/IPs/Lib/AutoUnblock.php +14 -17
- src/lib/src/Modules/IPs/Lib/BlockRequest.php +16 -30
- src/lib/src/Modules/IPs/Lib/Bots/BotEventListener.php +80 -0
- src/lib/src/Modules/IPs/Lib/Bots/BotSignalsController.php +3 -3
- src/lib/src/Modules/IPs/Lib/OffenseTracker.php +22 -25
- src/lib/src/Modules/IPs/Lib/ProcessOffenses.php +9 -9
- src/lib/src/Modules/IPs/ModCon.php +1 -2
- src/lib/src/Modules/IPs/Options.php +2 -6
- src/lib/src/Modules/IPs/Strings.php +21 -21
- src/lib/src/Modules/IPs/UI.php +0 -21
- src/lib/src/Modules/Insights/AjaxHandler.php +49 -0
- src/lib/src/Modules/Insights/Lib/Requests/DynamicPageLoader.php +95 -0
- src/lib/src/Modules/Insights/Lib/SideMenuBuilder.php +477 -0
- src/lib/src/Modules/Insights/ModCon.php +45 -13
- src/lib/src/Modules/Insights/UI.php +45 -94
- src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/ExtensionSettingsPage.php +2 -2
- src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/PageRender/SitesList.php +1 -1
- src/lib/src/Modules/Integrations/Strings.php +1 -0
- src/lib/src/Modules/License/UI.php +0 -23
- src/lib/src/Modules/LoginGuard/Lib/AntiBot/AntibotSetup.php +14 -14
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/MfaController.php +47 -1
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/Email.php +18 -1
- src/lib/src/Modules/LoginGuard/Processor.php +1 -1
- src/lib/src/Modules/Plugin/AjaxHandler.php +9 -30
- src/lib/src/Modules/Plugin/Insights/DashboardCards.php +1 -9
- src/lib/src/Modules/Plugin/Lib/Debug/Collate.php +9 -7
- src/lib/src/Modules/Plugin/Lib/ImportExport/ImportExportController.php +12 -20
- src/lib/src/Modules/Plugin/Lib/ImportExport/Options/BuildTransferableOptions.php +4 -4
- src/lib/src/Modules/Plugin/Lib/ImportExport/Options/SaveExcludedOptions.php +6 -6
- src/lib/src/Modules/Plugin/Lib/TourManager.php +2 -1
- src/lib/src/Modules/Plugin/ModCon.php +1 -26
- src/lib/src/Modules/Plugin/Strings.php +16 -12
- src/lib/src/Modules/Plugin/UI.php +10 -19
- src/lib/src/Modules/Reporting/AjaxHandler.php +2 -1
- src/lib/src/Modules/Reporting/Lib/ReportingController.php +4 -6
- src/lib/src/Modules/Reporting/Lib/Reports/CreateReportVO.php +13 -15
- src/lib/src/Modules/Reporting/Options.php +1 -1
- src/lib/src/Modules/SecurityAdmin/AjaxHandler.php +9 -14
- src/lib/src/Modules/SecurityAdmin/Insights/OverviewCards.php +5 -5
- src/lib/src/Modules/SecurityAdmin/Lib/{Actions → SecurityAdmin/Ops}/RemoveSecAdmin.php +3 -3
- src/lib/src/Modules/SecurityAdmin/Lib/{Actions → SecurityAdmin/Ops}/SetSecAdminPin.php +1 -1
- src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Ops/ToggleSecAdminStatus.php +50 -0
- src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Ops/VerifyPinRequest.php +33 -0
- src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/Base.php +12 -0
- src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/BaseCapabilitiesRestrict.php +54 -0
- src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/Plugins.php +44 -0
- src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/Posts.php +38 -0
- src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/Themes.php +18 -0
- src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/Users.php +176 -0
- src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/WpOptions.php +48 -0
- src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/SecurityAdminController.php +185 -0
- src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/VerifySecurityAdminList.php +39 -0
- src/lib/src/Modules/SecurityAdmin/Lib/WhiteLabel/ApplyLabels.php +15 -9
- src/lib/src/Modules/SecurityAdmin/ModCon.php +150 -202
- src/lib/src/Modules/SecurityAdmin/Options.php +13 -2
- src/lib/src/Modules/SecurityAdmin/Processor.php +30 -284
- src/lib/src/Modules/SecurityAdmin/Strings.php +2 -2
- src/lib/src/Modules/SecurityAdmin/UI.php +2 -2
- src/lib/src/Modules/SecurityAdmin/WpCli/Pin.php +3 -3
- src/lib/src/Modules/Sessions/ModCon.php +1 -2
- src/lib/src/Modules/Traffic/UI.php +0 -10
- src/lib/src/Modules/UserManagement/Lib/Registration/EmailValidate.php +4 -4
- src/lib/src/Modules/UserManagement/UI.php +0 -16
- src/lib/src/Scans/Base/Table/BaseEntryFormatter.php +8 -14
- src/lib/src/Scans/Base/Table/BaseFileEntryFormatter.php +19 -22
- src/lib/src/Scans/Mal/Table/EntryFormatter.php +19 -23
- src/lib/src/Scans/Ptg/Table/EntryFormatter.php +60 -66
- src/lib/src/Scans/Ufc/BuildScanAction.php +7 -7
- src/lib/src/Scans/Ufc/FileScanner.php +15 -23
- src/lib/src/Scans/Ufc/Table/EntryFormatter.php +6 -9
- src/lib/src/Scans/Wcf/Table/EntryFormatter.php +20 -23
- src/lib/src/Scans/Wpv/WpVulnDb/WpVulnVO.php +0 -8
- src/lib/src/Tables/Build/BaseBuild.php +4 -10
- src/lib/src/Tables/Build/ScanAggregate.php +27 -30
- src/lib/src/Tables/Build/ScanBase.php +12 -15
- src/lib/src/Tables/Render/WpListTable/ScanAggregate.php +11 -11
- src/lib/src/Tables/Render/WpListTable/ScanBase.php +6 -6
- src/lib/src/Tables/Render/WpListTable/ScanMal.php +9 -9
- src/lib/src/Tables/Render/WpListTable/ScanPtg.php +5 -5
- src/lib/src/Tables/Render/WpListTable/ScanUfc.php +7 -7
- src/lib/src/Tables/Render/WpListTable/ScanWcf.php +7 -7
- src/lib/src/Utilities/Nonce/Handler.php +26 -0
- src/lib/vendor/composer/autoload_classmap.php +26 -3
- src/lib/vendor/composer/autoload_static.php +26 -3
- src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Request.php +9 -33
- src/wizards/base.php +3 -9
- src/wizards/base_wpsf.php +13 -16
- src/wizards/plugin.php +15 -16
- templates/php/snippets/plugin-deactivate-survey.php +0 -14
- templates/twig/components/events/stats/stat_box.twig +8 -0
- templates/twig/components/events/stats/stats_collection.twig +10 -0
- templates/twig/components/options_form/main.twig +21 -12
- templates/twig/components/search/dialog.twig +22 -0
- templates/twig/components/search/options.twig +21 -0
- templates/twig/components/security_admin/login_box.twig +68 -0
- templates/twig/email/lp_2fa_email_code.twig +2 -0
- templates/twig/pages/block/blocklist_die.twig +5 -6
- templates/twig/snippets/select_search_options.twig +0 -21
- templates/twig/wizard/slides/common/security_admin_verify.twig +1 -1
- templates/twig/wizard/slides/welcome/admin_access_restriction.twig +1 -1
- templates/twig/wpadmin_pages/base.twig +25 -1
- templates/twig/wpadmin_pages/components/page/nav_sidebar.twig +56 -0
- templates/twig/wpadmin_pages/insights/audit/audit_table.twig +61 -75
- templates/twig/wpadmin_pages/insights/base.twig +3 -27
- templates/twig/wpadmin_pages/insights/dashboard/card_settings.twig +1 -1
- templates/twig/wpadmin_pages/insights/docs/index.twig +1 -0
- templates/twig/wpadmin_pages/insights/overview/cards/shuffle.twig +7 -0
- templates/twig/wpadmin_pages/insights/scans/index.twig +0 -10
- templates/twig/wpadmin_pages/insights/scans/results/index.twig +10 -0
- templates/twig/wpadmin_pages/insights/scans/{realtime → results/realtime}/file_locker/file_diff.twig +7 -2
- templates/twig/wpadmin_pages/insights/scans/{realtime → results/realtime}/file_locker/index.twig +6 -5
- templates/twig/wpadmin_pages/insights/scans/results/{aggregate.twig → results/aggregate.twig} +0 -0
- templates/twig/wpadmin_pages/insights/scans/results/{apc.twig → results/apc.twig} +2 -2
- templates/twig/wpadmin_pages/insights/scans/results/{common_disabled.twig → results/common_disabled.twig} +0 -0
- templates/twig/wpadmin_pages/insights/scans/results/{common_unavailable.twig → results/common_unavailable.twig} +0 -0
- templates/twig/wpadmin_pages/insights/scans/results/{mal.twig → results/mal.twig} +2 -2
- templates/twig/wpadmin_pages/insights/scans/results/{ptg.twig → results/ptg.twig} +3 -3
- templates/twig/wpadmin_pages/insights/scans/results/{ptg_table.twig → results/ptg_table.twig} +0 -0
- templates/twig/wpadmin_pages/insights/scans/results/{ufc.twig → results/ufc.twig} +0 -0
- templates/twig/wpadmin_pages/insights/scans/results/{wcf.twig → results/wcf.twig} +16 -2
- templates/twig/wpadmin_pages/insights/scans/results/{wpv.twig → results/wpv.twig} +2 -2
- templates/twig/wpadmin_pages/insights/scans/{scan_results.twig → results/scan_results.twig} +11 -5
- templates/twig/wpadmin_pages/insights/scans/run/index.twig +11 -0
- templates/twig/wpadmin_pages/insights/scans/{scan_areas.twig → run/scan_areas.twig} +9 -7
- templates/twig/wpadmin_pages/insights/scans/scan_start.twig +0 -46
- templates/twig/wpadmin_pages/insights/settings/index.twig +0 -59
- templates/twig/wpadmin_pages/insights/stats/index.twig +33 -0
- templates/twig/wpadmin_pages/insights/traffic/traffic_table.twig +1 -1
- templates/twig/wpadmin_pages/security_admin/index.twig +1 -5
- unsupported.php +4 -4
cl.json
CHANGED
@@ -1,10 +1,82 @@
|
|
1 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
"11.0": {
|
3 |
"version": "11.0",
|
4 |
"released_at": 1616666000,
|
5 |
"hrefs": {
|
6 |
-
"release": "https://shsec.io/
|
7 |
-
"upgrade": "https://shsec.io/
|
8 |
},
|
9 |
"href": "https://shsec.io/",
|
10 |
"title": "All-New Shield AntiBot Detection Engine",
|
1 |
{
|
2 |
+
"11.1": {
|
3 |
+
"version": "11.1",
|
4 |
+
"released_at": 1616666000,
|
5 |
+
"hrefs": {
|
6 |
+
"release": "https://shsec.io/shieldrelease111",
|
7 |
+
"upgrade": "https://shsec.io/shieldupgradeguide111"
|
8 |
+
},
|
9 |
+
"href": "https://shsec.io/",
|
10 |
+
"title": "UI Cleanup and Enhancement",
|
11 |
+
"description": [
|
12 |
+
"With Shield being such a large plugin, it's been a challenge to get a UI that everyone is happy with.",
|
13 |
+
"This release aims to improve the UI and make it easier for everyone to get their security task done as efficiently as possible."
|
14 |
+
],
|
15 |
+
"items": [
|
16 |
+
{
|
17 |
+
"type": "new",
|
18 |
+
"pro_only": false,
|
19 |
+
"title": "Improved Dashboard UI and Navigation",
|
20 |
+
"description": [
|
21 |
+
"Detecting bad bots on your WordPress sites is a huge challenge, but it's notoriously difficult to do this.",
|
22 |
+
"We have developed an exclusive system for the detection of bad bots and the option to block requests from them."
|
23 |
+
],
|
24 |
+
"href": "https://shsec.io/jb"
|
25 |
+
},
|
26 |
+
{
|
27 |
+
"type": "new",
|
28 |
+
"title": "A new Quick Stats screen is available to see the activity of Shield over time.",
|
29 |
+
"description": [
|
30 |
+
"The implementation is currently basic, but it forms the foundation of future development and offers users the option to offer suggestions."
|
31 |
+
]
|
32 |
+
},
|
33 |
+
{
|
34 |
+
"type": "improved",
|
35 |
+
"title": "Code overhaul for Security Admin system to improve reliability and fix various bugs.",
|
36 |
+
"description": []
|
37 |
+
},
|
38 |
+
{
|
39 |
+
"type": "improved",
|
40 |
+
"title": "Automatic User Unblock now makes use of Shield's AntiBot Detection Engine.",
|
41 |
+
"description": []
|
42 |
+
},
|
43 |
+
{
|
44 |
+
"type": "improved",
|
45 |
+
"title": "File Locker will better handle the scenario where a site is moved/migrated.",
|
46 |
+
"description": [
|
47 |
+
"File Locker for wp-config.php files will also better detect when this file is placed 1 directory higher than the site."
|
48 |
+
]
|
49 |
+
},
|
50 |
+
{
|
51 |
+
"type": "improved",
|
52 |
+
"title": "White Label settings that are empty aren't applied and defaults remain.",
|
53 |
+
"description": []
|
54 |
+
},
|
55 |
+
{
|
56 |
+
"type": "fixed",
|
57 |
+
"title": "Statistics in reporting emails were under-reporting the full stats.",
|
58 |
+
"description": []
|
59 |
+
},
|
60 |
+
{
|
61 |
+
"type": "fixed",
|
62 |
+
"title": "Audit Trail didn't capture all upgrades when upgrading plugins/themes in-bulk.",
|
63 |
+
"description": [
|
64 |
+
"The Audit Trial would only capture 1 upgrade when a bulk upgrade was performed."
|
65 |
+
]
|
66 |
+
},
|
67 |
+
{
|
68 |
+
"type": "fixed",
|
69 |
+
"title": "Exclusions for unrecognised file scanner weren't stored correctly in the case of regular expressions.",
|
70 |
+
"description": []
|
71 |
+
}
|
72 |
+
]
|
73 |
+
},
|
74 |
"11.0": {
|
75 |
"version": "11.0",
|
76 |
"released_at": 1616666000,
|
77 |
"hrefs": {
|
78 |
+
"release": "https://shsec.io/shieldrelease110",
|
79 |
+
"upgrade": "https://shsec.io/shieldupgradeguide110"
|
80 |
},
|
81 |
"href": "https://shsec.io/",
|
82 |
"title": "All-New Shield AntiBot Detection Engine",
|
icwp-wpsf.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: Shield Security
|
4 |
* Plugin URI: https://shsec.io/2f
|
5 |
* Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
|
6 |
-
* Version: 11.0
|
7 |
* Text Domain: wp-simple-firewall
|
8 |
* Domain Path: /languages
|
9 |
* Author: Shield Security
|
3 |
* Plugin Name: Shield Security
|
4 |
* Plugin URI: https://shsec.io/2f
|
5 |
* Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
|
6 |
+
* Version: 11.1.0
|
7 |
* Text Domain: wp-simple-firewall
|
8 |
* Domain Path: /languages
|
9 |
* Author: Shield Security
|
plugin-spec.php
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
{
|
2 |
"properties": {
|
3 |
-
"version": "11.0
|
4 |
-
"release_timestamp":
|
5 |
-
"build": "
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield Security",
|
@@ -52,14 +52,16 @@
|
|
52 |
"select2",
|
53 |
"plugin",
|
54 |
"featherlight",
|
55 |
-
"introjs"
|
|
|
56 |
],
|
57 |
"js": [
|
58 |
"select2",
|
59 |
"plugin",
|
60 |
"featherlight",
|
61 |
"jquery.fileDownload",
|
62 |
-
"shield/tours"
|
|
|
63 |
]
|
64 |
},
|
65 |
"frontend": {
|
@@ -83,6 +85,12 @@
|
|
83 |
"bootstrap"
|
84 |
]
|
85 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
"global-plugin": {},
|
87 |
"plugin": {
|
88 |
"deps": [
|
@@ -112,7 +120,8 @@
|
|
112 |
"deps": [
|
113 |
"plugin"
|
114 |
]
|
115 |
-
}
|
|
|
116 |
},
|
117 |
"js": {
|
118 |
"bootstrap": {
|
@@ -133,6 +142,12 @@
|
|
133 |
"bootstrap"
|
134 |
]
|
135 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
"global-plugin": {
|
137 |
"deps": [
|
138 |
"wp-jquery"
|
@@ -142,6 +157,7 @@
|
|
142 |
"deps": [
|
143 |
"bootstrap",
|
144 |
"global-plugin",
|
|
|
145 |
"base64.min",
|
146 |
"lz-string.min"
|
147 |
]
|
@@ -197,6 +213,12 @@
|
|
197 |
"wp-jquery"
|
198 |
]
|
199 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
"shield/tables": {
|
201 |
"deps": [
|
202 |
"plugin"
|
@@ -226,7 +248,7 @@
|
|
226 |
"plugin"
|
227 |
]
|
228 |
},
|
229 |
-
"shield/mainwp
|
230 |
"deps": [
|
231 |
"wp-jquery"
|
232 |
]
|
@@ -304,7 +326,7 @@
|
|
304 |
{
|
305 |
"name": "Security Dashboard",
|
306 |
"title": "Go To Security Dashboard",
|
307 |
-
"href": "
|
308 |
"target": "_top",
|
309 |
"show": "always"
|
310 |
},
|
1 |
{
|
2 |
"properties": {
|
3 |
+
"version": "11.1.0",
|
4 |
+
"release_timestamp": 1617870687,
|
5 |
+
"build": "202104.0801",
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield Security",
|
52 |
"select2",
|
53 |
"plugin",
|
54 |
"featherlight",
|
55 |
+
"introjs",
|
56 |
+
"bootstrap-select"
|
57 |
],
|
58 |
"js": [
|
59 |
"select2",
|
60 |
"plugin",
|
61 |
"featherlight",
|
62 |
"jquery.fileDownload",
|
63 |
+
"shield/tours",
|
64 |
+
"bootstrap-select"
|
65 |
]
|
66 |
},
|
67 |
"frontend": {
|
85 |
"bootstrap"
|
86 |
]
|
87 |
},
|
88 |
+
"bootstrap-select": {
|
89 |
+
"url": "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.18/css/bootstrap-select.min.css",
|
90 |
+
"deps": [
|
91 |
+
"bootstrap"
|
92 |
+
]
|
93 |
+
},
|
94 |
"global-plugin": {},
|
95 |
"plugin": {
|
96 |
"deps": [
|
120 |
"deps": [
|
121 |
"plugin"
|
122 |
]
|
123 |
+
},
|
124 |
+
"shield/mainwp": {}
|
125 |
},
|
126 |
"js": {
|
127 |
"bootstrap": {
|
142 |
"bootstrap"
|
143 |
]
|
144 |
},
|
145 |
+
"bootstrap-select": {
|
146 |
+
"url": "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.18/js/bootstrap-select.min.js",
|
147 |
+
"deps": [
|
148 |
+
"bootstrap"
|
149 |
+
]
|
150 |
+
},
|
151 |
"global-plugin": {
|
152 |
"deps": [
|
153 |
"wp-jquery"
|
157 |
"deps": [
|
158 |
"bootstrap",
|
159 |
"global-plugin",
|
160 |
+
"shield/navigation",
|
161 |
"base64.min",
|
162 |
"lz-string.min"
|
163 |
]
|
213 |
"wp-jquery"
|
214 |
]
|
215 |
},
|
216 |
+
"shield/navigation": {},
|
217 |
+
"shield/secadmin": {
|
218 |
+
"deps": [
|
219 |
+
"wp-jquery"
|
220 |
+
]
|
221 |
+
},
|
222 |
"shield/tables": {
|
223 |
"deps": [
|
224 |
"plugin"
|
248 |
"plugin"
|
249 |
]
|
250 |
},
|
251 |
+
"shield/mainwp": {
|
252 |
"deps": [
|
253 |
"wp-jquery"
|
254 |
]
|
326 |
{
|
327 |
"name": "Security Dashboard",
|
328 |
"title": "Go To Security Dashboard",
|
329 |
+
"href": "getPluginUrl_DashboardHome",
|
330 |
"target": "_top",
|
331 |
"show": "always"
|
332 |
},
|
readme.txt
CHANGED
@@ -8,7 +8,7 @@ Requires at least: 3.5.2
|
|
8 |
Requires PHP: 7.0
|
9 |
Recommended PHP: 7.4
|
10 |
Tested up to: 5.7
|
11 |
-
Stable tag: 11.0
|
12 |
Security against hackers and brute force bots with firewall, login security hiding and hardening, Antispam, Audit Trail, Live Traffic, and much more...
|
13 |
|
14 |
== Description ==
|
8 |
Requires PHP: 7.0
|
9 |
Recommended PHP: 7.4
|
10 |
Tested up to: 5.7
|
11 |
+
Stable tag: 11.1.0
|
12 |
Security against hackers and brute force bots with firewall, login security hiding and hardening, Antispam, Audit Trail, Live Traffic, and much more...
|
13 |
|
14 |
== Description ==
|
resources/css/plugin.css
CHANGED
@@ -151,17 +151,6 @@ p.code-description {
|
|
151 |
.bootstrap-wpadmin .form-horizontal .form-actions {
|
152 |
padding-left: 200px;
|
153 |
}
|
154 |
-
/** Section summaries **/
|
155 |
-
a.section-help-video {
|
156 |
-
text-decoration: none;
|
157 |
-
margin: 0 12px 0 0;
|
158 |
-
}
|
159 |
-
a.section-help-video > span {
|
160 |
-
font-size: 28px;
|
161 |
-
color: #008000;
|
162 |
-
margin-top: -2px;
|
163 |
-
}
|
164 |
-
/** End-Section summaries **/
|
165 |
.wrap .icon32 {
|
166 |
width: 32px;
|
167 |
}
|
@@ -1052,7 +1041,7 @@ input[type=checkbox].form-check-input {
|
|
1052 |
margin-right: 5px;
|
1053 |
}
|
1054 |
/** copied from bootstrap to override WP admin styles */
|
1055 |
-
.
|
1056 |
font-size: 14px;
|
1057 |
padding-top: 10px;
|
1058 |
}
|
@@ -1092,31 +1081,26 @@ input[type=checkbox].form-check-input {
|
|
1092 |
font-style: italic;
|
1093 |
font-size: 12px;
|
1094 |
}
|
1095 |
-
.
|
1096 |
border-top: 0 none;
|
1097 |
padding-top: 14px;
|
1098 |
}
|
1099 |
-
.
|
1100 |
/*margin-bottom: 20px;*/
|
1101 |
padding: 15px 0 25px;
|
1102 |
border-bottom: 1px dashed rgba(0, 0, 0, 0.08);
|
1103 |
}
|
1104 |
-
.
|
1105 |
border-left: 1px solid rgba(0, 0, 0, 0.1);
|
1106 |
}
|
1107 |
-
.
|
1108 |
margin-bottom: 5px;
|
1109 |
}
|
1110 |
-
.
|
1111 |
position: relative;
|
1112 |
/*display: block;*/
|
1113 |
}
|
1114 |
-
.
|
1115 |
-
/*position: absolute;*/
|
1116 |
-
/*right: -18px;*/
|
1117 |
-
/*top: -5px;*/
|
1118 |
-
}
|
1119 |
-
.content-options .option_link_info > .dashicons {
|
1120 |
font-size: 16px;
|
1121 |
text-decoration: none;
|
1122 |
width: 1px;
|
@@ -1530,6 +1514,11 @@ a.card_help {
|
|
1530 |
bottom: 0;
|
1531 |
padding-left: 160px;
|
1532 |
transition: 0.5s ease;
|
|
|
|
|
|
|
|
|
|
|
1533 |
}
|
1534 |
body.folded #FooterBannerGoPro {
|
1535 |
padding-left: 40px;
|
@@ -1551,8 +1540,52 @@ body.folded #FooterBannerGoPro {
|
|
1551 |
}
|
1552 |
}
|
1553 |
#odp-PageFoot {
|
1554 |
-
height:
|
1555 |
}
|
1556 |
.select2-selection {
|
1557 |
font-weight: normal;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1558 |
}
|
151 |
.bootstrap-wpadmin .form-horizontal .form-actions {
|
152 |
padding-left: 200px;
|
153 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
.wrap .icon32 {
|
155 |
width: 32px;
|
156 |
}
|
1041 |
margin-right: 5px;
|
1042 |
}
|
1043 |
/** copied from bootstrap to override WP admin styles */
|
1044 |
+
.icwpOptionsForm {
|
1045 |
font-size: 14px;
|
1046 |
padding-top: 10px;
|
1047 |
}
|
1081 |
font-style: italic;
|
1082 |
font-size: 12px;
|
1083 |
}
|
1084 |
+
.icwpOptionsForm .tab-content {
|
1085 |
border-top: 0 none;
|
1086 |
padding-top: 14px;
|
1087 |
}
|
1088 |
+
.icwpOptionsForm .form-group.row {
|
1089 |
/*margin-bottom: 20px;*/
|
1090 |
padding: 15px 0 25px;
|
1091 |
border-bottom: 1px dashed rgba(0, 0, 0, 0.08);
|
1092 |
}
|
1093 |
+
.icwpOptionsForm .option-description {
|
1094 |
border-left: 1px solid rgba(0, 0, 0, 0.1);
|
1095 |
}
|
1096 |
+
.icwpOptionsForm .option-description p {
|
1097 |
margin-bottom: 5px;
|
1098 |
}
|
1099 |
+
.icwpOptionsForm .option_label_name {
|
1100 |
position: relative;
|
1101 |
/*display: block;*/
|
1102 |
}
|
1103 |
+
.icwpOptionsForm .option_link_info > .dashicons {
|
|
|
|
|
|
|
|
|
|
|
1104 |
font-size: 16px;
|
1105 |
text-decoration: none;
|
1106 |
width: 1px;
|
1514 |
bottom: 0;
|
1515 |
padding-left: 160px;
|
1516 |
transition: 0.5s ease;
|
1517 |
+
z-index: 1;
|
1518 |
+
}
|
1519 |
+
#adminmenuback {
|
1520 |
+
/** To account for the promo bar at the bottom **/
|
1521 |
+
z-index: 2;
|
1522 |
}
|
1523 |
body.folded #FooterBannerGoPro {
|
1524 |
padding-left: 40px;
|
1540 |
}
|
1541 |
}
|
1542 |
#odp-PageFoot {
|
1543 |
+
height: 12px;
|
1544 |
}
|
1545 |
.select2-selection {
|
1546 |
font-weight: normal;
|
1547 |
+
}
|
1548 |
+
#odp-PageHead {
|
1549 |
+
}
|
1550 |
+
#apto-PageMainSide {
|
1551 |
+
background-color: rgba(85, 178, 87, 0.06);
|
1552 |
+
border-color: rgba(85, 178, 87, 0.2);
|
1553 |
+
border-width: 1px 1px 1px 0;
|
1554 |
+
border-style: solid;
|
1555 |
+
}
|
1556 |
+
#NavSideBar a.nav-link:hover {
|
1557 |
+
color: black;
|
1558 |
+
}
|
1559 |
+
#NavSideBar a.nav-link.active {
|
1560 |
+
font-weight: bolder;
|
1561 |
+
}
|
1562 |
+
.primary_sub_menu {
|
1563 |
+
}
|
1564 |
+
|
1565 |
+
#SearchDialog .modal-body {
|
1566 |
+
min-height: 450px;
|
1567 |
+
}
|
1568 |
+
#SearchDialog .bootstrap-select {
|
1569 |
+
width: 100%;
|
1570 |
+
}
|
1571 |
+
#SearchDialog .bootstrap-select > .dropdown-toggle.bs-placeholder {
|
1572 |
+
color: #333333;
|
1573 |
+
}
|
1574 |
+
|
1575 |
+
#StatsNav {
|
1576 |
+
background-color: #f1f1f1;
|
1577 |
+
display: inline-block;
|
1578 |
+
position: sticky;
|
1579 |
+
top: 88px;
|
1580 |
+
z-index: 5;
|
1581 |
+
}
|
1582 |
+
.stat_box .card-header {
|
1583 |
+
text-align: center;
|
1584 |
+
}
|
1585 |
+
.stat_box .card-body {
|
1586 |
+
background-color: #c3c3d6;
|
1587 |
+
}
|
1588 |
+
.stat_box .stat_count {
|
1589 |
+
font-size: 3rem;
|
1590 |
+
line-height: 3.5rem;
|
1591 |
}
|
resources/css/{mainwp-extension.css → shield/mainwp.css}
RENAMED
File without changes
|
resources/images/bootstrap/arrow-down-up.svg
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
<svg
|
2 |
<path fill-rule="evenodd" d="M11.5 15a.5.5 0 0 0 .5-.5V2.707l3.146 3.147a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 1 0 .708.708L11 2.707V14.5a.5.5 0 0 0 .5.5zm-7-14a.5.5 0 0 1 .5.5v11.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 .708-.708L4 13.293V1.5a.5.5 0 0 1 .5-.5z"/>
|
3 |
</svg>
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down-up" viewBox="0 0 16 16">
|
2 |
<path fill-rule="evenodd" d="M11.5 15a.5.5 0 0 0 .5-.5V2.707l3.146 3.147a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 1 0 .708.708L11 2.707V14.5a.5.5 0 0 0 .5.5zm-7-14a.5.5 0 0 1 .5.5v11.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 .708-.708L4 13.293V1.5a.5.5 0 0 1 .5-.5z"/>
|
3 |
</svg>
|
resources/images/bootstrap/award.svg
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<svg
|
2 |
-
<path
|
3 |
<path d="M4 11.794V16l4-1 4 1v-4.206l-2.018.306L8 13.126 6.018 12.1 4 11.794z"/>
|
4 |
</svg>
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-award" viewBox="0 0 16 16">
|
2 |
+
<path d="M9.669.864 8 0 6.331.864l-1.858.282-.842 1.68-1.337 1.32L2.6 6l-.306 1.854 1.337 1.32.842 1.68 1.858.282L8 12l1.669-.864 1.858-.282.842-1.68 1.337-1.32L13.4 6l.306-1.854-1.337-1.32-.842-1.68L9.669.864zm1.196 1.193.684 1.365 1.086 1.072L12.387 6l.248 1.506-1.086 1.072-.684 1.365-1.51.229L8 10.874l-1.355-.702-1.51-.229-.684-1.365-1.086-1.072L3.614 6l-.25-1.506 1.087-1.072.684-1.365 1.51-.229L8 1.126l1.356.702 1.509.229z"/>
|
3 |
<path d="M4 11.794V16l4-1 4 1v-4.206l-2.018.306L8 13.126 6.018 12.1 4 11.794z"/>
|
4 |
</svg>
|
resources/images/bootstrap/binoculars.svg
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
<svg
|
2 |
-
<path
|
3 |
</svg>
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-binoculars" viewBox="0 0 16 16">
|
2 |
+
<path d="M3 2.5A1.5 1.5 0 0 1 4.5 1h1A1.5 1.5 0 0 1 7 2.5V5h2V2.5A1.5 1.5 0 0 1 10.5 1h1A1.5 1.5 0 0 1 13 2.5v2.382a.5.5 0 0 0 .276.447l.895.447A1.5 1.5 0 0 1 15 7.118V14.5a1.5 1.5 0 0 1-1.5 1.5h-3A1.5 1.5 0 0 1 9 14.5v-3a.5.5 0 0 1 .146-.354l.854-.853V9.5a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 0-.5.5v.793l.854.853A.5.5 0 0 1 7 11.5v3A1.5 1.5 0 0 1 5.5 16h-3A1.5 1.5 0 0 1 1 14.5V7.118a1.5 1.5 0 0 1 .83-1.342l.894-.447A.5.5 0 0 0 3 4.882V2.5zM4.5 2a.5.5 0 0 0-.5.5V3h2v-.5a.5.5 0 0 0-.5-.5h-1zM6 4H4v.882a1.5 1.5 0 0 1-.83 1.342l-.894.447A.5.5 0 0 0 2 7.118V13h4v-1.293l-.854-.853A.5.5 0 0 1 5 10.5v-1A1.5 1.5 0 0 1 6.5 8h3A1.5 1.5 0 0 1 11 9.5v1a.5.5 0 0 1-.146.354l-.854.853V13h4V7.118a.5.5 0 0 0-.276-.447l-.895-.447A1.5 1.5 0 0 1 12 4.882V4h-2v1.5a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5V4zm4-1h2v-.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5V3zm4 11h-4v.5a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5V14zm-8 0H2v.5a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5V14z"/>
|
3 |
</svg>
|
resources/images/bootstrap/book-half.svg
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
<svg
|
2 |
-
<path
|
3 |
</svg>
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-book-half" viewBox="0 0 16 16">
|
2 |
+
<path d="M8.5 2.687c.654-.689 1.782-.886 3.112-.752 1.234.124 2.503.523 3.388.893v9.923c-.918-.35-2.107-.692-3.287-.81-1.094-.111-2.278-.039-3.213.492V2.687zM8 1.783C7.015.936 5.587.81 4.287.94c-1.514.153-3.042.672-3.994 1.105A.5.5 0 0 0 0 2.5v11a.5.5 0 0 0 .707.455c.882-.4 2.303-.881 3.68-1.02 1.409-.142 2.59.087 3.223.877a.5.5 0 0 0 .78 0c.633-.79 1.814-1.019 3.222-.877 1.378.139 2.8.62 3.681 1.02A.5.5 0 0 0 16 13.5v-11a.5.5 0 0 0-.293-.455c-.952-.433-2.48-.952-3.994-1.105C10.413.809 8.985.936 8 1.783z"/>
|
3 |
</svg>
|
resources/images/bootstrap/bug.svg
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
<svg
|
2 |
-
<path
|
3 |
</svg>
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-bug" viewBox="0 0 16 16">
|
2 |
+
<path d="M4.355.522a.5.5 0 0 1 .623.333l.291.956A4.979 4.979 0 0 1 8 1c1.007 0 1.946.298 2.731.811l.29-.956a.5.5 0 1 1 .957.29l-.41 1.352A4.985 4.985 0 0 1 13 6h.5a.5.5 0 0 0 .5-.5V5a.5.5 0 0 1 1 0v.5A1.5 1.5 0 0 1 13.5 7H13v1h1.5a.5.5 0 0 1 0 1H13v1h.5a1.5 1.5 0 0 1 1.5 1.5v.5a.5.5 0 1 1-1 0v-.5a.5.5 0 0 0-.5-.5H13a5 5 0 0 1-10 0h-.5a.5.5 0 0 0-.5.5v.5a.5.5 0 1 1-1 0v-.5A1.5 1.5 0 0 1 2.5 10H3V9H1.5a.5.5 0 0 1 0-1H3V7h-.5A1.5 1.5 0 0 1 1 5.5V5a.5.5 0 0 1 1 0v.5a.5.5 0 0 0 .5.5H3c0-1.364.547-2.601 1.432-3.503l-.41-1.352a.5.5 0 0 1 .333-.623zM4 7v4a4 4 0 0 0 3.5 3.97V7H4zm4.5 0v7.97A4 4 0 0 0 12 11V7H8.5zM12 6a3.989 3.989 0 0 0-1.334-2.982A3.983 3.983 0 0 0 8 2a3.983 3.983 0 0 0-2.667 1.018A3.989 3.989 0 0 0 4 6h8z"/>
|
3 |
</svg>
|
resources/images/bootstrap/chat-right-dots-fill.svg
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
<svg
|
2 |
-
<path
|
3 |
</svg>
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chat-right-dots-fill" viewBox="0 0 16 16">
|
2 |
+
<path d="M16 2a2 2 0 0 0-2-2H2a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h9.586a1 1 0 0 1 .707.293l2.853 2.853a.5.5 0 0 0 .854-.353V2zM5 6a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm4 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm3 1a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
|
3 |
</svg>
|
resources/images/bootstrap/diagram-3.svg
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
<svg
|
2 |
<path fill-rule="evenodd" d="M6 3.5A1.5 1.5 0 0 1 7.5 2h1A1.5 1.5 0 0 1 10 3.5v1A1.5 1.5 0 0 1 8.5 6v1H14a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-1 0V8h-5v.5a.5.5 0 0 1-1 0V8h-5v.5a.5.5 0 0 1-1 0v-1A.5.5 0 0 1 2 7h5.5V6A1.5 1.5 0 0 1 6 4.5v-1zM8.5 5a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1zM0 11.5A1.5 1.5 0 0 1 1.5 10h1A1.5 1.5 0 0 1 4 11.5v1A1.5 1.5 0 0 1 2.5 14h-1A1.5 1.5 0 0 1 0 12.5v-1zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1zm4.5.5A1.5 1.5 0 0 1 7.5 10h1a1.5 1.5 0 0 1 1.5 1.5v1A1.5 1.5 0 0 1 8.5 14h-1A1.5 1.5 0 0 1 6 12.5v-1zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1zm4.5.5a1.5 1.5 0 0 1 1.5-1.5h1a1.5 1.5 0 0 1 1.5 1.5v1a1.5 1.5 0 0 1-1.5 1.5h-1a1.5 1.5 0 0 1-1.5-1.5v-1zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1z"/>
|
3 |
</svg>
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-diagram-3" viewBox="0 0 16 16">
|
2 |
<path fill-rule="evenodd" d="M6 3.5A1.5 1.5 0 0 1 7.5 2h1A1.5 1.5 0 0 1 10 3.5v1A1.5 1.5 0 0 1 8.5 6v1H14a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-1 0V8h-5v.5a.5.5 0 0 1-1 0V8h-5v.5a.5.5 0 0 1-1 0v-1A.5.5 0 0 1 2 7h5.5V6A1.5 1.5 0 0 1 6 4.5v-1zM8.5 5a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1zM0 11.5A1.5 1.5 0 0 1 1.5 10h1A1.5 1.5 0 0 1 4 11.5v1A1.5 1.5 0 0 1 2.5 14h-1A1.5 1.5 0 0 1 0 12.5v-1zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1zm4.5.5A1.5 1.5 0 0 1 7.5 10h1a1.5 1.5 0 0 1 1.5 1.5v1A1.5 1.5 0 0 1 8.5 14h-1A1.5 1.5 0 0 1 6 12.5v-1zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1zm4.5.5a1.5 1.5 0 0 1 1.5-1.5h1a1.5 1.5 0 0 1 1.5 1.5v1a1.5 1.5 0 0 1-1.5 1.5h-1a1.5 1.5 0 0 1-1.5-1.5v-1zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1z"/>
|
3 |
</svg>
|
resources/images/bootstrap/emoji-smile.svg
CHANGED
@@ -1,5 +1,4 @@
|
|
1 |
-
<svg
|
2 |
-
<path
|
3 |
-
<path
|
4 |
-
<path d="M7 6.5C7 7.328 6.552 8 6 8s-1-.672-1-1.5S5.448 5 6 5s1 .672 1 1.5zm4 0c0 .828-.448 1.5-1 1.5s-1-.672-1-1.5S9.448 5 10 5s1 .672 1 1.5z"/>
|
5 |
</svg>
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-emoji-smile" viewBox="0 0 16 16">
|
2 |
+
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/>
|
3 |
+
<path d="M4.285 9.567a.5.5 0 0 1 .683.183A3.498 3.498 0 0 0 8 11.5a3.498 3.498 0 0 0 3.032-1.75.5.5 0 1 1 .866.5A4.498 4.498 0 0 1 8 12.5a4.498 4.498 0 0 1-3.898-2.25.5.5 0 0 1 .183-.683zM7 6.5C7 7.328 6.552 8 6 8s-1-.672-1-1.5S5.448 5 6 5s1 .672 1 1.5zm4 0c0 .828-.448 1.5-1 1.5s-1-.672-1-1.5S9.448 5 10 5s1 .672 1 1.5z"/>
|
|
|
4 |
</svg>
|
resources/images/bootstrap/graph-up.svg
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-graph-up" viewBox="0 0 16 16">
|
2 |
-
<path fill-rule="evenodd" d="M0 0h1v15h15v1H0V0zm10 3.5a.5.5 0 0 1 .5-.5h4a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-1 0V4.9l-3.613 4.417a.5.5 0 0 1-.74.037L7.06 6.767l-3.656 5.027a.5.5 0 0 1-.808-.588l4-5.5a.5.5 0 0 1 .758-.06l2.609 2.61L13.445 4H10.5a.5.5 0 0 1-.5-.5z"/>
|
3 |
</svg>
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-graph-up" viewBox="0 0 16 16">
|
2 |
+
<path fill-rule="evenodd" d="M0 0h1v15h15v1H0V0zm10 3.5a.5.5 0 0 1 .5-.5h4a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-1 0V4.9l-3.613 4.417a.5.5 0 0 1-.74.037L7.06 6.767l-3.656 5.027a.5.5 0 0 1-.808-.588l4-5.5a.5.5 0 0 1 .758-.06l2.609 2.61L13.445 4H10.5a.5.5 0 0 1-.5-.5z"/>
|
3 |
</svg>
|
resources/images/bootstrap/link-45deg.svg
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<svg
|
2 |
-
<path d="M4.715 6.
|
3 |
-
<path d="M6.586 4.672A3 3 0 0 0 7.414 9.5l.775-.776a2 2 0 0 1-.896-3.346L9.12 3.55a2 2 0
|
4 |
</svg>
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-link-45deg" viewBox="0 0 16 16">
|
2 |
+
<path d="M4.715 6.542 3.343 7.914a3 3 0 1 0 4.243 4.243l1.828-1.829A3 3 0 0 0 8.586 5.5L8 6.086a1.002 1.002 0 0 0-.154.199 2 2 0 0 1 .861 3.337L6.88 11.45a2 2 0 1 1-2.83-2.83l.793-.792a4.018 4.018 0 0 1-.128-1.287z"/>
|
3 |
+
<path d="M6.586 4.672A3 3 0 0 0 7.414 9.5l.775-.776a2 2 0 0 1-.896-3.346L9.12 3.55a2 2 0 1 1 2.83 2.83l-.793.792c.112.42.155.855.128 1.287l1.372-1.372a3 3 0 1 0-4.243-4.243L6.586 4.672z"/>
|
4 |
</svg>
|
resources/images/bootstrap/pencil-square.svg
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<svg
|
2 |
-
<path d="M15.502 1.94a.5.5 0 0 1 0 .706L14.459 3.69l-2-2L13.502.646a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.
|
3 |
<path fill-rule="evenodd" d="M1 13.5A1.5 1.5 0 0 0 2.5 15h11a1.5 1.5 0 0 0 1.5-1.5v-6a.5.5 0 0 0-1 0v6a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5v-11a.5.5 0 0 1 .5-.5H9a.5.5 0 0 0 0-1H2.5A1.5 1.5 0 0 0 1 2.5v11z"/>
|
4 |
</svg>
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pencil-square" viewBox="0 0 16 16">
|
2 |
+
<path d="M15.502 1.94a.5.5 0 0 1 0 .706L14.459 3.69l-2-2L13.502.646a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.456-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0 0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z"/>
|
3 |
<path fill-rule="evenodd" d="M1 13.5A1.5 1.5 0 0 0 2.5 15h11a1.5 1.5 0 0 0 1.5-1.5v-6a.5.5 0 0 0-1 0v6a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5v-11a.5.5 0 0 1 .5-.5H9a.5.5 0 0 0 0-1H2.5A1.5 1.5 0 0 0 1 2.5v11z"/>
|
4 |
</svg>
|
resources/images/bootstrap/people.svg
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
<svg
|
2 |
-
<path
|
3 |
</svg>
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-people" viewBox="0 0 16 16">
|
2 |
+
<path d="M15 14s1 0 1-1-1-4-5-4-5 3-5 4 1 1 1 1h8zm-7.978-1A.261.261 0 0 1 7 12.996c.001-.264.167-1.03.76-1.72C8.312 10.629 9.282 10 11 10c1.717 0 2.687.63 3.24 1.276.593.69.758 1.457.76 1.72l-.008.002a.274.274 0 0 1-.014.002H7.022zM11 7a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm3-2a3 3 0 1 1-6 0 3 3 0 0 1 6 0zM6.936 9.28a5.88 5.88 0 0 0-1.23-.247A7.35 7.35 0 0 0 5 9c-4 0-5 3-5 4 0 .667.333 1 1 1h4.216A2.238 2.238 0 0 1 5 13c0-1.01.377-2.042 1.09-2.904.243-.294.526-.569.846-.816zM4.92 10A5.493 5.493 0 0 0 4 13H1c0-.26.164-1.03.76-1.724.545-.636 1.492-1.256 3.16-1.275zM1.5 5.5a3 3 0 1 1 6 0 3 3 0 0 1-6 0zm3-2a2 2 0 1 0 0 4 2 2 0 0 0 0-4z"/>
|
3 |
</svg>
|
resources/images/bootstrap/person-badge.svg
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<svg
|
2 |
-
<path
|
3 |
-
<path
|
4 |
</svg>
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-person-badge" viewBox="0 0 16 16">
|
2 |
+
<path d="M6.5 2a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1h-3zM11 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/>
|
3 |
+
<path d="M4.5 0A2.5 2.5 0 0 0 2 2.5V14a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V2.5A2.5 2.5 0 0 0 11.5 0h-7zM3 2.5A1.5 1.5 0 0 1 4.5 1h7A1.5 1.5 0 0 1 13 2.5v10.795a4.2 4.2 0 0 0-.776-.492C11.392 12.387 10.063 12 8 12s-3.392.387-4.224.803a4.2 4.2 0 0 0-.776.492V2.5z"/>
|
4 |
</svg>
|
resources/images/bootstrap/person-lines-fill.svg
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
<svg
|
2 |
-
<path
|
3 |
</svg>
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-person-lines-fill" viewBox="0 0 16 16">
|
2 |
+
<path d="M6 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-5 6s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H1zM11 3.5a.5.5 0 0 1 .5-.5h4a.5.5 0 0 1 0 1h-4a.5.5 0 0 1-.5-.5zm.5 2.5a.5.5 0 0 0 0 1h4a.5.5 0 0 0 0-1h-4zm2 3a.5.5 0 0 0 0 1h2a.5.5 0 0 0 0-1h-2zm0 3a.5.5 0 0 0 0 1h2a.5.5 0 0 0 0-1h-2z"/>
|
3 |
</svg>
|
resources/images/bootstrap/plug-fill.svg
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-plug-fill" viewBox="0 0 16 16">
|
2 |
+
<path d="M6 0a.5.5 0 0 1 .5.5V3h3V.5a.5.5 0 0 1 1 0V3h1a.5.5 0 0 1 .5.5v3A3.5 3.5 0 0 1 8.5 10c-.002.434-.01.845-.04 1.22-.041.514-.126 1.003-.317 1.424a2.083 2.083 0 0 1-.97 1.028C6.725 13.9 6.169 14 5.5 14c-.998 0-1.61.33-1.974.718A1.922 1.922 0 0 0 3 16H2c0-.616.232-1.367.797-1.968C3.374 13.42 4.261 13 5.5 13c.581 0 .962-.088 1.218-.219.241-.123.4-.3.514-.55.121-.266.193-.621.23-1.09.027-.34.035-.718.037-1.141A3.5 3.5 0 0 1 4 6.5v-3a.5.5 0 0 1 .5-.5h1V.5A.5.5 0 0 1 6 0z"/>
|
3 |
+
</svg>
|
resources/images/bootstrap/puzzle-fill.svg
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-puzzle-fill" viewBox="0 0 16 16">
|
2 |
+
<path d="M3.112 3.645A1.5 1.5 0 0 1 4.605 2H7a.5.5 0 0 1 .5.5v.382c0 .696-.497 1.182-.872 1.469a.459.459 0 0 0-.115.118.113.113 0 0 0-.012.025L6.5 4.5v.003l.003.01c.004.01.014.028.036.053a.86.86 0 0 0 .27.194C7.09 4.9 7.51 5 8 5c.492 0 .912-.1 1.19-.24a.86.86 0 0 0 .271-.194.213.213 0 0 0 .036-.054l.003-.01v-.008a.112.112 0 0 0-.012-.025.459.459 0 0 0-.115-.118c-.375-.287-.872-.773-.872-1.469V2.5A.5.5 0 0 1 9 2h2.395a1.5 1.5 0 0 1 1.493 1.645L12.645 6.5h.237c.195 0 .42-.147.675-.48.21-.274.528-.52.943-.52.568 0 .947.447 1.154.862C15.877 6.807 16 7.387 16 8s-.123 1.193-.346 1.638c-.207.415-.586.862-1.154.862-.415 0-.733-.246-.943-.52-.255-.333-.48-.48-.675-.48h-.237l.243 2.855A1.5 1.5 0 0 1 11.395 14H9a.5.5 0 0 1-.5-.5v-.382c0-.696.497-1.182.872-1.469a.459.459 0 0 0 .115-.118.113.113 0 0 0 .012-.025L9.5 11.5v-.003l-.003-.01a.214.214 0 0 0-.036-.053.859.859 0 0 0-.27-.194C8.91 11.1 8.49 11 8 11c-.491 0-.912.1-1.19.24a.859.859 0 0 0-.271.194.214.214 0 0 0-.036.054l-.003.01v.002l.001.006a.113.113 0 0 0 .012.025c.016.027.05.068.115.118.375.287.872.773.872 1.469v.382a.5.5 0 0 1-.5.5H4.605a1.5 1.5 0 0 1-1.493-1.645L3.356 9.5h-.238c-.195 0-.42.147-.675.48-.21.274-.528.52-.943.52-.568 0-.947-.447-1.154-.862C.123 9.193 0 8.613 0 8s.123-1.193.346-1.638C.553 5.947.932 5.5 1.5 5.5c.415 0 .733.246.943.52.255.333.48.48.675.48h.238l-.244-2.855z"/>
|
3 |
+
</svg>
|
resources/images/bootstrap/search.svg
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-search" viewBox="0 0 16 16">
|
2 |
+
<path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z"/>
|
3 |
+
</svg>
|
resources/images/bootstrap/shield-shaded.svg
CHANGED
@@ -1,4 +1,3 @@
|
|
1 |
-
<svg
|
2 |
-
<path fill-rule="evenodd" d="
|
3 |
-
<path d="M8 2.25c.909 0 3.188.685 4.254 1.022a.94.94 0 0 1 .656.773c.814 6.424-4.13 9.452-4.91 9.452V2.25z"/>
|
4 |
</svg>
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-shield-shaded" viewBox="0 0 16 16">
|
2 |
+
<path fill-rule="evenodd" d="M8 14.933a.615.615 0 0 0 .1-.025c.076-.023.174-.061.294-.118.24-.113.547-.29.893-.533a10.726 10.726 0 0 0 2.287-2.233c1.527-1.997 2.807-5.031 2.253-9.188a.48.48 0 0 0-.328-.39c-.651-.213-1.75-.56-2.837-.855C9.552 1.29 8.531 1.067 8 1.067v13.866zM5.072.56C6.157.265 7.31 0 8 0s1.843.265 2.928.56c1.11.3 2.229.655 2.887.87a1.54 1.54 0 0 1 1.044 1.262c.596 4.477-.787 7.795-2.465 9.99a11.775 11.775 0 0 1-2.517 2.453 7.159 7.159 0 0 1-1.048.625c-.28.132-.581.24-.829.24s-.548-.108-.829-.24a7.158 7.158 0 0 1-1.048-.625 11.777 11.777 0 0 1-2.517-2.453C1.928 10.487.545 7.169 1.141 2.692A1.54 1.54 0 0 1 2.185 1.43 62.456 62.456 0 0 1 5.072.56z"/>
|
|
|
3 |
</svg>
|
resources/images/bootstrap/sliders.svg
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
<svg
|
2 |
<path fill-rule="evenodd" d="M11.5 2a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zM9.05 3a2.5 2.5 0 0 1 4.9 0H16v1h-2.05a2.5 2.5 0 0 1-4.9 0H0V3h9.05zM4.5 7a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zM2.05 8a2.5 2.5 0 0 1 4.9 0H16v1H6.95a2.5 2.5 0 0 1-4.9 0H0V8h2.05zm9.45 4a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zm-2.45 1a2.5 2.5 0 0 1 4.9 0H16v1h-2.05a2.5 2.5 0 0 1-4.9 0H0v-1h9.05z"/>
|
3 |
</svg>
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-sliders" viewBox="0 0 16 16">
|
2 |
<path fill-rule="evenodd" d="M11.5 2a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zM9.05 3a2.5 2.5 0 0 1 4.9 0H16v1h-2.05a2.5 2.5 0 0 1-4.9 0H0V3h9.05zM4.5 7a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zM2.05 8a2.5 2.5 0 0 1 4.9 0H16v1H6.95a2.5 2.5 0 0 1-4.9 0H0V8h2.05zm9.45 4a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zm-2.45 1a2.5 2.5 0 0 1 4.9 0H16v1h-2.05a2.5 2.5 0 0 1-4.9 0H0v-1h9.05z"/>
|
3 |
</svg>
|
resources/images/bootstrap/speedometer.svg
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-speedometer" viewBox="0 0 16 16">
|
2 |
+
<path d="M8 2a.5.5 0 0 1 .5.5V4a.5.5 0 0 1-1 0V2.5A.5.5 0 0 1 8 2zM3.732 3.732a.5.5 0 0 1 .707 0l.915.914a.5.5 0 1 1-.708.708l-.914-.915a.5.5 0 0 1 0-.707zM2 8a.5.5 0 0 1 .5-.5h1.586a.5.5 0 0 1 0 1H2.5A.5.5 0 0 1 2 8zm9.5 0a.5.5 0 0 1 .5-.5h1.5a.5.5 0 0 1 0 1H12a.5.5 0 0 1-.5-.5zm.754-4.246a.389.389 0 0 0-.527-.02L7.547 7.31A.91.91 0 1 0 8.85 8.569l3.434-4.297a.389.389 0 0 0-.029-.518z"/>
|
3 |
+
<path fill-rule="evenodd" d="M6.664 15.889A8 8 0 1 1 9.336.11a8 8 0 0 1-2.672 15.78zm-4.665-4.283A11.945 11.945 0 0 1 8 10c2.186 0 4.236.585 6.001 1.606a7 7 0 1 0-12.002 0z"/>
|
4 |
+
</svg>
|
resources/images/bootstrap/stickies.svg
CHANGED
@@ -1,5 +1,4 @@
|
|
1 |
-
<svg
|
2 |
-
<path
|
3 |
-
<path
|
4 |
-
<path fill-rule="evenodd" d="M10.5 10a.5.5 0 0 0-.5.5v5H9v-5A1.5 1.5 0 0 1 10.5 9h5v1h-5z"/>
|
5 |
</svg>
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-stickies" viewBox="0 0 16 16">
|
2 |
+
<path d="M1.5 0A1.5 1.5 0 0 0 0 1.5V13a1 1 0 0 0 1 1V1.5a.5.5 0 0 1 .5-.5H14a1 1 0 0 0-1-1H1.5z"/>
|
3 |
+
<path d="M3.5 2A1.5 1.5 0 0 0 2 3.5v11A1.5 1.5 0 0 0 3.5 16h6.086a1.5 1.5 0 0 0 1.06-.44l4.915-4.914A1.5 1.5 0 0 0 16 9.586V3.5A1.5 1.5 0 0 0 14.5 2h-11zM3 3.5a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 .5.5V9h-4.5A1.5 1.5 0 0 0 9 10.5V15H3.5a.5.5 0 0 1-.5-.5v-11zm7 11.293V10.5a.5.5 0 0 1 .5-.5h4.293L10 14.793z"/>
|
|
|
4 |
</svg>
|
resources/images/bootstrap/sticky.svg
CHANGED
@@ -1,4 +1,3 @@
|
|
1 |
-
<svg
|
2 |
-
<path
|
3 |
-
<path fill-rule="evenodd" d="M9.5 9a.5.5 0 0 0-.5.5v5H8v-5A1.5 1.5 0 0 1 9.5 8h5v1h-5z"/>
|
4 |
</svg>
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-sticky" viewBox="0 0 16 16">
|
2 |
+
<path d="M2.5 1A1.5 1.5 0 0 0 1 2.5v11A1.5 1.5 0 0 0 2.5 15h6.086a1.5 1.5 0 0 0 1.06-.44l4.915-4.914A1.5 1.5 0 0 0 15 8.586V2.5A1.5 1.5 0 0 0 13.5 1h-11zM2 2.5a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 .5.5V8H9.5A1.5 1.5 0 0 0 8 9.5V14H2.5a.5.5 0 0 1-.5-.5v-11zm7 11.293V9.5a.5.5 0 0 1 .5-.5h4.293L9 13.793z"/>
|
|
|
3 |
</svg>
|
resources/images/bootstrap/stoplights.svg
CHANGED
@@ -1,5 +1,4 @@
|
|
1 |
-
<svg
|
2 |
-
<path d="
|
3 |
-
<path
|
4 |
-
<path d="M14 2h-2v2c1.2-.4 1.833-1.5 2-2zM2 2h2v2c-1.2-.4-1.833-1.5-2-2zm12 4h-2v2c1.2-.4 1.833-1.5 2-2zM2 6h2v2c-1.2-.4-1.833-1.5-2-2zm12 4h-2v2c1.2-.4 1.833-1.5 2-2zM2 10h2v2c-1.2-.4-1.833-1.5-2-2z"/>
|
5 |
</svg>
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-stoplights" viewBox="0 0 16 16">
|
2 |
+
<path d="M8 5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm0 4a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm1.5 2.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"/>
|
3 |
+
<path d="M4 2a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2h2c-.167.5-.8 1.6-2 2v2h2c-.167.5-.8 1.6-2 2v2h2c-.167.5-.8 1.6-2 2v1a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-1c-1.2-.4-1.833-1.5-2-2h2V8c-1.2-.4-1.833-1.5-2-2h2V4c-1.2-.4-1.833-1.5-2-2h2zm2-1a1 1 0 0 0-1 1v11a1 1 0 0 0 1 1h4a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H6z"/>
|
|
|
4 |
</svg>
|
resources/images/bootstrap/tools.svg
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-tools" viewBox="0 0 16 16">
|
2 |
+
<path d="M1 0 0 1l2.2 3.081a1 1 0 0 0 .815.419h.07a1 1 0 0 1 .708.293l2.675 2.675-2.617 2.654A3.003 3.003 0 0 0 0 13a3 3 0 1 0 5.878-.851l2.654-2.617.968.968-.305.914a1 1 0 0 0 .242 1.023l3.356 3.356a1 1 0 0 0 1.414 0l1.586-1.586a1 1 0 0 0 0-1.414l-3.356-3.356a1 1 0 0 0-1.023-.242L10.5 9.5l-.96-.96 2.68-2.643A3.005 3.005 0 0 0 16 3c0-.269-.035-.53-.102-.777l-2.14 2.141L12 4l-.364-1.757L13.777.102a3 3 0 0 0-3.675 3.68L7.462 6.46 4.793 3.793a1 1 0 0 1-.293-.707v-.071a1 1 0 0 0-.419-.814L1 0zm9.646 10.646a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708zM3 11l.471.242.529.026.287.445.445.287.026.529L5 13l-.242.471-.026.529-.445.287-.287.445-.529.026L3 15l-.471-.242L2 14.732l-.287-.445L1.268 14l-.026-.529L1 13l.242-.471.026-.529.445-.287.287-.445.529-.026L3 11z"/>
|
3 |
+
</svg>
|
resources/js/global-plugin.js
CHANGED
@@ -11,33 +11,6 @@ var iCWP_WPSF_JSErrorTrack = new function () {
|
|
11 |
}();
|
12 |
iCWP_WPSF_JSErrorTrack.initialise();
|
13 |
|
14 |
-
var iCWP_WPSF_SecurityAdmin = new function () {
|
15 |
-
|
16 |
-
this.initialise = function () {
|
17 |
-
jQuery( document ).ready( function () {
|
18 |
-
jQuery( document ).on( "submit", '#SecurityAdminForm',
|
19 |
-
function ( event ) {
|
20 |
-
event.preventDefault();
|
21 |
-
iCWP_WPSF_StandardAjax.send_ajax_req( jQuery( event.target ).serialize() );
|
22 |
-
return false;
|
23 |
-
}
|
24 |
-
);
|
25 |
-
|
26 |
-
if ( typeof icwp_wpsf_vars_secadmin !== 'undefined' ) {
|
27 |
-
jQuery( document ).on( "click", '#SecAdminRemoveConfirmEmail',
|
28 |
-
function ( event ) {
|
29 |
-
event.preventDefault();
|
30 |
-
if ( confirm( icwp_wpsf_vars_secadmin.strings.are_you_sure ) ) {
|
31 |
-
iCWP_WPSF_StandardAjax.send_ajax_req( icwp_wpsf_vars_secadmin.ajax.req_email_remove );
|
32 |
-
}
|
33 |
-
return false;
|
34 |
-
}
|
35 |
-
);
|
36 |
-
}
|
37 |
-
} );
|
38 |
-
};
|
39 |
-
}();
|
40 |
-
|
41 |
var iCWP_WPSF_ParseAjaxResponse = new function () {
|
42 |
this.parseIt = function ( raw ) {
|
43 |
var parsed = {};
|
@@ -68,8 +41,12 @@ var iCWP_WPSF_ParseAjaxResponse = new function () {
|
|
68 |
}();
|
69 |
|
70 |
var iCWP_WPSF_StandardAjax = new function () {
|
71 |
-
|
72 |
-
|
|
|
|
|
|
|
|
|
73 |
|
74 |
reqData.apto_wrap_response = 1;
|
75 |
|
@@ -81,14 +58,27 @@ var iCWP_WPSF_StandardAjax = new function () {
|
|
81 |
success: function ( raw ) {
|
82 |
var resp = iCWP_WPSF_ParseAjaxResponse.parseIt( raw );
|
83 |
|
84 |
-
if ( typeof
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
}
|
90 |
|
91 |
-
if (
|
|
|
|
|
|
|
92 |
setTimeout( function () {
|
93 |
location.reload();
|
94 |
}, 2000 );
|
@@ -99,7 +89,7 @@ var iCWP_WPSF_StandardAjax = new function () {
|
|
99 |
}
|
100 |
} ).fail( function () {
|
101 |
alert( 'Something went wrong with the request - it was either blocked or there was an error.' );
|
102 |
-
} )
|
103 |
};
|
104 |
}();
|
105 |
|
@@ -275,54 +265,6 @@ if ( typeof icwp_wpsf_vars_lg !== 'undefined' ) {
|
|
275 |
iCWP_WPSF_LoginGuard_BackupCodes.initialise();
|
276 |
}
|
277 |
|
278 |
-
/** TODO: THIS AJAX IS NOT COMPLETE **/
|
279 |
-
var iCWP_WPSF_Autoupdates = new function () {
|
280 |
-
|
281 |
-
var bRequestCurrentlyRunning = false;
|
282 |
-
|
283 |
-
var togglePluginUpdate = function ( event ) {
|
284 |
-
if ( bRequestCurrentlyRunning ) {
|
285 |
-
return false;
|
286 |
-
}
|
287 |
-
|
288 |
-
$oInput = jQuery( this );
|
289 |
-
|
290 |
-
if ( $oInput.data( 'disabled' ) !== 'no' ) {
|
291 |
-
iCWP_WPSF_Growl.showMessage( $oInput.data( 'disabled' ), false );
|
292 |
-
return false;
|
293 |
-
}
|
294 |
-
|
295 |
-
return sendTogglePluginAutoupdate( $oInput.data( 'pluginfile' ), $oInput.data( 'nonce' ) );
|
296 |
-
};
|
297 |
-
|
298 |
-
var sendTogglePluginAutoupdate = function ( sPluginFile ) {
|
299 |
-
bRequestCurrentlyRunning = true;
|
300 |
-
|
301 |
-
var requestData = {
|
302 |
-
'action': 'icwp_wpsf_TogglePluginAutoupdate',
|
303 |
-
'pluginfile': sPluginFile
|
304 |
-
};
|
305 |
-
|
306 |
-
jQuery.post( ajaxurl, requestData,
|
307 |
-
function ( oResponse ) {
|
308 |
-
iCWP_WPSF_Growl.showMessage( oResponse.data.message, oResponse.success );
|
309 |
-
}
|
310 |
-
).always( function () {
|
311 |
-
bRequestCurrentlyRunning = false;
|
312 |
-
}
|
313 |
-
);
|
314 |
-
|
315 |
-
return true;
|
316 |
-
};
|
317 |
-
|
318 |
-
this.initialise = function () {
|
319 |
-
jQuery( document ).ready( function () {
|
320 |
-
jQuery( document ).on( "click", "input.icwp-autoupdate-plugin", togglePluginUpdate );
|
321 |
-
} );
|
322 |
-
};
|
323 |
-
|
324 |
-
}();
|
325 |
-
|
326 |
var iCWP_WPSF_Growl = new function () {
|
327 |
|
328 |
this.showMessage = function ( sMessage, bSuccess ) {
|
@@ -368,99 +310,14 @@ var iCWP_WPSF_BodyOverlay = new function () {
|
|
368 |
};
|
369 |
|
370 |
this.initialise = function () {
|
371 |
-
jQuery(
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
.appendTo( 'body' );
|
376 |
-
} );
|
377 |
};
|
378 |
|
379 |
}();
|
380 |
|
381 |
-
|
382 |
-
iCWP_WPSF_BodyOverlay.initialise();
|
383 |
-
|
384 |
-
|
385 |
-
if ( false && typeof icwp_wpsf_vars_plugin !== 'undefined' ) {
|
386 |
-
|
387 |
-
var iCWP_WPSF_Plugin_Deactivate_Survey = new function () {
|
388 |
-
|
389 |
-
this.initialise = function () {
|
390 |
-
jQuery( document ).ready( function () {
|
391 |
-
|
392 |
-
if ( !iCWP_WPSF_JSErrorTrack.hasError() ) {
|
393 |
-
jQuery( document ).on( "click",
|
394 |
-
'[data-plugin="' + icwp_wpsf_vars_plugin.file + '"] span.deactivate a',
|
395 |
-
promptSurvey
|
396 |
-
);
|
397 |
-
}
|
398 |
-
|
399 |
-
var oShareSettings = {
|
400 |
-
title: 'Care To Share?',
|
401 |
-
dialogClass: 'wp-dialog',
|
402 |
-
autoOpen: false,
|
403 |
-
draggable: false,
|
404 |
-
width: 'auto',
|
405 |
-
modal: true,
|
406 |
-
resizable: false,
|
407 |
-
closeOnEscape: true,
|
408 |
-
position: {
|
409 |
-
my: "center",
|
410 |
-
at: "center",
|
411 |
-
of: window
|
412 |
-
},
|
413 |
-
open: function () {
|
414 |
-
// close dialog by clicking the overlay behind it
|
415 |
-
jQuery( '.ui-widget-overlay' ).bind( 'click', function () {
|
416 |
-
jQuery( this ).dialog( 'close' );
|
417 |
-
} )
|
418 |
-
},
|
419 |
-
create: function () {
|
420 |
-
// style fix for WordPress admin
|
421 |
-
jQuery( '.ui-dialog-titlebar-close' ).addClass( 'ui-button' );
|
422 |
-
},
|
423 |
-
close: function () {
|
424 |
-
window.location.href = icwp_wpsf_vars_plugin.hrefs.deactivate;
|
425 |
-
}
|
426 |
-
};
|
427 |
-
|
428 |
-
var $oSurveyDialog = jQuery( '#icwpWpsfSurvey' );
|
429 |
-
oShareSettings[ 'buttons' ] = {
|
430 |
-
"Close (I don't want to help)": function () {
|
431 |
-
jQuery( this ).dialog( "close" );
|
432 |
-
},
|
433 |
-
"Yes (Send my feedback)": function () {
|
434 |
-
send_survey_deactivate();
|
435 |
-
jQuery( this ).dialog( "close" );
|
436 |
-
}
|
437 |
-
};
|
438 |
-
$oSurveyDialog.dialog( oShareSettings );
|
439 |
-
} );
|
440 |
-
};
|
441 |
-
|
442 |
-
var promptSurvey = function ( event ) {
|
443 |
-
event.preventDefault();
|
444 |
-
iCWP_WPSF_BodyOverlay.show();
|
445 |
-
jQuery( '#icwpWpsfSurvey' ).dialog( 'open' );
|
446 |
-
return false;
|
447 |
-
};
|
448 |
-
|
449 |
-
var send_survey_deactivate = function () {
|
450 |
-
|
451 |
-
var $aData = icwp_wpsf_vars_plugin.ajax.send_deactivate_survey;
|
452 |
-
jQuery.each( jQuery( '#icwpWpsfSurveyForm' ).serializeArray(),
|
453 |
-
function ( _, kv ) {
|
454 |
-
$aData[ kv.name ] = kv.value;
|
455 |
-
}
|
456 |
-
);
|
457 |
-
|
458 |
-
jQuery.post( ajaxurl, $aData );
|
459 |
-
setTimeout( function () {
|
460 |
-
}, 2000 ); // give the request time to complete
|
461 |
-
|
462 |
-
return false;
|
463 |
-
};
|
464 |
-
}();
|
465 |
-
iCWP_WPSF_Plugin_Deactivate_Survey.initialise();
|
466 |
-
}
|
11 |
}();
|
12 |
iCWP_WPSF_JSErrorTrack.initialise();
|
13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
var iCWP_WPSF_ParseAjaxResponse = new function () {
|
15 |
this.parseIt = function ( raw ) {
|
16 |
var parsed = {};
|
41 |
}();
|
42 |
|
43 |
var iCWP_WPSF_StandardAjax = new function () {
|
44 |
+
|
45 |
+
this.send_ajax_req = function ( reqData, quiet = false, triggerEvent = '' ) {
|
46 |
+
|
47 |
+
if ( !quiet ) {
|
48 |
+
iCWP_WPSF_BodyOverlay.show();
|
49 |
+
}
|
50 |
|
51 |
reqData.apto_wrap_response = 1;
|
52 |
|
58 |
success: function ( raw ) {
|
59 |
var resp = iCWP_WPSF_ParseAjaxResponse.parseIt( raw );
|
60 |
|
61 |
+
if ( typeof resp.data.show_toast === typeof undefined || resp.data.show_toast ) {
|
62 |
+
|
63 |
+
if ( typeof resp.data.message === typeof undefined ) {
|
64 |
+
resp.data.message = resp.success ?
|
65 |
+
'The request succeeded' : 'The request failed';
|
66 |
+
}
|
67 |
+
|
68 |
+
if ( !quiet ) {
|
69 |
+
if ( typeof iCWP_WPSF_Toaster !== 'undefined' ) {
|
70 |
+
iCWP_WPSF_Toaster.showMessage( resp.data.message, resp.success );
|
71 |
+
}
|
72 |
+
else {
|
73 |
+
iCWP_WPSF_Growl.showMessage( resp.data.message, resp.success );
|
74 |
+
}
|
75 |
+
}
|
76 |
}
|
77 |
|
78 |
+
if ( triggerEvent.length > 0 ) {
|
79 |
+
jQuery( document ).trigger( 'shield-'+triggerEvent, resp );
|
80 |
+
}
|
81 |
+
else if ( resp.data.page_reload ) {
|
82 |
setTimeout( function () {
|
83 |
location.reload();
|
84 |
}, 2000 );
|
89 |
}
|
90 |
} ).fail( function () {
|
91 |
alert( 'Something went wrong with the request - it was either blocked or there was an error.' );
|
92 |
+
} );
|
93 |
};
|
94 |
}();
|
95 |
|
265 |
iCWP_WPSF_LoginGuard_BackupCodes.initialise();
|
266 |
}
|
267 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
268 |
var iCWP_WPSF_Growl = new function () {
|
269 |
|
270 |
this.showMessage = function ( sMessage, bSuccess ) {
|
310 |
};
|
311 |
|
312 |
this.initialise = function () {
|
313 |
+
jQuery( '<div />' )
|
314 |
+
.attr( 'id', 'icwp-fade-wrapper' )
|
315 |
+
.html( '<div class="icwp-waiting"><div style="width: 4rem; height: 4rem;" class="spinner-grow text-success"></div></div>' )
|
316 |
+
.appendTo( 'body' );
|
|
|
|
|
317 |
};
|
318 |
|
319 |
}();
|
320 |
|
321 |
+
jQuery( document ).ready( function () {
|
322 |
+
iCWP_WPSF_BodyOverlay.initialise();
|
323 |
+
} );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
resources/js/icwp-options.js
DELETED
@@ -1,70 +0,0 @@
|
|
1 |
-
jQuery( document ).ready(
|
2 |
-
function () {
|
3 |
-
return;
|
4 |
-
|
5 |
-
var $oIcwpOptions = jQuery( 'div#icwp-options-form' );
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Initialise the default states of sections and inputs.
|
9 |
-
*/
|
10 |
-
jQuery( 'input:checked' ).parents( 'div.option_section' ).addClass( 'active' );
|
11 |
-
|
12 |
-
/**
|
13 |
-
* When the user clicks on a "section", this handler will adjust the radio/checkbox
|
14 |
-
* according to the current value. If the user clicked "section" but actually clicked
|
15 |
-
* on an input field within the section, this normal handler will get called, and the
|
16 |
-
* "section" handler will exit immediately.
|
17 |
-
*/
|
18 |
-
jQuery( '.option_section' ).on( 'click', onSectionClick );
|
19 |
-
|
20 |
-
/**
|
21 |
-
* When a checkbox, or associated label is clicked, the parent "section" style is updated.
|
22 |
-
*/
|
23 |
-
jQuery( '.option_section input[type=checkbox],.option_section label' ).on( 'click',
|
24 |
-
function ( inoEvent ) {
|
25 |
-
var $this = jQuery( this );
|
26 |
-
var oParent = $this.parents( 'div.option_section' );
|
27 |
-
|
28 |
-
var oInput = jQuery( 'input[type=checkbox]', oParent );
|
29 |
-
if ( oInput.is( ':checked' ) ) {
|
30 |
-
oParent.addClass( 'active' );
|
31 |
-
}
|
32 |
-
else {
|
33 |
-
oParent.removeClass( 'active' );
|
34 |
-
}
|
35 |
-
}
|
36 |
-
);
|
37 |
-
|
38 |
-
jQuery( 'select[name=option]', $oIcwpOptions ).trigger( 'change' );
|
39 |
-
}
|
40 |
-
);
|
41 |
-
|
42 |
-
function onSectionClick( inoEvent ) {
|
43 |
-
/**
|
44 |
-
* Don't manipulate the checkboxes/radios if the actual input or linked-label was
|
45 |
-
* the target of the click.
|
46 |
-
*/
|
47 |
-
var oDiv = jQuery( inoEvent.currentTarget );
|
48 |
-
if ( inoEvent.target.tagName && inoEvent.target.tagName.match( /input|label/i ) ) {
|
49 |
-
return true;
|
50 |
-
}
|
51 |
-
|
52 |
-
var oEl = oDiv.find( 'input[type=checkbox]' );
|
53 |
-
if ( oEl.length > 0 ) {
|
54 |
-
if ( oEl.is( ':checked' ) ) {
|
55 |
-
oEl.removeAttr( 'checked' );
|
56 |
-
oDiv.removeClass( 'active' );
|
57 |
-
}
|
58 |
-
else {
|
59 |
-
oEl.attr( 'checked', 'checked' );
|
60 |
-
oDiv.addClass( 'active' );
|
61 |
-
}
|
62 |
-
}
|
63 |
-
|
64 |
-
oEl = oDiv.find( 'input[type=radio]' );
|
65 |
-
if ( oEl.length > 0 && !oEl.is( ':checked' ) ) {
|
66 |
-
oEl.attr( 'checked', 'checked' );
|
67 |
-
oDiv.addClass( 'active' ).siblings().removeClass( 'active' );
|
68 |
-
}
|
69 |
-
|
70 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
resources/js/plugin.js
CHANGED
@@ -102,19 +102,19 @@ iCWP_WPSF_Toaster.initialise();
|
|
102 |
var iCWP_WPSF_OptionsFormSubmit = new function () {
|
103 |
|
104 |
let bRequestCurrentlyRunning = false;
|
105 |
-
var
|
106 |
|
107 |
-
this.submit = function (
|
108 |
-
let $oDiv = createDynDiv(
|
109 |
-
$oDiv.fadeIn().html(
|
110 |
setTimeout( function () {
|
111 |
$oDiv.fadeOut( 5000 );
|
112 |
$oDiv.remove();
|
113 |
}, 4000 );
|
114 |
};
|
115 |
|
116 |
-
this.updateAjaxReqParams = function (
|
117 |
-
|
118 |
};
|
119 |
|
120 |
/**
|
@@ -122,15 +122,21 @@ var iCWP_WPSF_OptionsFormSubmit = new function () {
|
|
122 |
* This works around mod_security rules that even unpack b64 encoded params and look
|
123 |
* for patterns within them.
|
124 |
*/
|
125 |
-
var sendForm = function ( $
|
126 |
|
127 |
-
let formData = $
|
128 |
if ( useCompression ) {
|
129 |
formData = LZString.compress( formData );
|
130 |
}
|
131 |
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
let reqs = jQuery.extend(
|
133 |
-
|
134 |
{
|
135 |
'form_params': Base64.encode( formData ),
|
136 |
'enc_params': useCompression ? 'lz-string' : 'b64',
|
@@ -154,7 +160,7 @@ var iCWP_WPSF_OptionsFormSubmit = new function () {
|
|
154 |
}
|
155 |
else {
|
156 |
iCWP_WPSF_Toaster.showMessage( 'The request was blocked. Retrying an alternative...', false );
|
157 |
-
sendForm( $
|
158 |
}
|
159 |
|
160 |
} ).always( function () {
|
@@ -188,23 +194,23 @@ var iCWP_WPSF_OptionsFormSubmit = new function () {
|
|
188 |
bRequestCurrentlyRunning = true;
|
189 |
event.preventDefault();
|
190 |
|
191 |
-
var $
|
192 |
|
193 |
-
var $
|
194 |
-
jQuery( 'input[type=password]', $
|
195 |
var $oPass = jQuery( this );
|
196 |
-
var $oConfirm = jQuery( '#' + $oPass.attr( 'id' ) + '_confirm', $
|
197 |
if ( typeof $oConfirm.attr( 'id' ) !== 'undefined' ) {
|
198 |
if ( $oPass.val() && !$oConfirm.val() ) {
|
199 |
$oConfirm.addClass( 'is-invalid' );
|
200 |
alert( 'Form not submitted due to error: password confirmation field not provided.' );
|
201 |
-
$
|
202 |
}
|
203 |
}
|
204 |
} );
|
205 |
|
206 |
-
if ( $
|
207 |
-
sendForm( $
|
208 |
}
|
209 |
};
|
210 |
|
@@ -218,72 +224,6 @@ var iCWP_WPSF_OptionsFormSubmit = new function () {
|
|
218 |
iCWP_WPSF_OptionsPages.initialise();
|
219 |
iCWP_WPSF_OptionsFormSubmit.initialise();
|
220 |
|
221 |
-
if ( typeof icwp_wpsf_vars_secadmin !== 'undefined' && icwp_wpsf_vars_secadmin.timeleft > 0 ) {
|
222 |
-
|
223 |
-
var iCWP_WPSF_SecurityAdminCheck = new function () {
|
224 |
-
|
225 |
-
var bCheckInPlace = false;
|
226 |
-
var bWarningShown = false;
|
227 |
-
var nIntervalTimeout = 500 * icwp_wpsf_vars_secadmin.timeleft;
|
228 |
-
|
229 |
-
var checkSecAdmin = function () {
|
230 |
-
|
231 |
-
bCheckInPlace = false;
|
232 |
-
|
233 |
-
jQuery.post( ajaxurl, icwp_wpsf_vars_secadmin.ajax.check,
|
234 |
-
function ( oResponse ) {
|
235 |
-
if ( oResponse.data.success ) {
|
236 |
-
var nLeft = oResponse.data.timeleft;
|
237 |
-
nIntervalTimeout = Math.max( 3, (nLeft / 2) ) * 1000;
|
238 |
-
|
239 |
-
if ( !bWarningShown && nLeft < 20 && nLeft > 8 ) {
|
240 |
-
bWarningShown = true;
|
241 |
-
iCWP_WPSF_Toaster.showMessage( icwp_wpsf_vars_secadmin.strings.nearly, false );
|
242 |
-
// iCWP_WPSF_Growl.showMessage( icwp_wpsf_vars_secadmin.strings.nearly, false );
|
243 |
-
}
|
244 |
-
|
245 |
-
scheduleSecAdminCheck();
|
246 |
-
}
|
247 |
-
else {
|
248 |
-
iCWP_WPSF_BodyOverlay.show();
|
249 |
-
setTimeout( function () {
|
250 |
-
if ( confirm( icwp_wpsf_vars_secadmin.strings.confirm ) ) {
|
251 |
-
window.location.reload();
|
252 |
-
}
|
253 |
-
else {
|
254 |
-
iCWP_WPSF_BodyOverlay.hide();
|
255 |
-
// Do nothing!
|
256 |
-
}
|
257 |
-
}, 1500 );
|
258 |
-
iCWP_WPSF_Toaster.showMessage( icwp_wpsf_vars_secadmin.strings.expired, oResponse.success );
|
259 |
-
// iCWP_WPSF_Growl.showMessage( icwp_wpsf_vars_secadmin.strings.expired, oResponse.success );
|
260 |
-
}
|
261 |
-
|
262 |
-
}
|
263 |
-
).always( function () {
|
264 |
-
}
|
265 |
-
);
|
266 |
-
};
|
267 |
-
|
268 |
-
let scheduleSecAdminCheck = function () {
|
269 |
-
if ( !bCheckInPlace ) {
|
270 |
-
setTimeout( function () {
|
271 |
-
checkSecAdmin();
|
272 |
-
}, nIntervalTimeout );
|
273 |
-
bCheckInPlace = true;
|
274 |
-
}
|
275 |
-
};
|
276 |
-
|
277 |
-
this.initialise = function () {
|
278 |
-
jQuery( document ).ready( function () {
|
279 |
-
scheduleSecAdminCheck();
|
280 |
-
} );
|
281 |
-
};
|
282 |
-
}();
|
283 |
-
|
284 |
-
iCWP_WPSF_SecurityAdminCheck.initialise();
|
285 |
-
}
|
286 |
-
|
287 |
jQuery.fn.icwpWpsfAjaxTable = function ( aOptions ) {
|
288 |
|
289 |
this.reloadTable = function () {
|
@@ -392,14 +332,14 @@ jQuery.fn.icwpWpsfAjaxTable = function ( aOptions ) {
|
|
392 |
if ( typeof icwp_wpsf_vars_plugin !== 'undefined' ) {
|
393 |
|
394 |
jQuery( document ).ready( function () {
|
395 |
-
jQuery( document ).on(
|
396 |
evt.preventDefault();
|
397 |
/** Cache busting **/
|
398 |
let url = jQuery( this ).attr( 'href' ) + '&rand='
|
399 |
+ Math.floor( 10000 * Math.random() );
|
400 |
jQuery.fileDownload( url, {
|
401 |
preparingMessageHtml: icwp_wpsf_vars_plugin.strings.downloading_file,
|
402 |
-
failMessageHtml: icwp_wpsf_vars_plugin.strings.
|
403 |
} );
|
404 |
return false;
|
405 |
} );
|
@@ -408,7 +348,8 @@ if ( typeof icwp_wpsf_vars_plugin !== 'undefined' ) {
|
|
408 |
|
409 |
jQuery( document ).ready( function () {
|
410 |
jQuery( document ).icwpWpsfTours();
|
411 |
-
jQuery(
|
|
|
412 |
width: 'resolve'
|
413 |
-
});
|
414 |
} );
|
102 |
var iCWP_WPSF_OptionsFormSubmit = new function () {
|
103 |
|
104 |
let bRequestCurrentlyRunning = false;
|
105 |
+
var reqParams = icwp_wpsf_vars_base.ajax.mod_options;
|
106 |
|
107 |
+
this.submit = function ( msg, success ) {
|
108 |
+
let $oDiv = createDynDiv( success ? 'success' : 'failed' );
|
109 |
+
$oDiv.fadeIn().html( msg );
|
110 |
setTimeout( function () {
|
111 |
$oDiv.fadeOut( 5000 );
|
112 |
$oDiv.remove();
|
113 |
}, 4000 );
|
114 |
};
|
115 |
|
116 |
+
this.updateAjaxReqParams = function ( params ) {
|
117 |
+
reqParams = params;
|
118 |
};
|
119 |
|
120 |
/**
|
122 |
* This works around mod_security rules that even unpack b64 encoded params and look
|
123 |
* for patterns within them.
|
124 |
*/
|
125 |
+
var sendForm = function ( $form, useCompression = false ) {
|
126 |
|
127 |
+
let formData = $form.serialize();
|
128 |
if ( useCompression ) {
|
129 |
formData = LZString.compress( formData );
|
130 |
}
|
131 |
|
132 |
+
/** Required since using dynamic AJAX loaded page content **/
|
133 |
+
if ( !$form.data( 'mod_slug' ) ) {
|
134 |
+
alert( 'Missing form data' );
|
135 |
+
return false;
|
136 |
+
}
|
137 |
+
reqParams.mod_slug = $form.data( 'mod_slug' );
|
138 |
let reqs = jQuery.extend(
|
139 |
+
reqParams,
|
140 |
{
|
141 |
'form_params': Base64.encode( formData ),
|
142 |
'enc_params': useCompression ? 'lz-string' : 'b64',
|
160 |
}
|
161 |
else {
|
162 |
iCWP_WPSF_Toaster.showMessage( 'The request was blocked. Retrying an alternative...', false );
|
163 |
+
sendForm( $form, true );
|
164 |
}
|
165 |
|
166 |
} ).always( function () {
|
194 |
bRequestCurrentlyRunning = true;
|
195 |
event.preventDefault();
|
196 |
|
197 |
+
var $form = jQuery( this );
|
198 |
|
199 |
+
var $passwordsReady = true;
|
200 |
+
jQuery( 'input[type=password]', $form ).each( function () {
|
201 |
var $oPass = jQuery( this );
|
202 |
+
var $oConfirm = jQuery( '#' + $oPass.attr( 'id' ) + '_confirm', $form );
|
203 |
if ( typeof $oConfirm.attr( 'id' ) !== 'undefined' ) {
|
204 |
if ( $oPass.val() && !$oConfirm.val() ) {
|
205 |
$oConfirm.addClass( 'is-invalid' );
|
206 |
alert( 'Form not submitted due to error: password confirmation field not provided.' );
|
207 |
+
$passwordsReady = false;
|
208 |
}
|
209 |
}
|
210 |
} );
|
211 |
|
212 |
+
if ( $passwordsReady ) {
|
213 |
+
sendForm( $form, false );
|
214 |
}
|
215 |
};
|
216 |
|
224 |
iCWP_WPSF_OptionsPages.initialise();
|
225 |
iCWP_WPSF_OptionsFormSubmit.initialise();
|
226 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
227 |
jQuery.fn.icwpWpsfAjaxTable = function ( aOptions ) {
|
228 |
|
229 |
this.reloadTable = function () {
|
332 |
if ( typeof icwp_wpsf_vars_plugin !== 'undefined' ) {
|
333 |
|
334 |
jQuery( document ).ready( function () {
|
335 |
+
jQuery( document ).on( 'click', 'a.shield_file_download, li.shield_file_download > a', function ( evt ) {
|
336 |
evt.preventDefault();
|
337 |
/** Cache busting **/
|
338 |
let url = jQuery( this ).attr( 'href' ) + '&rand='
|
339 |
+ Math.floor( 10000 * Math.random() );
|
340 |
jQuery.fileDownload( url, {
|
341 |
preparingMessageHtml: icwp_wpsf_vars_plugin.strings.downloading_file,
|
342 |
+
failMessageHtml: icwp_wpsf_vars_plugin.strings.downloading_file_problem
|
343 |
} );
|
344 |
return false;
|
345 |
} );
|
348 |
|
349 |
jQuery( document ).ready( function () {
|
350 |
jQuery( document ).icwpWpsfTours();
|
351 |
+
jQuery( document ).icwpWpsfPluginNavigation();
|
352 |
+
jQuery( '.select2picker' ).select2( {
|
353 |
width: 'resolve'
|
354 |
+
} );
|
355 |
} );
|
resources/js/shield/mainwp-extension.js
CHANGED
@@ -112,20 +112,6 @@
|
|
112 |
}
|
113 |
);
|
114 |
|
115 |
-
plugin.$element.on(
|
116 |
-
'click' + '.' + plugin._name,
|
117 |
-
'button.action.href-download',
|
118 |
-
function ( evt ) {
|
119 |
-
evt.preventDefault();
|
120 |
-
var $oButt = $( this );
|
121 |
-
var sHref = $oButt.data( 'href-download' );
|
122 |
-
if ( sHref !== undefined ) {
|
123 |
-
plugin.options[ 'working_href_download' ] = sHref;
|
124 |
-
plugin.hrefDownload.call( plugin );
|
125 |
-
}
|
126 |
-
}
|
127 |
-
);
|
128 |
-
|
129 |
},
|
130 |
unbindEvents: function () {
|
131 |
/*
|
112 |
}
|
113 |
);
|
114 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
},
|
116 |
unbindEvents: function () {
|
117 |
/*
|
resources/js/shield/navigation.js
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery.fn.icwpWpsfPluginNavigation = function ( options ) {
|
2 |
+
|
3 |
+
let currentMenuClickTarget;
|
4 |
+
|
5 |
+
var handleDynamicLoad = function ( evt, response ) {
|
6 |
+
document.querySelector( '#apto-PageMainBody' ).innerHTML = response.data.html;
|
7 |
+
|
8 |
+
window.history.replaceState(
|
9 |
+
{},
|
10 |
+
response.data.page_title,
|
11 |
+
response.data.page_url
|
12 |
+
);
|
13 |
+
|
14 |
+
document.getElementById( 'PageTitle' ).innerHTML = response.data.page_title;
|
15 |
+
|
16 |
+
let activeLinks = document.querySelectorAll( '#NavSideBar a.nav-link.active' );
|
17 |
+
for ( var i = 0; i < activeLinks.length; i++ ) {
|
18 |
+
activeLinks[ i ].classList.remove( 'active' );
|
19 |
+
}
|
20 |
+
currentMenuClickTarget.classList.add( 'active' );
|
21 |
+
|
22 |
+
let parentNav = currentMenuClickTarget.closest( 'ul' ).closest( 'li.nav-item' );
|
23 |
+
if ( parentNav !== null ) {
|
24 |
+
parentNav.querySelector( 'a.nav-link' ).classList.add( 'active' );
|
25 |
+
}
|
26 |
+
|
27 |
+
iCWP_WPSF_BodyOverlay.hide();
|
28 |
+
};
|
29 |
+
|
30 |
+
var renderDynamicPageLoad = function ( params ) {
|
31 |
+
sendReq( params );
|
32 |
+
};
|
33 |
+
|
34 |
+
var sendReq = function ( params ) {
|
35 |
+
document.querySelector( '#apto-PageMainBody' ).innerHTML = 'Loading ...';
|
36 |
+
shield_vars_navigation.ajax.dynamic_load.load_params = params;
|
37 |
+
iCWP_WPSF_StandardAjax.send_ajax_req(
|
38 |
+
shield_vars_navigation.ajax.dynamic_load, false, 'dynamic_load'
|
39 |
+
);
|
40 |
+
};
|
41 |
+
|
42 |
+
var initialise = function () {
|
43 |
+
|
44 |
+
jQuery( document ).ready( function () {
|
45 |
+
|
46 |
+
jQuery( document ).on( 'click', 'li.dynamic_body_load > a', function ( evt ) {
|
47 |
+
evt.preventDefault();
|
48 |
+
currentMenuClickTarget = evt.currentTarget;
|
49 |
+
renderDynamicPageLoad( jQuery( currentMenuClickTarget ).data() );
|
50 |
+
return false;
|
51 |
+
} );
|
52 |
+
|
53 |
+
jQuery( document ).on( 'shield-dynamic_load', handleDynamicLoad );
|
54 |
+
} );
|
55 |
+
};
|
56 |
+
|
57 |
+
var opts = jQuery.extend( {}, options );
|
58 |
+
initialise();
|
59 |
+
|
60 |
+
return this;
|
61 |
+
};
|
resources/js/shield/options.js
ADDED
@@ -0,0 +1,304 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery.fn.icwpWpsfTableWithFilter = function ( aOptions ) {
|
2 |
+
|
3 |
+
var resetFilters = function ( evt ) {
|
4 |
+
jQuery( 'input[type=text]', $oForm ).each( function () {
|
5 |
+
jQuery( this ).val( '' );
|
6 |
+
} );
|
7 |
+
jQuery( 'select', $oForm ).each( function () {
|
8 |
+
jQuery( this ).prop( 'selectedIndex', 0 );
|
9 |
+
} );
|
10 |
+
jQuery( 'input[type=checkbox]', $oForm ).each( function () {
|
11 |
+
jQuery( this ).prop( 'checked', false );
|
12 |
+
} );
|
13 |
+
aOpts[ 'table' ].renderTableFromForm( $oForm );
|
14 |
+
};
|
15 |
+
|
16 |
+
var submitFilters = function ( evt ) {
|
17 |
+
evt.preventDefault();
|
18 |
+
aOpts[ 'table' ].renderTableFromForm( $oForm );
|
19 |
+
return false;
|
20 |
+
};
|
21 |
+
|
22 |
+
var initialise = function () {
|
23 |
+
jQuery( document ).ready( function () {
|
24 |
+
$oForm = jQuery( aOpts[ 'selector_filter_form' ] );
|
25 |
+
$oForm.on( 'submit', submitFilters );
|
26 |
+
$oForm.on( 'click', 'a#ClearForm', resetFilters );
|
27 |
+
} );
|
28 |
+
};
|
29 |
+
|
30 |
+
var $oThis = this;
|
31 |
+
var aOpts = jQuery.extend( {}, aOptions );
|
32 |
+
var $oForm;
|
33 |
+
initialise();
|
34 |
+
|
35 |
+
return this;
|
36 |
+
};
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Add ajax actions to table buttons, and automatically refreshes the table.
|
40 |
+
*/
|
41 |
+
(function ( $, window, document, undefined ) {
|
42 |
+
|
43 |
+
var pluginName = 'icwpWpsfTableActions';
|
44 |
+
|
45 |
+
function Ob_TableActions( element, options ) {
|
46 |
+
this.element = element;
|
47 |
+
this._name = pluginName;
|
48 |
+
this._defaults = $.fn.icwpWpsfTableActions.defaults;
|
49 |
+
this.options = $.extend(
|
50 |
+
{
|
51 |
+
'forms': {
|
52 |
+
'insert': ''
|
53 |
+
}
|
54 |
+
},
|
55 |
+
this._defaults,
|
56 |
+
options
|
57 |
+
);
|
58 |
+
this.init();
|
59 |
+
}
|
60 |
+
|
61 |
+
$.extend(
|
62 |
+
Ob_TableActions.prototype,
|
63 |
+
{
|
64 |
+
init: function () {
|
65 |
+
this.buildCache();
|
66 |
+
this.bindEvents();
|
67 |
+
},
|
68 |
+
destroy: function () {
|
69 |
+
this.unbindEvents();
|
70 |
+
this.$element.removeData();
|
71 |
+
},
|
72 |
+
buildCache: function () {
|
73 |
+
this.$element = $( this.element );
|
74 |
+
this.$oFormInsert = this.options[ 'forms' ][ 'insert' ];
|
75 |
+
},
|
76 |
+
bindEvents: function () {
|
77 |
+
var plugin = this;
|
78 |
+
|
79 |
+
plugin.$element.on(
|
80 |
+
'click' + '.' + plugin._name,
|
81 |
+
'button.action.delete',
|
82 |
+
function ( evt ) {
|
83 |
+
evt.preventDefault();
|
84 |
+
if ( confirm( icwp_wpsf_vars_insights.strings.are_you_sure ) ) {
|
85 |
+
plugin.options[ 'working_rid' ] = $( this ).data( 'rid' );
|
86 |
+
plugin.deleteEntry.call( plugin );
|
87 |
+
}
|
88 |
+
}
|
89 |
+
);
|
90 |
+
|
91 |
+
plugin.$element.on(
|
92 |
+
'click' + '.' + plugin._name,
|
93 |
+
'button.action.ignore',
|
94 |
+
function ( evt ) {
|
95 |
+
evt.preventDefault();
|
96 |
+
plugin.options[ 'working_rid' ] = $( this ).data( 'rid' );
|
97 |
+
plugin.ignoreEntry.call( plugin );
|
98 |
+
}
|
99 |
+
);
|
100 |
+
|
101 |
+
if ( typeof this.$oFormInsert !== 'undefined' && this.$oFormInsert.length ) {
|
102 |
+
this.$oFormInsert.on(
|
103 |
+
'submit' + '.' + plugin._name,
|
104 |
+
function ( evt ) {
|
105 |
+
evt.preventDefault();
|
106 |
+
plugin.insertEntry.call( plugin );
|
107 |
+
}
|
108 |
+
);
|
109 |
+
}
|
110 |
+
|
111 |
+
plugin.$element.on(
|
112 |
+
'click' + '.' + plugin._name,
|
113 |
+
'button.action.repair',
|
114 |
+
function ( evt ) {
|
115 |
+
evt.preventDefault();
|
116 |
+
plugin.options[ 'working_rid' ] = $( this ).data( 'rid' );
|
117 |
+
plugin.repairEntry.call( plugin );
|
118 |
+
}
|
119 |
+
);
|
120 |
+
|
121 |
+
plugin.$element.on(
|
122 |
+
'click' + '.' + plugin._name,
|
123 |
+
'button.action.item_action',
|
124 |
+
function ( evt ) {
|
125 |
+
evt.preventDefault();
|
126 |
+
plugin.options[ 'working_rid' ] = $( this ).data( 'rid' );
|
127 |
+
plugin.options[ 'working_item_action' ] = $( this ).data( 'item_action' );
|
128 |
+
plugin.itemAction.call( plugin );
|
129 |
+
}
|
130 |
+
);
|
131 |
+
|
132 |
+
plugin.$element.on(
|
133 |
+
'click' + '.' + plugin._name,
|
134 |
+
'.tablenav.top input[type=submit].button.action',
|
135 |
+
function ( evt ) {
|
136 |
+
evt.preventDefault();
|
137 |
+
var sAction = $( '#bulk-action-selector-top', plugin.$element ).find( ":selected" ).val();
|
138 |
+
|
139 |
+
if ( sAction === "-1" ) {
|
140 |
+
alert( icwp_wpsf_vars_insights.strings.select_action );
|
141 |
+
}
|
142 |
+
else {
|
143 |
+
var aCheckedIds = $( "input:checkbox[name=ids]:checked", plugin.$element ).map(
|
144 |
+
function () {
|
145 |
+
return $( this ).val()
|
146 |
+
} ).get();
|
147 |
+
|
148 |
+
if ( aCheckedIds.length < 1 ) {
|
149 |
+
alert( 'No rows currently selected' );
|
150 |
+
}
|
151 |
+
else {
|
152 |
+
plugin.options[ 'req_params' ][ 'bulk_action' ] = sAction;
|
153 |
+
plugin.options[ 'req_params' ][ 'ids' ] = aCheckedIds;
|
154 |
+
plugin.bulkAction.call( plugin );
|
155 |
+
}
|
156 |
+
}
|
157 |
+
return false;
|
158 |
+
}
|
159 |
+
);
|
160 |
+
|
161 |
+
plugin.$element.on(
|
162 |
+
'click' + '.' + plugin._name,
|
163 |
+
'button.action.custom-action',
|
164 |
+
function ( evt ) {
|
165 |
+
evt.preventDefault();
|
166 |
+
var $oButt = $( this );
|
167 |
+
var sCustomAction = $oButt.data( 'custom-action' );
|
168 |
+
if ( sCustomAction in plugin.options[ 'custom_actions_ajax' ] ) {
|
169 |
+
plugin.options[ 'working_custom_action' ] = plugin.options[ 'custom_actions_ajax' ][ sCustomAction ];
|
170 |
+
plugin.options[ 'working_custom_action' ][ 'rid' ] = $oButt.data( 'rid' );
|
171 |
+
plugin.customAction.call( plugin );
|
172 |
+
}
|
173 |
+
else {
|
174 |
+
/** This should never be reached live: **/
|
175 |
+
alert( 'custom action not supported: ' + sCustomAction );
|
176 |
+
}
|
177 |
+
}
|
178 |
+
);
|
179 |
+
|
180 |
+
plugin.$element.on(
|
181 |
+
'click' + '.' + plugin._name,
|
182 |
+
'button.action.href-download',
|
183 |
+
function ( evt ) {
|
184 |
+
evt.preventDefault();
|
185 |
+
var $oButt = $( this );
|
186 |
+
var sHref = $oButt.data( 'href-download' );
|
187 |
+
if ( sHref !== undefined ) {
|
188 |
+
plugin.options[ 'working_href_download' ] = sHref;
|
189 |
+
plugin.hrefDownload.call( plugin );
|
190 |
+
}
|
191 |
+
}
|
192 |
+
);
|
193 |
+
|
194 |
+
},
|
195 |
+
unbindEvents: function () {
|
196 |
+
/*
|
197 |
+
Unbind all events in our plugin's namespace that are attached
|
198 |
+
to "this.$element".
|
199 |
+
*/
|
200 |
+
this.$element.off( '.' + this._name );
|
201 |
+
},
|
202 |
+
|
203 |
+
bulkAction: function () {
|
204 |
+
let aRequestData = this.options[ 'ajax_bulk_action' ];
|
205 |
+
this.sendReq( aRequestData );
|
206 |
+
},
|
207 |
+
|
208 |
+
deleteEntry: function () {
|
209 |
+
let aRequestData = this.options[ 'ajax_item_delete' ];
|
210 |
+
aRequestData[ 'rid' ] = this.options[ 'working_rid' ];
|
211 |
+
this.sendReq( aRequestData );
|
212 |
+
},
|
213 |
+
|
214 |
+
insertEntry: function () {
|
215 |
+
let requestData = this.options[ 'ajax_item_insert' ];
|
216 |
+
requestData[ 'form_params' ] = this.$oFormInsert.serialize();
|
217 |
+
this.sendReq( requestData );
|
218 |
+
this.$oFormInsert[ 0 ].reset();
|
219 |
+
},
|
220 |
+
|
221 |
+
ignoreEntry: function () {
|
222 |
+
let aRequestData = this.options[ 'ajax_item_ignore' ];
|
223 |
+
aRequestData[ 'rid' ] = this.options[ 'working_rid' ];
|
224 |
+
this.sendReq( aRequestData );
|
225 |
+
},
|
226 |
+
|
227 |
+
repairEntry: function () {
|
228 |
+
let aRequestData = this.options[ 'ajax_item_repair' ];
|
229 |
+
aRequestData[ 'rid' ] = this.options[ 'working_rid' ];
|
230 |
+
this.sendReq( aRequestData );
|
231 |
+
},
|
232 |
+
|
233 |
+
itemAction: function () {
|
234 |
+
let aRequestData = this.options[ 'ajax_item_action' ];
|
235 |
+
aRequestData[ 'rid' ] = this.options[ 'working_rid' ];
|
236 |
+
aRequestData[ 'item_action' ] = this.options[ 'working_item_action' ];
|
237 |
+
this.sendReq( aRequestData );
|
238 |
+
},
|
239 |
+
|
240 |
+
customAction: function () {
|
241 |
+
this.sendReq( this.options[ 'working_custom_action' ] );
|
242 |
+
},
|
243 |
+
|
244 |
+
hrefDownload: function () {
|
245 |
+
$.fileDownload( this.options[ 'working_href_download' ], {
|
246 |
+
preparingMessageHtml: icwp_wpsf_vars_plugin.strings.downloading_file,
|
247 |
+
failMessageHtml: icwp_wpsf_vars_plugin.strings.downloading_file_problem
|
248 |
+
} );
|
249 |
+
return false;
|
250 |
+
},
|
251 |
+
|
252 |
+
sendReq: function ( aRequestData ) {
|
253 |
+
iCWP_WPSF_BodyOverlay.show();
|
254 |
+
|
255 |
+
var plugin = this;
|
256 |
+
|
257 |
+
$.post( ajaxurl, $.extend( aRequestData, plugin.options[ 'req_params' ] ),
|
258 |
+
function ( oResponse ) {
|
259 |
+
|
260 |
+
if ( oResponse.success ) {
|
261 |
+
iCWP_WPSF_Toaster.showMessage( oResponse.data.message, oResponse.success );
|
262 |
+
if ( oResponse.data.page_reload ) {
|
263 |
+
location.reload();
|
264 |
+
}
|
265 |
+
else {
|
266 |
+
plugin.options[ 'table' ].reloadTable();
|
267 |
+
iCWP_WPSF_Toaster.showMessage( oResponse.data.message, oResponse.success );
|
268 |
+
iCWP_WPSF_BodyOverlay.hide();
|
269 |
+
}
|
270 |
+
}
|
271 |
+
else {
|
272 |
+
let sMessage = 'Communications error with site.';
|
273 |
+
if ( oResponse.data.message !== undefined ) {
|
274 |
+
sMessage = oResponse.data.message;
|
275 |
+
}
|
276 |
+
alert( sMessage );
|
277 |
+
iCWP_WPSF_BodyOverlay.hide();
|
278 |
+
}
|
279 |
+
}
|
280 |
+
).always( function () {
|
281 |
+
}
|
282 |
+
);
|
283 |
+
},
|
284 |
+
callback: function () {
|
285 |
+
}
|
286 |
+
}
|
287 |
+
);
|
288 |
+
|
289 |
+
$.fn.icwpWpsfTableActions = function ( aOptions ) {
|
290 |
+
return this.each(
|
291 |
+
function () {
|
292 |
+
if ( !$.data( this, "plugin_" + pluginName ) ) {
|
293 |
+
$.data( this, "plugin_" + pluginName, new Ob_TableActions( this, aOptions ) );
|
294 |
+
}
|
295 |
+
}
|
296 |
+
);
|
297 |
+
};
|
298 |
+
|
299 |
+
$.fn.icwpWpsfTableActions.defaults = {
|
300 |
+
'custom_actions_ajax': {},
|
301 |
+
'req_params': {}
|
302 |
+
};
|
303 |
+
|
304 |
+
})( jQuery );
|
resources/js/shield/scans.js
CHANGED
@@ -6,38 +6,37 @@ jQuery.fn.icwpWpsfScansStart = function ( aOptions ) {
|
|
6 |
return false;
|
7 |
};
|
8 |
|
9 |
-
let
|
|
|
|
|
|
|
|
|
10 |
iCWP_WPSF_BodyOverlay.show();
|
11 |
|
12 |
-
|
13 |
-
|
14 |
-
function ( oResponse ) {
|
15 |
|
16 |
-
if (
|
17 |
-
iCWP_WPSF_Toaster.showMessage(
|
18 |
-
if (
|
19 |
-
|
20 |
}
|
21 |
-
else if (
|
22 |
setTimeout( function () {
|
23 |
-
jQuery( document ).icwpWpsfScansCheck(
|
24 |
-
{
|
25 |
-
'ajax_scans_check': aOpts[ 'ajax_scans_check' ]
|
26 |
-
}
|
27 |
-
);
|
28 |
}, 1000 );
|
29 |
}
|
30 |
else {
|
31 |
plugin.options[ 'table' ].reloadTable();
|
32 |
-
iCWP_WPSF_Toaster.showMessage(
|
33 |
}
|
34 |
}
|
35 |
else {
|
36 |
-
let
|
37 |
-
if (
|
38 |
-
|
39 |
}
|
40 |
-
alert(
|
41 |
iCWP_WPSF_BodyOverlay.hide();
|
42 |
}
|
43 |
|
@@ -65,8 +64,6 @@ jQuery.fn.icwpWpsfScansStart = function ( aOptions ) {
|
|
65 |
return this;
|
66 |
};
|
67 |
|
68 |
-
/**
|
69 |
-
*/
|
70 |
jQuery.fn.icwpWpsfScansCheck = function ( aOptions ) {
|
71 |
|
72 |
let bFoundRunning = false;
|
@@ -103,7 +100,7 @@ jQuery.fn.icwpWpsfScansCheck = function ( aOptions ) {
|
|
103 |
}
|
104 |
else {
|
105 |
setTimeout( function () {
|
106 |
-
location.
|
107 |
}, 1000 );
|
108 |
}
|
109 |
}
|
6 |
return false;
|
7 |
};
|
8 |
|
9 |
+
let loadResultsPage = function ( evt ) {
|
10 |
+
window.location.href = aOpts[ 'href_scans_results' ];
|
11 |
+
};
|
12 |
+
|
13 |
+
let sendReq = function ( param ) {
|
14 |
iCWP_WPSF_BodyOverlay.show();
|
15 |
|
16 |
+
jQuery.post( ajaxurl, jQuery.extend( aOpts[ 'ajax_scans_start' ], param ),
|
17 |
+
function ( response ) {
|
|
|
18 |
|
19 |
+
if ( response.success ) {
|
20 |
+
iCWP_WPSF_Toaster.showMessage( response.data.message, response.success );
|
21 |
+
if ( response.data.page_reload ) {
|
22 |
+
loadResultsPage();
|
23 |
}
|
24 |
+
else if ( response.data.scans_running ) {
|
25 |
setTimeout( function () {
|
26 |
+
jQuery( document ).icwpWpsfScansCheck( aOpts );
|
|
|
|
|
|
|
|
|
27 |
}, 1000 );
|
28 |
}
|
29 |
else {
|
30 |
plugin.options[ 'table' ].reloadTable();
|
31 |
+
iCWP_WPSF_Toaster.showMessage( response.data.message, response.success );
|
32 |
}
|
33 |
}
|
34 |
else {
|
35 |
+
let msg = 'Communications error with site.';
|
36 |
+
if ( response.data.message !== undefined ) {
|
37 |
+
msg = response.data.message;
|
38 |
}
|
39 |
+
alert( msg );
|
40 |
iCWP_WPSF_BodyOverlay.hide();
|
41 |
}
|
42 |
|
64 |
return this;
|
65 |
};
|
66 |
|
|
|
|
|
67 |
jQuery.fn.icwpWpsfScansCheck = function ( aOptions ) {
|
68 |
|
69 |
let bFoundRunning = false;
|
100 |
}
|
101 |
else {
|
102 |
setTimeout( function () {
|
103 |
+
window.location.href = aOpts[ 'href_scans_results' ];
|
104 |
}, 1000 );
|
105 |
}
|
106 |
}
|
resources/js/shield/secadmin.js
ADDED
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
var iCWP_WPSF_SecurityAdmin = new function () {
|
2 |
+
|
3 |
+
var hasCheckInPlace = false;
|
4 |
+
var isWarningShown = false;
|
5 |
+
var timeoutInterval = 500 * shield_vars_secadmin.vars.time_remaining;
|
6 |
+
|
7 |
+
var checkSecAdmin = function () {
|
8 |
+
iCWP_WPSF_StandardAjax.send_ajax_req(
|
9 |
+
shield_vars_secadmin.ajax.sec_admin_check, true, 'sec_admin_check'
|
10 |
+
);
|
11 |
+
};
|
12 |
+
|
13 |
+
var handleSecAdminCheck = function ( evt, response ) {
|
14 |
+
if ( response.data.success ) {
|
15 |
+
var nLeft = response.data.time_remaining;
|
16 |
+
timeoutInterval = Math.abs( Math.max( 3, (nLeft / 2) ) * 1000 );
|
17 |
+
|
18 |
+
if ( !isWarningShown && nLeft < 20 && nLeft > 8 ) {
|
19 |
+
isWarningShown = true;
|
20 |
+
iCWP_WPSF_Toaster.showMessage( shield_vars_secadmin.strings.nearly, false );
|
21 |
+
// iCWP_WPSF_Growl.showMessage( shield_vars_secadmin.strings.nearly, false );
|
22 |
+
}
|
23 |
+
|
24 |
+
hasCheckInPlace = false;
|
25 |
+
scheduleSecAdminCheck();
|
26 |
+
}
|
27 |
+
else {
|
28 |
+
iCWP_WPSF_BodyOverlay.show();
|
29 |
+
setTimeout( function () {
|
30 |
+
alert( shield_vars_secadmin.strings.confirm )
|
31 |
+
window.location.reload();
|
32 |
+
}, 1500 );
|
33 |
+
iCWP_WPSF_Toaster.showMessage( shield_vars_secadmin.strings.expired, response.success );
|
34 |
+
// iCWP_WPSF_Growl.showMessage( shield_vars_secadmin.strings.expired, response.success );
|
35 |
+
}
|
36 |
+
};
|
37 |
+
|
38 |
+
let scheduleSecAdminCheck = function () {
|
39 |
+
if ( !hasCheckInPlace ) {
|
40 |
+
setTimeout( function () {
|
41 |
+
checkSecAdmin();
|
42 |
+
}, timeoutInterval );
|
43 |
+
hasCheckInPlace = true;
|
44 |
+
}
|
45 |
+
};
|
46 |
+
|
47 |
+
let restrictWPOptions = function () {
|
48 |
+
if ( shield_vars_secadmin.flags.restrict_options ) {
|
49 |
+
shield_vars_secadmin.vars.wp_options_to_restrict.forEach( function ( element ) {
|
50 |
+
let $element = jQuery( 'input[name=' + element + ']' );
|
51 |
+
$element.prop( 'disabled', true );
|
52 |
+
$element.parents( 'tr' ).addClass( 'restricted-option-row' );
|
53 |
+
$element.parents( 'td' ).append(
|
54 |
+
'<div style="clear:both"></div><div class="restricted-option">' +
|
55 |
+
'<span class="dashicons dashicons-lock"></span>' +
|
56 |
+
shield_vars_secadmin.strings.editing_restricted +
|
57 |
+
' ' + shield_vars_secadmin.strings.unlock_link +
|
58 |
+
'</div>' );
|
59 |
+
} );
|
60 |
+
}
|
61 |
+
};
|
62 |
+
|
63 |
+
let performSecAdminDialogLogin = function () {
|
64 |
+
|
65 |
+
let pinInput = document.getElementById( 'SecAdminPinInput' );
|
66 |
+
shield_vars_secadmin.ajax.sec_admin_login.sec_admin_key = pinInput.value;
|
67 |
+
console.log( shield_vars_secadmin.ajax.sec_admin_login );
|
68 |
+
|
69 |
+
let inputContainer = document.getElementById( 'SecAdminPinInputContainer' );
|
70 |
+
inputContainer.innerHTML = '<div class="spinner"></div>';
|
71 |
+
|
72 |
+
jQuery.post( ajaxurl, shield_vars_secadmin.ajax.sec_admin_login, function ( response ) {
|
73 |
+
if ( response.success ) {
|
74 |
+
location.reload();
|
75 |
+
}
|
76 |
+
if ( response.data ) {
|
77 |
+
inputContainer.innerHTML = response.data.html;
|
78 |
+
}
|
79 |
+
else {
|
80 |
+
inputContainer.innerHTML = 'There was an unknown error';
|
81 |
+
}
|
82 |
+
} );
|
83 |
+
};
|
84 |
+
|
85 |
+
this.initialise = function () {
|
86 |
+
|
87 |
+
restrictWPOptions();
|
88 |
+
|
89 |
+
if ( shield_vars_secadmin.flags.run_checks ) {
|
90 |
+
scheduleSecAdminCheck();
|
91 |
+
jQuery( document ).on( 'shield-sec_admin_check', handleSecAdminCheck );
|
92 |
+
}
|
93 |
+
|
94 |
+
jQuery( document ).on( 'submit', '#SecurityAdminForm',
|
95 |
+
function ( evt ) {
|
96 |
+
evt.preventDefault();
|
97 |
+
iCWP_WPSF_StandardAjax.send_ajax_req( jQuery( evt.target ).serialize() );
|
98 |
+
return false;
|
99 |
+
}
|
100 |
+
);
|
101 |
+
|
102 |
+
jQuery( document ).on( 'click', '#SecAdminRemoveConfirmEmail',
|
103 |
+
function ( evt ) {
|
104 |
+
evt.preventDefault();
|
105 |
+
if ( confirm( shield_vars_secadmin.strings.are_you_sure ) ) {
|
106 |
+
iCWP_WPSF_StandardAjax.send_ajax_req( shield_vars_secadmin.ajax.req_email_remove );
|
107 |
+
}
|
108 |
+
return false;
|
109 |
+
}
|
110 |
+
);
|
111 |
+
|
112 |
+
jQuery( document ).on( 'click', '#SecAdminDialog button', performSecAdminDialogLogin );
|
113 |
+
};
|
114 |
+
}();
|
115 |
+
|
116 |
+
jQuery( document ).ready( function () {
|
117 |
+
iCWP_WPSF_SecurityAdmin.initialise();
|
118 |
+
} );
|
resources/js/shield/tables.js
CHANGED
@@ -243,8 +243,8 @@ jQuery.fn.icwpWpsfTableWithFilter = function ( aOptions ) {
|
|
243 |
|
244 |
hrefDownload: function () {
|
245 |
$.fileDownload( this.options[ 'working_href_download' ], {
|
246 |
-
preparingMessageHtml:
|
247 |
-
failMessageHtml:
|
248 |
} );
|
249 |
return false;
|
250 |
},
|
243 |
|
244 |
hrefDownload: function () {
|
245 |
$.fileDownload( this.options[ 'working_href_download' ], {
|
246 |
+
preparingMessageHtml: icwp_wpsf_vars_plugin.strings.downloading_file,
|
247 |
+
failMessageHtml: icwp_wpsf_vars_plugin.strings.downloading_file_problem
|
248 |
} );
|
249 |
return false;
|
250 |
},
|
src/config/feature-admin_access_restriction.php
CHANGED
@@ -37,7 +37,7 @@
|
|
37 |
},
|
38 |
"sections": [
|
39 |
{
|
40 |
-
"slug": "
|
41 |
"primary": true,
|
42 |
"title": "Security Admin Restriction Settings",
|
43 |
"title_short": "Security Admin Settings",
|
@@ -95,7 +95,7 @@
|
|
95 |
},
|
96 |
{
|
97 |
"key": "admin_access_key",
|
98 |
-
"section": "
|
99 |
"sensitive": true,
|
100 |
"default": "",
|
101 |
"type": "password",
|
@@ -107,7 +107,7 @@
|
|
107 |
},
|
108 |
{
|
109 |
"key": "sec_admin_users",
|
110 |
-
"section": "
|
111 |
"advanced": true,
|
112 |
"sensitive": true,
|
113 |
"premium": true,
|
@@ -121,7 +121,7 @@
|
|
121 |
},
|
122 |
{
|
123 |
"key": "admin_access_timeout",
|
124 |
-
"section": "
|
125 |
"advanced": true,
|
126 |
"default": 30,
|
127 |
"type": "integer",
|
@@ -134,7 +134,7 @@
|
|
134 |
},
|
135 |
{
|
136 |
"key": "allow_email_override",
|
137 |
-
"section": "
|
138 |
"advanced": true,
|
139 |
"default": "Y",
|
140 |
"type": "checkbox",
|
37 |
},
|
38 |
"sections": [
|
39 |
{
|
40 |
+
"slug": "section_security_admin_settings",
|
41 |
"primary": true,
|
42 |
"title": "Security Admin Restriction Settings",
|
43 |
"title_short": "Security Admin Settings",
|
95 |
},
|
96 |
{
|
97 |
"key": "admin_access_key",
|
98 |
+
"section": "section_security_admin_settings",
|
99 |
"sensitive": true,
|
100 |
"default": "",
|
101 |
"type": "password",
|
107 |
},
|
108 |
{
|
109 |
"key": "sec_admin_users",
|
110 |
+
"section": "section_security_admin_settings",
|
111 |
"advanced": true,
|
112 |
"sensitive": true,
|
113 |
"premium": true,
|
121 |
},
|
122 |
{
|
123 |
"key": "admin_access_timeout",
|
124 |
+
"section": "section_security_admin_settings",
|
125 |
"advanced": true,
|
126 |
"default": 30,
|
127 |
"type": "integer",
|
134 |
},
|
135 |
{
|
136 |
"key": "allow_email_override",
|
137 |
+
"section": "section_security_admin_settings",
|
138 |
"advanced": true,
|
139 |
"default": "Y",
|
140 |
"type": "checkbox",
|
src/config/feature-audit_trail.php
CHANGED
@@ -18,8 +18,8 @@
|
|
18 |
},
|
19 |
"menu_items": [
|
20 |
{
|
21 |
-
"title":
|
22 |
-
"slug":
|
23 |
}
|
24 |
],
|
25 |
"custom_redirects": [
|
@@ -162,14 +162,13 @@
|
|
162 |
}
|
163 |
],
|
164 |
"definitions": {
|
165 |
-
"db_classes":
|
166 |
-
"audit_trail": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\AuditTrail\\Handler"
|
167 |
-
"audit": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\AuditTrail\\Handler"
|
168 |
},
|
169 |
-
"db_table_audit_trail":
|
170 |
-
"slug":
|
171 |
-
"has_updated_at":
|
172 |
-
"cols_custom":
|
173 |
"rid": "varchar(10) NOT NULL DEFAULT '' COMMENT 'Request ID'",
|
174 |
"ip": "varchar(40) NOT NULL DEFAULT 0 COMMENT 'Visitor IP Address'",
|
175 |
"wp_username": "varchar(255) NOT NULL DEFAULT '-' COMMENT 'WP User'",
|
@@ -180,30 +179,9 @@
|
|
180 |
"count": "SMALLINT(5) UNSIGNED NOT NULL DEFAULT 1 COMMENT 'Repeat Count'"
|
181 |
}
|
182 |
},
|
183 |
-
"audit_trail_free_max_entries":
|
184 |
-
"audit_trail_table_name":
|
185 |
-
"
|
186 |
-
"rid": "varchar(10) NOT NULL DEFAULT '' COMMENT 'Request ID'",
|
187 |
-
"ip": "varchar(40) NOT NULL DEFAULT 0 COMMENT 'Visitor IP Address'",
|
188 |
-
"wp_username": "varchar(255) NOT NULL DEFAULT '-' COMMENT 'WP User'",
|
189 |
-
"context": "varchar(32) NOT NULL DEFAULT 'none' COMMENT 'Audit Context'",
|
190 |
-
"event": "varchar(50) NOT NULL DEFAULT 'none' COMMENT 'Specific Audit Event'",
|
191 |
-
"category": "int(3) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Severity'",
|
192 |
-
"meta": "text COMMENT 'Audit Event Data'",
|
193 |
-
"count": "SMALLINT(5) UNSIGNED NOT NULL DEFAULT 1 COMMENT 'Repeat Count'"
|
194 |
-
},
|
195 |
-
"audittrail_table_timestamp_columns": {
|
196 |
-
"updated_at": "Updated"
|
197 |
-
},
|
198 |
-
"table_name_changetracking": "changetracking",
|
199 |
-
"table_columns_changetracking": [
|
200 |
-
"id",
|
201 |
-
"data",
|
202 |
-
"meta",
|
203 |
-
"created_at",
|
204 |
-
"deleted_at"
|
205 |
-
],
|
206 |
-
"events": {
|
207 |
"plugin_activated": {
|
208 |
"context": "plugins",
|
209 |
"audit_multiple": true
|
@@ -216,7 +194,8 @@
|
|
216 |
"context": "plugins"
|
217 |
},
|
218 |
"plugin_upgraded": {
|
219 |
-
"context":
|
|
|
220 |
},
|
221 |
"theme_activated": {
|
222 |
"context": "themes"
|
@@ -225,7 +204,8 @@
|
|
225 |
"context": "themes"
|
226 |
},
|
227 |
"theme_upgraded": {
|
228 |
-
"context":
|
|
|
229 |
},
|
230 |
"core_updated": {
|
231 |
"context": "wordpress"
|
18 |
},
|
19 |
"menu_items": [
|
20 |
{
|
21 |
+
"title": "Audit Trail",
|
22 |
+
"slug": "audit-redirect"
|
23 |
}
|
24 |
],
|
25 |
"custom_redirects": [
|
162 |
}
|
163 |
],
|
164 |
"definitions": {
|
165 |
+
"db_classes": {
|
166 |
+
"audit_trail": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\AuditTrail\\Handler"
|
|
|
167 |
},
|
168 |
+
"db_table_audit_trail": {
|
169 |
+
"slug": "audit_trail",
|
170 |
+
"has_updated_at": true,
|
171 |
+
"cols_custom": {
|
172 |
"rid": "varchar(10) NOT NULL DEFAULT '' COMMENT 'Request ID'",
|
173 |
"ip": "varchar(40) NOT NULL DEFAULT 0 COMMENT 'Visitor IP Address'",
|
174 |
"wp_username": "varchar(255) NOT NULL DEFAULT '-' COMMENT 'WP User'",
|
179 |
"count": "SMALLINT(5) UNSIGNED NOT NULL DEFAULT 1 COMMENT 'Repeat Count'"
|
180 |
}
|
181 |
},
|
182 |
+
"audit_trail_free_max_entries": 100,
|
183 |
+
"audit_trail_table_name": "audit_trail",
|
184 |
+
"events": {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
185 |
"plugin_activated": {
|
186 |
"context": "plugins",
|
187 |
"audit_multiple": true
|
194 |
"context": "plugins"
|
195 |
},
|
196 |
"plugin_upgraded": {
|
197 |
+
"context": "plugins",
|
198 |
+
"audit_multiple": true
|
199 |
},
|
200 |
"theme_activated": {
|
201 |
"context": "themes"
|
204 |
"context": "themes"
|
205 |
},
|
206 |
"theme_upgraded": {
|
207 |
+
"context": "themes",
|
208 |
+
"audit_multiple": true
|
209 |
},
|
210 |
"core_updated": {
|
211 |
"context": "wordpress"
|
src/config/feature-comments_filter.php
CHANGED
@@ -314,21 +314,18 @@
|
|
314 |
"comments_expire": 1800,
|
315 |
"url_spam_blacklist_terms": "https://raw.githubusercontent.com/splorp/wordpress-comment-blacklist/master/blacklist.txt",
|
316 |
"events": {
|
317 |
-
"
|
318 |
-
"
|
|
|
319 |
"offense": true
|
320 |
},
|
|
|
|
|
321 |
"spam_block_bot": {
|
322 |
-
"recent": true,
|
323 |
-
"offense": true
|
324 |
},
|
325 |
"spam_block_recaptcha": {
|
326 |
-
"recent": true,
|
327 |
-
"offense": true
|
328 |
},
|
329 |
"spam_block_human": {
|
330 |
-
"recent": true,
|
331 |
-
"offense": true
|
332 |
}
|
333 |
}
|
334 |
}
|
314 |
"comments_expire": 1800,
|
315 |
"url_spam_blacklist_terms": "https://raw.githubusercontent.com/splorp/wordpress-comment-blacklist/master/blacklist.txt",
|
316 |
"events": {
|
317 |
+
"comment_spam_block": {
|
318 |
+
"audit": false,
|
319 |
+
"stat": false,
|
320 |
"offense": true
|
321 |
},
|
322 |
+
"spam_block_antibot": {
|
323 |
+
},
|
324 |
"spam_block_bot": {
|
|
|
|
|
325 |
},
|
326 |
"spam_block_recaptcha": {
|
|
|
|
|
327 |
},
|
328 |
"spam_block_human": {
|
|
|
|
|
329 |
}
|
330 |
}
|
331 |
}
|
src/config/feature-events.php
CHANGED
@@ -56,10 +56,6 @@
|
|
56 |
"count": "int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Total'"
|
57 |
}
|
58 |
},
|
59 |
-
"events_table_name": "events"
|
60 |
-
"events_table_columns": {
|
61 |
-
"event": "varchar(50) NOT NULL DEFAULT 'none' COMMENT 'Event ID'",
|
62 |
-
"count": "int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Total'"
|
63 |
-
}
|
64 |
}
|
65 |
}
|
56 |
"count": "int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Total'"
|
57 |
}
|
58 |
},
|
59 |
+
"events_table_name": "events"
|
|
|
|
|
|
|
|
|
60 |
}
|
61 |
}
|
src/config/feature-firewall.php
CHANGED
@@ -320,7 +320,10 @@
|
|
320 |
"appId",
|
321 |
"/^et_.*/",
|
322 |
"ping_sites",
|
323 |
-
"aioseo-post-settings"
|
|
|
|
|
|
|
324 |
]
|
325 |
},
|
326 |
"firewall_patterns": {
|
320 |
"appId",
|
321 |
"/^et_.*/",
|
322 |
"ping_sites",
|
323 |
+
"aioseo-post-settings",
|
324 |
+
"joe-chnlcustid",
|
325 |
+
"spd-custhash",
|
326 |
+
"joe-custinfo"
|
327 |
]
|
328 |
},
|
329 |
"firewall_patterns": {
|
src/config/feature-hack_protect.php
CHANGED
@@ -21,8 +21,8 @@
|
|
21 |
},
|
22 |
"menu_items": [
|
23 |
{
|
24 |
-
"title":
|
25 |
-
"slug":
|
26 |
}
|
27 |
],
|
28 |
"custom_redirects": [
|
@@ -30,7 +30,7 @@
|
|
30 |
"source_mod_page": "scans-redirect",
|
31 |
"target_mod_page": "insights",
|
32 |
"query_args": {
|
33 |
-
"inav": "
|
34 |
}
|
35 |
}
|
36 |
],
|
@@ -331,7 +331,9 @@
|
|
331 |
"php.ini",
|
332 |
"web.config",
|
333 |
"php_mail.log",
|
334 |
-
"mail.log"
|
|
|
|
|
335 |
],
|
336 |
"type": "array",
|
337 |
"link_info": "https://shsec.io/9z",
|
@@ -406,13 +408,12 @@
|
|
406 |
}
|
407 |
],
|
408 |
"definitions": {
|
409 |
-
"db_classes":
|
410 |
-
"
|
411 |
-
"
|
412 |
-
"
|
413 |
-
"scanq": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\ScanQueue\\Handler"
|
414 |
},
|
415 |
-
"db_table_filelocker":
|
416 |
"slug": "filelocker",
|
417 |
"has_updated_at": true,
|
418 |
"cols_custom": {
|
@@ -428,7 +429,7 @@
|
|
428 |
"notified_at": "Notification Sent"
|
429 |
}
|
430 |
},
|
431 |
-
"db_table_scanner":
|
432 |
"slug": "scanner",
|
433 |
"cols_custom": {
|
434 |
"hash": "varchar(32) NOT NULL DEFAULT '' COMMENT 'Unique Item Hash'",
|
@@ -441,7 +442,7 @@
|
|
441 |
"notified_at": "Scan Notifiation Sent"
|
442 |
}
|
443 |
},
|
444 |
-
"db_table_scanq":
|
445 |
"slug": "scanq",
|
446 |
"cols_custom": {
|
447 |
"scan": "varchar(3) NOT NULL DEFAULT '' COMMENT 'Scan Slug'",
|
@@ -454,7 +455,7 @@
|
|
454 |
"finished_at": "Scan Completed"
|
455 |
}
|
456 |
},
|
457 |
-
"all_scan_slugs":
|
458 |
"apc",
|
459 |
"mal",
|
460 |
"ptg",
|
@@ -462,38 +463,27 @@
|
|
462 |
"wcf",
|
463 |
"ufc"
|
464 |
],
|
465 |
-
"table_name_filelocker":
|
466 |
-
"
|
467 |
-
|
468 |
-
|
469 |
-
"hash_current": "varchar(40) NOT NULL COMMENT 'SHA1 File Hash Current'",
|
470 |
-
"content": "MEDIUMBLOB COMMENT 'Content'",
|
471 |
-
"public_key_id": "TINYINT(2) UNSIGNED NOT NULL COMMENT 'Public Key ID'",
|
472 |
-
"detected_at": "int(15) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'TS Change Last Detected'",
|
473 |
-
"reverted_at": "int(15) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'TS Reverted To Backup'",
|
474 |
-
"notified_at": "int(15) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'TS Notification Sent'",
|
475 |
-
"updated_at": "int(15) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'TS Updated'"
|
476 |
-
},
|
477 |
-
"url_mal_sigs_simple": "https://raw.githubusercontent.com/scr34m/php-malware-scanner/master/definitions/patterns_raw.txt",
|
478 |
-
"url_mal_sigs_regex": "https://raw.githubusercontent.com/scr34m/php-malware-scanner/master/definitions/patterns_re.txt",
|
479 |
-
"malware_whitelist_paths": [
|
480 |
"wp-content/wflogs/",
|
481 |
"wp-content/cache/",
|
482 |
"wp-content/icwp/rollback/"
|
483 |
],
|
484 |
-
"cron_all_scans":
|
485 |
-
"wcf_exclusions":
|
486 |
"readme.html",
|
487 |
"license.txt",
|
488 |
"licens-sv_SE.txt",
|
489 |
"wp-config-sample.php",
|
490 |
"wp-content/"
|
491 |
],
|
492 |
-
"wcf_exclusions_missing_only":
|
493 |
"wp-admin/install.php",
|
494 |
"xmlrpc.php"
|
495 |
],
|
496 |
-
"events":
|
497 |
"apc_alert_sent": {
|
498 |
},
|
499 |
"mal_alert_sent": {
|
@@ -531,53 +521,65 @@
|
|
531 |
"recent": true
|
532 |
},
|
533 |
"apc_scan_found": {
|
534 |
-
"cat":
|
535 |
-
"
|
|
|
536 |
},
|
537 |
"mal_scan_found": {
|
538 |
-
"cat":
|
539 |
-
"
|
|
|
540 |
},
|
541 |
"ptg_scan_found": {
|
542 |
-
"cat":
|
543 |
-
"
|
|
|
544 |
},
|
545 |
"ufc_scan_found": {
|
546 |
-
"cat":
|
547 |
-
"
|
|
|
548 |
},
|
549 |
"wcf_scan_found": {
|
550 |
-
"cat":
|
551 |
-
"
|
|
|
552 |
},
|
553 |
"wpv_scan_found": {
|
554 |
-
"cat":
|
555 |
-
"
|
|
|
556 |
},
|
557 |
"apc_item_repair_success": {
|
|
|
558 |
},
|
559 |
"apc_item_repair_fail": {
|
560 |
},
|
561 |
"mal_item_repair_success": {
|
562 |
-
"
|
|
|
563 |
},
|
564 |
"mal_item_repair_fail": {
|
565 |
},
|
566 |
"ptg_item_repair_success": {
|
|
|
567 |
},
|
568 |
"ptg_item_repair_fail": {
|
569 |
},
|
570 |
"ufc_item_repair_success": {
|
571 |
-
"
|
|
|
572 |
},
|
573 |
"ufc_item_repair_fail": {
|
574 |
},
|
575 |
"wcf_item_repair_success": {
|
576 |
-
"
|
|
|
577 |
},
|
578 |
"wcf_item_repair_fail": {
|
579 |
},
|
580 |
"wpv_item_repair_success": {
|
|
|
581 |
},
|
582 |
"wpv_item_repair_fail": {
|
583 |
}
|
21 |
},
|
22 |
"menu_items": [
|
23 |
{
|
24 |
+
"title": "Scans",
|
25 |
+
"slug": "scans-redirect"
|
26 |
}
|
27 |
],
|
28 |
"custom_redirects": [
|
30 |
"source_mod_page": "scans-redirect",
|
31 |
"target_mod_page": "insights",
|
32 |
"query_args": {
|
33 |
+
"inav": "scans_results"
|
34 |
}
|
35 |
}
|
36 |
],
|
331 |
"php.ini",
|
332 |
"web.config",
|
333 |
"php_mail.log",
|
334 |
+
"mail.log",
|
335 |
+
"wp-content/uploads/bb-plugin/cache/",
|
336 |
+
"wp-content/uploads/cache/wpml/twig/"
|
337 |
],
|
338 |
"type": "array",
|
339 |
"link_info": "https://shsec.io/9z",
|
408 |
}
|
409 |
],
|
410 |
"definitions": {
|
411 |
+
"db_classes": {
|
412 |
+
"filelocker": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\FileLocker\\Handler",
|
413 |
+
"scanner": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Scanner\\Handler",
|
414 |
+
"scanq": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\ScanQueue\\Handler"
|
|
|
415 |
},
|
416 |
+
"db_table_filelocker": {
|
417 |
"slug": "filelocker",
|
418 |
"has_updated_at": true,
|
419 |
"cols_custom": {
|
429 |
"notified_at": "Notification Sent"
|
430 |
}
|
431 |
},
|
432 |
+
"db_table_scanner": {
|
433 |
"slug": "scanner",
|
434 |
"cols_custom": {
|
435 |
"hash": "varchar(32) NOT NULL DEFAULT '' COMMENT 'Unique Item Hash'",
|
442 |
"notified_at": "Scan Notifiation Sent"
|
443 |
}
|
444 |
},
|
445 |
+
"db_table_scanq": {
|
446 |
"slug": "scanq",
|
447 |
"cols_custom": {
|
448 |
"scan": "varchar(3) NOT NULL DEFAULT '' COMMENT 'Scan Slug'",
|
455 |
"finished_at": "Scan Completed"
|
456 |
}
|
457 |
},
|
458 |
+
"all_scan_slugs": [
|
459 |
"apc",
|
460 |
"mal",
|
461 |
"ptg",
|
463 |
"wcf",
|
464 |
"ufc"
|
465 |
],
|
466 |
+
"table_name_filelocker": "filelocker",
|
467 |
+
"url_mal_sigs_simple": "https://raw.githubusercontent.com/scr34m/php-malware-scanner/master/definitions/patterns_raw.txt",
|
468 |
+
"url_mal_sigs_regex": "https://raw.githubusercontent.com/scr34m/php-malware-scanner/master/definitions/patterns_re.txt",
|
469 |
+
"malware_whitelist_paths": [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
470 |
"wp-content/wflogs/",
|
471 |
"wp-content/cache/",
|
472 |
"wp-content/icwp/rollback/"
|
473 |
],
|
474 |
+
"cron_all_scans": "all-scans",
|
475 |
+
"wcf_exclusions": [
|
476 |
"readme.html",
|
477 |
"license.txt",
|
478 |
"licens-sv_SE.txt",
|
479 |
"wp-config-sample.php",
|
480 |
"wp-content/"
|
481 |
],
|
482 |
+
"wcf_exclusions_missing_only": [
|
483 |
"wp-admin/install.php",
|
484 |
"xmlrpc.php"
|
485 |
],
|
486 |
+
"events": {
|
487 |
"apc_alert_sent": {
|
488 |
},
|
489 |
"mal_alert_sent": {
|
521 |
"recent": true
|
522 |
},
|
523 |
"apc_scan_found": {
|
524 |
+
"cat": 2,
|
525 |
+
"audit_multiple": true,
|
526 |
+
"recent": true
|
527 |
},
|
528 |
"mal_scan_found": {
|
529 |
+
"cat": 3,
|
530 |
+
"audit_multiple": true,
|
531 |
+
"recent": true
|
532 |
},
|
533 |
"ptg_scan_found": {
|
534 |
+
"cat": 3,
|
535 |
+
"audit_multiple": true,
|
536 |
+
"recent": true
|
537 |
},
|
538 |
"ufc_scan_found": {
|
539 |
+
"cat": 3,
|
540 |
+
"audit_multiple": true,
|
541 |
+
"recent": true
|
542 |
},
|
543 |
"wcf_scan_found": {
|
544 |
+
"cat": 3,
|
545 |
+
"audit_multiple": true,
|
546 |
+
"recent": true
|
547 |
},
|
548 |
"wpv_scan_found": {
|
549 |
+
"cat": 3,
|
550 |
+
"audit_multiple": true,
|
551 |
+
"recent": true
|
552 |
},
|
553 |
"apc_item_repair_success": {
|
554 |
+
"audit_multiple": true
|
555 |
},
|
556 |
"apc_item_repair_fail": {
|
557 |
},
|
558 |
"mal_item_repair_success": {
|
559 |
+
"audit_multiple": true,
|
560 |
+
"recent": true
|
561 |
},
|
562 |
"mal_item_repair_fail": {
|
563 |
},
|
564 |
"ptg_item_repair_success": {
|
565 |
+
"audit_multiple": true
|
566 |
},
|
567 |
"ptg_item_repair_fail": {
|
568 |
},
|
569 |
"ufc_item_repair_success": {
|
570 |
+
"audit_multiple": true,
|
571 |
+
"recent": true
|
572 |
},
|
573 |
"ufc_item_repair_fail": {
|
574 |
},
|
575 |
"wcf_item_repair_success": {
|
576 |
+
"audit_multiple": true,
|
577 |
+
"recent": true
|
578 |
},
|
579 |
"wcf_item_repair_fail": {
|
580 |
},
|
581 |
"wpv_item_repair_success": {
|
582 |
+
"audit_multiple": true
|
583 |
},
|
584 |
"wpv_item_repair_fail": {
|
585 |
}
|
src/config/feature-headers.php
CHANGED
@@ -186,7 +186,7 @@
|
|
186 |
"link_blog": "",
|
187 |
"name": "Manual Rules",
|
188 |
"summary": "Manual CSP Rules",
|
189 |
-
"description": "Manual CSP rules
|
190 |
}
|
191 |
]
|
192 |
}
|
186 |
"link_blog": "",
|
187 |
"name": "Manual Rules",
|
188 |
"summary": "Manual CSP Rules",
|
189 |
+
"description": "Manual CSP rules."
|
190 |
}
|
191 |
]
|
192 |
}
|
src/config/feature-ips.php
CHANGED
@@ -551,22 +551,9 @@
|
|
551 |
"definitions": {
|
552 |
"db_classes": {
|
553 |
"botsignals": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\BotSignals\\Handler",
|
554 |
-
"ip_lists": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\IPs\\Handler"
|
555 |
-
"ips": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\IPs\\Handler"
|
556 |
},
|
557 |
"ip_lists_table_name": "ip_lists",
|
558 |
-
"ip_list_table_columns": {
|
559 |
-
"ip": "varchar(60) NOT NULL DEFAULT '' COMMENT 'Human readable IP address or range'",
|
560 |
-
"label": "varchar(255) NOT NULL DEFAULT '' COMMENT 'Description'",
|
561 |
-
"list": "varchar(4) NOT NULL DEFAULT '' COMMENT 'Block or Bypass'",
|
562 |
-
"ip6": "tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Is IPv6'",
|
563 |
-
"is_range": "tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Is Range'",
|
564 |
-
"transgressions": "int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Total Offenses'"
|
565 |
-
},
|
566 |
-
"ip_list_table_timestamp_columns": {
|
567 |
-
"last_access_at": "Last Access By IP",
|
568 |
-
"blocked_at": "IP Blocked"
|
569 |
-
},
|
570 |
"db_table_ip_lists": {
|
571 |
"slug": "ip_lists",
|
572 |
"cols_custom": {
|
551 |
"definitions": {
|
552 |
"db_classes": {
|
553 |
"botsignals": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\BotSignals\\Handler",
|
554 |
+
"ip_lists": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\IPs\\Handler"
|
|
|
555 |
},
|
556 |
"ip_lists_table_name": "ip_lists",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
557 |
"db_table_ip_lists": {
|
558 |
"slug": "ip_lists",
|
559 |
"cols_custom": {
|
src/config/feature-login_protect.php
CHANGED
@@ -501,18 +501,15 @@
|
|
501 |
"2fa_email_send_fail": {
|
502 |
},
|
503 |
"cooldown_fail": {
|
504 |
-
"offense": true
|
505 |
},
|
506 |
"honeypot_fail": {
|
507 |
-
"offense": true
|
508 |
},
|
509 |
"botbox_fail": {
|
510 |
-
"offense": true
|
511 |
},
|
512 |
"login_block": {
|
513 |
"audit": false,
|
514 |
"recent": true,
|
515 |
-
"offense":
|
516 |
},
|
517 |
"hide_login_url": {
|
518 |
"audit": false
|
501 |
"2fa_email_send_fail": {
|
502 |
},
|
503 |
"cooldown_fail": {
|
|
|
504 |
},
|
505 |
"honeypot_fail": {
|
|
|
506 |
},
|
507 |
"botbox_fail": {
|
|
|
508 |
},
|
509 |
"login_block": {
|
510 |
"audit": false,
|
511 |
"recent": true,
|
512 |
+
"offense": true
|
513 |
},
|
514 |
"hide_login_url": {
|
515 |
"audit": false
|
src/config/feature-plugin.php
CHANGED
@@ -246,17 +246,6 @@
|
|
246 |
"summary": "Display Plugin Specific Notices",
|
247 |
"description": "Disable this option to hide certain plugin admin notices about available updates and post-update notices."
|
248 |
},
|
249 |
-
{
|
250 |
-
"key": "display_plugin_badge",
|
251 |
-
"section": "section_general_plugin_options",
|
252 |
-
"default": "N",
|
253 |
-
"type": "checkbox",
|
254 |
-
"link_info": "https://shsec.io/5v",
|
255 |
-
"link_blog": "https://shsec.io/wpsf20",
|
256 |
-
"name": "Show Plugin Badge",
|
257 |
-
"summary": "Display Plugin Badge On Your Site",
|
258 |
-
"description": "Enabling this option helps support the plugin by spreading the word about it on your website. The plugin badge also demonstrates to visitors that you take your website security seriously."
|
259 |
-
},
|
260 |
{
|
261 |
"key": "enable_wpcli",
|
262 |
"section": "section_general_plugin_options",
|
@@ -270,6 +259,17 @@
|
|
270 |
"summary": "Allow Access And Control Of This Plugin Via WP-CLI",
|
271 |
"description": "Turn off this option to disable this plugin's WP-CLI integration."
|
272 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
273 |
{
|
274 |
"key": "enable_xmlrpc_compatibility",
|
275 |
"section": "section_defaults",
|
@@ -529,7 +529,6 @@
|
|
529 |
}
|
530 |
],
|
531 |
"definitions": {
|
532 |
-
"survey_email": "c3VwcG9ydEBvbmVkb2xsYXJwbHVnaW4uY29t",
|
533 |
"help_video_id": "",
|
534 |
"tracking_cron_handle": "plugin_tracking_cron",
|
535 |
"tracking_post_url": "https://tracking.icontrolwp.com/track/plugin/shield",
|
@@ -668,8 +667,7 @@
|
|
668 |
"audit": false
|
669 |
},
|
670 |
"recaptcha_fail": {
|
671 |
-
"
|
672 |
-
"audit": true
|
673 |
},
|
674 |
"antibot_pass": {
|
675 |
"stat": true,
|
246 |
"summary": "Display Plugin Specific Notices",
|
247 |
"description": "Disable this option to hide certain plugin admin notices about available updates and post-update notices."
|
248 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
249 |
{
|
250 |
"key": "enable_wpcli",
|
251 |
"section": "section_general_plugin_options",
|
259 |
"summary": "Allow Access And Control Of This Plugin Via WP-CLI",
|
260 |
"description": "Turn off this option to disable this plugin's WP-CLI integration."
|
261 |
},
|
262 |
+
{
|
263 |
+
"key": "display_plugin_badge",
|
264 |
+
"section": "section_general_plugin_options",
|
265 |
+
"default": "N",
|
266 |
+
"type": "checkbox",
|
267 |
+
"link_info": "https://shsec.io/5v",
|
268 |
+
"link_blog": "https://shsec.io/wpsf20",
|
269 |
+
"name": "Show Plugin Badge",
|
270 |
+
"summary": "Display Plugin Badge On Your Site",
|
271 |
+
"description": "Enabling this option helps support the plugin by spreading the word about it on your website. The plugin badge also demonstrates to visitors that you take your website security seriously."
|
272 |
+
},
|
273 |
{
|
274 |
"key": "enable_xmlrpc_compatibility",
|
275 |
"section": "section_defaults",
|
529 |
}
|
530 |
],
|
531 |
"definitions": {
|
|
|
532 |
"help_video_id": "",
|
533 |
"tracking_cron_handle": "plugin_tracking_cron",
|
534 |
"tracking_post_url": "https://tracking.icontrolwp.com/track/plugin/shield",
|
667 |
"audit": false
|
668 |
},
|
669 |
"recaptcha_fail": {
|
670 |
+
"audit": true
|
|
|
671 |
},
|
672 |
"antibot_pass": {
|
673 |
"stat": true,
|
src/config/feature-sessions.php
CHANGED
@@ -56,23 +56,9 @@
|
|
56 |
],
|
57 |
"definitions": {
|
58 |
"db_classes": {
|
59 |
-
"sessions": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Session\\Handler"
|
60 |
-
"session": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Session\\Handler"
|
61 |
},
|
62 |
"sessions_table_name": "sessions",
|
63 |
-
"sessions_table_columns": {
|
64 |
-
"session_id": "varchar(32) NOT NULL DEFAULT ''",
|
65 |
-
"wp_username": "varchar(255) NOT NULL DEFAULT ''",
|
66 |
-
"ip": "varchar(60) NOT NULL DEFAULT '0'",
|
67 |
-
"browser": "varchar(32) NOT NULL DEFAULT ''",
|
68 |
-
"last_activity_uri": "text NOT NULL DEFAULT ''"
|
69 |
-
},
|
70 |
-
"sessions_table_timestamp_columns": {
|
71 |
-
"logged_in_at": "Session Started",
|
72 |
-
"last_activity_at": "Last Seen At",
|
73 |
-
"login_intent_expires_at": "2FA Window Expires",
|
74 |
-
"secadmin_at": "Security Admin Authenticated"
|
75 |
-
},
|
76 |
"db_table_sessions": {
|
77 |
"slug": "sessions",
|
78 |
"cols_custom": {
|
56 |
],
|
57 |
"definitions": {
|
58 |
"db_classes": {
|
59 |
+
"sessions": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Session\\Handler"
|
|
|
60 |
},
|
61 |
"sessions_table_name": "sessions",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
"db_table_sessions": {
|
63 |
"slug": "sessions",
|
64 |
"cols_custom": {
|
src/config/feature-traffic.php
CHANGED
@@ -231,16 +231,6 @@
|
|
231 |
}
|
232 |
},
|
233 |
"traffic_table_name": "traffic",
|
234 |
-
"traffic_table_columns": {
|
235 |
-
"rid": "varchar(10) NOT NULL DEFAULT '' COMMENT 'Request ID'",
|
236 |
-
"uid": "int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'User ID'",
|
237 |
-
"ip": "varbinary(16) DEFAULT NULL COMMENT 'Visitor IP Address'",
|
238 |
-
"path": "text NOT NULL DEFAULT '' COMMENT 'Request Path or URI'",
|
239 |
-
"code": "int(5) NOT NULL DEFAULT '200' COMMENT 'HTTP Response Code'",
|
240 |
-
"verb": "varchar(10) NOT NULL DEFAULT 'get' COMMENT 'HTTP Method'",
|
241 |
-
"ua": "text COMMENT 'Browser User Agent String'",
|
242 |
-
"trans": "tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Trangression'"
|
243 |
-
},
|
244 |
"events": {
|
245 |
"request_limit_exceeded": {
|
246 |
"cat": 3,
|
231 |
}
|
232 |
},
|
233 |
"traffic_table_name": "traffic",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
234 |
"events": {
|
235 |
"request_limit_exceeded": {
|
236 |
"cat": 3,
|
src/lib/src/Controller/Config/ConfigVO.php
CHANGED
@@ -66,13 +66,4 @@ class ConfigVO extends DynPropertiesClass {
|
|
66 |
|
67 |
return $val;
|
68 |
}
|
69 |
-
|
70 |
-
/**
|
71 |
-
* @param $key
|
72 |
-
* @return mixed|null
|
73 |
-
* @deprecated 10.3
|
74 |
-
*/
|
75 |
-
private function __adapterGet( $key ) {
|
76 |
-
return $this->getRawData()[ $key ] ?? null;
|
77 |
-
}
|
78 |
}
|
66 |
|
67 |
return $val;
|
68 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
}
|
src/lib/src/Controller/Controller.php
CHANGED
@@ -26,6 +26,7 @@ use FernleafSystems\Wordpress\Services\Utilities\Options\Transient;
|
|
26 |
* @property string $base_file
|
27 |
* @property string $root_file
|
28 |
* @property bool $is_my_upgrade
|
|
|
29 |
* @property bool $user_can_base_permissions
|
30 |
* @property Shield\Modules\Events\Lib\EventsService $service_events
|
31 |
* @property mixed[]|Shield\Modules\Base\ModCon[] $modules
|
@@ -178,6 +179,14 @@ class Controller extends DynPropertiesClass {
|
|
178 |
}
|
179 |
break;
|
180 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
181 |
default:
|
182 |
break;
|
183 |
}
|
@@ -185,15 +194,6 @@ class Controller extends DynPropertiesClass {
|
|
185 |
return $val;
|
186 |
}
|
187 |
|
188 |
-
/**
|
189 |
-
* @param $key
|
190 |
-
* @return mixed|null
|
191 |
-
* @deprecated 10.3
|
192 |
-
*/
|
193 |
-
private function __adapterGet( $key ) {
|
194 |
-
return $this->getRawData()[ $key ] ?? null;
|
195 |
-
}
|
196 |
-
|
197 |
/**
|
198 |
* @throws \Exception
|
199 |
*/
|
@@ -454,11 +454,26 @@ class Controller extends DynPropertiesClass {
|
|
454 |
if ( $this->isModulePage() ) {
|
455 |
add_filter( 'nocache_headers', [ $this, 'adjustNocacheHeaders' ] );
|
456 |
}
|
|
|
457 |
( new Ajax\Init() )
|
458 |
->setCon( $this )
|
459 |
->execute();
|
460 |
}
|
461 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
462 |
/**
|
463 |
* Only set to rebuild as required if you're doing so at the same point in the WordPress load each time.
|
464 |
* Certain plugins can modify the ID at different points in the load.
|
@@ -871,17 +886,6 @@ class Controller extends DynPropertiesClass {
|
|
871 |
return $this->cfg;
|
872 |
}
|
873 |
|
874 |
-
/**
|
875 |
-
* @return array
|
876 |
-
* @deprecated 10.2
|
877 |
-
*/
|
878 |
-
public function getPluginSpec() {
|
879 |
-
if ( isset( $this->cfg ) ) {
|
880 |
-
return $this->cfg->getRawData();
|
881 |
-
}
|
882 |
-
return $this->getPluginControllerOptions()->plugin_spec;
|
883 |
-
}
|
884 |
-
|
885 |
/**
|
886 |
* @param string $key
|
887 |
* @return string|null
|
@@ -998,18 +1002,8 @@ class Controller extends DynPropertiesClass {
|
|
998 |
return add_query_arg( [ 'ver' => $this->getVersion() ], plugins_url( $path, $this->getRootFile() ) );
|
999 |
}
|
1000 |
|
1001 |
-
|
1002 |
-
|
1003 |
-
*/
|
1004 |
-
public function getPluginUrl_Image( string $asset ) :string {
|
1005 |
-
return $this->urls->forImage( $asset );
|
1006 |
-
}
|
1007 |
-
|
1008 |
-
/**
|
1009 |
-
* @deprecated 10.3
|
1010 |
-
*/
|
1011 |
-
public function getPluginUrl_Js( string $asset ) :string {
|
1012 |
-
return $this->urls->forJs( $asset );
|
1013 |
}
|
1014 |
|
1015 |
public function getPluginUrl_AdminMainPage() :string {
|
@@ -1021,33 +1015,6 @@ class Controller extends DynPropertiesClass {
|
|
1021 |
return empty( $asset ) ? $base : path_join( $base, ltrim( $asset, '/' ) );
|
1022 |
}
|
1023 |
|
1024 |
-
/**
|
1025 |
-
* @param string $flag
|
1026 |
-
* @return string
|
1027 |
-
* @deprecated 10.3
|
1028 |
-
*/
|
1029 |
-
public function getPath_Flags( string $flag = '' ) :string {
|
1030 |
-
if ( isset( $this->paths ) ) {
|
1031 |
-
return $this->paths->forFlag( $flag );
|
1032 |
-
}
|
1033 |
-
$base = path_join( $this->getRootDir(), $this->getPluginSpec_Path( 'flags' ) );
|
1034 |
-
return empty( $flag ) ? $base : path_join( $base, $flag );
|
1035 |
-
}
|
1036 |
-
|
1037 |
-
/**
|
1038 |
-
* @param string $sTmpFile
|
1039 |
-
* @return string
|
1040 |
-
*/
|
1041 |
-
public function getPath_Temp( $sTmpFile = '' ) {
|
1042 |
-
$sTempPath = null;
|
1043 |
-
|
1044 |
-
$sBase = path_join( $this->getRootDir(), $this->getPluginSpec_Path( 'temp' ) );
|
1045 |
-
if ( Services::WpFs()->mkdir( $sBase ) ) {
|
1046 |
-
$sTempPath = $sBase;
|
1047 |
-
}
|
1048 |
-
return empty( $sTmpFile ) ? $sTempPath : path_join( $sTempPath, $sTmpFile );
|
1049 |
-
}
|
1050 |
-
|
1051 |
public function getPath_AssetCss( string $asset = '' ) :string {
|
1052 |
return $this->getPath_Assets( 'css/'.$asset );
|
1053 |
}
|
@@ -1160,6 +1127,11 @@ class Controller extends DynPropertiesClass {
|
|
1160 |
return empty( $action ) ? '' : $action;
|
1161 |
}
|
1162 |
|
|
|
|
|
|
|
|
|
|
|
1163 |
/**
|
1164 |
* @return \stdClass
|
1165 |
*/
|
26 |
* @property string $base_file
|
27 |
* @property string $root_file
|
28 |
* @property bool $is_my_upgrade
|
29 |
+
* @property Shield\Utilities\Nonce\Handler $nonce_handler
|
30 |
* @property bool $user_can_base_permissions
|
31 |
* @property Shield\Modules\Events\Lib\EventsService $service_events
|
32 |
* @property mixed[]|Shield\Modules\Base\ModCon[] $modules
|
179 |
}
|
180 |
break;
|
181 |
|
182 |
+
case 'nonce_handler':
|
183 |
+
if ( is_null( $val ) ) {
|
184 |
+
$val = ( new Shield\Utilities\Nonce\Handler() )
|
185 |
+
->setCon( $this );
|
186 |
+
$this->nonce_handler = $val;
|
187 |
+
}
|
188 |
+
break;
|
189 |
+
|
190 |
default:
|
191 |
break;
|
192 |
}
|
194 |
return $val;
|
195 |
}
|
196 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
197 |
/**
|
198 |
* @throws \Exception
|
199 |
*/
|
454 |
if ( $this->isModulePage() ) {
|
455 |
add_filter( 'nocache_headers', [ $this, 'adjustNocacheHeaders' ] );
|
456 |
}
|
457 |
+
$this->processShieldNonceActions();
|
458 |
( new Ajax\Init() )
|
459 |
->setCon( $this )
|
460 |
->execute();
|
461 |
}
|
462 |
|
463 |
+
private function processShieldNonceActions() {
|
464 |
+
$shieldNonceAction = $this->getShieldNonceAction();
|
465 |
+
$shieldNonce = Services::Request()->request( 'shield_nonce' );
|
466 |
+
if ( !empty( $shieldNonceAction ) && !empty( $shieldNonce ) ) {
|
467 |
+
$shieldNonce = Services::Request()->request( 'shield_nonce' );
|
468 |
+
if ( $this->nonce_handler->verify( $shieldNonceAction, $shieldNonce ) ) {
|
469 |
+
do_action( $this->prefix( 'shield_nonce_action' ), $shieldNonceAction );
|
470 |
+
}
|
471 |
+
else {
|
472 |
+
wp_die( 'It appears that this action and nonce has expired. Please retry the action.' );
|
473 |
+
}
|
474 |
+
}
|
475 |
+
}
|
476 |
+
|
477 |
/**
|
478 |
* Only set to rebuild as required if you're doing so at the same point in the WordPress load each time.
|
479 |
* Certain plugins can modify the ID at different points in the load.
|
886 |
return $this->cfg;
|
887 |
}
|
888 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
889 |
/**
|
890 |
* @param string $key
|
891 |
* @return string|null
|
1002 |
return add_query_arg( [ 'ver' => $this->getVersion() ], plugins_url( $path, $this->getRootFile() ) );
|
1003 |
}
|
1004 |
|
1005 |
+
public function getPluginUrl_DashboardHome() :string {
|
1006 |
+
return $this->getModule_Insights()->getUrl_SubInsightsPage( 'overview' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1007 |
}
|
1008 |
|
1009 |
public function getPluginUrl_AdminMainPage() :string {
|
1015 |
return empty( $asset ) ? $base : path_join( $base, ltrim( $asset, '/' ) );
|
1016 |
}
|
1017 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1018 |
public function getPath_AssetCss( string $asset = '' ) :string {
|
1019 |
return $this->getPath_Assets( 'css/'.$asset );
|
1020 |
}
|
1127 |
return empty( $action ) ? '' : $action;
|
1128 |
}
|
1129 |
|
1130 |
+
public function getShieldNonceAction() :string {
|
1131 |
+
$action = sanitize_key( Services::Request()->query( 'shield_nonce_action', '' ) );
|
1132 |
+
return empty( $action ) ? '' : $action;
|
1133 |
+
}
|
1134 |
+
|
1135 |
/**
|
1136 |
* @return \stdClass
|
1137 |
*/
|
src/lib/src/Databases/AuditTrail/Handler.php
CHANGED
@@ -14,15 +14,11 @@ class Handler extends Base\Handler {
|
|
14 |
$this->tableTrimExcess( $opts->getMaxEntries() );
|
15 |
}
|
16 |
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
protected function getDefaultTableName() :string {
|
22 |
return $this->getOptions()->getDef( 'audit_trail_table_name' );
|
23 |
}
|
24 |
-
|
25 |
-
protected function getTimestampColumns() :array {
|
26 |
-
return $this->getOptions()->getDef( 'audittrail_table_timestamp_columns' );
|
27 |
-
}
|
28 |
}
|
14 |
$this->tableTrimExcess( $opts->getMaxEntries() );
|
15 |
}
|
16 |
|
17 |
+
/**
|
18 |
+
* @return string
|
19 |
+
* @deprecated 11.1
|
20 |
+
*/
|
21 |
protected function getDefaultTableName() :string {
|
22 |
return $this->getOptions()->getDef( 'audit_trail_table_name' );
|
23 |
}
|
|
|
|
|
|
|
|
|
24 |
}
|
src/lib/src/Databases/Base/BaseQuery.php
CHANGED
@@ -408,7 +408,7 @@ abstract class BaseQuery {
|
|
408 |
if ( empty( $sGroupByColumn ) ) {
|
409 |
$this->sGroupBy = '';
|
410 |
}
|
411 |
-
elseif ( $this->getDbH()->hasColumn( $sGroupByColumn ) ) {
|
412 |
$this->sGroupBy = $sGroupByColumn;
|
413 |
}
|
414 |
return $this;
|
408 |
if ( empty( $sGroupByColumn ) ) {
|
409 |
$this->sGroupBy = '';
|
410 |
}
|
411 |
+
elseif ( $this->getDbH()->getTableSchema()->hasColumn( $sGroupByColumn ) ) {
|
412 |
$this->sGroupBy = $sGroupByColumn;
|
413 |
}
|
414 |
return $this;
|
src/lib/src/Databases/Base/Handler.php
CHANGED
@@ -71,32 +71,22 @@ abstract class Handler {
|
|
71 |
private function setupTableSchema() :TableSchema {
|
72 |
$this->schema = new TableSchema();
|
73 |
|
74 |
-
$
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
'primary_key' => 'id',
|
88 |
-
'cols_custom' => [],
|
89 |
-
'cols_timestamps' => [],
|
90 |
-
'has_updated_at' => false,
|
91 |
-
'col_older_than' => 'created_at',
|
92 |
-
'autoexpire' => 0,
|
93 |
-
'has_ip_col' => false,
|
94 |
-
],
|
95 |
-
$spec
|
96 |
-
) );
|
97 |
-
}
|
98 |
|
99 |
$this->schema->table = $this->getTable();
|
|
|
100 |
return $this->schema;
|
101 |
}
|
102 |
|
@@ -126,15 +116,7 @@ abstract class Handler {
|
|
126 |
|
127 |
public function getTable() :string {
|
128 |
return Services::WpDb()->getPrefix()
|
129 |
-
.esc_sql( $this->getCon()->prefixOption( $this->
|
130 |
-
}
|
131 |
-
|
132 |
-
/**
|
133 |
-
* @return string
|
134 |
-
* @deprecated 10.3
|
135 |
-
*/
|
136 |
-
protected function getTableSlug() {
|
137 |
-
return empty( $this->sTable ) ? $this->getDefaultTableName() : $this->sTable;
|
138 |
}
|
139 |
|
140 |
/**
|
@@ -194,15 +176,6 @@ abstract class Handler {
|
|
194 |
return new $class();
|
195 |
}
|
196 |
|
197 |
-
/**
|
198 |
-
* @param string $col
|
199 |
-
* @return bool
|
200 |
-
* @deprecated 10.3 - moved to schema
|
201 |
-
*/
|
202 |
-
public function hasColumn( string $col ) :bool {
|
203 |
-
return in_array( strtolower( $col ), $this->getTableSchema()->getColumnNames() );
|
204 |
-
}
|
205 |
-
|
206 |
/**
|
207 |
* @return $this
|
208 |
* @throws \Exception
|
@@ -261,35 +234,15 @@ abstract class Handler {
|
|
261 |
return $this->bIsReady;
|
262 |
}
|
263 |
|
264 |
-
protected function getDefaultTableName() :string {
|
265 |
-
return $this->getTableSchema()->slug;
|
266 |
-
}
|
267 |
-
|
268 |
-
/**
|
269 |
-
* @return string[]
|
270 |
-
* @deprecated 10.3
|
271 |
-
*/
|
272 |
-
protected function getCustomColumns() :array {
|
273 |
-
return [];
|
274 |
-
}
|
275 |
-
|
276 |
/**
|
277 |
-
* @return string
|
278 |
-
* @deprecated
|
279 |
*/
|
280 |
-
protected function
|
281 |
-
return
|
282 |
}
|
283 |
|
284 |
public function getTableSchema() :TableSchema {
|
285 |
-
if ( empty( $this->schema ) ) { // TODO: Delete empty test after 10.3
|
286 |
-
$sch = new TableSchema();
|
287 |
-
$sch->table = $this->getTable();
|
288 |
-
$sch->col_older_than = 'created_at';
|
289 |
-
$sch->cols_custom = $this->getCustomColumns();
|
290 |
-
$sch->cols_timestamps = $this->getTimestampColumns();
|
291 |
-
return $sch;
|
292 |
-
}
|
293 |
return $this->schema;
|
294 |
}
|
295 |
|
71 |
private function setupTableSchema() :TableSchema {
|
72 |
$this->schema = new TableSchema();
|
73 |
|
74 |
+
$this->schema->applyFromArray( array_merge(
|
75 |
+
[
|
76 |
+
'slug' => $this->slug,
|
77 |
+
'primary_key' => 'id',
|
78 |
+
'cols_custom' => [],
|
79 |
+
'cols_timestamps' => [],
|
80 |
+
'has_updated_at' => false,
|
81 |
+
'col_older_than' => 'created_at',
|
82 |
+
'autoexpire' => 0,
|
83 |
+
'has_ip_col' => false,
|
84 |
+
],
|
85 |
+
$this->getOptions()->getDef( 'db_table_'.$this->slug )
|
86 |
+
) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
|
88 |
$this->schema->table = $this->getTable();
|
89 |
+
|
90 |
return $this->schema;
|
91 |
}
|
92 |
|
116 |
|
117 |
public function getTable() :string {
|
118 |
return Services::WpDb()->getPrefix()
|
119 |
+
.esc_sql( $this->getCon()->prefixOption( $this->getTableSchema()->slug ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
}
|
121 |
|
122 |
/**
|
176 |
return new $class();
|
177 |
}
|
178 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
/**
|
180 |
* @return $this
|
181 |
* @throws \Exception
|
234 |
return $this->bIsReady;
|
235 |
}
|
236 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
237 |
/**
|
238 |
+
* @return string
|
239 |
+
* @deprecated 11.1
|
240 |
*/
|
241 |
+
protected function getDefaultTableName() :string {
|
242 |
+
return $this->getTableSchema()->slug;
|
243 |
}
|
244 |
|
245 |
public function getTableSchema() :TableSchema {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
246 |
return $this->schema;
|
247 |
}
|
248 |
|
src/lib/src/Databases/Base/Insert.php
CHANGED
@@ -23,9 +23,7 @@ class Insert extends BaseQuery {
|
|
23 |
* @return bool
|
24 |
*/
|
25 |
public function insert( $entry ) :bool {
|
26 |
-
|
27 |
-
$data = (array)$entry->getRawData();
|
28 |
-
return $this->setInsertData( $data )->query() === 1;
|
29 |
}
|
30 |
|
31 |
/**
|
@@ -47,7 +45,7 @@ class Insert extends BaseQuery {
|
|
47 |
*/
|
48 |
protected function verifyInsertData() {
|
49 |
$baseData = [ 'created_at' => Services::Request()->ts() ];
|
50 |
-
if ( $this->getDbH()->hasColumn( 'updated_at' ) ) {
|
51 |
$baseData[ 'updated_at' ] = Services::Request()->ts();
|
52 |
}
|
53 |
return $this->setInsertData( array_merge( $baseData, $this->getInsertData() ) );
|
23 |
* @return bool
|
24 |
*/
|
25 |
public function insert( $entry ) :bool {
|
26 |
+
return $this->setInsertData( $entry->getRawData() )->query() === 1;
|
|
|
|
|
27 |
}
|
28 |
|
29 |
/**
|
45 |
*/
|
46 |
protected function verifyInsertData() {
|
47 |
$baseData = [ 'created_at' => Services::Request()->ts() ];
|
48 |
+
if ( $this->getDbH()->getTableSchema()->hasColumn( 'updated_at' ) ) {
|
49 |
$baseData[ 'updated_at' ] = Services::Request()->ts();
|
50 |
}
|
51 |
return $this->setInsertData( array_merge( $baseData, $this->getInsertData() ) );
|
src/lib/src/Databases/Base/Select.php
CHANGED
@@ -14,7 +14,7 @@ class Select extends BaseQuery {
|
|
14 |
/**
|
15 |
* @var bool
|
16 |
*/
|
17 |
-
protected $
|
18 |
|
19 |
/**
|
20 |
* @var bool
|
@@ -85,19 +85,19 @@ class Select extends BaseQuery {
|
|
85 |
* @return string
|
86 |
*/
|
87 |
protected function buildSelect() {
|
88 |
-
$
|
89 |
|
90 |
if ( $this->isCount() ) {
|
91 |
$sSubstitute = 'COUNT(*)';
|
92 |
}
|
93 |
elseif ( $this->isSum() ) {
|
94 |
-
$sSubstitute = sprintf( 'SUM(%s)', array_shift( $
|
95 |
}
|
96 |
elseif ( $this->isDistinct() && $this->hasColumnsToSelect() ) {
|
97 |
-
$sSubstitute = sprintf( 'DISTINCT %s', implode( ',', $
|
98 |
}
|
99 |
elseif ( $this->hasColumnsToSelect() ) {
|
100 |
-
$sSubstitute = implode( ',', $
|
101 |
}
|
102 |
elseif ( $this->isCustomSelect() ) {
|
103 |
$sSubstitute = $this->sCustomSelect;
|
@@ -108,6 +108,10 @@ class Select extends BaseQuery {
|
|
108 |
return $sSubstitute;
|
109 |
}
|
110 |
|
|
|
|
|
|
|
|
|
111 |
public function count() :int {
|
112 |
return (int)$this->setIsCount( true )->query();
|
113 |
}
|
@@ -163,7 +167,7 @@ class Select extends BaseQuery {
|
|
163 |
}
|
164 |
|
165 |
public function isCount() :bool {
|
166 |
-
return (bool)$this->
|
167 |
}
|
168 |
|
169 |
public function isSum() :bool {
|
@@ -286,7 +290,7 @@ class Select extends BaseQuery {
|
|
286 |
}
|
287 |
|
288 |
public function setIsCount( bool $isCount ) :self {
|
289 |
-
$this->
|
290 |
return $this;
|
291 |
}
|
292 |
|
14 |
/**
|
15 |
* @var bool
|
16 |
*/
|
17 |
+
protected $isCount = false;
|
18 |
|
19 |
/**
|
20 |
* @var bool
|
85 |
* @return string
|
86 |
*/
|
87 |
protected function buildSelect() {
|
88 |
+
$cols = $this->getColumnsToSelect();
|
89 |
|
90 |
if ( $this->isCount() ) {
|
91 |
$sSubstitute = 'COUNT(*)';
|
92 |
}
|
93 |
elseif ( $this->isSum() ) {
|
94 |
+
$sSubstitute = sprintf( 'SUM(%s)', array_shift( $cols ) );
|
95 |
}
|
96 |
elseif ( $this->isDistinct() && $this->hasColumnsToSelect() ) {
|
97 |
+
$sSubstitute = sprintf( 'DISTINCT %s', implode( ',', $cols ) );
|
98 |
}
|
99 |
elseif ( $this->hasColumnsToSelect() ) {
|
100 |
+
$sSubstitute = implode( ',', $cols );
|
101 |
}
|
102 |
elseif ( $this->isCustomSelect() ) {
|
103 |
$sSubstitute = $this->sCustomSelect;
|
108 |
return $sSubstitute;
|
109 |
}
|
110 |
|
111 |
+
public function sumColumn() :int {
|
112 |
+
return (int)$this->setIsCount( true )->query();
|
113 |
+
}
|
114 |
+
|
115 |
public function count() :int {
|
116 |
return (int)$this->setIsCount( true )->query();
|
117 |
}
|
167 |
}
|
168 |
|
169 |
public function isCount() :bool {
|
170 |
+
return (bool)$this->isCount;
|
171 |
}
|
172 |
|
173 |
public function isSum() :bool {
|
290 |
}
|
291 |
|
292 |
public function setIsCount( bool $isCount ) :self {
|
293 |
+
$this->isCount = $isCount;
|
294 |
return $this;
|
295 |
}
|
296 |
|
src/lib/src/Databases/Base/Update.php
CHANGED
@@ -71,7 +71,7 @@ class Update extends Insert {
|
|
71 |
$success = true;
|
72 |
}
|
73 |
else {
|
74 |
-
if ( $this->getDbH()->hasColumn( 'updated_at' ) && !isset( $updateData[ 'updated_at' ] ) ) {
|
75 |
$updateData[ 'updated_at' ] = Services::Request()->ts();
|
76 |
}
|
77 |
if ( $this->updateById( $entry->id, $updateData ) ) {
|
71 |
$success = true;
|
72 |
}
|
73 |
else {
|
74 |
+
if ( $this->getDbH()->getTableSchema()->hasColumn( 'updated_at' ) && !isset( $updateData[ 'updated_at' ] ) ) {
|
75 |
$updateData[ 'updated_at' ] = Services::Request()->ts();
|
76 |
}
|
77 |
if ( $this->updateById( $entry->id, $updateData ) ) {
|
src/lib/src/Databases/ChangeTracking/Handler.php
CHANGED
@@ -3,31 +3,7 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\ChangeTracking;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Base;
|
6 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\AuditTrail\Options;
|
7 |
|
8 |
class Handler extends Base\Handler {
|
9 |
|
10 |
-
/**
|
11 |
-
* @return string[]
|
12 |
-
*/
|
13 |
-
public function getColumns() :array {
|
14 |
-
return $this->getOptions()->getDef( 'table_columns_changetracking' );
|
15 |
-
}
|
16 |
-
|
17 |
-
protected function getDefaultTableName() :string {
|
18 |
-
/** @var Options $opts */
|
19 |
-
$opts = $this->getOptions();
|
20 |
-
return $opts->getDbTable_ChangeTracking();
|
21 |
-
}
|
22 |
-
|
23 |
-
protected function getDefaultCreateTableSql() :string {
|
24 |
-
return "CREATE TABLE %s (
|
25 |
-
id int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
26 |
-
data BLOB NOT NULL DEFAULT '' COMMENT 'Snapshot Data',
|
27 |
-
meta TEXT NOT NULL DEFAULT '' COMMENT 'Snapshot Meta',
|
28 |
-
created_at int(15) UNSIGNED NOT NULL DEFAULT 0,
|
29 |
-
deleted_at int(15) UNSIGNED NOT NULL DEFAULT 0,
|
30 |
-
PRIMARY KEY (id)
|
31 |
-
) %s;";
|
32 |
-
}
|
33 |
}
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\ChangeTracking;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Base;
|
|
|
6 |
|
7 |
class Handler extends Base\Handler {
|
8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
}
|
src/lib/src/Databases/Common/TableSchema.php
CHANGED
@@ -70,7 +70,7 @@ class TableSchema extends DynPropertiesClass {
|
|
70 |
return array_merge(
|
71 |
$this->getColumn_ID(),
|
72 |
$this->cols_custom ?? [],
|
73 |
-
|
74 |
);
|
75 |
}
|
76 |
|
@@ -111,35 +111,6 @@ class TableSchema extends DynPropertiesClass {
|
|
111 |
);
|
112 |
}
|
113 |
|
114 |
-
/**
|
115 |
-
* @return string[]
|
116 |
-
* @deprecated 10.3
|
117 |
-
*/
|
118 |
-
protected function getColumnns_Timestamps() :array {
|
119 |
-
|
120 |
-
$standardTsCols = [
|
121 |
-
'created_at' => 'Created At',
|
122 |
-
'deleted_at' => 'Soft Deleted At',
|
123 |
-
];
|
124 |
-
|
125 |
-
if ( $this->has_updated_at && !array_key_exists( 'updated_at', $this->cols_timestamps ) ) {
|
126 |
-
$standardTsCols = array_merge(
|
127 |
-
[ 'updated_at' => 'Updated At', ],
|
128 |
-
$standardTsCols
|
129 |
-
);
|
130 |
-
}
|
131 |
-
|
132 |
-
return array_map(
|
133 |
-
function ( $comment ) {
|
134 |
-
return $this->getTimestampColDef( $comment );
|
135 |
-
},
|
136 |
-
array_merge(
|
137 |
-
$this->cols_timestamps ?? [],
|
138 |
-
$standardTsCols
|
139 |
-
)
|
140 |
-
);
|
141 |
-
}
|
142 |
-
|
143 |
protected function getPrimaryKeyDef() :string {
|
144 |
return sprintf( 'PRIMARY KEY (%s)', $this->getPrimaryKeyColumnName() );
|
145 |
}
|
70 |
return array_merge(
|
71 |
$this->getColumn_ID(),
|
72 |
$this->cols_custom ?? [],
|
73 |
+
$this->getColumns_Timestamps()
|
74 |
);
|
75 |
}
|
76 |
|
111 |
);
|
112 |
}
|
113 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
protected function getPrimaryKeyDef() :string {
|
115 |
return sprintf( 'PRIMARY KEY (%s)', $this->getPrimaryKeyColumnName() );
|
116 |
}
|
src/lib/src/Databases/Events/Handler.php
CHANGED
@@ -37,10 +37,10 @@ class Handler extends Base\Handler {
|
|
37 |
return $QI->insert( $oEvt );
|
38 |
}
|
39 |
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
protected function getDefaultTableName() :string {
|
45 |
return $this->getOptions()->getDef( 'events_table_name' );
|
46 |
}
|
37 |
return $QI->insert( $oEvt );
|
38 |
}
|
39 |
|
40 |
+
/**
|
41 |
+
* @return string
|
42 |
+
* @deprecated 11.1
|
43 |
+
*/
|
44 |
protected function getDefaultTableName() :string {
|
45 |
return $this->getOptions()->getDef( 'events_table_name' );
|
46 |
}
|
src/lib/src/Databases/Events/Select.php
CHANGED
@@ -9,11 +9,11 @@ class Select extends Base\Select {
|
|
9 |
use Common;
|
10 |
|
11 |
/**
|
12 |
-
* @param string $
|
13 |
* @return int
|
14 |
*/
|
15 |
-
public function sumEvent( $
|
16 |
-
return $this->sumEvents( [ $
|
17 |
}
|
18 |
|
19 |
/**
|
@@ -77,7 +77,7 @@ class Select extends Base\Select {
|
|
77 |
/**
|
78 |
* @return string[]
|
79 |
*/
|
80 |
-
public function getAllEvents() {
|
81 |
return $this->reset()->getDistinctForColumn( 'event' );
|
82 |
}
|
83 |
|
9 |
use Common;
|
10 |
|
11 |
/**
|
12 |
+
* @param string $event
|
13 |
* @return int
|
14 |
*/
|
15 |
+
public function sumEvent( $event ) :int {
|
16 |
+
return $this->sumEvents( [ $event ] );
|
17 |
}
|
18 |
|
19 |
/**
|
77 |
/**
|
78 |
* @return string[]
|
79 |
*/
|
80 |
+
public function getAllEvents() :array {
|
81 |
return $this->reset()->getDistinctForColumn( 'event' );
|
82 |
}
|
83 |
|
src/lib/src/Databases/FileLocker/Handler.php
CHANGED
@@ -6,10 +6,10 @@ use FernleafSystems\Wordpress\Plugin\Shield\Databases\Base;
|
|
6 |
|
7 |
class Handler extends Base\Handler {
|
8 |
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
protected function getDefaultTableName() :string {
|
14 |
return $this->getOptions()->getDef( 'table_name_filelocker' );
|
15 |
}
|
6 |
|
7 |
class Handler extends Base\Handler {
|
8 |
|
9 |
+
/**
|
10 |
+
* @return string
|
11 |
+
* @deprecated 11.1
|
12 |
+
*/
|
13 |
protected function getDefaultTableName() :string {
|
14 |
return $this->getOptions()->getDef( 'table_name_filelocker' );
|
15 |
}
|
src/lib/src/Databases/IPs/Handler.php
CHANGED
@@ -31,26 +31,10 @@ class Handler extends Base\Handler {
|
|
31 |
}
|
32 |
|
33 |
/**
|
34 |
-
* @return string
|
35 |
-
* @deprecated
|
36 |
-
*/
|
37 |
-
protected function getCustomColumns() :array {
|
38 |
-
return $this->getOptions()->getDef( 'ip_list_table_columns' );
|
39 |
-
}
|
40 |
-
|
41 |
-
/**
|
42 |
-
* @return string[]
|
43 |
-
* @deprecated 10.3
|
44 |
*/
|
45 |
protected function getDefaultTableName() :string {
|
46 |
return $this->getOptions()->getDef( 'ip_lists_table_name' );
|
47 |
}
|
48 |
-
|
49 |
-
/**
|
50 |
-
* @return string[]
|
51 |
-
* @deprecated 10.3
|
52 |
-
*/
|
53 |
-
protected function getTimestampColumns() :array {
|
54 |
-
return $this->getOptions()->getDef( 'ip_list_table_timestamp_columns' );
|
55 |
-
}
|
56 |
}
|
31 |
}
|
32 |
|
33 |
/**
|
34 |
+
* @return string
|
35 |
+
* @deprecated 11.1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
*/
|
37 |
protected function getDefaultTableName() :string {
|
38 |
return $this->getOptions()->getDef( 'ip_lists_table_name' );
|
39 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
}
|
src/lib/src/Databases/ScanQueue/Select.php
CHANGED
@@ -36,21 +36,17 @@ class Select extends Base\Select {
|
|
36 |
->setColumnsToSelect( [ 'scan' ] )
|
37 |
->filterByNotFinished()
|
38 |
->query();
|
39 |
-
$
|
40 |
-
/** @var EntryVO $
|
41 |
-
foreach ( $aResults as $
|
42 |
-
$
|
43 |
}
|
44 |
-
return array_keys( $
|
45 |
}
|
46 |
|
47 |
-
|
48 |
-
* @param string $sScan
|
49 |
-
* @return int
|
50 |
-
*/
|
51 |
-
public function countForScan( $sScan ) {
|
52 |
return $this->reset()
|
53 |
-
->filterByScan( $
|
54 |
->count();
|
55 |
}
|
56 |
}
|
36 |
->setColumnsToSelect( [ 'scan' ] )
|
37 |
->filterByNotFinished()
|
38 |
->query();
|
39 |
+
$scans = [];
|
40 |
+
/** @var EntryVO $entry */
|
41 |
+
foreach ( $aResults as $entry ) {
|
42 |
+
$scans[ $entry->scan ] = 1;
|
43 |
}
|
44 |
+
return array_keys( $scans );
|
45 |
}
|
46 |
|
47 |
+
public function countForScan( string $scan ) :int {
|
|
|
|
|
|
|
|
|
48 |
return $this->reset()
|
49 |
+
->filterByScan( $scan )
|
50 |
->count();
|
51 |
}
|
52 |
}
|
src/lib/src/Databases/Scanner/Select.php
CHANGED
@@ -8,24 +8,20 @@ class Select extends Base\Select {
|
|
8 |
|
9 |
use Common;
|
10 |
|
11 |
-
|
12 |
-
* @param string $sScan
|
13 |
-
* @return int
|
14 |
-
*/
|
15 |
-
public function countForScan( $sScan ) {
|
16 |
return $this->reset()
|
17 |
->filterByNotIgnored()
|
18 |
-
->filterByScan( $
|
19 |
->count();
|
20 |
}
|
21 |
|
22 |
/**
|
23 |
-
* @param string $
|
24 |
* @return EntryVO[]
|
25 |
*/
|
26 |
-
public function forScan( $
|
27 |
return $this->reset()
|
28 |
-
->filterByScan( $
|
29 |
->query();
|
30 |
}
|
31 |
}
|
8 |
|
9 |
use Common;
|
10 |
|
11 |
+
public function countForScan( string $scan ) :int {
|
|
|
|
|
|
|
|
|
12 |
return $this->reset()
|
13 |
->filterByNotIgnored()
|
14 |
+
->filterByScan( $scan )
|
15 |
->count();
|
16 |
}
|
17 |
|
18 |
/**
|
19 |
+
* @param string $scan
|
20 |
* @return EntryVO[]
|
21 |
*/
|
22 |
+
public function forScan( $scan ) {
|
23 |
return $this->reset()
|
24 |
+
->filterByScan( $scan )
|
25 |
->query();
|
26 |
}
|
27 |
}
|
src/lib/src/Databases/Session/Handler.php
CHANGED
@@ -10,15 +10,11 @@ class Handler extends Base\Handler {
|
|
10 |
$this->tableCleanExpired( 30 );
|
11 |
}
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
protected function getDefaultTableName() :string {
|
18 |
return $this->getOptions()->getDef( 'sessions_table_name' );
|
19 |
}
|
20 |
-
|
21 |
-
protected function getTimestampColumns() :array {
|
22 |
-
return $this->getOptions()->getDef( 'sessions_table_timestamp_columns' );
|
23 |
-
}
|
24 |
}
|
10 |
$this->tableCleanExpired( 30 );
|
11 |
}
|
12 |
|
13 |
+
/**
|
14 |
+
* @return string
|
15 |
+
* @deprecated 11.1
|
16 |
+
*/
|
17 |
protected function getDefaultTableName() :string {
|
18 |
return $this->getOptions()->getDef( 'sessions_table_name' );
|
19 |
}
|
|
|
|
|
|
|
|
|
20 |
}
|
src/lib/src/Databases/Traffic/Handler.php
CHANGED
@@ -14,11 +14,11 @@ class Handler extends Base\Handler {
|
|
14 |
$this->tableTrimExcess( $opts->getMaxEntries() );
|
15 |
}
|
16 |
|
|
|
|
|
|
|
|
|
17 |
protected function getDefaultTableName() :string {
|
18 |
return $this->getOptions()->getDef( 'traffic_table_name' );
|
19 |
}
|
20 |
-
|
21 |
-
protected function getCustomColumns() :array {
|
22 |
-
return $this->getOptions()->getDef( 'traffic_table_columns' );
|
23 |
-
}
|
24 |
}
|
14 |
$this->tableTrimExcess( $opts->getMaxEntries() );
|
15 |
}
|
16 |
|
17 |
+
/**
|
18 |
+
* @return string
|
19 |
+
* @deprecated 11.1
|
20 |
+
*/
|
21 |
protected function getDefaultTableName() :string {
|
22 |
return $this->getOptions()->getDef( 'traffic_table_name' );
|
23 |
}
|
|
|
|
|
|
|
|
|
24 |
}
|
src/lib/src/Modules/AuditTrail/Auditors/Base.php
CHANGED
@@ -1,10 +1,12 @@
|
|
1 |
-
<?php
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\AuditTrail\Auditors;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
6 |
|
7 |
class Base {
|
8 |
|
9 |
use Modules\ModConsumer;
|
|
|
10 |
}
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\AuditTrail\Auditors;
|
4 |
|
5 |
+
use FernleafSystems\Utilities\Logic\ExecOnce;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
7 |
|
8 |
class Base {
|
9 |
|
10 |
use Modules\ModConsumer;
|
11 |
+
use ExecOnce;
|
12 |
}
|
src/lib/src/Modules/AuditTrail/Auditors/Emails.php
CHANGED
@@ -6,7 +6,7 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
6 |
|
7 |
class Emails extends Base {
|
8 |
|
9 |
-
|
10 |
add_filter( 'wp_mail', [ $this, 'auditEmailSend' ], PHP_INT_MAX );
|
11 |
}
|
12 |
|
6 |
|
7 |
class Emails extends Base {
|
8 |
|
9 |
+
protected function run() {
|
10 |
add_filter( 'wp_mail', [ $this, 'auditEmailSend' ], PHP_INT_MAX );
|
11 |
}
|
12 |
|
src/lib/src/Modules/AuditTrail/Auditors/Plugins.php
CHANGED
@@ -4,7 +4,7 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\AuditTrail\Auditors;
|
|
4 |
|
5 |
class Plugins extends Base {
|
6 |
|
7 |
-
|
8 |
add_action( 'deactivated_plugin', [ $this, 'auditDeactivatedPlugin' ] );
|
9 |
add_action( 'activated_plugin', [ $this, 'auditActivatedPlugin' ] );
|
10 |
add_action( 'check_admin_referer', [ $this, 'auditEditedFile' ], 10, 2 );
|
4 |
|
5 |
class Plugins extends Base {
|
6 |
|
7 |
+
protected function run() {
|
8 |
add_action( 'deactivated_plugin', [ $this, 'auditDeactivatedPlugin' ] );
|
9 |
add_action( 'activated_plugin', [ $this, 'auditActivatedPlugin' ] );
|
10 |
add_action( 'check_admin_referer', [ $this, 'auditEditedFile' ], 10, 2 );
|
src/lib/src/Modules/AuditTrail/Auditors/Posts.php
CHANGED
@@ -6,7 +6,7 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
6 |
|
7 |
class Posts extends Base {
|
8 |
|
9 |
-
|
10 |
add_action( 'deleted_post', [ $this, 'auditDeletedPost' ] );
|
11 |
add_action( 'transition_post_status', [ $this, 'auditPostStatus' ], 30, 3 );
|
12 |
}
|
6 |
|
7 |
class Posts extends Base {
|
8 |
|
9 |
+
protected function run() {
|
10 |
add_action( 'deleted_post', [ $this, 'auditDeletedPost' ] );
|
11 |
add_action( 'transition_post_status', [ $this, 'auditPostStatus' ], 30, 3 );
|
12 |
}
|
src/lib/src/Modules/AuditTrail/Auditors/Themes.php
CHANGED
@@ -4,7 +4,7 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\AuditTrail\Auditors;
|
|
4 |
|
5 |
class Themes extends Base {
|
6 |
|
7 |
-
|
8 |
add_action( 'switch_theme', [ $this, 'auditSwitchTheme' ] );
|
9 |
add_action( 'check_admin_referer', [ $this, 'auditEditedThemeFile' ], 10, 2 );
|
10 |
}
|
4 |
|
5 |
class Themes extends Base {
|
6 |
|
7 |
+
protected function run() {
|
8 |
add_action( 'switch_theme', [ $this, 'auditSwitchTheme' ] );
|
9 |
add_action( 'check_admin_referer', [ $this, 'auditEditedThemeFile' ], 10, 2 );
|
10 |
}
|
src/lib/src/Modules/AuditTrail/Auditors/Upgrades.php
CHANGED
@@ -16,10 +16,24 @@ class Upgrades extends Base {
|
|
16 |
*/
|
17 |
private $themes;
|
18 |
|
19 |
-
|
20 |
$this->init();
|
21 |
add_action( 'upgrader_process_complete', [ $this, 'auditUpgrades' ], 10, 2 );
|
22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
}
|
24 |
|
25 |
private function init() {
|
@@ -59,30 +73,39 @@ class Upgrades extends Base {
|
|
59 |
private function handlePlugin( string $item ) {
|
60 |
$WPP = Services::WpPlugins();
|
61 |
$VO = $WPP->getPluginAsVo( $item, true );
|
62 |
-
$
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
'
|
67 |
-
|
68 |
-
|
|
|
|
|
69 |
]
|
70 |
-
|
71 |
-
|
72 |
}
|
73 |
|
|
|
|
|
|
|
|
|
|
|
74 |
private function handleTheme( string $item ) {
|
75 |
$WPT = Services::WpThemes();
|
76 |
$VO = $WPT->getThemeAsVo( $item, true );
|
77 |
-
$
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
'
|
82 |
-
|
83 |
-
|
|
|
|
|
84 |
]
|
85 |
-
|
86 |
-
|
87 |
}
|
88 |
}
|
16 |
*/
|
17 |
private $themes;
|
18 |
|
19 |
+
protected function run() {
|
20 |
$this->init();
|
21 |
add_action( 'upgrader_process_complete', [ $this, 'auditUpgrades' ], 10, 2 );
|
22 |
+
add_filter( 'upgrader_post_install', [ $this, 'auditUpgrade2' ], 10, 2 );
|
23 |
+
}
|
24 |
+
|
25 |
+
public function auditUpgrade2( $true, $hooksExtra ) {
|
26 |
+
add_action( $this->getCon()->prefix( 'pre_plugin_shutdown' ),
|
27 |
+
function () use ( $hooksExtra ) {
|
28 |
+
if ( !empty( $hooksExtra[ 'plugin' ] ) ) {
|
29 |
+
$this->handlePlugin( $hooksExtra[ 'plugin' ] );
|
30 |
+
}
|
31 |
+
elseif ( !empty( $hooksExtra[ 'theme' ] ) ) {
|
32 |
+
$this->handleTheme( $hooksExtra[ 'theme' ] );
|
33 |
+
}
|
34 |
+
}
|
35 |
+
);
|
36 |
+
return $true;
|
37 |
}
|
38 |
|
39 |
private function init() {
|
73 |
private function handlePlugin( string $item ) {
|
74 |
$WPP = Services::WpPlugins();
|
75 |
$VO = $WPP->getPluginAsVo( $item, true );
|
76 |
+
if ( !empty( $VO ) ) {
|
77 |
+
$this->getCon()->fireEvent(
|
78 |
+
'plugin_upgraded',
|
79 |
+
[
|
80 |
+
'audit' => [
|
81 |
+
'file' => $VO->Name,
|
82 |
+
'from' => $this->plugins[ $item ],
|
83 |
+
'to' => $VO->Version,
|
84 |
+
]
|
85 |
]
|
86 |
+
);
|
87 |
+
}
|
88 |
}
|
89 |
|
90 |
+
/**
|
91 |
+
* Hooked into 'shutdown' to ensure that the latest theme data is avaiable
|
92 |
+
* so that we can get the "upgraded to" version correctly.
|
93 |
+
* @param string $item
|
94 |
+
*/
|
95 |
private function handleTheme( string $item ) {
|
96 |
$WPT = Services::WpThemes();
|
97 |
$VO = $WPT->getThemeAsVo( $item, true );
|
98 |
+
if ( !empty( $VO ) ) {
|
99 |
+
$this->getCon()->fireEvent(
|
100 |
+
'theme_upgraded',
|
101 |
+
[
|
102 |
+
'audit' => [
|
103 |
+
'file' => $VO->Name,
|
104 |
+
'from' => $this->themes[ $item ],
|
105 |
+
'to' => $VO->Version,
|
106 |
+
]
|
107 |
]
|
108 |
+
);
|
109 |
+
}
|
110 |
}
|
111 |
}
|
src/lib/src/Modules/AuditTrail/Auditors/Users.php
CHANGED
@@ -9,7 +9,7 @@ class Users extends Base {
|
|
9 |
|
10 |
use WpLoginCapture;
|
11 |
|
12 |
-
|
13 |
$this->setupLoginCaptureHooks();
|
14 |
$this->setToCaptureApplicationLogin( true );
|
15 |
|
9 |
|
10 |
use WpLoginCapture;
|
11 |
|
12 |
+
protected function run() {
|
13 |
$this->setupLoginCaptureHooks();
|
14 |
$this->setToCaptureApplicationLogin( true );
|
15 |
|
src/lib/src/Modules/AuditTrail/Auditors/Wordpress.php
CHANGED
@@ -6,7 +6,7 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
6 |
|
7 |
class Wordpress extends Base {
|
8 |
|
9 |
-
|
10 |
add_action( '_core_updated_successfully', [ $this, 'auditCoreUpdated' ] );
|
11 |
add_action( 'update_option_permalink_structure', [ $this, 'auditPermalinkStructure' ], 10, 2 );
|
12 |
}
|
6 |
|
7 |
class Wordpress extends Base {
|
8 |
|
9 |
+
protected function run() {
|
10 |
add_action( '_core_updated_successfully', [ $this, 'auditCoreUpdated' ] );
|
11 |
add_action( 'update_option_permalink_structure', [ $this, 'auditPermalinkStructure' ], 10, 2 );
|
12 |
}
|
src/lib/src/Modules/AuditTrail/Lib/AuditWriter.php
CHANGED
@@ -18,27 +18,30 @@ class AuditWriter extends EventsListener {
|
|
18 |
|
19 |
/**
|
20 |
* @param string $evt
|
21 |
-
* @param array $
|
|
|
22 |
*/
|
23 |
-
protected function captureEvent( $evt, $
|
24 |
-
$
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
$
|
30 |
-
$
|
31 |
-
$
|
32 |
-
$
|
|
|
|
|
33 |
|
34 |
$aLogs = $this->getLogs();
|
35 |
|
36 |
// cater for where certain events may happen more than once in the same request
|
37 |
-
if ( !empty( $
|
38 |
-
$aLogs[] = $
|
39 |
}
|
40 |
else {
|
41 |
-
$aLogs[ $evt ] = $
|
42 |
}
|
43 |
|
44 |
$this->setLogs( $aLogs );
|
18 |
|
19 |
/**
|
20 |
* @param string $evt
|
21 |
+
* @param array $meta
|
22 |
+
* @param array $def
|
23 |
*/
|
24 |
+
protected function captureEvent( string $evt, $meta = [], $def = [] ) {
|
25 |
+
$con = $this->getCon();
|
26 |
+
if ( empty( $def ) ) { // TODO: @deprecated 11.1 - remove this if
|
27 |
+
$def = $con->loadEventsService()->getEventDef( $evt );
|
28 |
+
}
|
29 |
+
if ( $def[ 'audit' ] && empty( $meta[ 'suppress_audit' ] ) ) { // only audit if it's an auditable event
|
30 |
+
$entry = new AuditTrail\EntryVO();
|
31 |
+
$entry->rid = $con->getShortRequestId();
|
32 |
+
$entry->event = $evt;
|
33 |
+
$entry->category = $def[ 'cat' ];
|
34 |
+
$entry->context = $def[ 'context' ];
|
35 |
+
$entry->meta = isset( $meta[ 'audit' ] ) ? $meta[ 'audit' ] : [];
|
36 |
|
37 |
$aLogs = $this->getLogs();
|
38 |
|
39 |
// cater for where certain events may happen more than once in the same request
|
40 |
+
if ( !empty( $def[ 'audit_multiple' ] ) ) {
|
41 |
+
$aLogs[] = $entry;
|
42 |
}
|
43 |
else {
|
44 |
+
$aLogs[ $evt ] = $entry;
|
45 |
}
|
46 |
|
47 |
$this->setLogs( $aLogs );
|
src/lib/src/Modules/AuditTrail/ModCon.php
CHANGED
@@ -10,8 +10,7 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
10 |
class ModCon extends BaseShield\ModCon {
|
11 |
|
12 |
public function getDbHandler_AuditTrail() :Shield\Databases\AuditTrail\Handler {
|
13 |
-
|
14 |
-
return empty( $new ) ? $this->getDbH( 'audit' ) : $new;
|
15 |
}
|
16 |
|
17 |
protected function handleFileDownload( string $downloadID ) {
|
10 |
class ModCon extends BaseShield\ModCon {
|
11 |
|
12 |
public function getDbHandler_AuditTrail() :Shield\Databases\AuditTrail\Handler {
|
13 |
+
return $this->getDbH( 'audit_trail' );
|
|
|
14 |
}
|
15 |
|
16 |
protected function handleFileDownload( string $downloadID ) {
|
src/lib/src/Modules/AuditTrail/Processor.php
CHANGED
@@ -35,25 +35,25 @@ class Processor extends BaseShield\Processor {
|
|
35 |
|
36 |
( new Auditors\Users() )
|
37 |
->setMod( $this->getMod() )
|
38 |
-
->
|
39 |
( new Auditors\Plugins() )
|
40 |
->setMod( $this->getMod() )
|
41 |
-
->
|
42 |
( new Auditors\Themes() )
|
43 |
->setMod( $this->getMod() )
|
44 |
-
->
|
45 |
( new Auditors\Wordpress() )
|
46 |
->setMod( $this->getMod() )
|
47 |
-
->
|
48 |
( new Auditors\Posts() )
|
49 |
->setMod( $this->getMod() )
|
50 |
-
->
|
51 |
( new Auditors\Emails() )
|
52 |
->setMod( $this->getMod() )
|
53 |
-
->
|
54 |
( new Auditors\Upgrades() )
|
55 |
->setMod( $this->getMod() )
|
56 |
-
->
|
57 |
}
|
58 |
|
59 |
/**
|
35 |
|
36 |
( new Auditors\Users() )
|
37 |
->setMod( $this->getMod() )
|
38 |
+
->execute();
|
39 |
( new Auditors\Plugins() )
|
40 |
->setMod( $this->getMod() )
|
41 |
+
->execute();
|
42 |
( new Auditors\Themes() )
|
43 |
->setMod( $this->getMod() )
|
44 |
+
->execute();
|
45 |
( new Auditors\Wordpress() )
|
46 |
->setMod( $this->getMod() )
|
47 |
+
->execute();
|
48 |
( new Auditors\Posts() )
|
49 |
->setMod( $this->getMod() )
|
50 |
+
->execute();
|
51 |
( new Auditors\Emails() )
|
52 |
->setMod( $this->getMod() )
|
53 |
+
->execute();
|
54 |
( new Auditors\Upgrades() )
|
55 |
->setMod( $this->getMod() )
|
56 |
+
->execute();
|
57 |
}
|
58 |
|
59 |
/**
|
src/lib/src/Modules/AuditTrail/UI.php
CHANGED
@@ -50,14 +50,4 @@ class UI extends BaseShield\UI {
|
|
50 |
true
|
51 |
);
|
52 |
}
|
53 |
-
|
54 |
-
protected function getSettingsRelatedLinks() :array {
|
55 |
-
$modInsights = $this->getCon()->getModule_Insights();
|
56 |
-
return [
|
57 |
-
[
|
58 |
-
'href' => $modInsights->getUrl_SubInsightsPage( 'audit' ),
|
59 |
-
'title' => __( 'View Audit Trail', 'wp-simple-firewall' ),
|
60 |
-
]
|
61 |
-
];
|
62 |
-
}
|
63 |
}
|
50 |
true
|
51 |
);
|
52 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
}
|
src/lib/src/Modules/Base/AjaxHandler.php
CHANGED
@@ -2,8 +2,8 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
-
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
8 |
abstract class AjaxHandler {
|
9 |
|
@@ -32,41 +32,6 @@ abstract class AjaxHandler {
|
|
32 |
return $ajaxResponse;
|
33 |
}
|
34 |
|
35 |
-
/**
|
36 |
-
* @param string $encoding
|
37 |
-
* @return array
|
38 |
-
*/
|
39 |
-
protected function getAjaxFormParams( $encoding = 'none' ) {
|
40 |
-
$req = Services::Request();
|
41 |
-
$aFormParams = [];
|
42 |
-
$sRaw = $req->post( 'form_params', '' );
|
43 |
-
|
44 |
-
if ( !empty( $sRaw ) ) {
|
45 |
-
|
46 |
-
$sMaybeEncoding = $req->post( 'enc_params' );
|
47 |
-
if ( in_array( $sMaybeEncoding, [ 'none', 'lz-string', 'b64' ] ) ) {
|
48 |
-
$encoding = $sMaybeEncoding;
|
49 |
-
}
|
50 |
-
|
51 |
-
switch ( $encoding ) {
|
52 |
-
case 'lz-string':
|
53 |
-
$sRaw = \LZCompressor\LZString::decompress( base64_decode( $sRaw ) );
|
54 |
-
break;
|
55 |
-
|
56 |
-
case 'b64':
|
57 |
-
$sRaw = base64_decode( $sRaw );
|
58 |
-
break;
|
59 |
-
|
60 |
-
case 'none':
|
61 |
-
default:
|
62 |
-
break;
|
63 |
-
}
|
64 |
-
|
65 |
-
parse_str( $sRaw, $aFormParams );
|
66 |
-
}
|
67 |
-
return $aFormParams;
|
68 |
-
}
|
69 |
-
|
70 |
protected function processAjaxAction( string $action ) :array {
|
71 |
return [];
|
72 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
4 |
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Lib\Request\FormParams;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
|
|
7 |
|
8 |
abstract class AjaxHandler {
|
9 |
|
32 |
return $ajaxResponse;
|
33 |
}
|
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
protected function processAjaxAction( string $action ) :array {
|
36 |
return [];
|
37 |
}
|
src/lib/src/Modules/Base/Lib/Request/FormParams.php
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Lib\Request;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
class FormParams {
|
9 |
+
|
10 |
+
const ENC_NONE = 'none';
|
11 |
+
const ENC_LZ = 'lz-string';
|
12 |
+
const ENC_BASE64 = 'b64';
|
13 |
+
use ModConsumer;
|
14 |
+
|
15 |
+
public static function Retrieve( string $encoding = self::ENC_NONE ) :array {
|
16 |
+
$req = Services::Request();
|
17 |
+
$formParams = [];
|
18 |
+
$raw = $req->post( 'form_params', '' );
|
19 |
+
|
20 |
+
if ( empty( $raw ) ) {
|
21 |
+
$formParams = $req->post;
|
22 |
+
}
|
23 |
+
else {
|
24 |
+
$maybeEncoding = $req->post( 'enc_params' );
|
25 |
+
if ( in_array( $maybeEncoding, [ 'none', 'lz-string', 'b64' ] ) ) {
|
26 |
+
$encoding = $maybeEncoding;
|
27 |
+
}
|
28 |
+
|
29 |
+
switch ( $encoding ) {
|
30 |
+
case 'lz-string':
|
31 |
+
$raw = \LZCompressor\LZString::decompress( base64_decode( $raw ) );
|
32 |
+
break;
|
33 |
+
|
34 |
+
case 'b64':
|
35 |
+
$raw = base64_decode( $raw );
|
36 |
+
break;
|
37 |
+
|
38 |
+
case 'none':
|
39 |
+
default:
|
40 |
+
break;
|
41 |
+
}
|
42 |
+
|
43 |
+
parse_str( $raw, $formParams );
|
44 |
+
}
|
45 |
+
|
46 |
+
return is_array( $formParams ) ? $formParams : [];
|
47 |
+
}
|
48 |
+
}
|
src/lib/src/Modules/Base/ModCon.php
CHANGED
@@ -4,6 +4,7 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
|
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
9 |
/**
|
@@ -67,27 +68,27 @@ abstract class ModCon {
|
|
67 |
|
68 |
/**
|
69 |
* @param Shield\Controller\Controller $pluginCon
|
70 |
-
* @param array $
|
71 |
* @throws \Exception
|
72 |
*/
|
73 |
-
public function __construct( $pluginCon, $
|
74 |
if ( !$pluginCon instanceof Shield\Controller\Controller ) {
|
75 |
throw new \Exception( 'Plugin controller not supplied to Module' );
|
76 |
}
|
77 |
$this->setCon( $pluginCon );
|
78 |
|
79 |
-
if ( empty( $
|
80 |
throw new \Exception( 'Module storage key AND slug are undefined' );
|
81 |
}
|
82 |
|
83 |
-
$this->sOptionsStoreKey = empty( $
|
84 |
-
if ( isset( $
|
85 |
-
$this->sModSlug = $
|
86 |
}
|
87 |
|
88 |
if ( $this->verifyModuleMeetRequirements() ) {
|
89 |
$this->handleAutoPageRedirects();
|
90 |
-
$this->setupHooks( $
|
91 |
$this->doPostConstruction();
|
92 |
}
|
93 |
}
|
@@ -205,41 +206,6 @@ abstract class ModCon {
|
|
205 |
return $this->loadModElement( 'Upgrade' );
|
206 |
}
|
207 |
|
208 |
-
/**
|
209 |
-
* @param string $sEncoding
|
210 |
-
* @return array
|
211 |
-
*/
|
212 |
-
public function getAjaxFormParams( $sEncoding = 'none' ) {
|
213 |
-
$oReq = Services::Request();
|
214 |
-
$aFormParams = [];
|
215 |
-
$sRaw = $oReq->post( 'form_params', '' );
|
216 |
-
|
217 |
-
if ( !empty( $sRaw ) ) {
|
218 |
-
|
219 |
-
$sMaybeEncoding = $oReq->post( 'enc_params' );
|
220 |
-
if ( in_array( $sMaybeEncoding, [ 'none', 'lz-string', 'b64' ] ) ) {
|
221 |
-
$sEncoding = $sMaybeEncoding;
|
222 |
-
}
|
223 |
-
|
224 |
-
switch ( $sEncoding ) {
|
225 |
-
case 'lz-string':
|
226 |
-
$sRaw = \LZCompressor\LZString::decompress( base64_decode( $sRaw ) );
|
227 |
-
break;
|
228 |
-
|
229 |
-
case 'b64':
|
230 |
-
$sRaw = base64_decode( $sRaw );
|
231 |
-
break;
|
232 |
-
|
233 |
-
case 'none':
|
234 |
-
default:
|
235 |
-
break;
|
236 |
-
}
|
237 |
-
|
238 |
-
parse_str( $sRaw, $aFormParams );
|
239 |
-
}
|
240 |
-
return $aFormParams;
|
241 |
-
}
|
242 |
-
|
243 |
/**
|
244 |
* @param array $aAdminNotices
|
245 |
* @return array
|
@@ -521,14 +487,14 @@ abstract class ModCon {
|
|
521 |
}
|
522 |
|
523 |
public function isModuleEnabled() :bool {
|
524 |
-
/** @var Shield\Modules\Plugin\Options $
|
525 |
-
$
|
526 |
|
527 |
if ( $this->getOptions()->getFeatureProperty( 'auto_enabled' ) === true ) {
|
528 |
// Auto enabled modules always run regardless
|
529 |
$enabled = true;
|
530 |
}
|
531 |
-
elseif ( $
|
532 |
$enabled = false;
|
533 |
}
|
534 |
elseif ( $this->getCon()->getIfForceOffActive() ) {
|
@@ -652,54 +618,51 @@ abstract class ModCon {
|
|
652 |
);
|
653 |
}
|
654 |
|
655 |
-
|
656 |
-
* @return array
|
657 |
-
*/
|
658 |
-
public function buildSummaryData() {
|
659 |
$opts = $this->getOptions();
|
660 |
-
$
|
661 |
|
662 |
-
$
|
663 |
-
foreach ( $
|
664 |
try {
|
665 |
-
$
|
666 |
-
foreach ( $
|
667 |
-
unset( $
|
668 |
-
$
|
669 |
}
|
670 |
}
|
671 |
catch ( \Exception $e ) {
|
672 |
}
|
673 |
}
|
674 |
|
675 |
-
$
|
676 |
'slug' => $this->getSlug(),
|
677 |
'enabled' => $this->getUIHandler()->isEnabledForUiSummary(),
|
678 |
'active' => $this->isThisModulePage() || $this->isPage_InsightsThisModule(),
|
679 |
'name' => $this->getMainFeatureName(),
|
680 |
'sidebar_name' => $opts->getFeatureProperty( 'sidebar_name' ),
|
681 |
-
'menu_title' => empty( $
|
682 |
'href' => network_admin_url( 'admin.php?page='.$this->getModSlug() ),
|
683 |
-
'sections' => $
|
684 |
'options' => [],
|
685 |
'show_mod_opts' => $this->getIfShowModuleOpts(),
|
686 |
];
|
687 |
|
688 |
-
foreach ( $opts->getVisibleOptionsKeys() as $
|
689 |
try {
|
690 |
-
$
|
691 |
-
$
|
692 |
-
$
|
693 |
}
|
694 |
catch ( \Exception $e ) {
|
695 |
}
|
696 |
}
|
697 |
|
698 |
-
$
|
699 |
'%s',
|
700 |
-
empty( $
|
701 |
);
|
702 |
-
return $
|
703 |
}
|
704 |
|
705 |
public function getIfShowModuleMenuItem() :bool {
|
@@ -893,9 +856,9 @@ abstract class ModCon {
|
|
893 |
}
|
894 |
|
895 |
public function onPluginDelete() {
|
896 |
-
foreach ( $this->getDbHandlers( true ) as $
|
897 |
-
if ( !empty( $
|
898 |
-
$
|
899 |
}
|
900 |
}
|
901 |
$this->getOptions()->deleteStorage();
|
@@ -980,8 +943,17 @@ abstract class ModCon {
|
|
980 |
return $this;
|
981 |
}
|
982 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
983 |
protected function isAdminOptionsPage() :bool {
|
984 |
-
return is_admin() && !Services::WpGeneral()->isAjax()
|
|
|
985 |
}
|
986 |
|
987 |
public function isPremium() :bool {
|
@@ -992,11 +964,12 @@ abstract class ModCon {
|
|
992 |
* @throws \Exception
|
993 |
*/
|
994 |
private function doSaveStandardOptions() {
|
995 |
-
|
|
|
996 |
|
997 |
foreach ( $this->getAllFormOptionsAndTypes() as $sKey => $sOptType ) {
|
998 |
|
999 |
-
$sOptionValue = isset( $
|
1000 |
if ( is_null( $sOptionValue ) ) {
|
1001 |
|
1002 |
if ( in_array( $sOptType, [ 'text', 'email' ] ) ) { //text box, and it's null, don't update
|
@@ -1026,7 +999,7 @@ abstract class ModCon {
|
|
1026 |
continue;
|
1027 |
}
|
1028 |
|
1029 |
-
$sConfirm = isset( $
|
1030 |
if ( $sTempValue !== $sConfirm ) {
|
1031 |
throw new \Exception( __( 'Password values do not match.', 'wp-simple-firewall' ) );
|
1032 |
}
|
@@ -1052,7 +1025,7 @@ abstract class ModCon {
|
|
1052 |
if ( $this->isPremium() ) {
|
1053 |
( new Shield\Modules\Plugin\Lib\ImportExport\Options\SaveExcludedOptions() )
|
1054 |
->setMod( $this )
|
1055 |
-
->save( $
|
1056 |
}
|
1057 |
}
|
1058 |
|
@@ -1213,16 +1186,16 @@ abstract class ModCon {
|
|
1213 |
public function renderOptionsForm() {
|
1214 |
|
1215 |
if ( $this->canDisplayOptionsForm() ) {
|
1216 |
-
$
|
1217 |
}
|
1218 |
else {
|
1219 |
-
$
|
1220 |
}
|
1221 |
|
1222 |
try {
|
1223 |
return $this->getCon()
|
1224 |
->getRenderer()
|
1225 |
-
->setTemplate( $
|
1226 |
->setRenderVars( $this->getUIHandler()->getBaseDisplayData() )
|
1227 |
->setTemplateEngineTwig()
|
1228 |
->render();
|
@@ -1255,13 +1228,6 @@ abstract class ModCon {
|
|
1255 |
return [];
|
1256 |
}
|
1257 |
|
1258 |
-
/**
|
1259 |
-
* Override this with custom JS vars for your particular module.
|
1260 |
-
* @deprecated 10.2
|
1261 |
-
*/
|
1262 |
-
public function insertCustomJsVars_Admin() {
|
1263 |
-
}
|
1264 |
-
|
1265 |
/**
|
1266 |
* @param array $aData
|
1267 |
* @param string $sSubView
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Lib\Request\FormParams;
|
8 |
use FernleafSystems\Wordpress\Services\Services;
|
9 |
|
10 |
/**
|
68 |
|
69 |
/**
|
70 |
* @param Shield\Controller\Controller $pluginCon
|
71 |
+
* @param array $mod
|
72 |
* @throws \Exception
|
73 |
*/
|
74 |
+
public function __construct( $pluginCon, $mod = [] ) {
|
75 |
if ( !$pluginCon instanceof Shield\Controller\Controller ) {
|
76 |
throw new \Exception( 'Plugin controller not supplied to Module' );
|
77 |
}
|
78 |
$this->setCon( $pluginCon );
|
79 |
|
80 |
+
if ( empty( $mod[ 'storage_key' ] ) && empty( $mod[ 'slug' ] ) ) {
|
81 |
throw new \Exception( 'Module storage key AND slug are undefined' );
|
82 |
}
|
83 |
|
84 |
+
$this->sOptionsStoreKey = empty( $mod[ 'storage_key' ] ) ? $mod[ 'slug' ] : $mod[ 'storage_key' ];
|
85 |
+
if ( isset( $mod[ 'slug' ] ) ) {
|
86 |
+
$this->sModSlug = $mod[ 'slug' ];
|
87 |
}
|
88 |
|
89 |
if ( $this->verifyModuleMeetRequirements() ) {
|
90 |
$this->handleAutoPageRedirects();
|
91 |
+
$this->setupHooks( $mod );
|
92 |
$this->doPostConstruction();
|
93 |
}
|
94 |
}
|
206 |
return $this->loadModElement( 'Upgrade' );
|
207 |
}
|
208 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
209 |
/**
|
210 |
* @param array $aAdminNotices
|
211 |
* @return array
|
487 |
}
|
488 |
|
489 |
public function isModuleEnabled() :bool {
|
490 |
+
/** @var Shield\Modules\Plugin\Options $pluginOpts */
|
491 |
+
$pluginOpts = $this->getCon()->getModule_Plugin()->getOptions();
|
492 |
|
493 |
if ( $this->getOptions()->getFeatureProperty( 'auto_enabled' ) === true ) {
|
494 |
// Auto enabled modules always run regardless
|
495 |
$enabled = true;
|
496 |
}
|
497 |
+
elseif ( $pluginOpts->isPluginGloballyDisabled() ) {
|
498 |
$enabled = false;
|
499 |
}
|
500 |
elseif ( $this->getCon()->getIfForceOffActive() ) {
|
618 |
);
|
619 |
}
|
620 |
|
621 |
+
public function buildSummaryData() :array {
|
|
|
|
|
|
|
622 |
$opts = $this->getOptions();
|
623 |
+
$menuTitle = $opts->getFeatureProperty( 'menu_title' );
|
624 |
|
625 |
+
$sections = $opts->getSections();
|
626 |
+
foreach ( $sections as $slug => $section ) {
|
627 |
try {
|
628 |
+
$strings = $this->getStrings()->getSectionStrings( $section[ 'slug' ] );
|
629 |
+
foreach ( $strings as $key => $val ) {
|
630 |
+
unset( $section[ $key ] );
|
631 |
+
$section[ $key ] = $val;
|
632 |
}
|
633 |
}
|
634 |
catch ( \Exception $e ) {
|
635 |
}
|
636 |
}
|
637 |
|
638 |
+
$summary = [
|
639 |
'slug' => $this->getSlug(),
|
640 |
'enabled' => $this->getUIHandler()->isEnabledForUiSummary(),
|
641 |
'active' => $this->isThisModulePage() || $this->isPage_InsightsThisModule(),
|
642 |
'name' => $this->getMainFeatureName(),
|
643 |
'sidebar_name' => $opts->getFeatureProperty( 'sidebar_name' ),
|
644 |
+
'menu_title' => empty( $menuTitle ) ? $this->getMainFeatureName() : __( $menuTitle, 'wp-simple-firewall' ),
|
645 |
'href' => network_admin_url( 'admin.php?page='.$this->getModSlug() ),
|
646 |
+
'sections' => $sections,
|
647 |
'options' => [],
|
648 |
'show_mod_opts' => $this->getIfShowModuleOpts(),
|
649 |
];
|
650 |
|
651 |
+
foreach ( $opts->getVisibleOptionsKeys() as $optKey ) {
|
652 |
try {
|
653 |
+
$optData = $this->getStrings()->getOptionStrings( $optKey );
|
654 |
+
$optData[ 'href' ] = $this->getUrl_DirectLinkToOption( $optKey );
|
655 |
+
$summary[ 'options' ][ $optKey ] = $optData;
|
656 |
}
|
657 |
catch ( \Exception $e ) {
|
658 |
}
|
659 |
}
|
660 |
|
661 |
+
$summary[ 'tooltip' ] = sprintf(
|
662 |
'%s',
|
663 |
+
empty( $summary[ 'sidebar_name' ] ) ? $summary[ 'name' ] : __( $summary[ 'sidebar_name' ], 'wp-simple-firewall' )
|
664 |
);
|
665 |
+
return $summary;
|
666 |
}
|
667 |
|
668 |
public function getIfShowModuleMenuItem() :bool {
|
856 |
}
|
857 |
|
858 |
public function onPluginDelete() {
|
859 |
+
foreach ( $this->getDbHandlers( true ) as $dbh ) {
|
860 |
+
if ( !empty( $dbh ) ) {
|
861 |
+
$dbh->tableDelete();
|
862 |
}
|
863 |
}
|
864 |
$this->getOptions()->deleteStorage();
|
943 |
return $this;
|
944 |
}
|
945 |
|
946 |
+
protected function isThisModAdminPage() :bool {
|
947 |
+
return is_admin() && !Services::WpGeneral()->isAjax()
|
948 |
+
&& Services::Request()->isGet() && $this->isThisModulePage();
|
949 |
+
}
|
950 |
+
|
951 |
+
/**
|
952 |
+
* @deprecated 11.1
|
953 |
+
*/
|
954 |
protected function isAdminOptionsPage() :bool {
|
955 |
+
return is_admin() && !Services::WpGeneral()->isAjax()
|
956 |
+
&& Services::Request()->isGet() && $this->isThisModulePage();
|
957 |
}
|
958 |
|
959 |
public function isPremium() :bool {
|
964 |
* @throws \Exception
|
965 |
*/
|
966 |
private function doSaveStandardOptions() {
|
967 |
+
// standard options use b64 and fail-over to lz-string
|
968 |
+
$form = FormParams::Retrieve( FormParams::ENC_BASE64 );
|
969 |
|
970 |
foreach ( $this->getAllFormOptionsAndTypes() as $sKey => $sOptType ) {
|
971 |
|
972 |
+
$sOptionValue = isset( $form[ $sKey ] ) ? $form[ $sKey ] : null;
|
973 |
if ( is_null( $sOptionValue ) ) {
|
974 |
|
975 |
if ( in_array( $sOptType, [ 'text', 'email' ] ) ) { //text box, and it's null, don't update
|
999 |
continue;
|
1000 |
}
|
1001 |
|
1002 |
+
$sConfirm = isset( $form[ $sKey.'_confirm' ] ) ? $form[ $sKey.'_confirm' ] : null;
|
1003 |
if ( $sTempValue !== $sConfirm ) {
|
1004 |
throw new \Exception( __( 'Password values do not match.', 'wp-simple-firewall' ) );
|
1005 |
}
|
1025 |
if ( $this->isPremium() ) {
|
1026 |
( new Shield\Modules\Plugin\Lib\ImportExport\Options\SaveExcludedOptions() )
|
1027 |
->setMod( $this )
|
1028 |
+
->save( $form );
|
1029 |
}
|
1030 |
}
|
1031 |
|
1186 |
public function renderOptionsForm() {
|
1187 |
|
1188 |
if ( $this->canDisplayOptionsForm() ) {
|
1189 |
+
$template = 'components/options_form/main.twig';
|
1190 |
}
|
1191 |
else {
|
1192 |
+
$template = 'subfeature-access_restricted';
|
1193 |
}
|
1194 |
|
1195 |
try {
|
1196 |
return $this->getCon()
|
1197 |
->getRenderer()
|
1198 |
+
->setTemplate( $template )
|
1199 |
->setRenderVars( $this->getUIHandler()->getBaseDisplayData() )
|
1200 |
->setTemplateEngineTwig()
|
1201 |
->render();
|
1228 |
return [];
|
1229 |
}
|
1230 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1231 |
/**
|
1232 |
* @param array $aData
|
1233 |
* @param string $sSubView
|
src/lib/src/Modules/Base/Options.php
CHANGED
@@ -955,7 +955,7 @@ class Options {
|
|
955 |
if ( !$this->getConfigFileExists() ) {
|
956 |
throw new \Exception( sprintf( 'Configuration file "%s" does not exist.', $this->getPathToConfig() ) );
|
957 |
}
|
958 |
-
return Services::Data()->
|
959 |
}
|
960 |
|
961 |
public function getConfigStorageKey() :string {
|
955 |
if ( !$this->getConfigFileExists() ) {
|
956 |
throw new \Exception( sprintf( 'Configuration file "%s" does not exist.', $this->getPathToConfig() ) );
|
957 |
}
|
958 |
+
return Services::Data()->readFileWithInclude( $this->getPathToConfig() );
|
959 |
}
|
960 |
|
961 |
public function getConfigStorageKey() :string {
|
src/lib/src/Modules/Base/Strings.php
CHANGED
@@ -169,12 +169,12 @@ class Strings {
|
|
169 |
* @throws \Exception
|
170 |
*/
|
171 |
public function getOptionStrings( string $key ) :array {
|
172 |
-
$
|
173 |
-
if ( is_array( $
|
174 |
return [
|
175 |
-
'name' => __( $
|
176 |
-
'summary' => __( $
|
177 |
-
'description' => __( $
|
178 |
];
|
179 |
}
|
180 |
throw new \Exception( sprintf( 'An option has been defined but without strings assigned to it. Option key: "%s".', $key ) );
|
169 |
* @throws \Exception
|
170 |
*/
|
171 |
public function getOptionStrings( string $key ) :array {
|
172 |
+
$opt = $this->getOptions()->getOptDefinition( $key );
|
173 |
+
if ( is_array( $opt ) && !empty( $opt[ 'name' ] ) && !empty( $opt[ 'summary' ] ) && !empty( $opt[ 'description' ] ) ) {
|
174 |
return [
|
175 |
+
'name' => __( $opt[ 'name' ], 'wp-simple-firewall' ),
|
176 |
+
'summary' => __( $opt[ 'summary' ], 'wp-simple-firewall' ),
|
177 |
+
'description' => __( $opt[ 'description' ], 'wp-simple-firewall' ),
|
178 |
];
|
179 |
}
|
180 |
throw new \Exception( sprintf( 'An option has been defined but without strings assigned to it. Option key: "%s".', $key ) );
|
src/lib/src/Modules/Base/UI.php
CHANGED
@@ -207,26 +207,28 @@ class UI {
|
|
207 |
->build(),
|
208 |
'hidden_options' => $this->getOptions()->getHiddenOptions()
|
209 |
],
|
|
|
|
|
|
|
210 |
'ajax' => [
|
211 |
'mod_options' => $mod->getAjaxActionData( 'mod_options', true ),
|
212 |
'mod_opts_form_render' => $mod->getAjaxActionData( 'mod_opts_form_render', true ),
|
213 |
-
// 'mod_options' => $mod->getAjaxActionData( 'mod_options' ),
|
214 |
],
|
215 |
'vendors' => [
|
216 |
'widget_freshdesk' => '3000000081' /* TODO: plugin spec config */
|
217 |
],
|
218 |
'strings' => $mod->getStrings()->getDisplayStrings(),
|
219 |
'flags' => [
|
220 |
-
'access_restricted'
|
221 |
-
'show_ads'
|
222 |
-
'wrap_page_content'
|
223 |
-
'show_standard_options'
|
224 |
-
'show_content_help'
|
225 |
-
'show_alt_content'
|
226 |
-
'has_wizard'
|
227 |
-
'is_premium'
|
228 |
-
'show_transfer_switch'
|
229 |
-
'is_wpcli'
|
230 |
],
|
231 |
'hrefs' => [
|
232 |
'go_pro' => 'https://shsec.io/shieldgoprofeature',
|
207 |
->build(),
|
208 |
'hidden_options' => $this->getOptions()->getHiddenOptions()
|
209 |
],
|
210 |
+
'vars' => [
|
211 |
+
'mod_slug' => $mod->getModSlug( true ),
|
212 |
+
],
|
213 |
'ajax' => [
|
214 |
'mod_options' => $mod->getAjaxActionData( 'mod_options', true ),
|
215 |
'mod_opts_form_render' => $mod->getAjaxActionData( 'mod_opts_form_render', true ),
|
|
|
216 |
],
|
217 |
'vendors' => [
|
218 |
'widget_freshdesk' => '3000000081' /* TODO: plugin spec config */
|
219 |
],
|
220 |
'strings' => $mod->getStrings()->getDisplayStrings(),
|
221 |
'flags' => [
|
222 |
+
'access_restricted' => !$mod->canDisplayOptionsForm(),
|
223 |
+
'show_ads' => $mod->getIsShowMarketing(),
|
224 |
+
'wrap_page_content' => true,
|
225 |
+
'show_standard_options' => true,
|
226 |
+
'show_content_help' => true,
|
227 |
+
'show_alt_content' => false,
|
228 |
+
'has_wizard' => $mod->hasWizard(),
|
229 |
+
'is_premium' => $con->isPremiumActive(),
|
230 |
+
'show_transfer_switch' => $con->isPremiumActive(),
|
231 |
+
'is_wpcli' => $pluginOptions->isEnabledWpcli(),
|
232 |
],
|
233 |
'hrefs' => [
|
234 |
'go_pro' => 'https://shsec.io/shieldgoprofeature',
|
src/lib/src/Modules/BaseShield/ModCon.php
CHANGED
@@ -97,6 +97,10 @@ class ModCon extends Base\ModCon {
|
|
97 |
return $data;
|
98 |
}
|
99 |
|
|
|
|
|
|
|
|
|
100 |
protected function getSecAdminCheckAjaxData() :array {
|
101 |
// We set a custom mod_slug so that this module handles the ajax request
|
102 |
$dat = $this->getAjaxActionData( 'sec_admin_check' );
|
@@ -127,26 +131,28 @@ class ModCon extends Base\ModCon {
|
|
127 |
$secOpts = $this->getCon()
|
128 |
->getModule_SecAdmin()
|
129 |
->getOptions();
|
130 |
-
$
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
|
|
|
|
150 |
}
|
151 |
|
152 |
public function getIfSupport3rdParty() :bool {
|
97 |
return $data;
|
98 |
}
|
99 |
|
100 |
+
/**
|
101 |
+
* @return array
|
102 |
+
* @deprecated 11.1
|
103 |
+
*/
|
104 |
protected function getSecAdminCheckAjaxData() :array {
|
105 |
// We set a custom mod_slug so that this module handles the ajax request
|
106 |
$dat = $this->getAjaxActionData( 'sec_admin_check' );
|
131 |
$secOpts = $this->getCon()
|
132 |
->getModule_SecAdmin()
|
133 |
->getOptions();
|
134 |
+
return $this->renderTemplate(
|
135 |
+
'/wpadmin_pages/security_admin/index.twig',
|
136 |
+
Services::DataManipulation()
|
137 |
+
->mergeArraysRecursive(
|
138 |
+
$this->getUIHandler()->getBaseDisplayData(),
|
139 |
+
[
|
140 |
+
'ajax' => [
|
141 |
+
'restricted_access' => $this->getAjaxActionData( 'restricted_access' ),
|
142 |
+
],
|
143 |
+
'strings' => [
|
144 |
+
'force_remove_email' => __( "If you've forgotten your PIN, a link can be sent to the plugin administrator email address to remove this restriction.", 'wp-simple-firewall' ),
|
145 |
+
'click_email' => __( "Click here to send the verification email.", 'wp-simple-firewall' ),
|
146 |
+
'send_to_email' => sprintf( __( "Email will be sent to %s", 'wp-simple-firewall' ),
|
147 |
+
Utilities\Obfuscate::Email( $this->getPluginReportEmail() ) ),
|
148 |
+
'no_email_override' => __( "The Security Administrator has restricted the use of the email override feature.", 'wp-simple-firewall' ),
|
149 |
+
],
|
150 |
+
'flags' => [
|
151 |
+
'allow_email_override' => $secOpts->isEmailOverridePermitted()
|
152 |
+
]
|
153 |
+
]
|
154 |
+
),
|
155 |
+
true );
|
156 |
}
|
157 |
|
158 |
public function getIfSupport3rdParty() :bool {
|
src/lib/src/Modules/BaseShield/UI.php
CHANGED
@@ -56,14 +56,7 @@ class UI extends Base\UI {
|
|
56 |
Services::Request()->query( 'inav', '' )
|
57 |
] ) )
|
58 |
],
|
59 |
-
'vars' => [
|
60 |
-
'related_hrefs' => $this->getSettingsRelatedLinks()
|
61 |
-
]
|
62 |
]
|
63 |
);
|
64 |
}
|
65 |
-
|
66 |
-
protected function getSettingsRelatedLinks() :array {
|
67 |
-
return [];
|
68 |
-
}
|
69 |
}
|
56 |
Services::Request()->query( 'inav', '' )
|
57 |
] ) )
|
58 |
],
|
|
|
|
|
|
|
59 |
]
|
60 |
);
|
61 |
}
|
|
|
|
|
|
|
|
|
62 |
}
|
src/lib/src/Modules/CommentsFilter/Scan/Scanner.php
CHANGED
@@ -102,6 +102,7 @@ class Scanner {
|
|
102 |
'spam_block_'.$mResult->get_error_code(),
|
103 |
[ 'audit' => $mResult->get_error_data() ]
|
104 |
);
|
|
|
105 |
|
106 |
if ( $mResult->get_error_code() == 'human' ) {
|
107 |
$status = $opts->getOpt( 'comments_default_action_human_spam' );
|
102 |
'spam_block_'.$mResult->get_error_code(),
|
103 |
[ 'audit' => $mResult->get_error_data() ]
|
104 |
);
|
105 |
+
$this->getCon()->fireEvent( 'comment_spam_block' );
|
106 |
|
107 |
if ( $mResult->get_error_code() == 'human' ) {
|
108 |
$status = $opts->getOpt( 'comments_default_action_human_spam' );
|
src/lib/src/Modules/Events/Consolidate/ConsolidateAllEvents.php
CHANGED
@@ -12,12 +12,12 @@ class ConsolidateAllEvents {
|
|
12 |
use ModConsumer;
|
13 |
|
14 |
public function run() {
|
15 |
-
foreach ( $this->getAllEvents() as $
|
16 |
-
$this->consolidateEventIntoHourly( $
|
17 |
-
$this->consolidateEventIntoDaily( $
|
18 |
-
$this->consolidateEventIntoWeekly( $
|
19 |
-
$this->consolidateEventIntoMonthly( $
|
20 |
-
$this->consolidateEventIntoYearly( $
|
21 |
}
|
22 |
}
|
23 |
|
@@ -178,9 +178,9 @@ class ConsolidateAllEvents {
|
|
178 |
/**
|
179 |
* Consolidates each event in Daily sums. Doesn't process events from the previous 48hrs.
|
180 |
* Processes event for the 7 days previous to the last 48 hours.
|
181 |
-
* @param $
|
182 |
*/
|
183 |
-
protected function consolidateEventIntoMonthly( $
|
184 |
/** @var ModCon $mod */
|
185 |
$mod = $this->getMod();
|
186 |
$dbh = $mod->getDbHandler_Events();
|
@@ -192,28 +192,28 @@ class ConsolidateAllEvents {
|
|
192 |
|
193 |
$nMonthCount = 0;
|
194 |
do {
|
195 |
-
/** @var Events\Select $
|
196 |
-
$
|
197 |
-
$nRecords = $
|
198 |
-
|
199 |
-
|
200 |
|
201 |
if ( $nRecords > 1 ) {
|
202 |
/** @var Events\Select $oSel */
|
203 |
-
$
|
204 |
/** @var Events\EntryVO[] $aRecords */
|
205 |
-
$nSum = $
|
206 |
-
|
207 |
|
208 |
if ( $nSum > 0 ) {
|
209 |
/** @var Events\Delete $oDel */
|
210 |
$oDel = $dbh->getQueryDeleter();
|
211 |
$oDel->filterByBoundary_Month( $oTime->timestamp )
|
212 |
-
->filterByEvent( $
|
213 |
->query();
|
214 |
|
215 |
$oEntry = new Events\EntryVO();
|
216 |
-
$oEntry->event = $
|
217 |
$oEntry->count = $nSum;
|
218 |
$oEntry->created_at = $oTime->timestamp + 1;
|
219 |
/** @var Events\Insert $oQI */
|
@@ -282,11 +282,11 @@ class ConsolidateAllEvents {
|
|
282 |
/**
|
283 |
* @return string[]
|
284 |
*/
|
285 |
-
protected function getAllEvents() {
|
286 |
/** @var ModCon $mod */
|
287 |
$mod = $this->getMod();
|
288 |
-
/** @var Events\Select $
|
289 |
-
$
|
290 |
-
return $
|
291 |
}
|
292 |
}
|
12 |
use ModConsumer;
|
13 |
|
14 |
public function run() {
|
15 |
+
foreach ( $this->getAllEvents() as $event ) {
|
16 |
+
$this->consolidateEventIntoHourly( $event );
|
17 |
+
$this->consolidateEventIntoDaily( $event );
|
18 |
+
$this->consolidateEventIntoWeekly( $event );
|
19 |
+
$this->consolidateEventIntoMonthly( $event );
|
20 |
+
$this->consolidateEventIntoYearly( $event );
|
21 |
}
|
22 |
}
|
23 |
|
178 |
/**
|
179 |
* Consolidates each event in Daily sums. Doesn't process events from the previous 48hrs.
|
180 |
* Processes event for the 7 days previous to the last 48 hours.
|
181 |
+
* @param $event
|
182 |
*/
|
183 |
+
protected function consolidateEventIntoMonthly( $event ) {
|
184 |
/** @var ModCon $mod */
|
185 |
$mod = $this->getMod();
|
186 |
$dbh = $mod->getDbHandler_Events();
|
192 |
|
193 |
$nMonthCount = 0;
|
194 |
do {
|
195 |
+
/** @var Events\Select $select */
|
196 |
+
$select = $dbh->getQuerySelector();
|
197 |
+
$nRecords = $select->filterByBoundary_Month( $oTime->timestamp )
|
198 |
+
->filterByEvent( $event )
|
199 |
+
->count();
|
200 |
|
201 |
if ( $nRecords > 1 ) {
|
202 |
/** @var Events\Select $oSel */
|
203 |
+
$select = $dbh->getQuerySelector();
|
204 |
/** @var Events\EntryVO[] $aRecords */
|
205 |
+
$nSum = $select->filterByBoundary_Month( $oTime->timestamp )
|
206 |
+
->sumEvent( $event );
|
207 |
|
208 |
if ( $nSum > 0 ) {
|
209 |
/** @var Events\Delete $oDel */
|
210 |
$oDel = $dbh->getQueryDeleter();
|
211 |
$oDel->filterByBoundary_Month( $oTime->timestamp )
|
212 |
+
->filterByEvent( $event )
|
213 |
->query();
|
214 |
|
215 |
$oEntry = new Events\EntryVO();
|
216 |
+
$oEntry->event = $event;
|
217 |
$oEntry->count = $nSum;
|
218 |
$oEntry->created_at = $oTime->timestamp + 1;
|
219 |
/** @var Events\Insert $oQI */
|
282 |
/**
|
283 |
* @return string[]
|
284 |
*/
|
285 |
+
protected function getAllEvents() :array {
|
286 |
/** @var ModCon $mod */
|
287 |
$mod = $this->getMod();
|
288 |
+
/** @var Events\Select $select */
|
289 |
+
$select = $mod->getDbHandler_Events()->getQuerySelector();
|
290 |
+
return $select->getAllEvents();
|
291 |
}
|
292 |
}
|
src/lib/src/Modules/Events/Lib/EventsListener.php
CHANGED
@@ -22,10 +22,9 @@ abstract class EventsListener {
|
|
22 |
$this->setCon( $con );
|
23 |
|
24 |
add_action( $con->prefix( 'event' ),
|
25 |
-
function ( $event, $meta = [] ) use ( $con ) {
|
26 |
-
|
27 |
-
|
28 |
-
}
|
29 |
}, 10, 2 );
|
30 |
|
31 |
add_action( $con->prefix( 'plugin_shutdown' ), function () {
|
@@ -35,9 +34,10 @@ abstract class EventsListener {
|
|
35 |
|
36 |
/**
|
37 |
* @param string $evt
|
38 |
-
* @param array $
|
|
|
39 |
*/
|
40 |
-
abstract protected function captureEvent( $evt, $
|
41 |
|
42 |
protected function onShutdown() {
|
43 |
|
22 |
$this->setCon( $con );
|
23 |
|
24 |
add_action( $con->prefix( 'event' ),
|
25 |
+
function ( $event, $meta = [], $def = [] ) use ( $con ) {
|
26 |
+
// TODO @deprecated 11.1 remove ??
|
27 |
+
$this->captureEvent( $event, $meta, $def ?? [] );
|
|
|
28 |
}, 10, 2 );
|
29 |
|
30 |
add_action( $con->prefix( 'plugin_shutdown' ), function () {
|
34 |
|
35 |
/**
|
36 |
* @param string $evt
|
37 |
+
* @param array $meta
|
38 |
+
* @param array $def
|
39 |
*/
|
40 |
+
abstract protected function captureEvent( string $evt, $meta = [], $def = [] );
|
41 |
|
42 |
protected function onShutdown() {
|
43 |
|
src/lib/src/Modules/Events/Lib/EventsService.php
CHANGED
@@ -18,9 +18,14 @@ class EventsService {
|
|
18 |
* @param array $meta
|
19 |
* @return $this
|
20 |
*/
|
21 |
-
public function fireEvent( $event, $meta = [] ) {
|
22 |
if ( $this->isSupportedEvent( $event ) ) {
|
23 |
-
do_action(
|
|
|
|
|
|
|
|
|
|
|
24 |
}
|
25 |
return $this;
|
26 |
}
|
18 |
* @param array $meta
|
19 |
* @return $this
|
20 |
*/
|
21 |
+
public function fireEvent( string $event, $meta = [] ) {
|
22 |
if ( $this->isSupportedEvent( $event ) ) {
|
23 |
+
do_action(
|
24 |
+
$this->getCon()->prefix( 'event' ),
|
25 |
+
$event,
|
26 |
+
$meta,
|
27 |
+
$this->getEventDef( $event )
|
28 |
+
);
|
29 |
}
|
30 |
return $this;
|
31 |
}
|
src/lib/src/Modules/Events/Lib/Reports/KeyStats.php
CHANGED
@@ -12,16 +12,16 @@ class KeyStats extends BaseReporter {
|
|
12 |
* @inheritDoc
|
13 |
*/
|
14 |
public function build() {
|
15 |
-
$
|
16 |
|
17 |
/** @var Events\ModCon $mod */
|
18 |
$mod = $this->getMod();
|
19 |
-
/** @var DBEvents\Select $
|
20 |
-
$
|
21 |
-
/** @var Events\Strings $
|
22 |
-
$
|
23 |
|
24 |
-
$
|
25 |
'ip_offense',
|
26 |
'ip_blocked',
|
27 |
'conn_kill',
|
@@ -38,19 +38,18 @@ class KeyStats extends BaseReporter {
|
|
38 |
'spam_block_human',
|
39 |
];
|
40 |
|
41 |
-
$
|
42 |
|
43 |
-
$
|
44 |
-
foreach ( $
|
45 |
try {
|
46 |
-
$
|
47 |
-
->
|
48 |
-
->
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
'
|
53 |
-
'name' => $oStrings->getEventName( $sEvent ),
|
54 |
];
|
55 |
}
|
56 |
}
|
@@ -58,12 +57,12 @@ class KeyStats extends BaseReporter {
|
|
58 |
}
|
59 |
}
|
60 |
|
61 |
-
if ( count( $
|
62 |
-
$
|
63 |
'/components/reports/mod/events/info_keystats.twig',
|
64 |
[
|
65 |
'vars' => [
|
66 |
-
'counts' => $
|
67 |
],
|
68 |
'strings' => [
|
69 |
'title' => __( 'Top Security Statistics', 'wp-simple-firewall' ),
|
@@ -74,6 +73,6 @@ class KeyStats extends BaseReporter {
|
|
74 |
);
|
75 |
}
|
76 |
|
77 |
-
return $
|
78 |
}
|
79 |
}
|
12 |
* @inheritDoc
|
13 |
*/
|
14 |
public function build() {
|
15 |
+
$alerts = [];
|
16 |
|
17 |
/** @var Events\ModCon $mod */
|
18 |
$mod = $this->getMod();
|
19 |
+
/** @var DBEvents\Select $selector */
|
20 |
+
$selector = $mod->getDbHandler_Events()->getQuerySelector();
|
21 |
+
/** @var Events\Strings $strings */
|
22 |
+
$strings = $mod->getStrings();
|
23 |
|
24 |
+
$eventKeys = [
|
25 |
'ip_offense',
|
26 |
'ip_blocked',
|
27 |
'conn_kill',
|
38 |
'spam_block_human',
|
39 |
];
|
40 |
|
41 |
+
$rep = $this->getReport();
|
42 |
|
43 |
+
$sums = [];
|
44 |
+
foreach ( $eventKeys as $event ) {
|
45 |
try {
|
46 |
+
$eventSum = $selector
|
47 |
+
->filterByBoundary( $rep->interval_start_at, $rep->interval_end_at )
|
48 |
+
->sumEvent( $event );
|
49 |
+
if ( $eventSum > 0 ) {
|
50 |
+
$sums[ $event ] = [
|
51 |
+
'count' => $eventSum,
|
52 |
+
'name' => $strings->getEventName( $event ),
|
|
|
53 |
];
|
54 |
}
|
55 |
}
|
57 |
}
|
58 |
}
|
59 |
|
60 |
+
if ( count( $sums ) > 0 ) {
|
61 |
+
$alerts[] = $this->getMod()->renderTemplate(
|
62 |
'/components/reports/mod/events/info_keystats.twig',
|
63 |
[
|
64 |
'vars' => [
|
65 |
+
'counts' => $sums
|
66 |
],
|
67 |
'strings' => [
|
68 |
'title' => __( 'Top Security Statistics', 'wp-simple-firewall' ),
|
73 |
);
|
74 |
}
|
75 |
|
76 |
+
return $alerts;
|
77 |
}
|
78 |
}
|
src/lib/src/Modules/Events/Lib/StatsWriter.php
CHANGED
@@ -17,12 +17,18 @@ class StatsWriter extends EventsListener {
|
|
17 |
|
18 |
/**
|
19 |
* @param string $evt
|
20 |
-
* @param array $
|
|
|
21 |
*/
|
22 |
-
protected function captureEvent( $evt, $
|
23 |
-
|
24 |
-
|
25 |
-
|
|
|
|
|
|
|
|
|
|
|
26 |
}
|
27 |
|
28 |
protected function onShutdown() {
|
17 |
|
18 |
/**
|
19 |
* @param string $evt
|
20 |
+
* @param array $meta
|
21 |
+
* @param array $def
|
22 |
*/
|
23 |
+
protected function captureEvent( string $evt, $meta = [], $def = [] ) {
|
24 |
+
if ( empty( $def ) ) {
|
25 |
+
$def = $this->getCon()->loadEventsService()->getEventDef( $evt );
|
26 |
+
}
|
27 |
+
if ( !empty( $def[ 'stat' ] ) ) {
|
28 |
+
$stats = $this->getEventStats();
|
29 |
+
$stats[ $evt ] = $meta[ 'ts' ] ?? Services::Request()->ts();
|
30 |
+
$this->setEventStats( $stats );
|
31 |
+
}
|
32 |
}
|
33 |
|
34 |
protected function onShutdown() {
|
src/lib/src/Modules/Events/Strings.php
CHANGED
@@ -37,6 +37,8 @@ class Strings extends Base\Strings {
|
|
37 |
'ip_offense' => __( 'Offense Triggered', 'wp-simple-firewall' ),
|
38 |
'ip_blocked' => __( 'IP Blocked', 'wp-simple-firewall' ),
|
39 |
'ip_unblock_flag' => __( 'IP Unblocked Using Flag File', 'wp-simple-firewall' ),
|
|
|
|
|
40 |
'bottrack_404' => sprintf( '%s: %s',
|
41 |
__( 'Bot Detection', 'wp-simple-firewall' ),
|
42 |
'404'
|
@@ -216,6 +218,10 @@ class Strings extends Base\Strings {
|
|
216 |
'password_policy_block' => __( 'Password Change Blocked', 'wp-simple-firewall' ),
|
217 |
'user_hard_suspended' => __( 'User Hard-Suspended', 'wp-simple-firewall' ),
|
218 |
'user_hard_unsuspended' => __( 'User Hard-Unsuspended', 'wp-simple-firewall' ),
|
|
|
|
|
|
|
|
|
219 |
'spam_block_bot' => sprintf( '%s: %s',
|
220 |
__( 'SPAM Blocked', 'wp-simple-firewall' ),
|
221 |
__( 'Bot', 'wp-simple-firewall' )
|
37 |
'ip_offense' => __( 'Offense Triggered', 'wp-simple-firewall' ),
|
38 |
'ip_blocked' => __( 'IP Blocked', 'wp-simple-firewall' ),
|
39 |
'ip_unblock_flag' => __( 'IP Unblocked Using Flag File', 'wp-simple-firewall' ),
|
40 |
+
'antibot_fail' => __( 'Fail AntiBot Test', 'wp-simple-firewall' ),
|
41 |
+
'antibot_pass' => __( 'Pass AntiBot Test', 'wp-simple-firewall' ),
|
42 |
'bottrack_404' => sprintf( '%s: %s',
|
43 |
__( 'Bot Detection', 'wp-simple-firewall' ),
|
44 |
'404'
|
218 |
'password_policy_block' => __( 'Password Change Blocked', 'wp-simple-firewall' ),
|
219 |
'user_hard_suspended' => __( 'User Hard-Suspended', 'wp-simple-firewall' ),
|
220 |
'user_hard_unsuspended' => __( 'User Hard-Unsuspended', 'wp-simple-firewall' ),
|
221 |
+
'spam_block_antibot' => sprintf( '%s: %s',
|
222 |
+
__( 'SPAM Blocked', 'wp-simple-firewall' ),
|
223 |
+
__( 'AntiBot System', 'wp-simple-firewall' )
|
224 |
+
),
|
225 |
'spam_block_bot' => sprintf( '%s: %s',
|
226 |
__( 'SPAM Blocked', 'wp-simple-firewall' ),
|
227 |
__( 'Bot', 'wp-simple-firewall' )
|
src/lib/src/Modules/Events/UI.php
ADDED
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Events;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Databases;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class UI extends BaseShield\UI {
|
10 |
+
|
11 |
+
public function buildInsightsVars() :array {
|
12 |
+
$stats = $this->buildStats();
|
13 |
+
return [
|
14 |
+
'flags' => [
|
15 |
+
'has_stats' => !empty( $stats )
|
16 |
+
],
|
17 |
+
'strings' => [
|
18 |
+
'no_stats' => __('No stats yet. It wont take long though, so check back here soon.')
|
19 |
+
],
|
20 |
+
'vars' => [
|
21 |
+
'stats' => $stats,
|
22 |
+
'stat_intervals' => [
|
23 |
+
'days_1' => '24 Hours',
|
24 |
+
'days_7' => '7 Days',
|
25 |
+
'months_1' => '1 Month',
|
26 |
+
'lifetime' => 'Lifetime',
|
27 |
+
]
|
28 |
+
],
|
29 |
+
];
|
30 |
+
}
|
31 |
+
|
32 |
+
private function buildStats() :array {
|
33 |
+
$allStats = [];
|
34 |
+
|
35 |
+
/** @var ModCon $mod */
|
36 |
+
$mod = $this->getMod();
|
37 |
+
/** @var Strings $strings */
|
38 |
+
$strings = $mod->getStrings();
|
39 |
+
foreach ( $this->getAllEvents() as $eventSection ) {
|
40 |
+
$stats = [];
|
41 |
+
foreach ( $eventSection as $event ) {
|
42 |
+
$sums = $this->buildSums( $event );
|
43 |
+
if ( !empty( array_filter( $sums ) ) ) {
|
44 |
+
$stats[ $event ] = [
|
45 |
+
'key' => $event,
|
46 |
+
'name' => $strings->getEventName( $event ),
|
47 |
+
'counts' => $this->buildSums( $event ),
|
48 |
+
];
|
49 |
+
}
|
50 |
+
}
|
51 |
+
if ( !empty( $stats ) ) {
|
52 |
+
$allStats[] = $stats;
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
return $allStats;
|
57 |
+
}
|
58 |
+
|
59 |
+
private function buildSums( $event ) :array {
|
60 |
+
/** @var ModCon $mod */
|
61 |
+
$mod = $this->getMod();
|
62 |
+
/** @var Databases\Events\Select $selector */
|
63 |
+
$selector = $mod->getDbHandler_Events()->getQuerySelector();
|
64 |
+
$carbon = Services::Request()->carbon( true );
|
65 |
+
return [
|
66 |
+
'lifetime' => $selector->sumEvent( $event ),
|
67 |
+
'months_1' => $selector
|
68 |
+
->filterByCreatedAt( ( clone $carbon )->subDays( 30 )->startOfDay()->timestamp, '>' )
|
69 |
+
->sumEvent( $event ),
|
70 |
+
'days_7' => $selector
|
71 |
+
->filterByCreatedAt( ( clone $carbon )->subDays( 7 )->startOfDay()->timestamp, '>' )
|
72 |
+
->sumEvent( $event ),
|
73 |
+
'days_1' => $selector
|
74 |
+
->filterByCreatedAt( ( clone $carbon )->subHours( 24 )->timestamp, '>' )
|
75 |
+
->sumEvent( $event ),
|
76 |
+
];
|
77 |
+
}
|
78 |
+
|
79 |
+
private function getAllEvents() :array {
|
80 |
+
return [
|
81 |
+
[
|
82 |
+
'ip_offense',
|
83 |
+
'conn_kill',
|
84 |
+
'ip_blocked',
|
85 |
+
],
|
86 |
+
[
|
87 |
+
'antibot_fail',
|
88 |
+
'antibot_pass',
|
89 |
+
'bottrack_404',
|
90 |
+
'bottrack_fakewebcrawler',
|
91 |
+
'bottrack_linkcheese',
|
92 |
+
'bottrack_loginfailed',
|
93 |
+
'bottrack_logininvalid',
|
94 |
+
'bottrack_useragent',
|
95 |
+
'bottrack_xmlrpc',
|
96 |
+
'bottrack_invalidscript',
|
97 |
+
],
|
98 |
+
[
|
99 |
+
'spam_block_antibot',
|
100 |
+
'spam_block_bot',
|
101 |
+
'spam_block_recaptcha',
|
102 |
+
'spam_block_human',
|
103 |
+
],
|
104 |
+
[
|
105 |
+
'cooldown_fail',
|
106 |
+
'honeypot_fail',
|
107 |
+
'botbox_fail',
|
108 |
+
'login_block',
|
109 |
+
'2fa_success',
|
110 |
+
],
|
111 |
+
];
|
112 |
+
}
|
113 |
+
}
|
src/lib/src/Modules/Firewall/Lib/Scan/CanScan.php
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Firewall\Lib\Scan;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Firewall\Options;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class CanScan {
|
10 |
+
|
11 |
+
use ModConsumer;
|
12 |
+
|
13 |
+
public function run() :bool {
|
14 |
+
/** @var Options $opts */
|
15 |
+
$opts = $this->getOptions();
|
16 |
+
$req = Services::Request();
|
17 |
+
|
18 |
+
$canScan = count( $req->getRawRequestParams( false ) ) > 0 && !empty( $req->getPath() );
|
19 |
+
if ( $canScan ) {
|
20 |
+
$paramsToScan = ( new ParametersToScan() )
|
21 |
+
->setMod( $this->getMod() )
|
22 |
+
->retrieve();
|
23 |
+
$canScan = count( $paramsToScan ) > 0
|
24 |
+
&& ( !$opts->isIgnoreAdmin() && is_super_admin() );
|
25 |
+
}
|
26 |
+
return $canScan;
|
27 |
+
}
|
28 |
+
}
|
src/lib/src/Modules/Firewall/Lib/Scan/Checks/Base.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Firewall\Lib\Scan\Checks;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
+
|
7 |
+
class Base {
|
8 |
+
|
9 |
+
use ModConsumer;
|
10 |
+
|
11 |
+
protected $check;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @param string $check
|
15 |
+
* @return $this
|
16 |
+
*/
|
17 |
+
public function setCheck( string $check ) {
|
18 |
+
$this->check = $check;
|
19 |
+
return $this;
|
20 |
+
}
|
21 |
+
|
22 |
+
protected function getFirewallPatterns() :array {
|
23 |
+
return $this->getOptions()->getDef( 'firewall_patterns' )[ $this->check ] ?? [];
|
24 |
+
}
|
25 |
+
|
26 |
+
protected function getFirewallPatterns_Regex() :array {
|
27 |
+
return array_map(
|
28 |
+
function ( $regex ) {
|
29 |
+
return '/'.$regex.'/i';
|
30 |
+
},
|
31 |
+
$this->getFirewallPatterns()[ 'regex' ] ?? []
|
32 |
+
);
|
33 |
+
}
|
34 |
+
|
35 |
+
protected function getFirewallPatterns_Simple() :array {
|
36 |
+
return $this->getFirewallPatterns()[ 'simple' ] ?? [];
|
37 |
+
}
|
38 |
+
}
|
src/lib/src/Modules/Firewall/Lib/Scan/Checks/ExeFiles.php
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Firewall\Lib\Scan\Checks;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
+
|
7 |
+
class ExeFiles extends Base {
|
8 |
+
|
9 |
+
use ModConsumer;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @return false|\WP_Error
|
13 |
+
*/
|
14 |
+
public function run() {
|
15 |
+
$found = false;
|
16 |
+
foreach ( $this->getFileNames() as $param => $file ) {
|
17 |
+
foreach ( $this->getFirewallPatterns_Regex() as $term ) {
|
18 |
+
if ( preg_match( $term, $file ) ) {
|
19 |
+
$found = new \WP_Error( 'shield-firewall', '', [
|
20 |
+
'term' => $term,
|
21 |
+
'param' => $param,
|
22 |
+
'value' => $file,
|
23 |
+
'check' => $this->check,
|
24 |
+
'type' => 'regex',
|
25 |
+
] );
|
26 |
+
break( 2 );
|
27 |
+
}
|
28 |
+
}
|
29 |
+
}
|
30 |
+
return $found;
|
31 |
+
}
|
32 |
+
|
33 |
+
private function getFileNames() :array {
|
34 |
+
return array_filter( array_map(
|
35 |
+
function ( $file ) {
|
36 |
+
return $file[ 'name' ] ?? '';
|
37 |
+
},
|
38 |
+
( !empty( $_FILES ) && is_array( $_FILES ) ) ? $_FILES : []
|
39 |
+
) );
|
40 |
+
}
|
41 |
+
}
|
src/lib/src/Modules/Firewall/Lib/Scan/Checks/Standard.php
ADDED
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Firewall\Lib\Scan\Checks;
|
4 |
+
|
5 |
+
class Standard extends Base {
|
6 |
+
|
7 |
+
private $params;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @param array $params
|
11 |
+
* @return false|\WP_Error
|
12 |
+
*/
|
13 |
+
public function run( array $params ) {
|
14 |
+
$checkResult = false;
|
15 |
+
|
16 |
+
$this->params = $params;
|
17 |
+
|
18 |
+
if ( !empty( $this->getFirewallPatterns() ) ) {
|
19 |
+
$checkResult = $this->testSimplePatterns();
|
20 |
+
if ( !is_wp_error( $checkResult ) ) {
|
21 |
+
$checkResult = $this->testRegexPatterns();
|
22 |
+
}
|
23 |
+
}
|
24 |
+
|
25 |
+
return $checkResult;
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @return false|\WP_Error
|
30 |
+
*/
|
31 |
+
protected function testRegexPatterns() {
|
32 |
+
$found = false;
|
33 |
+
foreach ( $this->getFirewallPatterns_Regex() as $term ) {
|
34 |
+
foreach ( $this->params as $param => $value ) {
|
35 |
+
if ( preg_match( $term, $value ) ) {
|
36 |
+
$found = new \WP_Error( 'shield-firewall', '', [
|
37 |
+
'param' => $param,
|
38 |
+
'value' => $value,
|
39 |
+
'check' => $this->check,
|
40 |
+
'type' => 'regex',
|
41 |
+
] );
|
42 |
+
break( 2 );
|
43 |
+
}
|
44 |
+
}
|
45 |
+
}
|
46 |
+
return $found;
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* @return false|\WP_Error
|
51 |
+
*/
|
52 |
+
protected function testSimplePatterns() {
|
53 |
+
$found = false;
|
54 |
+
foreach ( $this->getFirewallPatterns_Simple() as $term ) {
|
55 |
+
foreach ( $this->params as $param => $value ) {
|
56 |
+
if ( stripos( $value, $term ) !== false ) {
|
57 |
+
$found = new \WP_Error( 'shield-firewall', '', [
|
58 |
+
'param' => $param,
|
59 |
+
'value' => $value,
|
60 |
+
'check' => $this->check,
|
61 |
+
'type' => 'simple',
|
62 |
+
] );
|
63 |
+
break( 2 );
|
64 |
+
}
|
65 |
+
}
|
66 |
+
}
|
67 |
+
return $found;
|
68 |
+
}
|
69 |
+
}
|
src/lib/src/Modules/Firewall/Lib/Scan/ParametersToScan.php
ADDED
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Firewall\Lib\Scan;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Firewall\Options;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class ParametersToScan {
|
10 |
+
|
11 |
+
use ModConsumer;
|
12 |
+
|
13 |
+
private $params = [];
|
14 |
+
|
15 |
+
public function retrieve() :array {
|
16 |
+
|
17 |
+
// Ensure strings and remove non-scalar entries
|
18 |
+
$this->params = array_map( 'strval', array_filter(
|
19 |
+
Services::Request()->getRawRequestParams( false ),
|
20 |
+
function ( $value ) {
|
21 |
+
return is_scalar( $value );
|
22 |
+
}
|
23 |
+
) );
|
24 |
+
|
25 |
+
if ( !empty( $this->params ) ) {
|
26 |
+
$this->removeParamsBasedOnPageName();
|
27 |
+
}
|
28 |
+
|
29 |
+
if ( !empty( $this->params ) ) {
|
30 |
+
$this->removeAllPageParams();
|
31 |
+
}
|
32 |
+
|
33 |
+
return $this->params;
|
34 |
+
}
|
35 |
+
|
36 |
+
private function removeAllPageParams() {
|
37 |
+
foreach ( $this->getAllPageWhitelistedParameters() as $listParam ) {
|
38 |
+
|
39 |
+
if ( preg_match( '#^/.+/$#', $listParam ) ) {
|
40 |
+
foreach ( array_keys( $this->params ) as $param ) {
|
41 |
+
if ( preg_match( $listParam, $param ) ) {
|
42 |
+
unset( $this->params[ $param ] );
|
43 |
+
}
|
44 |
+
}
|
45 |
+
}
|
46 |
+
elseif ( isset( $params[ $listParam ] ) ) {
|
47 |
+
unset( $params[ $listParam ] );
|
48 |
+
}
|
49 |
+
}
|
50 |
+
}
|
51 |
+
|
52 |
+
private function removeParamsBasedOnPageName() {
|
53 |
+
// Now we run through the list of whitelist pages
|
54 |
+
$thePage = Services::Request()->getPath();
|
55 |
+
foreach ( $this->getWhitelistedParameters() as $pageName => $pageParams ) {
|
56 |
+
|
57 |
+
// if the page is white listed
|
58 |
+
if ( $pageName !== '*' && strpos( $thePage, $pageName ) !== false ) {
|
59 |
+
|
60 |
+
/**
|
61 |
+
* If the page has no parameters, then remove all parameters to scan
|
62 |
+
* Otherwise, remove only those parameter specified
|
63 |
+
*/
|
64 |
+
$this->params = empty( $pageParams ) ? []
|
65 |
+
: array_diff_key( $this->params, array_flip( $pageParams ) );
|
66 |
+
break;
|
67 |
+
}
|
68 |
+
}
|
69 |
+
}
|
70 |
+
|
71 |
+
private function getAllPageWhitelistedParameters() :array {
|
72 |
+
$all = $this->getWhitelistedParameters()[ '*' ] ?? [];
|
73 |
+
return is_array( $all ) ? $all : [];
|
74 |
+
}
|
75 |
+
|
76 |
+
private function getWhitelistedParameters() :array {
|
77 |
+
/** @var Options $opts */
|
78 |
+
$opts = $this->getOptions();
|
79 |
+
return Services::DataManipulation()
|
80 |
+
->mergeArraysRecursive(
|
81 |
+
$opts->getDef( 'default_whitelist' ),
|
82 |
+
$opts->getCustomWhitelist()
|
83 |
+
);
|
84 |
+
}
|
85 |
+
}
|
src/lib/src/Modules/Firewall/Lib/Scan/PerformScan.php
ADDED
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Firewall\Lib\Scan;
|
4 |
+
|
5 |
+
use FernleafSystems\Utilities\Logic\ExecOnce;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
+
|
8 |
+
class PerformScan {
|
9 |
+
|
10 |
+
use ModConsumer;
|
11 |
+
use ExecOnce;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var false|\WP_Error
|
15 |
+
*/
|
16 |
+
private $checkResult = false;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @return false|\WP_Error
|
20 |
+
*/
|
21 |
+
public function getCheckResult() {
|
22 |
+
return $this->checkResult;
|
23 |
+
}
|
24 |
+
|
25 |
+
protected function canRun() :bool {
|
26 |
+
return ( new CanScan() )
|
27 |
+
->setMod( $this->getMod() )
|
28 |
+
->run();
|
29 |
+
}
|
30 |
+
|
31 |
+
protected function run() {
|
32 |
+
$opts = $this->getOptions();
|
33 |
+
|
34 |
+
$params = ( new ParametersToScan() )
|
35 |
+
->setMod( $this->getMod() )
|
36 |
+
->retrieve();
|
37 |
+
|
38 |
+
$standardChecker = ( new Checks\Standard() )
|
39 |
+
->setMod( $this->getMod() );
|
40 |
+
foreach ( $this->getStandardChecks() as $opt => $check ) {
|
41 |
+
if ( $opts->isOpt( 'block_'.$opt, 'Y' ) ) {
|
42 |
+
$this->checkResult = $standardChecker
|
43 |
+
->setCheck( $check )
|
44 |
+
->run( $params );
|
45 |
+
if ( is_wp_error( $this->checkResult ) ) {
|
46 |
+
break;
|
47 |
+
}
|
48 |
+
}
|
49 |
+
}
|
50 |
+
|
51 |
+
if ( !is_wp_error( $this->checkResult ) ) {
|
52 |
+
$this->checkResult = ( new Checks\ExeFiles() )
|
53 |
+
->setMod( $this->getMod() )
|
54 |
+
->setCheck( 'exefile' )
|
55 |
+
->run();
|
56 |
+
}
|
57 |
+
}
|
58 |
+
|
59 |
+
private function getStandardChecks() :array {
|
60 |
+
return [
|
61 |
+
'dir_traversal' => 'dirtraversal',
|
62 |
+
'sql_queries' => 'sqlqueries',
|
63 |
+
'wordpress_terms' => 'wpterms',
|
64 |
+
'field_truncation' => 'fieldtruncation',
|
65 |
+
'php_code' => 'phpcode',
|
66 |
+
'leading_schema' => 'schema',
|
67 |
+
'aggressive' => 'aggressive',
|
68 |
+
];
|
69 |
+
}
|
70 |
+
}
|
src/lib/src/Modules/Firewall/Options.php
CHANGED
@@ -7,8 +7,8 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield;
|
|
7 |
class Options extends BaseShield\Options {
|
8 |
|
9 |
public function getCustomWhitelist() :array {
|
10 |
-
$
|
11 |
-
return is_array( $
|
12 |
}
|
13 |
|
14 |
public function isIgnoreAdmin() :bool {
|
7 |
class Options extends BaseShield\Options {
|
8 |
|
9 |
public function getCustomWhitelist() :array {
|
10 |
+
$w = $this->getOpt( 'page_params_whitelist', [] );
|
11 |
+
return is_array( $w ) ? $w : [];
|
12 |
}
|
13 |
|
14 |
public function isIgnoreAdmin() :bool {
|
src/lib/src/Modules/Firewall/Processor.php
CHANGED
@@ -10,7 +10,7 @@ class Processor extends BaseShield\Processor {
|
|
10 |
/**
|
11 |
* @var array
|
12 |
*/
|
13 |
-
private $
|
14 |
|
15 |
/**
|
16 |
* @var array
|
@@ -48,12 +48,11 @@ class Processor extends BaseShield\Processor {
|
|
48 |
/** @var Options $opts */
|
49 |
$opts = $this->getOptions();
|
50 |
|
51 |
-
$
|
52 |
-
|
53 |
if ( count( $this->getRawRequestParams() ) == 0 ) {
|
54 |
$bPerformScan = false;
|
55 |
}
|
56 |
-
elseif ( empty( $
|
57 |
$this->getCon()->fireEvent( 'firewall_skip' );
|
58 |
$bPerformScan = false;
|
59 |
}
|
@@ -68,6 +67,13 @@ class Processor extends BaseShield\Processor {
|
|
68 |
return $bPerformScan;
|
69 |
}
|
70 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
private function isVisitorRequestPermitted() :bool {
|
72 |
$opts = $this->getOptions();
|
73 |
|
@@ -277,10 +283,10 @@ class Processor extends BaseShield\Processor {
|
|
277 |
}
|
278 |
|
279 |
protected function getFirewallDieMessage() :array {
|
280 |
-
if ( !isset( $this->
|
281 |
-
$this->
|
282 |
}
|
283 |
-
return $this->
|
284 |
}
|
285 |
|
286 |
protected function getFirewallDieMessageForDisplay() :string {
|
@@ -292,13 +298,13 @@ class Processor extends BaseShield\Processor {
|
|
292 |
}
|
293 |
|
294 |
/**
|
295 |
-
* @param string $
|
296 |
* @return $this
|
297 |
*/
|
298 |
-
protected function addToFirewallDieMessage( $
|
299 |
-
$
|
300 |
-
$
|
301 |
-
$this->
|
302 |
return $this;
|
303 |
}
|
304 |
|
@@ -363,7 +369,7 @@ class Processor extends BaseShield\Processor {
|
|
363 |
}
|
364 |
|
365 |
private function getRawRequestParams() :array {
|
366 |
-
return Services::Request()->getRawRequestParams(
|
367 |
}
|
368 |
|
369 |
private function sendBlockEmail( string $recipient ) :bool {
|
10 |
/**
|
11 |
* @var array
|
12 |
*/
|
13 |
+
private $dieMessage;
|
14 |
|
15 |
/**
|
16 |
* @var array
|
48 |
/** @var Options $opts */
|
49 |
$opts = $this->getOptions();
|
50 |
|
51 |
+
$path = Services::Request()->getPath();
|
|
|
52 |
if ( count( $this->getRawRequestParams() ) == 0 ) {
|
53 |
$bPerformScan = false;
|
54 |
}
|
55 |
+
elseif ( empty( $path ) ) {
|
56 |
$this->getCon()->fireEvent( 'firewall_skip' );
|
57 |
$bPerformScan = false;
|
58 |
}
|
67 |
return $bPerformScan;
|
68 |
}
|
69 |
|
70 |
+
private function runScan() :bool {
|
71 |
+
$scanner = ( new Lib\Scan\PerformScan() )
|
72 |
+
->setMod( $this->getMod() );
|
73 |
+
$scanner->execute();
|
74 |
+
$result = $scanner->getCheckResult();
|
75 |
+
}
|
76 |
+
|
77 |
private function isVisitorRequestPermitted() :bool {
|
78 |
$opts = $this->getOptions();
|
79 |
|
283 |
}
|
284 |
|
285 |
protected function getFirewallDieMessage() :array {
|
286 |
+
if ( !isset( $this->dieMessage ) || !is_array( $this->dieMessage ) ) {
|
287 |
+
$this->dieMessage = [ $this->getMod()->getTextOpt( 'text_firewalldie' ) ];
|
288 |
}
|
289 |
+
return $this->dieMessage;
|
290 |
}
|
291 |
|
292 |
protected function getFirewallDieMessageForDisplay() :string {
|
298 |
}
|
299 |
|
300 |
/**
|
301 |
+
* @param string $msg
|
302 |
* @return $this
|
303 |
*/
|
304 |
+
protected function addToFirewallDieMessage( string $msg ) {
|
305 |
+
$messages = $this->getFirewallDieMessage();
|
306 |
+
$messages[] = $msg;
|
307 |
+
$this->dieMessage = $messages;
|
308 |
return $this;
|
309 |
}
|
310 |
|
369 |
}
|
370 |
|
371 |
private function getRawRequestParams() :array {
|
372 |
+
return Services::Request()->getRawRequestParams( false );
|
373 |
}
|
374 |
|
375 |
private function sendBlockEmail( string $recipient ) :bool {
|
src/lib/src/Modules/HackGuard/AjaxHandler.php
CHANGED
@@ -4,6 +4,7 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
|
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases;
|
|
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\FileLocker;
|
8 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan;
|
9 |
use FernleafSystems\Wordpress\Services\Services;
|
@@ -66,8 +67,7 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
66 |
/** @var ModCon $mod */
|
67 |
$mod = $this->getMod();
|
68 |
|
69 |
-
|
70 |
-
switch ( $sScanSlug ) {
|
71 |
|
72 |
case 'aggregate':
|
73 |
$oTableBuilder = new Shield\Tables\Build\ScanAggregate();
|
@@ -147,6 +147,8 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
147 |
'modified_file' => __( 'Modified File' ),
|
148 |
'locked' => __( 'Locked' ),
|
149 |
'modified_timestamp' => __( 'File Modified Timestamp' ),
|
|
|
|
|
150 |
'modified' => __( 'Modified' ),
|
151 |
'download' => __( 'Download' ),
|
152 |
'change_detected_at' => __( 'Change Detected' ),
|
@@ -156,14 +158,17 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
156 |
'download_modified' => __( 'Download Modified' ),
|
157 |
'file_download' => __( 'File Download' ),
|
158 |
'file_info' => __( 'File Info' ),
|
159 |
-
'file_accept' => __( 'File
|
160 |
'file_accept_checkbox' => __( 'Are you sure you want to keep the file changes?' ),
|
161 |
-
'file_restore' => __( 'File
|
162 |
'file_restore_checkbox' => __( 'Are you sure you want to restore the original file contents?' ),
|
163 |
'file_restore_button' => __( 'Are you sure you want to restore the original file contents?' ),
|
164 |
]
|
165 |
];
|
166 |
try {
|
|
|
|
|
|
|
167 |
|
168 |
$lock = $oFLCon->getFileLock( $nRID );
|
169 |
$bDiff = $lock->detected_at > 0;
|
@@ -174,11 +179,24 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
174 |
->setMod( $this->getMod() )
|
175 |
->run( $nRID, 'diff' ) : '';
|
176 |
|
177 |
-
$
|
178 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
$data[ 'vars' ][ 'file_modified_at' ] =
|
180 |
Services::WpGeneral()->getTimeStampForDisplay( $FS->getModifiedTime( $lock->file ) );
|
181 |
-
$data[ 'vars' ][ '
|
|
|
|
|
182 |
$data[ 'vars' ][ 'file_size_locked' ] = Shield\Utilities\Tool\FormatBytes::Format( strlen(
|
183 |
( new FileLocker\Ops\ReadOriginalFileContent() )
|
184 |
->setMod( $mod )
|
@@ -199,7 +217,7 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
199 |
'message' => $data[ 'error' ],
|
200 |
'html' => $this->getMod()
|
201 |
->renderTemplate(
|
202 |
-
'/wpadmin_pages/insights/scans/realtime/file_locker/file_diff.twig',
|
203 |
$data,
|
204 |
true
|
205 |
)
|
@@ -255,10 +273,10 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
255 |
|
256 |
/**
|
257 |
* @param string $action
|
258 |
-
* @param bool $
|
259 |
* @return array
|
260 |
*/
|
261 |
-
private function ajaxExec_ScanItemAction( $action, $
|
262 |
/** @var ModCon $mod */
|
263 |
$mod = $this->getMod();
|
264 |
|
@@ -270,7 +288,7 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
270 |
$msg = __( 'File download has started.', 'wp-simple-firewall' );
|
271 |
}
|
272 |
else {
|
273 |
-
if ( $
|
274 |
$itemIDs = (array)Services::Request()->post( 'ids', [] );
|
275 |
}
|
276 |
else {
|
@@ -380,7 +398,7 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
380 |
$success = false;
|
381 |
$reloadPage = false;
|
382 |
$msg = __( 'No scans were selected', 'wp-simple-firewall' );
|
383 |
-
$formParams =
|
384 |
|
385 |
$scanCon = $mod->getScanQueueController();
|
386 |
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Lib\Request\FormParams;
|
8 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\FileLocker;
|
9 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan;
|
10 |
use FernleafSystems\Wordpress\Services\Services;
|
67 |
/** @var ModCon $mod */
|
68 |
$mod = $this->getMod();
|
69 |
|
70 |
+
switch ( Services::Request()->post( 'fScan', '' ) ) {
|
|
|
71 |
|
72 |
case 'aggregate':
|
73 |
$oTableBuilder = new Shield\Tables\Build\ScanAggregate();
|
147 |
'modified_file' => __( 'Modified File' ),
|
148 |
'locked' => __( 'Locked' ),
|
149 |
'modified_timestamp' => __( 'File Modified Timestamp' ),
|
150 |
+
'file_modified' => __( 'File Modified' ),
|
151 |
+
'relative_path' => __( 'Relative Path' ),
|
152 |
'modified' => __( 'Modified' ),
|
153 |
'download' => __( 'Download' ),
|
154 |
'change_detected_at' => __( 'Change Detected' ),
|
158 |
'download_modified' => __( 'Download Modified' ),
|
159 |
'file_download' => __( 'File Download' ),
|
160 |
'file_info' => __( 'File Info' ),
|
161 |
+
'file_accept' => __( 'Accept File Changes' ),
|
162 |
'file_accept_checkbox' => __( 'Are you sure you want to keep the file changes?' ),
|
163 |
+
'file_restore' => __( 'Restore Original File' ),
|
164 |
'file_restore_checkbox' => __( 'Are you sure you want to restore the original file contents?' ),
|
165 |
'file_restore_button' => __( 'Are you sure you want to restore the original file contents?' ),
|
166 |
]
|
167 |
];
|
168 |
try {
|
169 |
+
if ( !is_numeric( $nRID ) ) {
|
170 |
+
throw new \Exception( 'Not a valid file lock request.' );
|
171 |
+
}
|
172 |
|
173 |
$lock = $oFLCon->getFileLock( $nRID );
|
174 |
$bDiff = $lock->detected_at > 0;
|
179 |
->setMod( $this->getMod() )
|
180 |
->run( $nRID, 'diff' ) : '';
|
181 |
|
182 |
+
$carb = Services::Request()->carbon( true );
|
183 |
+
|
184 |
+
$absPath = wp_normalize_path( ABSPATH );
|
185 |
+
$filePath = wp_normalize_path( $lock->file );
|
186 |
+
if ( strpos( $filePath, $absPath ) !== false ) {
|
187 |
+
$data[ 'vars' ][ 'relative_path' ] = str_replace( $absPath, '/', $filePath );
|
188 |
+
}
|
189 |
+
else {
|
190 |
+
$data[ 'vars' ][ 'relative_path' ] = '../'.basename( $filePath );
|
191 |
+
}
|
192 |
+
|
193 |
+
$data[ 'vars' ][ 'relative_path' ] = str_replace( wp_normalize_path( ABSPATH ), '/', wp_normalize_path( $lock->file ) );
|
194 |
+
$data[ 'vars' ][ 'locked_at' ] = $carb->setTimestamp( $lock->created_at )->diffForHumans();
|
195 |
$data[ 'vars' ][ 'file_modified_at' ] =
|
196 |
Services::WpGeneral()->getTimeStampForDisplay( $FS->getModifiedTime( $lock->file ) );
|
197 |
+
$data[ 'vars' ][ 'file_modified_ago' ] =
|
198 |
+
$carb->setTimestamp( $FS->getModifiedTime( $lock->file ) )->diffForHumans();
|
199 |
+
$data[ 'vars' ][ 'change_detected_at' ] = $carb->setTimestamp( $lock->detected_at )->diffForHumans();
|
200 |
$data[ 'vars' ][ 'file_size_locked' ] = Shield\Utilities\Tool\FormatBytes::Format( strlen(
|
201 |
( new FileLocker\Ops\ReadOriginalFileContent() )
|
202 |
->setMod( $mod )
|
217 |
'message' => $data[ 'error' ],
|
218 |
'html' => $this->getMod()
|
219 |
->renderTemplate(
|
220 |
+
'/wpadmin_pages/insights/scans/results/realtime/file_locker/file_diff.twig',
|
221 |
$data,
|
222 |
true
|
223 |
)
|
273 |
|
274 |
/**
|
275 |
* @param string $action
|
276 |
+
* @param bool $isBulkAction
|
277 |
* @return array
|
278 |
*/
|
279 |
+
private function ajaxExec_ScanItemAction( $action, $isBulkAction = false ) :array {
|
280 |
/** @var ModCon $mod */
|
281 |
$mod = $this->getMod();
|
282 |
|
288 |
$msg = __( 'File download has started.', 'wp-simple-firewall' );
|
289 |
}
|
290 |
else {
|
291 |
+
if ( $isBulkAction ) {
|
292 |
$itemIDs = (array)Services::Request()->post( 'ids', [] );
|
293 |
}
|
294 |
else {
|
398 |
$success = false;
|
399 |
$reloadPage = false;
|
400 |
$msg = __( 'No scans were selected', 'wp-simple-firewall' );
|
401 |
+
$formParams = FormParams::Retrieve();
|
402 |
|
403 |
$scanCon = $mod->getScanQueueController();
|
404 |
|
src/lib/src/Modules/HackGuard/Insights/OverviewCards.php
CHANGED
@@ -85,7 +85,7 @@ class OverviewCards extends Shield\Modules\Base\Insights\OverviewCards {
|
|
85 |
$cards[ 'wcf_problem' ] = [
|
86 |
'name' => __( 'Core Files Changed', 'wp-simple-firewall' ),
|
87 |
'summary' => __( 'WordPress core files have been modified.', 'wp-simple-firewall' ),
|
88 |
-
'href' => $this->
|
89 |
'state' => -2,
|
90 |
'help' => __( 'Scan WP core files and repair any files that are flagged as modified.', 'wp-simple-firewall' )
|
91 |
];
|
@@ -129,7 +129,7 @@ class OverviewCards extends Shield\Modules\Base\Insights\OverviewCards {
|
|
129 |
'summary' => __( 'Unrecognised files found in WordPress Core directory.', 'wp-simple-firewall' ),
|
130 |
'help' => __( 'Scan and remove any files that are not meant to be in the WP core directories.', 'wp-simple-firewall' ),
|
131 |
'state' => -2,
|
132 |
-
'href' => $this->
|
133 |
];
|
134 |
}
|
135 |
|
@@ -158,7 +158,7 @@ class OverviewCards extends Shield\Modules\Base\Insights\OverviewCards {
|
|
158 |
'name' => $scanCon->getScanName(),
|
159 |
'summary' => __( 'A plugin/theme was found to have been modified.', 'wp-simple-firewall' ),
|
160 |
'state' => -2,
|
161 |
-
'href' => $this->
|
162 |
'help' => __( 'Reviewing modifications to your plugins/themes is recommended.', 'wp-simple-firewall' ),
|
163 |
|
164 |
];
|
@@ -189,7 +189,7 @@ class OverviewCards extends Shield\Modules\Base\Insights\OverviewCards {
|
|
189 |
'name' => __( 'Malware Detected', 'wp-simple-firewall' ),
|
190 |
'summary' => __( 'Potential Malware files have been discovered.', 'wp-simple-firewall' ),
|
191 |
'state' => -2,
|
192 |
-
'href' => $this->
|
193 |
'help' => __( 'Files identified as potential malware should be examined as soon as possible.', 'wp-simple-firewall' ),
|
194 |
];
|
195 |
}
|
@@ -218,7 +218,7 @@ class OverviewCards extends Shield\Modules\Base\Insights\OverviewCards {
|
|
218 |
'name' => __( 'Plugin Abandoned' ),
|
219 |
'summary' => __( 'At least 1 plugin on your site is abandoned.', 'wp-simple-firewall' ),
|
220 |
'state' => -1,
|
221 |
-
'href' => $this->
|
222 |
'help' => __( 'Plugins that have been abandoned represent a potential risk to your site.', 'wp-simple-firewall' )
|
223 |
];
|
224 |
}
|
@@ -260,7 +260,7 @@ class OverviewCards extends Shield\Modules\Base\Insights\OverviewCards {
|
|
260 |
'name' => __( 'Vulnerable Plugin', 'wp-simple-firewall' ),
|
261 |
'summary' => __( 'Plugin with vulnerabilities found on site.', 'wp-simple-firewall' ),
|
262 |
'state' => -2,
|
263 |
-
'href' => $this->
|
264 |
'help' => __( 'Items with known vulnerabilities should be updated, removed, or replaced.', 'wp-simple-firewall' )
|
265 |
];
|
266 |
}
|
@@ -268,7 +268,7 @@ class OverviewCards extends Shield\Modules\Base\Insights\OverviewCards {
|
|
268 |
return $cards;
|
269 |
}
|
270 |
|
271 |
-
private function
|
272 |
-
return $this->getCon()->getModule_Insights()->
|
273 |
}
|
274 |
}
|
85 |
$cards[ 'wcf_problem' ] = [
|
86 |
'name' => __( 'Core Files Changed', 'wp-simple-firewall' ),
|
87 |
'summary' => __( 'WordPress core files have been modified.', 'wp-simple-firewall' ),
|
88 |
+
'href' => $this->getUrlForScanResults(),
|
89 |
'state' => -2,
|
90 |
'help' => __( 'Scan WP core files and repair any files that are flagged as modified.', 'wp-simple-firewall' )
|
91 |
];
|
129 |
'summary' => __( 'Unrecognised files found in WordPress Core directory.', 'wp-simple-firewall' ),
|
130 |
'help' => __( 'Scan and remove any files that are not meant to be in the WP core directories.', 'wp-simple-firewall' ),
|
131 |
'state' => -2,
|
132 |
+
'href' => $this->getUrlForScanResults(),
|
133 |
];
|
134 |
}
|
135 |
|
158 |
'name' => $scanCon->getScanName(),
|
159 |
'summary' => __( 'A plugin/theme was found to have been modified.', 'wp-simple-firewall' ),
|
160 |
'state' => -2,
|
161 |
+
'href' => $this->getUrlForScanResults(),
|
162 |
'help' => __( 'Reviewing modifications to your plugins/themes is recommended.', 'wp-simple-firewall' ),
|
163 |
|
164 |
];
|
189 |
'name' => __( 'Malware Detected', 'wp-simple-firewall' ),
|
190 |
'summary' => __( 'Potential Malware files have been discovered.', 'wp-simple-firewall' ),
|
191 |
'state' => -2,
|
192 |
+
'href' => $this->getUrlForScanResults(),
|
193 |
'help' => __( 'Files identified as potential malware should be examined as soon as possible.', 'wp-simple-firewall' ),
|
194 |
];
|
195 |
}
|
218 |
'name' => __( 'Plugin Abandoned' ),
|
219 |
'summary' => __( 'At least 1 plugin on your site is abandoned.', 'wp-simple-firewall' ),
|
220 |
'state' => -1,
|
221 |
+
'href' => $this->getUrlForScanResults(),
|
222 |
'help' => __( 'Plugins that have been abandoned represent a potential risk to your site.', 'wp-simple-firewall' )
|
223 |
];
|
224 |
}
|
260 |
'name' => __( 'Vulnerable Plugin', 'wp-simple-firewall' ),
|
261 |
'summary' => __( 'Plugin with vulnerabilities found on site.', 'wp-simple-firewall' ),
|
262 |
'state' => -2,
|
263 |
+
'href' => $this->getUrlForScanResults(),
|
264 |
'help' => __( 'Items with known vulnerabilities should be updated, removed, or replaced.', 'wp-simple-firewall' )
|
265 |
];
|
266 |
}
|
268 |
return $cards;
|
269 |
}
|
270 |
|
271 |
+
private function getUrlForScanResults() :string{
|
272 |
+
return $this->getCon()->getModule_Insights()->getUrl_ScansResults();
|
273 |
}
|
274 |
}
|
src/lib/src/Modules/HackGuard/Lib/FileLocker/File.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\FileLocker;
|
4 |
|
5 |
-
use FernleafSystems\Utilities\Data\Adapter\
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
8 |
/**
|
@@ -13,15 +13,24 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
13 |
* @property int $max_levels
|
14 |
* @property int $max_paths
|
15 |
*/
|
16 |
-
class File {
|
17 |
-
|
18 |
-
use DynProperties;
|
19 |
|
20 |
public function __construct( string $filename, $dir = ABSPATH ) {
|
21 |
$this->file = $filename;
|
22 |
$this->dir = wp_normalize_path( $dir );
|
23 |
}
|
24 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
/**
|
26 |
* @return string[]
|
27 |
*/
|
@@ -50,14 +59,10 @@ class File {
|
|
50 |
$workingDir = dirname( $workingDir );
|
51 |
$dirCount++;
|
52 |
} while (
|
53 |
-
$dirCount < $this->
|
54 |
-
&& ( empty( $this->max_paths ) || count( $paths )
|
55 |
);
|
56 |
|
57 |
return $paths;
|
58 |
}
|
59 |
-
|
60 |
-
protected function getMaxDirLevels() :int {
|
61 |
-
return (int)max( 1, (int)$this->max_levels );
|
62 |
-
}
|
63 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\FileLocker;
|
4 |
|
5 |
+
use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
8 |
/**
|
13 |
* @property int $max_levels
|
14 |
* @property int $max_paths
|
15 |
*/
|
16 |
+
class File extends DynPropertiesClass {
|
|
|
|
|
17 |
|
18 |
public function __construct( string $filename, $dir = ABSPATH ) {
|
19 |
$this->file = $filename;
|
20 |
$this->dir = wp_normalize_path( $dir );
|
21 |
}
|
22 |
|
23 |
+
public function __get( string $key ) {
|
24 |
+
$value = parent::__get( $key );
|
25 |
+
switch ( $key ) {
|
26 |
+
case 'max_paths':
|
27 |
+
case 'max_level':
|
28 |
+
$value = (int)max( 1, $value );
|
29 |
+
break;
|
30 |
+
}
|
31 |
+
return $value;
|
32 |
+
}
|
33 |
+
|
34 |
/**
|
35 |
* @return string[]
|
36 |
*/
|
59 |
$workingDir = dirname( $workingDir );
|
60 |
$dirCount++;
|
61 |
} while (
|
62 |
+
$dirCount < $this->max_levels
|
63 |
+
&& ( empty( $this->max_paths ) || count( $paths ) <= $this->max_paths )
|
64 |
);
|
65 |
|
66 |
return $paths;
|
67 |
}
|
|
|
|
|
|
|
|
|
68 |
}
|
src/lib/src/Modules/HackGuard/Lib/FileLocker/FileLockerController.php
CHANGED
@@ -38,10 +38,15 @@ class FileLockerController {
|
|
38 |
|
39 |
public function processFileLocks() {
|
40 |
if ( !$this->getCon()->plugin_deactivating && !$this->getCon()->is_my_upgrade ) {
|
41 |
-
$this->
|
42 |
}
|
43 |
}
|
44 |
|
|
|
|
|
|
|
|
|
|
|
45 |
public function addAdminMenuBarItem( array $items ) :array {
|
46 |
$problems = $this->countProblems();
|
47 |
if ( $problems > 0 ) {
|
@@ -49,7 +54,7 @@ class FileLockerController {
|
|
49 |
'id' => $this->getCon()->prefix( 'filelocker_problems' ),
|
50 |
'title' => __( 'File Locker', 'wp-simple-firewall' )
|
51 |
.sprintf( '<div class="wp-core-ui wp-ui-notification shield-counter"><span aria-hidden="true">%s</span></div>', $problems ),
|
52 |
-
'href' => $this->getCon()->getModule_Insights()->
|
53 |
'warnings' => $problems
|
54 |
];
|
55 |
}
|
@@ -171,62 +176,63 @@ class FileLockerController {
|
|
171 |
}
|
172 |
if ( $lockCreated ) {
|
173 |
$state[ 'last_locks_created_at' ] = Services::Request()->ts();
|
174 |
-
$this->setState( $state );
|
175 |
}
|
|
|
|
|
|
|
176 |
}
|
177 |
}
|
178 |
|
179 |
/**
|
180 |
* @param string $fileKey
|
181 |
-
* @return File
|
182 |
* @throws \Exception
|
183 |
*/
|
184 |
-
private function getFile( $fileKey ) {
|
185 |
-
$
|
186 |
|
187 |
-
$
|
188 |
-
$
|
189 |
switch ( $fileKey ) {
|
190 |
case 'wpconfig':
|
191 |
$fileKey = 'wp-config.php';
|
192 |
-
$
|
193 |
-
$
|
194 |
-
|
195 |
$openBaseDir = ini_get( 'open_basedir' );
|
196 |
if ( !empty( $openBaseDir ) ) {
|
197 |
-
$
|
198 |
}
|
199 |
-
// TODO: is split URL?
|
200 |
break;
|
201 |
|
202 |
case 'root_htaccess':
|
203 |
$fileKey = '.htaccess';
|
204 |
-
$
|
205 |
break;
|
206 |
|
207 |
case 'root_webconfig':
|
208 |
$fileKey = 'Web.Config';
|
209 |
-
$
|
210 |
break;
|
211 |
|
212 |
case 'root_index':
|
213 |
$fileKey = 'index.php';
|
214 |
-
$
|
215 |
break;
|
216 |
default:
|
217 |
if ( Services::WpFs()->isAbsPath( $fileKey ) && Services::WpFs()->isFile( $fileKey ) ) {
|
218 |
-
$
|
219 |
-
$
|
220 |
}
|
221 |
else {
|
222 |
throw new \Exception( 'Not a supported file lock type' );
|
223 |
}
|
224 |
break;
|
225 |
}
|
226 |
-
|
227 |
-
$
|
228 |
-
$
|
229 |
-
|
|
|
230 |
}
|
231 |
|
232 |
protected function getState() :array {
|
@@ -234,7 +240,8 @@ class FileLockerController {
|
|
234 |
$opts = $this->getOptions();
|
235 |
return array_merge(
|
236 |
[
|
237 |
-
'
|
|
|
238 |
],
|
239 |
is_array( $opts->getOpt( 'filelocker_state' ) ) ? $opts->getOpt( 'filelocker_state' ) : []
|
240 |
);
|
38 |
|
39 |
public function processFileLocks() {
|
40 |
if ( !$this->getCon()->plugin_deactivating && !$this->getCon()->is_my_upgrade ) {
|
41 |
+
$this->isFileLockerStateChanged() ? $this->deleteAllLocks() : $this->runAnalysis();
|
42 |
}
|
43 |
}
|
44 |
|
45 |
+
private function isFileLockerStateChanged() :bool {
|
46 |
+
return $this->getOptions()->isOptChanged( 'file_locker' )
|
47 |
+
|| $this->getState()[ 'abspath' ] !== ABSPATH;
|
48 |
+
}
|
49 |
+
|
50 |
public function addAdminMenuBarItem( array $items ) :array {
|
51 |
$problems = $this->countProblems();
|
52 |
if ( $problems > 0 ) {
|
54 |
'id' => $this->getCon()->prefix( 'filelocker_problems' ),
|
55 |
'title' => __( 'File Locker', 'wp-simple-firewall' )
|
56 |
.sprintf( '<div class="wp-core-ui wp-ui-notification shield-counter"><span aria-hidden="true">%s</span></div>', $problems ),
|
57 |
+
'href' => $this->getCon()->getModule_Insights()->getUrl_ScansResults(),
|
58 |
'warnings' => $problems
|
59 |
];
|
60 |
}
|
176 |
}
|
177 |
if ( $lockCreated ) {
|
178 |
$state[ 'last_locks_created_at' ] = Services::Request()->ts();
|
|
|
179 |
}
|
180 |
+
|
181 |
+
$state[ 'abspath' ] = ABSPATH;
|
182 |
+
$this->setState( $state );
|
183 |
}
|
184 |
}
|
185 |
|
186 |
/**
|
187 |
* @param string $fileKey
|
188 |
+
* @return File
|
189 |
* @throws \Exception
|
190 |
*/
|
191 |
+
private function getFile( string $fileKey ) :File {
|
192 |
+
$file = null;
|
193 |
|
194 |
+
$isSplitWpUrl = false; // TODO: is split URL?
|
195 |
+
$maxPaths = 1;
|
196 |
switch ( $fileKey ) {
|
197 |
case 'wpconfig':
|
198 |
$fileKey = 'wp-config.php';
|
199 |
+
$maxPaths = 1;
|
200 |
+
$levels = $isSplitWpUrl ? 3 : 2;
|
|
|
201 |
$openBaseDir = ini_get( 'open_basedir' );
|
202 |
if ( !empty( $openBaseDir ) ) {
|
203 |
+
$levels--;
|
204 |
}
|
|
|
205 |
break;
|
206 |
|
207 |
case 'root_htaccess':
|
208 |
$fileKey = '.htaccess';
|
209 |
+
$levels = $isSplitWpUrl ? 2 : 1;
|
210 |
break;
|
211 |
|
212 |
case 'root_webconfig':
|
213 |
$fileKey = 'Web.Config';
|
214 |
+
$levels = $isSplitWpUrl ? 2 : 1;
|
215 |
break;
|
216 |
|
217 |
case 'root_index':
|
218 |
$fileKey = 'index.php';
|
219 |
+
$levels = $isSplitWpUrl ? 2 : 1;
|
220 |
break;
|
221 |
default:
|
222 |
if ( Services::WpFs()->isAbsPath( $fileKey ) && Services::WpFs()->isFile( $fileKey ) ) {
|
223 |
+
$levels = 1;
|
224 |
+
$maxPaths = 1;
|
225 |
}
|
226 |
else {
|
227 |
throw new \Exception( 'Not a supported file lock type' );
|
228 |
}
|
229 |
break;
|
230 |
}
|
231 |
+
|
232 |
+
$file = new File( $fileKey );
|
233 |
+
$file->max_levels = $levels;
|
234 |
+
$file->max_paths = $maxPaths;
|
235 |
+
return $file;
|
236 |
}
|
237 |
|
238 |
protected function getState() :array {
|
240 |
$opts = $this->getOptions();
|
241 |
return array_merge(
|
242 |
[
|
243 |
+
'abspath' => ABSPATH,
|
244 |
+
'last_locks_created_at' => 0,
|
245 |
],
|
246 |
is_array( $opts->getOpt( 'filelocker_state' ) ) ? $opts->getOpt( 'filelocker_state' ) : []
|
247 |
);
|
src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/BaseOps.php
CHANGED
@@ -19,28 +19,28 @@ class BaseOps {
|
|
19 |
/**
|
20 |
* @var FileLocker\File
|
21 |
*/
|
22 |
-
protected $
|
23 |
|
24 |
/**
|
25 |
* @return Databases\FileLocker\EntryVO|null
|
26 |
*/
|
27 |
protected function findLockRecordForFile() {
|
28 |
-
$
|
29 |
-
foreach ( $this->
|
30 |
-
foreach ( $this->getFileLocks() as $
|
31 |
-
if ( $
|
32 |
-
$
|
33 |
break;
|
34 |
}
|
35 |
}
|
36 |
}
|
37 |
-
return $
|
38 |
}
|
39 |
|
40 |
/**
|
41 |
-
* @return Databases\FileLocker\EntryVO[]
|
42 |
*/
|
43 |
-
protected function getFileLocks() {
|
44 |
return ( new LoadFileLocks() )
|
45 |
->setMod( $this->getMod() )
|
46 |
->loadLocks();
|
@@ -71,11 +71,11 @@ class BaseOps {
|
|
71 |
}
|
72 |
|
73 |
/**
|
74 |
-
* @param FileLocker\File $
|
75 |
* @return $this
|
76 |
*/
|
77 |
-
public function setWorkingFile( FileLocker\File $
|
78 |
-
$this->
|
79 |
return $this;
|
80 |
}
|
81 |
}
|
19 |
/**
|
20 |
* @var FileLocker\File
|
21 |
*/
|
22 |
+
protected $file;
|
23 |
|
24 |
/**
|
25 |
* @return Databases\FileLocker\EntryVO|null
|
26 |
*/
|
27 |
protected function findLockRecordForFile() {
|
28 |
+
$theLock = null;
|
29 |
+
foreach ( $this->file->getPossiblePaths() as $sPath ) {
|
30 |
+
foreach ( $this->getFileLocks() as $lock ) {
|
31 |
+
if ( $lock->file === $sPath ) {
|
32 |
+
$theLock = $lock;
|
33 |
break;
|
34 |
}
|
35 |
}
|
36 |
}
|
37 |
+
return $theLock;
|
38 |
}
|
39 |
|
40 |
/**
|
41 |
+
* @return Databases\FileLocker\EntryVO[]
|
42 |
*/
|
43 |
+
protected function getFileLocks() :array {
|
44 |
return ( new LoadFileLocks() )
|
45 |
->setMod( $this->getMod() )
|
46 |
->loadLocks();
|
71 |
}
|
72 |
|
73 |
/**
|
74 |
+
* @param FileLocker\File $file
|
75 |
* @return $this
|
76 |
*/
|
77 |
+
public function setWorkingFile( FileLocker\File $file ) {
|
78 |
+
$this->file = $file;
|
79 |
return $this;
|
80 |
}
|
81 |
}
|
src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/CreateFileLocks.php
CHANGED
@@ -17,7 +17,7 @@ class CreateFileLocks extends BaseOps {
|
|
17 |
*/
|
18 |
public function create() :bool {
|
19 |
$pathsProcessed = false;
|
20 |
-
foreach ( $this->
|
21 |
$theLock = null;
|
22 |
foreach ( $this->getFileLocks() as $maybeLock ) {
|
23 |
if ( $maybeLock->file === $path ) {
|
@@ -52,9 +52,9 @@ class CreateFileLocks extends BaseOps {
|
|
52 |
->setMod( $mod )
|
53 |
->build( $path, reset( $publicKey ) );
|
54 |
|
55 |
-
/** @var FileLocker\Insert $
|
56 |
-
$
|
57 |
-
$success = $
|
58 |
|
59 |
$this->clearFileLocksCache();
|
60 |
}
|
17 |
*/
|
18 |
public function create() :bool {
|
19 |
$pathsProcessed = false;
|
20 |
+
foreach ( $this->file->getExistingPossiblePaths() as $path ) {
|
21 |
$theLock = null;
|
22 |
foreach ( $this->getFileLocks() as $maybeLock ) {
|
23 |
if ( $maybeLock->file === $path ) {
|
52 |
->setMod( $mod )
|
53 |
->build( $path, reset( $publicKey ) );
|
54 |
|
55 |
+
/** @var FileLocker\Insert $inserter */
|
56 |
+
$inserter = $mod->getDbHandler_FileLocker()->getQueryInserter();
|
57 |
+
$success = $inserter->insert( $entry );
|
58 |
|
59 |
$this->clearFileLocksCache();
|
60 |
}
|
src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/DeleteFileLock.php
CHANGED
@@ -5,29 +5,25 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\FileLock
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases\FileLocker;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\ModCon;
|
7 |
|
8 |
-
/**
|
9 |
-
* Class DeleteFileLock
|
10 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\FileLocker\Ops
|
11 |
-
*/
|
12 |
class DeleteFileLock extends BaseOps {
|
13 |
|
14 |
/**
|
15 |
-
* @param FileLocker\EntryVO $
|
16 |
* @return bool
|
17 |
*/
|
18 |
-
public function delete( $
|
19 |
/** @var ModCon $mod */
|
20 |
$mod = $this->getMod();
|
21 |
-
if ( empty( $
|
22 |
-
$
|
23 |
}
|
24 |
-
$
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
if ( $
|
29 |
$this->clearFileLocksCache();
|
30 |
}
|
31 |
-
return $
|
32 |
}
|
33 |
}
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases\FileLocker;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\ModCon;
|
7 |
|
|
|
|
|
|
|
|
|
8 |
class DeleteFileLock extends BaseOps {
|
9 |
|
10 |
/**
|
11 |
+
* @param FileLocker\EntryVO|null $lock
|
12 |
* @return bool
|
13 |
*/
|
14 |
+
public function delete( $lock = null ) :bool {
|
15 |
/** @var ModCon $mod */
|
16 |
$mod = $this->getMod();
|
17 |
+
if ( empty( $lock ) ) {
|
18 |
+
$lock = $this->findLockRecordForFile();
|
19 |
}
|
20 |
+
$success = $lock instanceof FileLocker\EntryVO
|
21 |
+
&& $mod->getDbHandler_FileLocker()
|
22 |
+
->getQueryDeleter()
|
23 |
+
->deleteEntry( $lock );
|
24 |
+
if ( $success ) {
|
25 |
$this->clearFileLocksCache();
|
26 |
}
|
27 |
+
return $success;
|
28 |
}
|
29 |
}
|
src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/LoadFileLocks.php
CHANGED
@@ -22,7 +22,7 @@ class LoadFileLocks {
|
|
22 |
/**
|
23 |
* @return FileLocker\EntryVO[]
|
24 |
*/
|
25 |
-
public function loadLocks() {
|
26 |
if ( is_null( self::$aFileLockRecords ) ) {
|
27 |
/** @var ModCon $mod */
|
28 |
$mod = $this->getMod();
|
22 |
/**
|
23 |
* @return FileLocker\EntryVO[]
|
24 |
*/
|
25 |
+
public function loadLocks() :array {
|
26 |
if ( is_null( self::$aFileLockRecords ) ) {
|
27 |
/** @var ModCon $mod */
|
28 |
$mod = $this->getMod();
|
src/lib/src/Modules/HackGuard/Lib/Reports/FileLockerAlerts.php
CHANGED
@@ -35,7 +35,7 @@ class FileLockerAlerts extends BaseReporter {
|
|
35 |
'view_results' => __( 'Click Here To View File Locker Results', 'wp-simple-firewall' ),
|
36 |
],
|
37 |
'hrefs' => [
|
38 |
-
'view_results' => $this->getCon()->getModule_Insights()->
|
39 |
],
|
40 |
]
|
41 |
);
|
35 |
'view_results' => __( 'Click Here To View File Locker Results', 'wp-simple-firewall' ),
|
36 |
],
|
37 |
'hrefs' => [
|
38 |
+
'view_results' => $this->getCon()->getModule_Insights()->getUrl_ScansResults(),
|
39 |
],
|
40 |
]
|
41 |
);
|
src/lib/src/Modules/HackGuard/Lib/Reports/ScanAlerts.php
CHANGED
@@ -13,6 +13,9 @@ class ScanAlerts extends BaseReporter {
|
|
13 |
* @inheritDoc
|
14 |
*/
|
15 |
public function build() {
|
|
|
|
|
|
|
16 |
$alerts = [];
|
17 |
|
18 |
/** @var HackGuard\Strings $strings */
|
@@ -43,7 +46,9 @@ class ScanAlerts extends BaseReporter {
|
|
43 |
'view_results' => __( 'Click Here To View Scan Results Details', 'wp-simple-firewall' ),
|
44 |
],
|
45 |
'hrefs' => [
|
46 |
-
'view_results' => $this->getCon()
|
|
|
|
|
47 |
],
|
48 |
]
|
49 |
);
|
13 |
* @inheritDoc
|
14 |
*/
|
15 |
public function build() {
|
16 |
+
/** @var HackGuard\ModCon $mod */
|
17 |
+
$mod = $this->getMod();
|
18 |
+
|
19 |
$alerts = [];
|
20 |
|
21 |
/** @var HackGuard\Strings $strings */
|
46 |
'view_results' => __( 'Click Here To View Scan Results Details', 'wp-simple-firewall' ),
|
47 |
],
|
48 |
'hrefs' => [
|
49 |
+
'view_results' => $this->getCon()
|
50 |
+
->getModule_Insights()
|
51 |
+
->getUrl_ScansResults(),
|
52 |
],
|
53 |
]
|
54 |
);
|
src/lib/src/Modules/HackGuard/ModCon.php
CHANGED
@@ -139,27 +139,29 @@ class ModCon extends BaseShield\ModCon {
|
|
139 |
protected function cleanFileExclusions() {
|
140 |
/** @var Options $opts */
|
141 |
$opts = $this->getOptions();
|
142 |
-
$
|
143 |
|
144 |
-
$
|
145 |
-
if ( is_array( $
|
146 |
-
foreach ( $
|
147 |
-
$sExclusion = wp_normalize_path( trim( $sExclusion ) );
|
148 |
|
149 |
-
if ( preg_match( '/^#(.+)#$/', $
|
150 |
-
|
151 |
}
|
152 |
-
|
153 |
-
$
|
|
|
|
|
|
|
154 |
}
|
155 |
|
156 |
-
if ( !empty( $
|
157 |
-
$
|
158 |
}
|
159 |
}
|
160 |
}
|
161 |
|
162 |
-
$opts->setOpt( 'ufc_exclusions', array_unique( $
|
163 |
}
|
164 |
|
165 |
public function isPtgEnabled() :bool {
|
@@ -190,8 +192,7 @@ class ModCon extends BaseShield\ModCon {
|
|
190 |
}
|
191 |
|
192 |
public function getDbHandler_FileLocker() :Databases\FileLocker\Handler {
|
193 |
-
|
194 |
-
return empty( $new ) ? $this->getDbH( 'file_protect' ) : $new;
|
195 |
}
|
196 |
|
197 |
public function getDbHandler_ScanQueue() :Databases\ScanQueue\Handler {
|
139 |
protected function cleanFileExclusions() {
|
140 |
/** @var Options $opts */
|
141 |
$opts = $this->getOptions();
|
142 |
+
$excl = [];
|
143 |
|
144 |
+
$toClean = $opts->getOpt( 'ufc_exclusions', [] );
|
145 |
+
if ( is_array( $toClean ) ) {
|
146 |
+
foreach ( $toClean as $exclusion ) {
|
|
|
147 |
|
148 |
+
if ( preg_match( '/^#(.+)#$/', $exclusion, $matches ) ) { // it's not regex
|
149 |
+
$exclusion = str_replace( '\\', '\\\\', $exclusion );
|
150 |
}
|
151 |
+
else {
|
152 |
+
$exclusion = wp_normalize_path( trim( $exclusion ) );
|
153 |
+
if ( strpos( $exclusion, '/' ) === false ) { // filename only
|
154 |
+
$exclusion = trim( preg_replace( '#[^.0-9a-z_-]#i', '', $exclusion ) );
|
155 |
+
}
|
156 |
}
|
157 |
|
158 |
+
if ( !empty( $exclusion ) ) {
|
159 |
+
$excl[] = $exclusion;
|
160 |
}
|
161 |
}
|
162 |
}
|
163 |
|
164 |
+
$opts->setOpt( 'ufc_exclusions', array_unique( $excl ) );
|
165 |
}
|
166 |
|
167 |
public function isPtgEnabled() :bool {
|
192 |
}
|
193 |
|
194 |
public function getDbHandler_FileLocker() :Databases\FileLocker\Handler {
|
195 |
+
return $this->getDbH( 'filelocker' );
|
|
|
196 |
}
|
197 |
|
198 |
public function getDbHandler_ScanQueue() :Databases\ScanQueue\Handler {
|
src/lib/src/Modules/HackGuard/Scan/Queue/Build/QueueBuilder.php
CHANGED
@@ -58,7 +58,7 @@ class QueueBuilder extends Utilities\BackgroundProcessing\BackgroundProcess {
|
|
58 |
( new HackGuard\Scan\Queue\ScanInitiate() )
|
59 |
->setMod( $this->getMod() )
|
60 |
->setQueueProcessor( $this->getQueueProcessor() )
|
61 |
-
->init( $slug );
|
62 |
}
|
63 |
catch ( \Exception $e ) {
|
64 |
// error_log( $e->getMessage() );
|
58 |
( new HackGuard\Scan\Queue\ScanInitiate() )
|
59 |
->setMod( $this->getMod() )
|
60 |
->setQueueProcessor( $this->getQueueProcessor() )
|
61 |
+
->init( (string)$slug );
|
62 |
}
|
63 |
catch ( \Exception $e ) {
|
64 |
// error_log( $e->getMessage() );
|
src/lib/src/Modules/HackGuard/Scan/Queue/IsScanEnqueued.php
CHANGED
@@ -12,13 +12,9 @@ class IsScanEnqueued {
|
|
12 |
|
13 |
use Databases\Base\HandlerConsumer;
|
14 |
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
public function check( $sScanSlug ) {
|
20 |
-
/** @var Databases\ScanQueue\Select $oSel */
|
21 |
-
$oSel = $this->getDbHandler()->getQuerySelector();
|
22 |
-
return $oSel->countForScan( $sScanSlug ) > 0;
|
23 |
}
|
24 |
}
|
12 |
|
13 |
use Databases\Base\HandlerConsumer;
|
14 |
|
15 |
+
public function check( string $scan ) :bool {
|
16 |
+
/** @var Databases\ScanQueue\Select $selector */
|
17 |
+
$selector = $this->getDbHandler()->getQuerySelector();
|
18 |
+
return $selector->countForScan( $scan ) > 0;
|
|
|
|
|
|
|
|
|
19 |
}
|
20 |
}
|
src/lib/src/Modules/HackGuard/Scan/Queue/ScanInitiate.php
CHANGED
@@ -20,7 +20,7 @@ class ScanInitiate {
|
|
20 |
* @param string $slug
|
21 |
* @throws \Exception
|
22 |
*/
|
23 |
-
public function init( $slug ) {
|
24 |
/** @var ModCon $mod */
|
25 |
$mod = $this->getMod();
|
26 |
$dbh = $mod->getDbHandler_ScanQueue();
|
20 |
* @param string $slug
|
21 |
* @throws \Exception
|
22 |
*/
|
23 |
+
public function init( string $slug ) {
|
24 |
/** @var ModCon $mod */
|
25 |
$mod = $this->getMod();
|
26 |
$dbh = $mod->getDbHandler_ScanQueue();
|
src/lib/src/Modules/HackGuard/Strings.php
CHANGED
@@ -21,7 +21,7 @@ class Strings extends Base\Strings {
|
|
21 |
'ptg' => __( 'Plugin/Theme Guard', 'wp-simple-firewall' ),
|
22 |
'mal' => __( 'Malware', 'wp-simple-firewall' ),
|
23 |
'ufc' => __( 'Unrecognised Files', 'wp-simple-firewall' ),
|
24 |
-
'wcf' => __( '
|
25 |
'wpv' => __( 'Vulnerabilities', 'wp-simple-firewall' ),
|
26 |
];
|
27 |
}
|
@@ -30,29 +30,29 @@ class Strings extends Base\Strings {
|
|
30 |
* @return string[][]
|
31 |
*/
|
32 |
protected function getAuditMessages() :array {
|
33 |
-
$
|
34 |
-
foreach ( $this->getScanNames() as $
|
35 |
-
$
|
36 |
-
sprintf( __( '%s scan alert sent.', 'wp-simple-firewall' ), $
|
37 |
.' '.__( 'Alert sent to %s via %s.' )
|
38 |
];
|
39 |
-
$
|
40 |
-
sprintf( __( '%s scan completed and items were discovered.', 'wp-simple-firewall' ), $
|
41 |
sprintf( '%s: %s',
|
42 |
__( 'Note', 'wp-simple-firewall' ),
|
43 |
__( "These items wont display in results if you've previously marked them as ignored.", 'wp-simple-firewall' )
|
44 |
)
|
45 |
];
|
46 |
-
$
|
47 |
-
sprintf( __( '%s scan repaired a item found in the scan.', 'wp-simple-firewall' ), $
|
48 |
.' '.__( 'Item repaired: "%s"', 'wp-simple-firewall' ),
|
49 |
];
|
50 |
-
$
|
51 |
-
sprintf( __( '%s scan could not repair item.', 'wp-simple-firewall' ), $
|
52 |
.' '.__( 'Failed repair item: "%s"', 'wp-simple-firewall' ),
|
53 |
];
|
54 |
}
|
55 |
-
return $
|
56 |
}
|
57 |
|
58 |
/**
|
21 |
'ptg' => __( 'Plugin/Theme Guard', 'wp-simple-firewall' ),
|
22 |
'mal' => __( 'Malware', 'wp-simple-firewall' ),
|
23 |
'ufc' => __( 'Unrecognised Files', 'wp-simple-firewall' ),
|
24 |
+
'wcf' => __( 'WordPress Core Files', 'wp-simple-firewall' ),
|
25 |
'wpv' => __( 'Vulnerabilities', 'wp-simple-firewall' ),
|
26 |
];
|
27 |
}
|
30 |
* @return string[][]
|
31 |
*/
|
32 |
protected function getAuditMessages() :array {
|
33 |
+
$messages = [];
|
34 |
+
foreach ( $this->getScanNames() as $slug => $scanName ) {
|
35 |
+
$messages[ $slug.'_alert_sent' ] = [
|
36 |
+
sprintf( __( '%s scan alert sent.', 'wp-simple-firewall' ), $scanName )
|
37 |
.' '.__( 'Alert sent to %s via %s.' )
|
38 |
];
|
39 |
+
$messages[ $slug.'_scan_found' ] = [
|
40 |
+
sprintf( __( '%s scan completed and items were discovered.', 'wp-simple-firewall' ), $scanName ),
|
41 |
sprintf( '%s: %s',
|
42 |
__( 'Note', 'wp-simple-firewall' ),
|
43 |
__( "These items wont display in results if you've previously marked them as ignored.", 'wp-simple-firewall' )
|
44 |
)
|
45 |
];
|
46 |
+
$messages[ $slug.'_item_repair_success' ] = [
|
47 |
+
sprintf( __( '%s scan repaired a item found in the scan.', 'wp-simple-firewall' ), $scanName )
|
48 |
.' '.__( 'Item repaired: "%s"', 'wp-simple-firewall' ),
|
49 |
];
|
50 |
+
$messages[ $slug.'_item_repair_fail' ] = [
|
51 |
+
sprintf( __( '%s scan could not repair item.', 'wp-simple-firewall' ), $scanName )
|
52 |
.' '.__( 'Failed repair item: "%s"', 'wp-simple-firewall' ),
|
53 |
];
|
54 |
}
|
55 |
+
return $messages;
|
56 |
}
|
57 |
|
58 |
/**
|
src/lib/src/Modules/HackGuard/UI.php
CHANGED
@@ -14,16 +14,16 @@ class UI extends BaseShield\UI {
|
|
14 |
/** @var Options $opts */
|
15 |
$opts = $this->getOptions();
|
16 |
|
17 |
-
$
|
18 |
-
if ( empty( $
|
19 |
-
$
|
20 |
}
|
21 |
|
22 |
// Can Scan Checks:
|
23 |
$reasonsCantScan = $mod->getScansCon()->getReasonsScansCantExecute();
|
24 |
|
25 |
-
/** @var \FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner\Select $
|
26 |
-
$
|
27 |
$data = [
|
28 |
'ajax' => [
|
29 |
'scans_start' => $mod->getAjaxActionData( 'scans_start', true ),
|
@@ -69,12 +69,11 @@ class UI extends BaseShield\UI {
|
|
69 |
'vars' => [
|
70 |
'initial_check' => $mod->getScanQueueController()->hasRunningScans(),
|
71 |
'cannot_scan_reasons' => $reasonsCantScan,
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
]
|
78 |
],
|
79 |
'scan_results' => [
|
80 |
],
|
@@ -91,32 +90,39 @@ class UI extends BaseShield\UI {
|
|
91 |
'title' => __( 'File Scan', 'wp-simple-firewall' ),
|
92 |
'subtitle' => __( "Results of all file scans", 'wp-simple-firewall' )
|
93 |
],
|
94 |
-
'count' => $
|
95 |
-
|
96 |
-
|
97 |
],
|
98 |
'file_locker' => $this->getFileLockerVars(),
|
99 |
'scans' => [
|
100 |
-
'
|
101 |
'flags' => [
|
102 |
-
'has_items' =>
|
103 |
-
'show_table' =>
|
104 |
],
|
105 |
'hrefs' => [],
|
106 |
'vars' => [],
|
107 |
'strings' => [
|
108 |
-
'subtitle'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
],
|
110 |
],
|
111 |
-
'
|
112 |
'flags' => [
|
113 |
'has_items' => true,
|
114 |
-
'show_table' =>
|
115 |
],
|
116 |
'hrefs' => [],
|
117 |
'vars' => [],
|
118 |
'strings' => [
|
119 |
-
'subtitle' => __( "
|
120 |
],
|
121 |
],
|
122 |
'ufc' => [
|
@@ -167,11 +173,13 @@ class UI extends BaseShield\UI {
|
|
167 |
continue;
|
168 |
}
|
169 |
$lastScanAt = $scon->getLastScanAt();
|
170 |
-
|
|
|
171 |
$scData[ 'flags' ][ 'is_available' ] = $scon->isScanningAvailable();
|
|
|
172 |
$scData[ 'flags' ][ 'is_restricted' ] = !$scon->isScanningAvailable();
|
173 |
$scData[ 'flags' ][ 'is_enabled' ] = $scon->isEnabled();
|
174 |
-
$scData[ 'flags' ][ 'is_selected' ] = $scon->isScanningAvailable() && in_array( $slug, $
|
175 |
$scData[ 'vars' ][ 'last_scan_at_ts' ] = $lastScanAt;
|
176 |
$scData[ 'flags' ][ 'has_last_scan' ] = $lastScanAt > 0;
|
177 |
$scData[ 'vars' ][ 'last_scan_at' ] = sprintf(
|
@@ -183,7 +191,7 @@ class UI extends BaseShield\UI {
|
|
183 |
$scData[ 'strings' ][ 'title' ] = $name[ $slug ];
|
184 |
$scData[ 'hrefs' ][ 'options' ] = $mod->getUrl_DirectLinkToSection( 'section_scan_'.$slug );
|
185 |
$scData[ 'hrefs' ][ 'please_enable' ] = $mod->getUrl_DirectLinkToSection( 'section_scan_'.$slug );
|
186 |
-
$scData[ 'count' ] = $
|
187 |
}
|
188 |
|
189 |
return $data;
|
@@ -299,14 +307,4 @@ class UI extends BaseShield\UI {
|
|
299 |
|
300 |
return $aWarnings;
|
301 |
}
|
302 |
-
|
303 |
-
protected function getSettingsRelatedLinks() :array {
|
304 |
-
$modInsights = $this->getCon()->getModule_Insights();
|
305 |
-
return [
|
306 |
-
[
|
307 |
-
'href' => $modInsights->getUrl_SubInsightsPage( 'scans' ),
|
308 |
-
'title' => __( 'Run Scans', 'wp-simple-firewall' ),
|
309 |
-
]
|
310 |
-
];
|
311 |
-
}
|
312 |
}
|
14 |
/** @var Options $opts */
|
15 |
$opts = $this->getOptions();
|
16 |
|
17 |
+
$uiTrack = $mod->getUiTrack();
|
18 |
+
if ( empty( $uiTrack[ 'selected_scans' ] ) ) {
|
19 |
+
$uiTrack[ 'selected_scans' ] = $opts->getScanSlugs();
|
20 |
}
|
21 |
|
22 |
// Can Scan Checks:
|
23 |
$reasonsCantScan = $mod->getScansCon()->getReasonsScansCantExecute();
|
24 |
|
25 |
+
/** @var \FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner\Select $selector */
|
26 |
+
$selector = $mod->getDbHandler_ScanResults()->getQuerySelector();
|
27 |
$data = [
|
28 |
'ajax' => [
|
29 |
'scans_start' => $mod->getAjaxActionData( 'scans_start', true ),
|
69 |
'vars' => [
|
70 |
'initial_check' => $mod->getScanQueueController()->hasRunningScans(),
|
71 |
'cannot_scan_reasons' => $reasonsCantScan,
|
72 |
+
],
|
73 |
+
'hrefs' => [
|
74 |
+
'scans_results' => $this->getCon()
|
75 |
+
->getModule_Insights()
|
76 |
+
->getUrl_ScansResults(),
|
|
|
77 |
],
|
78 |
'scan_results' => [
|
79 |
],
|
90 |
'title' => __( 'File Scan', 'wp-simple-firewall' ),
|
91 |
'subtitle' => __( "Results of all file scans", 'wp-simple-firewall' )
|
92 |
],
|
93 |
+
'count' => $selector->filterByScans( [ 'ptg', 'mal', 'wcf', 'ufc' ] )
|
94 |
+
->filterByNotIgnored()
|
95 |
+
->count()
|
96 |
],
|
97 |
'file_locker' => $this->getFileLockerVars(),
|
98 |
'scans' => [
|
99 |
+
'wcf' => [
|
100 |
'flags' => [
|
101 |
+
'has_items' => false,
|
102 |
+
'show_table' => false,
|
103 |
],
|
104 |
'hrefs' => [],
|
105 |
'vars' => [],
|
106 |
'strings' => [
|
107 |
+
'subtitle' => __( "Detect changes to core WordPress files when compared to the official distribution", 'wp-simple-firewall' ),
|
108 |
+
'explanation' => [
|
109 |
+
__( 'The files listed below are WordPress Core files - official files that are installed with every WordPress website.', 'wp-simple-firewall' ),
|
110 |
+
__( 'However, they have either been deleted, or their contents have changed in some way.', 'wp-simple-firewall' ),
|
111 |
+
__( 'Under normal circumstances this should never happen.', 'wp-simple-firewall' ),
|
112 |
+
__( 'You should review each file below and repair them. Repair can mean either re-install, or replace contents, with an original.', 'wp-simple-firewall' ),
|
113 |
+
__( "If you know why a file has been changed and you're happy to keep those changes, you can click to Ignore that file.", 'wp-simple-firewall' ),
|
114 |
+
],
|
115 |
],
|
116 |
],
|
117 |
+
'apc' => [
|
118 |
'flags' => [
|
119 |
'has_items' => true,
|
120 |
+
'show_table' => true,
|
121 |
],
|
122 |
'hrefs' => [],
|
123 |
'vars' => [],
|
124 |
'strings' => [
|
125 |
+
'subtitle' => __( "Discover plugins that may have been abandoned by their authors", 'wp-simple-firewall' ),
|
126 |
],
|
127 |
],
|
128 |
'ufc' => [
|
173 |
continue;
|
174 |
}
|
175 |
$lastScanAt = $scon->getLastScanAt();
|
176 |
+
$scData[ 'vars' ][ 'slug' ] = $slug;
|
177 |
+
$scData[ 'count' ] = $selector->countForScan( $slug );
|
178 |
$scData[ 'flags' ][ 'is_available' ] = $scon->isScanningAvailable();
|
179 |
+
// $scData[ 'flags' ][ 'show_table' ] = $scData[ 'count' ] > 0;
|
180 |
$scData[ 'flags' ][ 'is_restricted' ] = !$scon->isScanningAvailable();
|
181 |
$scData[ 'flags' ][ 'is_enabled' ] = $scon->isEnabled();
|
182 |
+
$scData[ 'flags' ][ 'is_selected' ] = $scon->isScanningAvailable() && in_array( $slug, $uiTrack[ 'selected_scans' ] );
|
183 |
$scData[ 'vars' ][ 'last_scan_at_ts' ] = $lastScanAt;
|
184 |
$scData[ 'flags' ][ 'has_last_scan' ] = $lastScanAt > 0;
|
185 |
$scData[ 'vars' ][ 'last_scan_at' ] = sprintf(
|
191 |
$scData[ 'strings' ][ 'title' ] = $name[ $slug ];
|
192 |
$scData[ 'hrefs' ][ 'options' ] = $mod->getUrl_DirectLinkToSection( 'section_scan_'.$slug );
|
193 |
$scData[ 'hrefs' ][ 'please_enable' ] = $mod->getUrl_DirectLinkToSection( 'section_scan_'.$slug );
|
194 |
+
$scData[ 'count' ] = $selector->countForScan( $slug );
|
195 |
}
|
196 |
|
197 |
return $data;
|
307 |
|
308 |
return $aWarnings;
|
309 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
310 |
}
|
src/lib/src/Modules/Headers/ModCon.php
CHANGED
@@ -24,10 +24,4 @@ class ModCon extends BaseShield\ModCon {
|
|
24 |
$opts->getOpt( 'xcsp_custom', [] )
|
25 |
) ) ) );
|
26 |
}
|
27 |
-
|
28 |
-
/**
|
29 |
-
* @deprecated 10.3
|
30 |
-
*/
|
31 |
-
private function cleanCspHosts() {
|
32 |
-
}
|
33 |
}
|
24 |
$opts->getOpt( 'xcsp_custom', [] )
|
25 |
) ) ) );
|
26 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
}
|
src/lib/src/Modules/Headers/Strings.php
CHANGED
@@ -105,7 +105,6 @@ class Strings extends Base\Strings {
|
|
105 |
$sName = __( 'Manual Rules', 'wp-simple-firewall' );
|
106 |
$sSummary = __( 'Manual CSP Rules', 'wp-simple-firewall' );
|
107 |
$sDescription = [
|
108 |
-
__( 'Manual CSP rules which are not covered by the rules above.', 'wp-simple-firewall' ),
|
109 |
'- '.__( 'Take a new line per rule.', 'wp-simple-firewall' ),
|
110 |
'- '.__( 'We provide this feature as-is: to allow you to add custom CSP rules to your site.', 'wp-simple-firewall' ),
|
111 |
'- '.__( "We don't provide support for creating CSP rules and whether they're correct for your site.", 'wp-simple-firewall' ),
|
105 |
$sName = __( 'Manual Rules', 'wp-simple-firewall' );
|
106 |
$sSummary = __( 'Manual CSP Rules', 'wp-simple-firewall' );
|
107 |
$sDescription = [
|
|
|
108 |
'- '.__( 'Take a new line per rule.', 'wp-simple-firewall' ),
|
109 |
'- '.__( 'We provide this feature as-is: to allow you to add custom CSP rules to your site.', 'wp-simple-firewall' ),
|
110 |
'- '.__( "We don't provide support for creating CSP rules and whether they're correct for your site.", 'wp-simple-firewall' ),
|
src/lib/src/Modules/IPs/AjaxHandler.php
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
|
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Ops;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
use FernleafSystems\Wordpress\Services\Utilities\Net\IpID;
|
@@ -71,13 +72,13 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
71 |
$mod = $this->getMod();
|
72 |
$oIpServ = Services::IP();
|
73 |
|
74 |
-
$
|
75 |
|
76 |
$success = false;
|
77 |
$msg = __( "IP address wasn't added to the list", 'wp-simple-firewall' );
|
78 |
|
79 |
-
$ip = preg_replace( '#[^/:.a-f\d]#i', '', ( isset( $
|
80 |
-
$sList = isset( $
|
81 |
|
82 |
$bAcceptableIp = $oIpServ->isValidIp( $ip )
|
83 |
|| $oIpServ->isValidIp4Range( $ip )
|
@@ -105,7 +106,7 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
105 |
$msg = __( "This IP is reserved and can't be blacklisted.", 'wp-simple-firewall' );
|
106 |
}
|
107 |
else {
|
108 |
-
$label = $
|
109 |
$oIP = null;
|
110 |
switch ( $sList ) {
|
111 |
case $mod::LIST_MANUAL_WHITE:
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Lib\Request\FormParams;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Ops;
|
8 |
use FernleafSystems\Wordpress\Services\Services;
|
9 |
use FernleafSystems\Wordpress\Services\Utilities\Net\IpID;
|
72 |
$mod = $this->getMod();
|
73 |
$oIpServ = Services::IP();
|
74 |
|
75 |
+
$formParams = FormParams::Retrieve();
|
76 |
|
77 |
$success = false;
|
78 |
$msg = __( "IP address wasn't added to the list", 'wp-simple-firewall' );
|
79 |
|
80 |
+
$ip = preg_replace( '#[^/:.a-f\d]#i', '', ( isset( $formParams[ 'ip' ] ) ? $formParams[ 'ip' ] : '' ) );
|
81 |
+
$sList = isset( $formParams[ 'list' ] ) ? $formParams[ 'list' ] : '';
|
82 |
|
83 |
$bAcceptableIp = $oIpServ->isValidIp( $ip )
|
84 |
|| $oIpServ->isValidIp4Range( $ip )
|
106 |
$msg = __( "This IP is reserved and can't be blacklisted.", 'wp-simple-firewall' );
|
107 |
}
|
108 |
else {
|
109 |
+
$label = $formParams[ 'label' ] ?? '';
|
110 |
$oIP = null;
|
111 |
switch ( $sList ) {
|
112 |
case $mod::LIST_MANUAL_WHITE:
|
src/lib/src/Modules/IPs/BotTrack/TrackLinkCheese.php
CHANGED
@@ -86,19 +86,4 @@ class TrackLinkCheese extends Base {
|
|
86 |
private function getCheeseWord() :string {
|
87 |
return $this->getCon()->prefix( self::CHEESE_WORD );
|
88 |
}
|
89 |
-
|
90 |
-
/**
|
91 |
-
* @return string[]
|
92 |
-
* @deprecated 10.3
|
93 |
-
*/
|
94 |
-
private function getPossibleWords() {
|
95 |
-
return [
|
96 |
-
'mouse',
|
97 |
-
'cheese',
|
98 |
-
'venus',
|
99 |
-
'stilton',
|
100 |
-
'cheddar',
|
101 |
-
'holey',
|
102 |
-
];
|
103 |
-
}
|
104 |
}
|
86 |
private function getCheeseWord() :string {
|
87 |
return $this->getCon()->prefix( self::CHEESE_WORD );
|
88 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
}
|
src/lib/src/Modules/IPs/Lib/AutoUnblock.php
CHANGED
@@ -2,6 +2,7 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
@@ -28,9 +29,6 @@ class AutoUnblock {
|
|
28 |
catch ( \Exception $e ) {
|
29 |
}
|
30 |
}
|
31 |
-
if ( !$unblocked ) {
|
32 |
-
$unblocked = $this->checkForBlockedServiceBot();
|
33 |
-
}
|
34 |
return $unblocked;
|
35 |
}
|
36 |
|
@@ -75,36 +73,35 @@ class AutoUnblock {
|
|
75 |
throw new \Exception( 'Email should not be provided in honeypot' );
|
76 |
}
|
77 |
|
78 |
-
$
|
79 |
-
if ( $req->post( 'ip' )
|
80 |
throw new \Exception( 'IP does not match' );
|
81 |
}
|
82 |
|
83 |
-
|
84 |
-
|
85 |
-
if ( empty( $sGasp ) ) {
|
86 |
-
throw new \Exception( 'GASP failed' );
|
87 |
}
|
88 |
|
89 |
-
|
90 |
-
|
91 |
-
|
|
|
92 |
|
93 |
{
|
94 |
-
$
|
95 |
-
$
|
96 |
$opts->setOpt( 'autounblock_ips',
|
97 |
-
array_filter( $
|
98 |
return Services::Request()
|
99 |
->carbon()
|
100 |
-
->
|
101 |
} )
|
102 |
);
|
103 |
}
|
104 |
|
105 |
( new IPs\Lib\Ops\DeleteIp() )
|
106 |
->setMod( $mod )
|
107 |
-
->setIP( $
|
108 |
->fromBlacklist();
|
109 |
$unblocked = true;
|
110 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib;
|
4 |
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\CommentsFilter\Scan\AntiBot;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
8 |
use FernleafSystems\Wordpress\Services\Services;
|
29 |
catch ( \Exception $e ) {
|
30 |
}
|
31 |
}
|
|
|
|
|
|
|
32 |
return $unblocked;
|
33 |
}
|
34 |
|
73 |
throw new \Exception( 'Email should not be provided in honeypot' );
|
74 |
}
|
75 |
|
76 |
+
$ip = Services::IP()->getRequestIp();
|
77 |
+
if ( empty( $ip ) || $req->post( 'ip' ) !== Services::IP()->getRequestIp() ) {
|
78 |
throw new \Exception( 'IP does not match' );
|
79 |
}
|
80 |
|
81 |
+
if ( !$opts->getCanIpRequestAutoUnblock( $ip ) ) {
|
82 |
+
throw new \Exception( 'IP already processed in the last 1hr' );
|
|
|
|
|
83 |
}
|
84 |
|
85 |
+
// Perform the test
|
86 |
+
( new AntiBot() )
|
87 |
+
->setMod( $this->getMod() )
|
88 |
+
->scan();
|
89 |
|
90 |
{
|
91 |
+
$existing = $opts->getAutoUnblockIps();
|
92 |
+
$existing[ $ip ] = Services::Request()->ts();
|
93 |
$opts->setOpt( 'autounblock_ips',
|
94 |
+
array_filter( $existing, function ( $ts ) {
|
95 |
return Services::Request()
|
96 |
->carbon()
|
97 |
+
->subHours( 1 )->timestamp < $ts;
|
98 |
} )
|
99 |
);
|
100 |
}
|
101 |
|
102 |
( new IPs\Lib\Ops\DeleteIp() )
|
103 |
->setMod( $mod )
|
104 |
+
->setIP( $ip )
|
105 |
->fromBlacklist();
|
106 |
$unblocked = true;
|
107 |
}
|
src/lib/src/Modules/IPs/Lib/BlockRequest.php
CHANGED
@@ -46,19 +46,16 @@ class BlockRequest {
|
|
46 |
/** @var IPs\Options $opts */
|
47 |
$opts = $this->getOptions();
|
48 |
$con = $this->getCon();
|
49 |
-
$oLoginMod = $con->getModule_LoginGuard();
|
50 |
|
51 |
-
$
|
52 |
-
|
53 |
-
$sIP = Services::IP()->getRequestIp();
|
54 |
-
$nTimeRemaining = max( floor( $opts->getAutoExpireTime()/60 ), 0 );
|
55 |
|
56 |
$user = Services::WpUsers()->getCurrentWpUser();
|
57 |
-
$
|
58 |
-
$
|
59 |
-
|
60 |
-
|
61 |
-
$
|
62 |
|
63 |
if ( !empty( $con->getLabels()[ 'PluginURI' ] ) ) {
|
64 |
$homeURL = $con->getLabels()[ 'PluginURI' ];
|
@@ -77,7 +74,7 @@ class BlockRequest {
|
|
77 |
),
|
78 |
'lines' => [
|
79 |
sprintf( __( 'Time remaining on black list: %s', 'wp-simple-firewall' ),
|
80 |
-
sprintf( _n( '%s minute', '%s minutes', $
|
81 |
),
|
82 |
sprintf( __( 'You tripped the security plugin defenses a total of %s times making you a suspect.', 'wp-simple-firewall' ), $opts->getOffenseLimit() ),
|
83 |
sprintf( __( 'If you believe this to be in error, please contact the site owner and quote your IP address below.', 'wp-simple-firewall' ) ),
|
@@ -92,28 +89,17 @@ class BlockRequest {
|
|
92 |
'content' => [
|
93 |
'email_unblock' => $this->renderEmailMagicLinkContent()
|
94 |
],
|
|
|
|
|
|
|
95 |
'vars' => [
|
96 |
-
'nonce'
|
97 |
-
'ip'
|
98 |
-
'gasp_element' => $mod->renderTemplate(
|
99 |
-
'snippets/gasp_js.php',
|
100 |
-
[
|
101 |
-
'sCbName' => $oLoginMod->getGaspKey(),
|
102 |
-
'sLabel' => $oLoginMod->getTextImAHuman(),
|
103 |
-
'sAlert' => $oLoginMod->getTextPleaseCheckBox(),
|
104 |
-
'sMustJs' => __( 'You MUST enable Javascript to be able to login', 'wp-simple-firewall' ),
|
105 |
-
'sUniqId' => $sUniqId,
|
106 |
-
'sUniqElem' => 'icwp_wpsf_login_p'.$sUniqId,
|
107 |
-
'strings' => [
|
108 |
-
'loading' => __( 'Loading', 'wp-simple-firewall' )
|
109 |
-
]
|
110 |
-
]
|
111 |
-
),
|
112 |
],
|
113 |
'flags' => [
|
114 |
-
'is_autorecover' => $
|
115 |
-
'is_uaug_permitted' => $
|
116 |
-
'is_uaum_permitted' => $
|
117 |
],
|
118 |
];
|
119 |
Services::WpGeneral()
|
46 |
/** @var IPs\Options $opts */
|
47 |
$opts = $this->getOptions();
|
48 |
$con = $this->getCon();
|
|
|
49 |
|
50 |
+
$ip = Services::IP()->getRequestIp();
|
51 |
+
$timeRemaining = max( floor( $opts->getAutoExpireTime()/60 ), 0 );
|
|
|
|
|
52 |
|
53 |
$user = Services::WpUsers()->getCurrentWpUser();
|
54 |
+
$canUauBot = $opts->isEnabledAutoVisitorRecover() && !empty( $ip ) && $opts->getCanIpRequestAutoUnblock( $ip );
|
55 |
+
$canUauMagic = $opts->isEnabledMagicEmailLinkRecover() &&
|
56 |
+
$user instanceof \WP_User
|
57 |
+
&& $opts->getCanRequestAutoUnblockEmailLink( $user );
|
58 |
+
$canAutoRecover = $canUauBot || $canUauMagic;
|
59 |
|
60 |
if ( !empty( $con->getLabels()[ 'PluginURI' ] ) ) {
|
61 |
$homeURL = $con->getLabels()[ 'PluginURI' ];
|
74 |
),
|
75 |
'lines' => [
|
76 |
sprintf( __( 'Time remaining on black list: %s', 'wp-simple-firewall' ),
|
77 |
+
sprintf( _n( '%s minute', '%s minutes', $timeRemaining, 'wp-simple-firewall' ), $timeRemaining )
|
78 |
),
|
79 |
sprintf( __( 'You tripped the security plugin defenses a total of %s times making you a suspect.', 'wp-simple-firewall' ), $opts->getOffenseLimit() ),
|
80 |
sprintf( __( 'If you believe this to be in error, please contact the site owner and quote your IP address below.', 'wp-simple-firewall' ) ),
|
89 |
'content' => [
|
90 |
'email_unblock' => $this->renderEmailMagicLinkContent()
|
91 |
],
|
92 |
+
'hrefs' => [
|
93 |
+
'home' => Services::WpGeneral()->getHomeUrl()
|
94 |
+
],
|
95 |
'vars' => [
|
96 |
+
'nonce' => $mod->getNonceActionData( 'uau' ),
|
97 |
+
'ip' => $ip,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
],
|
99 |
'flags' => [
|
100 |
+
'is_autorecover' => $canAutoRecover,
|
101 |
+
'is_uaug_permitted' => $canUauBot,
|
102 |
+
'is_uaum_permitted' => $canUauMagic,
|
103 |
],
|
104 |
];
|
105 |
Services::WpGeneral()
|
src/lib/src/Modules/IPs/Lib/Bots/BotEventListener.php
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots;
|
4 |
+
|
5 |
+
use FernleafSystems\Utilities\Logic\ExecOnce;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\ModCon;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
8 |
+
use FernleafSystems\Wordpress\Services\Services;
|
9 |
+
|
10 |
+
class BotEventListener {
|
11 |
+
|
12 |
+
use ModConsumer;
|
13 |
+
use ExecOnce;
|
14 |
+
|
15 |
+
public function fireEventForIP( $ip, $event ) {
|
16 |
+
$events = $this->getEventsToColumn();
|
17 |
+
|
18 |
+
foreach ( $events as $eventTrigger => $column ) {
|
19 |
+
if ( $eventTrigger === $event || preg_match( sprintf( '#^%s$#', $eventTrigger ), $event ) ) {
|
20 |
+
try {
|
21 |
+
( new BotSignalsRecord() )
|
22 |
+
->setMod( $this->getMod() )
|
23 |
+
->setIP( $ip )
|
24 |
+
->updateSignalField( $column );
|
25 |
+
}
|
26 |
+
catch ( \LogicException $e ) {
|
27 |
+
error_log( 'Error updating bot signal: '.$e->getMessage() );
|
28 |
+
}
|
29 |
+
}
|
30 |
+
}
|
31 |
+
}
|
32 |
+
|
33 |
+
protected function canRun() :bool {
|
34 |
+
/** @var ModCon $mod */
|
35 |
+
$mod = $this->getMod();
|
36 |
+
return !$mod->isVerifiedBot();
|
37 |
+
}
|
38 |
+
|
39 |
+
protected function run() {
|
40 |
+
add_action( $this->getCon()->prefix( 'event' ), function ( $event ) {
|
41 |
+
$this->fireEventForIP( Services::IP()->getRequestIp(), $event );
|
42 |
+
} );
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @return string[]
|
47 |
+
*/
|
48 |
+
private function getEventsToColumn() :array {
|
49 |
+
return array_map(
|
50 |
+
function ( $column ) {
|
51 |
+
return str_replace( '_at', '', $column ).'_at';
|
52 |
+
},
|
53 |
+
[
|
54 |
+
'bottrack_notbot' => 'notbot',
|
55 |
+
'frontpage_load' => 'frontpage',
|
56 |
+
'bottrack_404' => 'bt404',
|
57 |
+
'bottrack_fakewebcrawler' => 'btfake',
|
58 |
+
'bottrack_linkcheese' => 'btcheese',
|
59 |
+
'bottrack_loginfailed' => 'btloginfail',
|
60 |
+
'bottrack_useragent' => 'btua',
|
61 |
+
'bottrack_xmlrpc' => 'btxml',
|
62 |
+
'bottrack_logininvalid' => 'btlogininvalid',
|
63 |
+
'bottrack_invalidscript' => 'btinvalidscript',
|
64 |
+
'cooldown_fail' => 'cooldown',
|
65 |
+
'recaptcha_success' => 'captchapass',
|
66 |
+
'request_limit_exceeded' => 'ratelimit',
|
67 |
+
'recaptcha_fail' => 'captchafail',
|
68 |
+
'spam_block_human' => 'humanspam',
|
69 |
+
'comment_markspam' => 'markspam',
|
70 |
+
'comment_unmarkspam' => 'unmarkspam',
|
71 |
+
'blockparam_.*' => 'firewall',
|
72 |
+
'ip_offense' => 'offense',
|
73 |
+
'ip_blocked' => 'blocked',
|
74 |
+
'ip_unblock' => 'unblocked',
|
75 |
+
'ip_bypass' => 'bypass',
|
76 |
+
'login_success' => 'auth',
|
77 |
+
]
|
78 |
+
);
|
79 |
+
}
|
80 |
+
}
|
src/lib/src/Modules/IPs/Lib/Bots/BotSignalsController.php
CHANGED
@@ -18,7 +18,7 @@ class BotSignalsController {
|
|
18 |
private $handlerNotBot;
|
19 |
|
20 |
/**
|
21 |
-
* @var
|
22 |
*/
|
23 |
private $eventListener;
|
24 |
|
@@ -53,9 +53,9 @@ class BotSignalsController {
|
|
53 |
return $this->handlerNotBot;
|
54 |
}
|
55 |
|
56 |
-
public function getEventListener() :
|
57 |
if ( !isset( $this->eventListener ) ) {
|
58 |
-
$this->eventListener = ( new
|
59 |
}
|
60 |
return $this->eventListener;
|
61 |
}
|
18 |
private $handlerNotBot;
|
19 |
|
20 |
/**
|
21 |
+
* @var BotEventListener
|
22 |
*/
|
23 |
private $eventListener;
|
24 |
|
53 |
return $this->handlerNotBot;
|
54 |
}
|
55 |
|
56 |
+
public function getEventListener() :BotEventListener {
|
57 |
if ( !isset( $this->eventListener ) ) {
|
58 |
+
$this->eventListener = ( new BotEventListener() )->setMod( $this->getMod() );
|
59 |
}
|
60 |
return $this->eventListener;
|
61 |
}
|
src/lib/src/Modules/IPs/Lib/OffenseTracker.php
CHANGED
@@ -18,16 +18,19 @@ class OffenseTracker extends EventsListener {
|
|
18 |
|
19 |
/**
|
20 |
* @param string $evt
|
21 |
-
* @param array $
|
|
|
22 |
*/
|
23 |
-
protected function captureEvent( $evt, $
|
24 |
-
|
25 |
-
|
26 |
-
|
|
|
|
|
27 |
|
28 |
-
if ( !empty( $
|
29 |
-
$this->incrementCount(
|
30 |
-
if ( !empty( $
|
31 |
$this->setIsBlocked( true );
|
32 |
}
|
33 |
}
|
@@ -40,43 +43,37 @@ class OffenseTracker extends EventsListener {
|
|
40 |
return $this->isBlocked() || $this->getOffenseCount() > 0;
|
41 |
}
|
42 |
|
43 |
-
|
44 |
-
* @return bool
|
45 |
-
*/
|
46 |
-
public function isBlocked() {
|
47 |
return (bool)$this->bIsBlocked;
|
48 |
}
|
49 |
|
50 |
-
|
51 |
-
* @return int
|
52 |
-
*/
|
53 |
-
public function getOffenseCount() {
|
54 |
return (int)$this->nOffenseCount;
|
55 |
}
|
56 |
|
57 |
/**
|
58 |
-
* @param bool $
|
59 |
* @return $this
|
60 |
*/
|
61 |
-
public function setIsBlocked( $
|
62 |
-
$this->bIsBlocked = $
|
63 |
return $this;
|
64 |
}
|
65 |
|
66 |
/**
|
67 |
-
* @param int $
|
68 |
* @return $this
|
69 |
*/
|
70 |
-
public function incrementCount( $
|
71 |
-
return $this->setOffenseCount( $this->getOffenseCount() + (int)$
|
72 |
}
|
73 |
|
74 |
/**
|
75 |
-
* @param int $
|
76 |
* @return $this
|
77 |
*/
|
78 |
-
public function setOffenseCount( $
|
79 |
-
$this->nOffenseCount = max( $
|
80 |
return $this;
|
81 |
}
|
82 |
}
|
18 |
|
19 |
/**
|
20 |
* @param string $evt
|
21 |
+
* @param array $meta
|
22 |
+
* @param array $def
|
23 |
*/
|
24 |
+
protected function captureEvent( string $evt, $meta = [], $def = [] ) {
|
25 |
+
if ( empty( $def ) ) {
|
26 |
+
$def = $this->getCon()
|
27 |
+
->loadEventsService()
|
28 |
+
->getEventDef( $evt );
|
29 |
+
}
|
30 |
|
31 |
+
if ( !empty( $def[ 'offense' ] ) && empty( $meta[ 'suppress_offense' ] ) ) {
|
32 |
+
$this->incrementCount( (int)( $meta[ 'offense_count' ] ?? 1) );
|
33 |
+
if ( !empty( $meta[ 'block' ] ) ) {
|
34 |
$this->setIsBlocked( true );
|
35 |
}
|
36 |
}
|
43 |
return $this->isBlocked() || $this->getOffenseCount() > 0;
|
44 |
}
|
45 |
|
46 |
+
public function isBlocked() :bool {
|
|
|
|
|
|
|
47 |
return (bool)$this->bIsBlocked;
|
48 |
}
|
49 |
|
50 |
+
public function getOffenseCount() :int {
|
|
|
|
|
|
|
51 |
return (int)$this->nOffenseCount;
|
52 |
}
|
53 |
|
54 |
/**
|
55 |
+
* @param bool $isBlocked
|
56 |
* @return $this
|
57 |
*/
|
58 |
+
public function setIsBlocked( bool $isBlocked ) {
|
59 |
+
$this->bIsBlocked = $isBlocked;
|
60 |
return $this;
|
61 |
}
|
62 |
|
63 |
/**
|
64 |
+
* @param int $increment
|
65 |
* @return $this
|
66 |
*/
|
67 |
+
public function incrementCount( int $increment = 1 ) {
|
68 |
+
return $this->setOffenseCount( $this->getOffenseCount() + (int)$increment );
|
69 |
}
|
70 |
|
71 |
/**
|
72 |
+
* @param int $offenseCount
|
73 |
* @return $this
|
74 |
*/
|
75 |
+
public function setOffenseCount( int $offenseCount ) {
|
76 |
+
$this->nOffenseCount = max( $offenseCount, (int)$this->nOffenseCount );
|
77 |
return $this;
|
78 |
}
|
79 |
}
|
src/lib/src/Modules/IPs/Lib/ProcessOffenses.php
CHANGED
@@ -34,9 +34,9 @@ class ProcessOffenses {
|
|
34 |
/** @var IPs\ModCon $mod */
|
35 |
$mod = $this->getMod();
|
36 |
|
37 |
-
$
|
38 |
if ( !$this->getCon()->plugin_deleting
|
39 |
-
&& $
|
40 |
( new IPs\Components\ProcessOffense() )
|
41 |
->setMod( $mod )
|
42 |
->setIp( Services::IP()->getRequestIp() )
|
@@ -66,14 +66,14 @@ class ProcessOffenses {
|
|
66 |
|
67 |
/**
|
68 |
* Allows 3rd parties to trigger Shield offenses
|
69 |
-
* @param string $
|
70 |
-
* @param int $
|
71 |
* @param bool $bIncludeLoggedIn
|
72 |
*/
|
73 |
-
public function processCustomShieldOffense( $
|
74 |
if ( $this->getCon()->isPremiumActive() ) {
|
75 |
-
if ( empty( $
|
76 |
-
$
|
77 |
}
|
78 |
|
79 |
if ( $bIncludeLoggedIn || !did_action( 'init' ) || !Services::WpUsers()->isUserLoggedIn() ) {
|
@@ -81,8 +81,8 @@ class ProcessOffenses {
|
|
81 |
->fireEvent(
|
82 |
'custom_offense',
|
83 |
[
|
84 |
-
'audit' => [ 'message' => $
|
85 |
-
'offense_count' => $
|
86 |
]
|
87 |
);
|
88 |
}
|
34 |
/** @var IPs\ModCon $mod */
|
35 |
$mod = $this->getMod();
|
36 |
|
37 |
+
$tracker = $mod->loadOffenseTracker();
|
38 |
if ( !$this->getCon()->plugin_deleting
|
39 |
+
&& $tracker->hasVisitorOffended() && $tracker->isCommit() ) {
|
40 |
( new IPs\Components\ProcessOffense() )
|
41 |
->setMod( $mod )
|
42 |
->setIp( Services::IP()->getRequestIp() )
|
66 |
|
67 |
/**
|
68 |
* Allows 3rd parties to trigger Shield offenses
|
69 |
+
* @param string $message
|
70 |
+
* @param int $offenseCount
|
71 |
* @param bool $bIncludeLoggedIn
|
72 |
*/
|
73 |
+
public function processCustomShieldOffense( $message, $offenseCount = 1, $bIncludeLoggedIn = true ) {
|
74 |
if ( $this->getCon()->isPremiumActive() ) {
|
75 |
+
if ( empty( $message ) ) {
|
76 |
+
$message = __( 'No custom message provided.', 'wp-simple-firewall' );
|
77 |
}
|
78 |
|
79 |
if ( $bIncludeLoggedIn || !did_action( 'init' ) || !Services::WpUsers()->isUserLoggedIn() ) {
|
81 |
->fireEvent(
|
82 |
'custom_offense',
|
83 |
[
|
84 |
+
'audit' => [ 'message' => $message ],
|
85 |
+
'offense_count' => (int)$offenseCount
|
86 |
]
|
87 |
);
|
88 |
}
|
src/lib/src/Modules/IPs/ModCon.php
CHANGED
@@ -48,8 +48,7 @@ class ModCon extends BaseShield\ModCon {
|
|
48 |
}
|
49 |
|
50 |
public function getDbHandler_IPs() :Shield\Databases\IPs\Handler {
|
51 |
-
|
52 |
-
return empty( $new ) ? $this->getDbH( 'ips' ) : $new;
|
53 |
}
|
54 |
|
55 |
/**
|
48 |
}
|
49 |
|
50 |
public function getDbHandler_IPs() :Shield\Databases\IPs\Handler {
|
51 |
+
return $this->getDbH( 'ip_lists' );
|
|
|
52 |
}
|
53 |
|
54 |
/**
|
src/lib/src/Modules/IPs/Options.php
CHANGED
@@ -30,14 +30,10 @@ class Options extends BaseShield\Options {
|
|
30 |
return is_array( $aIps ) ? $aIps : [];
|
31 |
}
|
32 |
|
33 |
-
|
34 |
-
* @param string $ip
|
35 |
-
* @return bool
|
36 |
-
*/
|
37 |
-
public function getCanIpRequestAutoUnblock( $ip ) {
|
38 |
$existing = $this->getAutoUnblockIps();
|
39 |
return !array_key_exists( $ip, $existing )
|
40 |
-
|| ( Services::Request()->carbon()->
|
41 |
}
|
42 |
|
43 |
/**
|
30 |
return is_array( $aIps ) ? $aIps : [];
|
31 |
}
|
32 |
|
33 |
+
public function getCanIpRequestAutoUnblock( string $ip ) :bool {
|
|
|
|
|
|
|
|
|
34 |
$existing = $this->getAutoUnblockIps();
|
35 |
return !array_key_exists( $ip, $existing )
|
36 |
+
|| ( Services::Request()->carbon()->subHour( 1 )->timestamp > $existing[ $ip ] );
|
37 |
}
|
38 |
|
39 |
/**
|
src/lib/src/Modules/IPs/Strings.php
CHANGED
@@ -21,9 +21,9 @@ class Strings extends Base\Strings {
|
|
21 |
switch ( $section ) {
|
22 |
|
23 |
case 'section_enable_plugin_feature_ips' :
|
24 |
-
$
|
25 |
-
$
|
26 |
-
$
|
27 |
sprintf( '%s - %s', __( 'Purpose', 'wp-simple-firewall' ), __( 'The IP Manager allows you to whitelist, blacklist and configure auto-blacklist rules.', 'wp-simple-firewall' ) ),
|
28 |
sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ), sprintf( __( 'Keep the %s feature turned on.', 'wp-simple-firewall' ), __( 'IP Manager', 'wp-simple-firewall' ) ) )
|
29 |
.'<br />'.__( 'You should also carefully review the automatic black list settings.', 'wp-simple-firewall' )
|
@@ -31,9 +31,9 @@ class Strings extends Base\Strings {
|
|
31 |
break;
|
32 |
|
33 |
case 'section_auto_black_list' :
|
34 |
-
$
|
35 |
-
$
|
36 |
-
$
|
37 |
sprintf( '%s - %s', __( 'Purpose', 'wp-simple-firewall' ), __( 'The Automatic IP Black List system will block the IP addresses of naughty visitors after a specified number of offenses.', 'wp-simple-firewall' ) ),
|
38 |
sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ), sprintf( __( 'Keep the %s feature turned on.', 'wp-simple-firewall' ), __( 'Automatic IP Black List', 'wp-simple-firewall' ) ) ),
|
39 |
__( "Think of 'offenses' as just a counter for the number of times a visitor does something bad.", 'wp-simple-firewall' )
|
@@ -46,9 +46,9 @@ class Strings extends Base\Strings {
|
|
46 |
break;
|
47 |
|
48 |
case 'section_enable_plugin_feature_bottrap' :
|
49 |
-
$
|
50 |
-
$
|
51 |
-
$
|
52 |
__( "A bot doesn't know what's real and what's not, so it probes many different avenues until it finds something it recognises.", 'wp-simple-firewall' ),
|
53 |
__( "Bot-Trap monitors a set of typical bot behaviours to help identify probing bots.", 'wp-simple-firewall' ),
|
54 |
sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ), __( 'Enable as many mouse traps as possible.', 'wp-simple-firewall' ) )
|
@@ -56,9 +56,9 @@ class Strings extends Base\Strings {
|
|
56 |
break;
|
57 |
|
58 |
case 'section_logins':
|
59 |
-
$
|
60 |
-
$
|
61 |
-
$
|
62 |
sprintf( '%s - %s', __( 'Summary', 'wp-simple-firewall' ),
|
63 |
__( "Certain bots are designed to test your logins and this feature lets you decide how to handle them.", 'wp-simple-firewall' ) ),
|
64 |
sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ),
|
@@ -69,9 +69,9 @@ class Strings extends Base\Strings {
|
|
69 |
break;
|
70 |
|
71 |
case 'section_probes':
|
72 |
-
$
|
73 |
-
$
|
74 |
-
$
|
75 |
sprintf( '%s - %s', __( 'Summary', 'wp-simple-firewall' ),
|
76 |
__( "Bots are designed to probe and this feature is dedicated to detecting probing bots.", 'wp-simple-firewall' ) ),
|
77 |
sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ),
|
@@ -80,9 +80,9 @@ class Strings extends Base\Strings {
|
|
80 |
break;
|
81 |
|
82 |
case 'section_behaviours':
|
83 |
-
$
|
84 |
-
$
|
85 |
-
$
|
86 |
sprintf( '%s - %s', __( 'Summary', 'wp-simple-firewall' ),
|
87 |
__( "Detect characteristics and behaviour commonly associated with illegitimate bots.", 'wp-simple-firewall' ) ),
|
88 |
sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ),
|
@@ -95,9 +95,9 @@ class Strings extends Base\Strings {
|
|
95 |
}
|
96 |
|
97 |
return [
|
98 |
-
'title' => $
|
99 |
-
'title_short' => $
|
100 |
-
'summary' => ( isset( $
|
101 |
];
|
102 |
}
|
103 |
|
21 |
switch ( $section ) {
|
22 |
|
23 |
case 'section_enable_plugin_feature_ips' :
|
24 |
+
$titleShort = sprintf( '%s/%s', __( 'On', 'wp-simple-firewall' ), __( 'Off', 'wp-simple-firewall' ) );
|
25 |
+
$title = sprintf( __( 'Enable Module: %s', 'wp-simple-firewall' ), $sModName );
|
26 |
+
$summary = [
|
27 |
sprintf( '%s - %s', __( 'Purpose', 'wp-simple-firewall' ), __( 'The IP Manager allows you to whitelist, blacklist and configure auto-blacklist rules.', 'wp-simple-firewall' ) ),
|
28 |
sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ), sprintf( __( 'Keep the %s feature turned on.', 'wp-simple-firewall' ), __( 'IP Manager', 'wp-simple-firewall' ) ) )
|
29 |
.'<br />'.__( 'You should also carefully review the automatic black list settings.', 'wp-simple-firewall' )
|
31 |
break;
|
32 |
|
33 |
case 'section_auto_black_list' :
|
34 |
+
$title = __( 'Auto IP Blocking Rules', 'wp-simple-firewall' );
|
35 |
+
$titleShort = __( 'Auto Blocking Rules', 'wp-simple-firewall' );
|
36 |
+
$summary = [
|
37 |
sprintf( '%s - %s', __( 'Purpose', 'wp-simple-firewall' ), __( 'The Automatic IP Black List system will block the IP addresses of naughty visitors after a specified number of offenses.', 'wp-simple-firewall' ) ),
|
38 |
sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ), sprintf( __( 'Keep the %s feature turned on.', 'wp-simple-firewall' ), __( 'Automatic IP Black List', 'wp-simple-firewall' ) ) ),
|
39 |
__( "Think of 'offenses' as just a counter for the number of times a visitor does something bad.", 'wp-simple-firewall' )
|
46 |
break;
|
47 |
|
48 |
case 'section_enable_plugin_feature_bottrap' :
|
49 |
+
$titleShort = __( 'Bot-Trap', 'wp-simple-firewall' );
|
50 |
+
$title = __( 'Identify And Capture Bots Based On Their Site Activity', 'wp-simple-firewall' );
|
51 |
+
$summary = [
|
52 |
__( "A bot doesn't know what's real and what's not, so it probes many different avenues until it finds something it recognises.", 'wp-simple-firewall' ),
|
53 |
__( "Bot-Trap monitors a set of typical bot behaviours to help identify probing bots.", 'wp-simple-firewall' ),
|
54 |
sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ), __( 'Enable as many mouse traps as possible.', 'wp-simple-firewall' ) )
|
56 |
break;
|
57 |
|
58 |
case 'section_logins':
|
59 |
+
$titleShort = __( 'Login Bots', 'wp-simple-firewall' );
|
60 |
+
$title = __( 'Detect & Capture Login Bots', 'wp-simple-firewall' );
|
61 |
+
$summary = [
|
62 |
sprintf( '%s - %s', __( 'Summary', 'wp-simple-firewall' ),
|
63 |
__( "Certain bots are designed to test your logins and this feature lets you decide how to handle them.", 'wp-simple-firewall' ) ),
|
64 |
sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ),
|
69 |
break;
|
70 |
|
71 |
case 'section_probes':
|
72 |
+
$titleShort = __( 'Probing Bots', 'wp-simple-firewall' );
|
73 |
+
$title = __( 'Detect & Capture Probing Bots', 'wp-simple-firewall' );
|
74 |
+
$summary = [
|
75 |
sprintf( '%s - %s', __( 'Summary', 'wp-simple-firewall' ),
|
76 |
__( "Bots are designed to probe and this feature is dedicated to detecting probing bots.", 'wp-simple-firewall' ) ),
|
77 |
sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ),
|
80 |
break;
|
81 |
|
82 |
case 'section_behaviours':
|
83 |
+
$titleShort = __( 'Bot Behaviours', 'wp-simple-firewall' );
|
84 |
+
$title = __( 'Detect Behaviours Common To Bots', 'wp-simple-firewall' );
|
85 |
+
$summary = [
|
86 |
sprintf( '%s - %s', __( 'Summary', 'wp-simple-firewall' ),
|
87 |
__( "Detect characteristics and behaviour commonly associated with illegitimate bots.", 'wp-simple-firewall' ) ),
|
88 |
sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ),
|
95 |
}
|
96 |
|
97 |
return [
|
98 |
+
'title' => $title,
|
99 |
+
'title_short' => $titleShort,
|
100 |
+
'summary' => ( isset( $summary ) && is_array( $summary ) ) ? $summary : [],
|
101 |
];
|
102 |
}
|
103 |
|
src/lib/src/Modules/IPs/UI.php
CHANGED
@@ -61,17 +61,6 @@ class UI extends BaseShield\UI {
|
|
61 |
'tab_ip_analysis' => __( 'IP Analysis', 'wp-simple-firewall' ),
|
62 |
],
|
63 |
'vars' => [
|
64 |
-
'related_hrefs' => [
|
65 |
-
[
|
66 |
-
'href' => $mod->getUrl_AdminPage(),
|
67 |
-
'title' => __( 'IP Block Settings', 'wp-simple-firewall' ),
|
68 |
-
],
|
69 |
-
[
|
70 |
-
'href' => $mod->createFileDownloadLink( 'db_ip' ),
|
71 |
-
'classes' => [ 'shield_file_download' ],
|
72 |
-
'title' => sprintf( __( 'Download (as %s)', 'wp-simple-firewall' ), 'CSV' ),
|
73 |
-
],
|
74 |
-
],
|
75 |
'unique_ips_black' => ( new RetrieveIpsForLists() )
|
76 |
->setDbHandler( $mod->getDbHandler_IPs() )
|
77 |
->black(),
|
@@ -136,14 +125,4 @@ class UI extends BaseShield\UI {
|
|
136 |
true
|
137 |
);
|
138 |
}
|
139 |
-
|
140 |
-
protected function getSettingsRelatedLinks() :array {
|
141 |
-
$modInsights = $this->getCon()->getModule_Insights();
|
142 |
-
return [
|
143 |
-
[
|
144 |
-
'href' => $modInsights->getUrl_SubInsightsPage( 'ips' ),
|
145 |
-
'title' => __( 'Analyse & Manage IPs', 'wp-simple-firewall' ),
|
146 |
-
]
|
147 |
-
];
|
148 |
-
}
|
149 |
}
|
61 |
'tab_ip_analysis' => __( 'IP Analysis', 'wp-simple-firewall' ),
|
62 |
],
|
63 |
'vars' => [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
'unique_ips_black' => ( new RetrieveIpsForLists() )
|
65 |
->setDbHandler( $mod->getDbHandler_IPs() )
|
66 |
->black(),
|
125 |
true
|
126 |
);
|
127 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
}
|
src/lib/src/Modules/Insights/AjaxHandler.php
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Insights;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
|
7 |
+
class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
8 |
+
|
9 |
+
protected function processAjaxAction( string $action ) :array {
|
10 |
+
|
11 |
+
switch ( $action ) {
|
12 |
+
case 'dynamic_load':
|
13 |
+
$response = $this->ajaxExec_DynamicLoad();
|
14 |
+
break;
|
15 |
+
|
16 |
+
default:
|
17 |
+
$response = parent::processAjaxAction( $action );
|
18 |
+
}
|
19 |
+
|
20 |
+
return $response;
|
21 |
+
}
|
22 |
+
|
23 |
+
private function ajaxExec_DynamicLoad() :array {
|
24 |
+
|
25 |
+
try {
|
26 |
+
$pageData = ( new Lib\Requests\DynamicPageLoader() )
|
27 |
+
->setMod( $this->getMod() )
|
28 |
+
->build( Shield\Modules\Base\Lib\Request\FormParams::Retrieve() );
|
29 |
+
$success = true;
|
30 |
+
}
|
31 |
+
catch ( \Exception $e ) {
|
32 |
+
$pageData = [
|
33 |
+
'message' => $e->getMessage(),
|
34 |
+
'success' => false,
|
35 |
+
];
|
36 |
+
$success = false;
|
37 |
+
}
|
38 |
+
|
39 |
+
return array_merge(
|
40 |
+
[
|
41 |
+
'success' => false,
|
42 |
+
'message' => 'no msg',
|
43 |
+
'html' => 'no html',
|
44 |
+
'show_toast' => !$success,
|
45 |
+
],
|
46 |
+
$pageData
|
47 |
+
);
|
48 |
+
}
|
49 |
+
}
|
src/lib/src/Modules/Insights/Lib/Requests/DynamicPageLoader.php
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Insights\Lib\Requests;
|
4 |
+
|
5 |
+
use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\ModCon;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Class DynamicPageLoader
|
11 |
+
* @package FernleafSystems\Wordpress\Plugin\Shield\Modules\Insights\Lib\Requests
|
12 |
+
* @property string $load_type
|
13 |
+
* @property string $load_variant
|
14 |
+
*/
|
15 |
+
class DynamicPageLoader extends DynPropertiesClass {
|
16 |
+
|
17 |
+
use ModConsumer;
|
18 |
+
|
19 |
+
private $params = [];
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @param array $params
|
23 |
+
* @return array
|
24 |
+
* @throws \Exception
|
25 |
+
*/
|
26 |
+
public function build( array $params ) :array {
|
27 |
+
if ( empty( $params ) || empty( $params[ 'load_params' ] ) ) {
|
28 |
+
throw new \Exception( 'No dynamic page loading params' );
|
29 |
+
}
|
30 |
+
$this->applyFromArray( $params[ 'load_params' ] );
|
31 |
+
return [
|
32 |
+
'html' => $this->getContent(),
|
33 |
+
'page_url' => $this->getPageUrl(),
|
34 |
+
'page_title' => $this->getPageTitle(),
|
35 |
+
];
|
36 |
+
}
|
37 |
+
|
38 |
+
private function getContent() :string {
|
39 |
+
|
40 |
+
switch ( $this->load_type ) {
|
41 |
+
case 'settings':
|
42 |
+
$content = $this->renderSettings();
|
43 |
+
break;
|
44 |
+
|
45 |
+
default:
|
46 |
+
throw new \Exception( 'Unsupported dynamic page load type' );
|
47 |
+
}
|
48 |
+
|
49 |
+
return $content;
|
50 |
+
}
|
51 |
+
|
52 |
+
private function getPageUrl() :string {
|
53 |
+
$con = $this->getCon();
|
54 |
+
|
55 |
+
switch ( $this->load_type ) {
|
56 |
+
case 'settings':
|
57 |
+
$url = $con->getModule( $this->load_variant )->getUrl_AdminPage();
|
58 |
+
break;
|
59 |
+
|
60 |
+
default:
|
61 |
+
throw new \Exception( 'Unsupported dynamic page load type' );
|
62 |
+
}
|
63 |
+
return $url;
|
64 |
+
}
|
65 |
+
|
66 |
+
private function getPageTitle() :string {
|
67 |
+
$con = $this->getCon();
|
68 |
+
|
69 |
+
switch ( $this->load_type ) {
|
70 |
+
case 'settings':
|
71 |
+
$title = sprintf( '%s: %s',
|
72 |
+
__( 'Settings', 'wp-simple-firewall' ),
|
73 |
+
$con->getModule( $this->load_variant )->getMainFeatureName()
|
74 |
+
);
|
75 |
+
break;
|
76 |
+
|
77 |
+
default:
|
78 |
+
throw new \Exception( 'Unsupported dynamic page load type' );
|
79 |
+
}
|
80 |
+
return $title;
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* @throws \Exception
|
85 |
+
*/
|
86 |
+
private function renderSettings() :string {
|
87 |
+
|
88 |
+
$mod = $this->getCon()->getModule( $this->load_variant );
|
89 |
+
if ( !$mod instanceof ModCon ) {
|
90 |
+
throw new \Exception( 'Invalid dynamic page load data (variant)' );
|
91 |
+
}
|
92 |
+
|
93 |
+
return $mod->renderOptionsForm();
|
94 |
+
}
|
95 |
+
}
|
src/lib/src/Modules/Insights/Lib/SideMenuBuilder.php
ADDED
@@ -0,0 +1,477 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Insights\Lib;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Insights\ModCon;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class SideMenuBuilder {
|
10 |
+
|
11 |
+
use ModConsumer;
|
12 |
+
|
13 |
+
public function build() :array {
|
14 |
+
$menu = [
|
15 |
+
$this->search(),
|
16 |
+
$this->overview(),
|
17 |
+
$this->stats(),
|
18 |
+
$this->settings(),
|
19 |
+
$this->scans(),
|
20 |
+
$this->ips(),
|
21 |
+
$this->audit(),
|
22 |
+
$this->traffic(),
|
23 |
+
$this->users(),
|
24 |
+
$this->integrations(),
|
25 |
+
$this->gopro(),
|
26 |
+
$this->tools(),
|
27 |
+
$this->docs(),
|
28 |
+
];
|
29 |
+
|
30 |
+
foreach ( $menu as $key => $item ) {
|
31 |
+
$item = Services::DataManipulation()->mergeArraysRecursive( [
|
32 |
+
'slug' => 'no-slug',
|
33 |
+
'title' => __( 'NO TITLE', 'wp-simple-firewall' ),
|
34 |
+
'href' => '#',
|
35 |
+
'classes' => [],
|
36 |
+
'id' => '',
|
37 |
+
'active' => $this->getInav() === $item[ 'slug' ],
|
38 |
+
'sub_items' => [],
|
39 |
+
'target' => '',
|
40 |
+
'data' => [],
|
41 |
+
'badge' => [],
|
42 |
+
], $item );
|
43 |
+
|
44 |
+
if ( !empty( $item[ 'sub_items' ] ) ) {
|
45 |
+
$item[ 'data' ][ 'toggle' ] = 'collapse';
|
46 |
+
$item[ 'href' ] = '#collapse-'.$item[ 'slug' ];
|
47 |
+
|
48 |
+
// Set parent active if any sub-items are active
|
49 |
+
if ( !$item[ 'active' ] ) {
|
50 |
+
$item[ 'active' ] = count( array_filter( $item[ 'sub_items' ], function ( $sub ) {
|
51 |
+
return $sub[ 'active' ] ?? false;
|
52 |
+
} ) );
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
$menu[ $key ] = $item;
|
57 |
+
}
|
58 |
+
|
59 |
+
return $menu;
|
60 |
+
}
|
61 |
+
|
62 |
+
private function ips() :array {
|
63 |
+
$con = $this->getCon();
|
64 |
+
/** @var ModCon $mod */
|
65 |
+
$mod = $this->getMod();
|
66 |
+
|
67 |
+
$slug = 'ips';
|
68 |
+
|
69 |
+
$subItems = [
|
70 |
+
[
|
71 |
+
'slug' => $slug.'-manage',
|
72 |
+
'title' => __( 'Manage IPs', 'wp-simple-firewall' ),
|
73 |
+
'href' => $mod->getUrl_SubInsightsPage( 'ips' ),
|
74 |
+
'active' => $this->getInav() === $slug,
|
75 |
+
],
|
76 |
+
[
|
77 |
+
'slug' => $slug.'-blocksettings',
|
78 |
+
'title' => sprintf( '%s: %s', __( 'Settings', 'wp-simple-firewall' ), __( 'IP Blocking', 'wp-simple-firewall' ) ),
|
79 |
+
'href' => $con->getModule_IPs()->getUrl_AdminPage(),
|
80 |
+
],
|
81 |
+
[
|
82 |
+
'slug' => $slug.'-antibotsettings',
|
83 |
+
'title' => sprintf( '%s: %s', __( 'Settings', 'wp-simple-firewall' ), __( 'AntiBot', 'wp-simple-firewall' ) ),
|
84 |
+
'href' => $con->getModule_IPs()->getUrl_DirectLinkToSection( 'section_antibot' ),
|
85 |
+
],
|
86 |
+
[
|
87 |
+
'slug' => 'ips-download',
|
88 |
+
'href' => $con->getModule_IPs()->createFileDownloadLink( 'db_ip' ),
|
89 |
+
'classes' => [ 'shield_file_download' ],
|
90 |
+
'title' => sprintf( __( 'Download (as %s)', 'wp-simple-firewall' ), 'CSV' ),
|
91 |
+
],
|
92 |
+
];
|
93 |
+
|
94 |
+
return [
|
95 |
+
'slug' => $slug,
|
96 |
+
'title' => __( 'IPs and Bots', 'wp-simple-firewall' ),
|
97 |
+
'img' => $this->getCon()->urls->forImage( 'bootstrap/diagram-3.svg' ),
|
98 |
+
'introjs' => __( "Protection begins by detecting bad bots - Review and Analyse all visitor IPs that have an impact on your site.", 'wp-simple-firewall' ),
|
99 |
+
'sub_items' => $subItems,
|
100 |
+
];
|
101 |
+
}
|
102 |
+
|
103 |
+
private function audit() :array {
|
104 |
+
$con = $this->getCon();
|
105 |
+
/** @var ModCon $mod */
|
106 |
+
$mod = $this->getMod();
|
107 |
+
|
108 |
+
$slug = 'audit';
|
109 |
+
$subItems = [
|
110 |
+
[
|
111 |
+
'slug' => $slug.'-log',
|
112 |
+
'title' => __( 'View Log', 'wp-simple-firewall' ),
|
113 |
+
'href' => $mod->getUrl_SubInsightsPage( $slug ),
|
114 |
+
'active' => $this->getInav() === $slug,
|
115 |
+
],
|
116 |
+
[
|
117 |
+
'slug' => $slug.'-settings',
|
118 |
+
'title' => __( 'Settings', 'wp-simple-firewall' ),
|
119 |
+
'href' => $con->getModule_AuditTrail()->getUrl_AdminPage(),
|
120 |
+
],
|
121 |
+
[
|
122 |
+
'slug' => 'audit-download',
|
123 |
+
'title' => sprintf( __( 'Download (as %s)', 'wp-simple-firewall' ), 'CSV' ),
|
124 |
+
'href' => $con->getModule_AuditTrail()->createFileDownloadLink( 'db_audit' ),
|
125 |
+
'classes' => [ 'shield_file_download' ],
|
126 |
+
],
|
127 |
+
[
|
128 |
+
'slug' => 'audit-glossary',
|
129 |
+
'title' => __( 'Audit Trail Glossary', 'wp-simple-firewall' ),
|
130 |
+
'href' => 'https://shsec.io/audittrailglossary',
|
131 |
+
'target' => '_blank',
|
132 |
+
],
|
133 |
+
];
|
134 |
+
|
135 |
+
return [
|
136 |
+
'slug' => 'audit',
|
137 |
+
'title' => __( 'Audit Trail', 'wp-simple-firewall' ),
|
138 |
+
'img' => $this->getCon()->urls->forImage( 'bootstrap/person-lines-fill.svg' ),
|
139 |
+
'introjs' => __( "Track and review all important actions taken on your site - see the Who, What and When.", 'wp-simple-firewall' ),
|
140 |
+
'sub_items' => $subItems,
|
141 |
+
];
|
142 |
+
}
|
143 |
+
|
144 |
+
private function scans() :array {
|
145 |
+
/** @var ModCon $mod */
|
146 |
+
$mod = $this->getMod();
|
147 |
+
$con = $this->getCon();
|
148 |
+
|
149 |
+
$slug = 'scans';
|
150 |
+
|
151 |
+
$subItems = [
|
152 |
+
[
|
153 |
+
'slug' => $slug.'-run',
|
154 |
+
'title' => __( 'Run Scan', 'wp-simple-firewall' ),
|
155 |
+
'href' => $mod->getUrl_ScansRun(),
|
156 |
+
'active' => $this->getInav() === 'scans_run',
|
157 |
+
],
|
158 |
+
[
|
159 |
+
'slug' => $slug.'-results',
|
160 |
+
'title' => __( 'Scan Results', 'wp-simple-firewall' ),
|
161 |
+
'href' => $mod->getUrl_ScansResults(),
|
162 |
+
'active' => $this->getInav() === 'scans_results',
|
163 |
+
],
|
164 |
+
[
|
165 |
+
'slug' => $slug.'-settings',
|
166 |
+
'title' => sprintf( '%s: %s', __( 'Settings', 'wp-simple-firewall' ), __( 'Automatic Scans', 'wp-simple-firewall' ) ),
|
167 |
+
'href' => $con->getModule_HackGuard()->getUrl_AdminPage(),
|
168 |
+
],
|
169 |
+
];
|
170 |
+
|
171 |
+
return [
|
172 |
+
'slug' => $slug,
|
173 |
+
'title' => __( 'Scans', 'wp-simple-firewall' ),
|
174 |
+
'img' => $this->getCon()->urls->forImage( 'bootstrap/shield-shaded.svg' ),
|
175 |
+
'introjs' => sprintf( __( "Run a %s scan at any time, or view the results from the latest scan.", 'wp-simple-firewall' ),
|
176 |
+
$this->getCon()->getHumanName() ),
|
177 |
+
'sub_items' => $subItems,
|
178 |
+
];
|
179 |
+
}
|
180 |
+
|
181 |
+
private function search() :array {
|
182 |
+
/** @var ModCon $mod */
|
183 |
+
$mod = $this->getMod();
|
184 |
+
return [
|
185 |
+
'slug' => 'search',
|
186 |
+
'title' => __( 'Search', 'wp-simple-firewall' ),
|
187 |
+
'img' => $this->getCon()->urls->forImage( 'bootstrap/search.svg' ),
|
188 |
+
'id' => 'NavMenuSearch',
|
189 |
+
'href' => $mod->getUrl_SubInsightsPage( 'overview' ),
|
190 |
+
'introjs' => __( 'Use Search to find any option within the entire plugin' ),
|
191 |
+
'data' => [
|
192 |
+
'toggle' => 'modal',
|
193 |
+
'target' => '#SearchDialog',
|
194 |
+
],
|
195 |
+
];
|
196 |
+
}
|
197 |
+
|
198 |
+
private function stats() :array {
|
199 |
+
/** @var ModCon $mod */
|
200 |
+
$mod = $this->getMod();
|
201 |
+
|
202 |
+
return [
|
203 |
+
'slug' => 'reports',
|
204 |
+
'title' => __( 'Reports', 'wp-simple-firewall' ),
|
205 |
+
'img' => $this->getCon()->urls->forImage( 'bootstrap/graph-up.svg' ),
|
206 |
+
'href' => $mod->getUrl_SubInsightsPage( 'reports' ),
|
207 |
+
'introjs' => __( 'Reports use the built-in stats to show you how Shield is working to secure your site.' ),
|
208 |
+
'sub_items' => [
|
209 |
+
[
|
210 |
+
'slug' => 'reports-stats',
|
211 |
+
'title' => __( 'Stats', 'wp-simple-firewall' ),
|
212 |
+
'href' => $mod->getUrl_SubInsightsPage( 'stats' ),
|
213 |
+
'active' => $this->getInav() === 'stats'
|
214 |
+
],
|
215 |
+
[
|
216 |
+
'slug' => 'reports-charts',
|
217 |
+
'title' => __( 'Charts', 'wp-simple-firewall' ),
|
218 |
+
'href' => $mod->getUrl_SubInsightsPage( 'reports' ),
|
219 |
+
'active' => $this->getInav() === 'reports'
|
220 |
+
],
|
221 |
+
],
|
222 |
+
];
|
223 |
+
}
|
224 |
+
|
225 |
+
private function overview() :array {
|
226 |
+
/** @var ModCon $mod */
|
227 |
+
$mod = $this->getMod();
|
228 |
+
return [
|
229 |
+
'slug' => 'overview',
|
230 |
+
'title' => __( 'Overview', 'wp-simple-firewall' ),
|
231 |
+
'img' => $this->getCon()->urls->forImage( 'bootstrap/binoculars.svg' ),
|
232 |
+
'href' => $mod->getUrl_SubInsightsPage( 'overview' ),
|
233 |
+
'introjs' => sprintf( __( "Review your entire %s configuration at a glance to see what's working and what's not.", 'wp-simple-firewall' ),
|
234 |
+
$this->getCon()->getHumanName() ),
|
235 |
+
];
|
236 |
+
}
|
237 |
+
|
238 |
+
private function settings() :array {
|
239 |
+
/** @var ModCon $mod */
|
240 |
+
$mod = $this->getMod();
|
241 |
+
$slug = 'settings';
|
242 |
+
|
243 |
+
$subItems = [];
|
244 |
+
foreach ( $mod->getModulesSummaryData() as $modData ) {
|
245 |
+
if ( $modData[ 'show_mod_opts' ] ) {
|
246 |
+
$subItems[] = [
|
247 |
+
'slug' => $slug.'-'.$modData[ 'slug' ],
|
248 |
+
'title' => $modData[ 'sidebar_name' ] ?? $modData[ 'name' ],
|
249 |
+
'href' => $modData[ 'href' ],
|
250 |
+
'classes' => [ 'dynamic_body_load' ],
|
251 |
+
'data' => [
|
252 |
+
'load_type' => $slug,
|
253 |
+
'load_variant' => $modData[ 'slug' ],
|
254 |
+
],
|
255 |
+
'active' => Services::Request()->query( 'subnav' ) === $modData[ 'slug' ]
|
256 |
+
];
|
257 |
+
}
|
258 |
+
}
|
259 |
+
|
260 |
+
return [
|
261 |
+
'slug' => $slug,
|
262 |
+
'title' => __( 'Settings', 'wp-simple-firewall' ),
|
263 |
+
'img' => $this->getCon()->urls->forImage( 'bootstrap/sliders.svg' ),
|
264 |
+
'introjs' => sprintf( __( "%s is a big plugin split into modules, and each with their own options - use these jump-off points to find the specific option you need.", 'wp-simple-firewall' ),
|
265 |
+
$this->getCon()->getHumanName() ),
|
266 |
+
'sub_items' => $subItems,
|
267 |
+
];
|
268 |
+
}
|
269 |
+
|
270 |
+
private function integrations() :array {
|
271 |
+
$con = $this->getCon();
|
272 |
+
return [
|
273 |
+
'slug' => 'integrations',
|
274 |
+
'img' => $this->getCon()->urls->forImage( 'bootstrap/puzzle-fill.svg' ),
|
275 |
+
'title' => __( 'Integrations', 'wp-simple-firewall' ),
|
276 |
+
'introjs' => __( "Integrate with your favourite plugins to block SPAM and manage Shield better.", 'wp-simple-firewall' ),
|
277 |
+
'sub_items' => [
|
278 |
+
[
|
279 |
+
'slug' => 'integrations-settings',
|
280 |
+
'title' => __( 'Settings', 'wp-simple-firewall' ),
|
281 |
+
'href' => $con->getModule_Integrations()->getUrl_AdminPage(),
|
282 |
+
],
|
283 |
+
[
|
284 |
+
'slug' => 'integrations-spam',
|
285 |
+
'title' => __( 'Contact Form SPAM', 'wp-simple-firewall' ),
|
286 |
+
'href' => $con->getModule_Integrations()->getUrl_DirectLinkToSection( 'section_spam' ),
|
287 |
+
],
|
288 |
+
],
|
289 |
+
];
|
290 |
+
}
|
291 |
+
|
292 |
+
private function reports() :array {
|
293 |
+
/** @var ModCon $mod */
|
294 |
+
$mod = $this->getMod();
|
295 |
+
return [
|
296 |
+
'slug' => 'reports',
|
297 |
+
'title' => __( 'Reports', 'wp-simple-firewall' ),
|
298 |
+
'img' => $this->getCon()->urls->forImage( 'bootstrap/graph-up.svg' ),
|
299 |
+
'href' => $mod->getUrl_SubInsightsPage( 'reports' ),
|
300 |
+
];
|
301 |
+
}
|
302 |
+
|
303 |
+
private function docs() :array {
|
304 |
+
/** @var ModCon $mod */
|
305 |
+
$mod = $this->getMod();
|
306 |
+
return [
|
307 |
+
'slug' => 'docs',
|
308 |
+
'title' => __( "View Docs", 'wp-simple-firewall' ),
|
309 |
+
'img' => $this->getCon()->urls->forImage( 'bootstrap/book-half.svg' ),
|
310 |
+
'href' => $mod->getUrl_SubInsightsPage( 'docs' ),
|
311 |
+
];
|
312 |
+
}
|
313 |
+
|
314 |
+
private function gopro() :array {
|
315 |
+
/** @var ModCon $mod */
|
316 |
+
$mod = $this->getMod();
|
317 |
+
|
318 |
+
$isPro = $this->getCon()->isPremiumActive();
|
319 |
+
|
320 |
+
if ( $isPro ) {
|
321 |
+
$subItems = [];
|
322 |
+
}
|
323 |
+
else {
|
324 |
+
$subItems = [
|
325 |
+
[
|
326 |
+
'slug' => 'license-gopro',
|
327 |
+
'title' => __( 'Check License', 'wp-simple-firewall' ),
|
328 |
+
'href' => $mod->getUrl_SubInsightsPage( 'license' ),
|
329 |
+
'active' => $this->getInav() === 'license'
|
330 |
+
],
|
331 |
+
[
|
332 |
+
'slug' => 'license-trial',
|
333 |
+
'title' => __( 'Free Trial', 'wp-simple-firewall' ),
|
334 |
+
'href' => $mod->getUrl_SubInsightsPage( 'free_trial' ),
|
335 |
+
'active' => $this->getInav() === 'free_trial'
|
336 |
+
],
|
337 |
+
[
|
338 |
+
'slug' => 'license-features',
|
339 |
+
'href' => 'https://shsec.io/gp',
|
340 |
+
'title' => __( 'ShieldPRO Features', 'wp-simple-firewall' ),
|
341 |
+
'target' => '_blank',
|
342 |
+
],
|
343 |
+
];
|
344 |
+
}
|
345 |
+
|
346 |
+
return [
|
347 |
+
'slug' => 'license',
|
348 |
+
'title' => $isPro ? __( 'ShieldPRO', 'wp-simple-firewall' ) : __( 'Go PRO!', 'wp-simple-firewall' ),
|
349 |
+
'img' => $this->getCon()->urls->forImage( 'bootstrap/award.svg' ),
|
350 |
+
'href' => $mod->getUrl_SubInsightsPage( 'license' ),
|
351 |
+
'sub_items' => $subItems,
|
352 |
+
];
|
353 |
+
}
|
354 |
+
|
355 |
+
private function tools() :array {
|
356 |
+
$con = $this->getCon();
|
357 |
+
/** @var ModCon $mod */
|
358 |
+
$mod = $this->getMod();
|
359 |
+
|
360 |
+
$slug = 'tools';
|
361 |
+
$subItems = [
|
362 |
+
[
|
363 |
+
'slug' => $slug.'-importexport',
|
364 |
+
'title' => __( 'Import / Export', 'wp-simple-firewall' ),
|
365 |
+
'href' => $mod->getUrl_SubInsightsPage( 'importexport' ),
|
366 |
+
'active' => $this->getInav() === 'importexport'
|
367 |
+
],
|
368 |
+
[
|
369 |
+
'slug' => $slug.'-whitelabel',
|
370 |
+
'title' => __( 'White Label', 'wp-simple-firewall' ),
|
371 |
+
'href' => $con->getModule_SecAdmin()->getUrl_DirectLinkToSection( 'section_whitelabel' ),
|
372 |
+
],
|
373 |
+
[
|
374 |
+
'slug' => $slug.'-notes',
|
375 |
+
'title' => __( 'Admin Notes', 'wp-simple-firewall' ),
|
376 |
+
'href' => $mod->getUrl_SubInsightsPage( 'notes' ),
|
377 |
+
'active' => $this->getInav() === 'notes'
|
378 |
+
],
|
379 |
+
[
|
380 |
+
'slug' => $slug.'-debug',
|
381 |
+
'title' => __( "Debug Info", 'wp-simple-firewall' ),
|
382 |
+
'href' => $mod->getUrl_SubInsightsPage( 'debug' ),
|
383 |
+
'active' => $this->getInav() === 'debug'
|
384 |
+
]
|
385 |
+
];
|
386 |
+
|
387 |
+
return [
|
388 |
+
'slug' => $slug,
|
389 |
+
'title' => __( 'Tools', 'wp-simple-firewall' ),
|
390 |
+
'img' => $this->getCon()->urls->forImage( 'bootstrap/tools.svg' ),
|
391 |
+
'introjs' => __( "Important security tools, such a import/export, whitelabel and admin notes.", 'wp-simple-firewall' ),
|
392 |
+
'sub_items' => $subItems,
|
393 |
+
];
|
394 |
+
}
|
395 |
+
|
396 |
+
private function traffic() :array {
|
397 |
+
$con = $this->getCon();
|
398 |
+
/** @var ModCon $mod */
|
399 |
+
$mod = $this->getMod();
|
400 |
+
|
401 |
+
$slug = 'traffic';
|
402 |
+
$subItems = [
|
403 |
+
[
|
404 |
+
'slug' => $slug.'-log',
|
405 |
+
'title' => __( 'View Log', 'wp-simple-firewall' ),
|
406 |
+
'href' => $mod->getUrl_SubInsightsPage( $slug ),
|
407 |
+
'active' => $this->getInav() === $slug,
|
408 |
+
],
|
409 |
+
[
|
410 |
+
'slug' => $slug.'-ratelimitsettings',
|
411 |
+
'title' => sprintf( '%s: %s', __( 'Settings', 'wp-simple-firewall' ), __( 'Rate Limiting', 'wp-simple-firewall' ) ),
|
412 |
+
'href' => $con->getModule_Traffic()->getUrl_DirectLinkToSection( 'section_traffic_limiter' ),
|
413 |
+
],
|
414 |
+
[
|
415 |
+
'slug' => 'traffic-download',
|
416 |
+
'href' => $con->getModule_Traffic()->createFileDownloadLink( 'db_traffic' ),
|
417 |
+
'classes' => [ 'shield_file_download' ],
|
418 |
+
'title' => sprintf( __( 'Download (as %s)', 'wp-simple-firewall' ), 'CSV' ),
|
419 |
+
],
|
420 |
+
];
|
421 |
+
|
422 |
+
return [
|
423 |
+
'slug' => 'traffic',
|
424 |
+
'title' => __( 'Traffic', 'wp-simple-firewall' ),
|
425 |
+
'img' => $this->getCon()->urls->forImage( 'bootstrap/stoplights.svg' ),
|
426 |
+
'introjs' => __( "Monitor and watch traffic as it hits your site.", 'wp-simple-firewall' ),
|
427 |
+
'sub_items' => $subItems,
|
428 |
+
];
|
429 |
+
}
|
430 |
+
|
431 |
+
private function users() :array {
|
432 |
+
$con = $this->getCon();
|
433 |
+
/** @var ModCon $mod */
|
434 |
+
$mod = $this->getMod();
|
435 |
+
|
436 |
+
$subItems = [
|
437 |
+
[
|
438 |
+
'slug' => 'users-sessions',
|
439 |
+
'title' => __( 'View Sessions', 'wp-simple-firewall' ),
|
440 |
+
'href' => $mod->getUrl_SubInsightsPage( 'users' ),
|
441 |
+
],
|
442 |
+
[
|
443 |
+
'slug' => 'users-secadmin',
|
444 |
+
'title' => sprintf( '%s: %s', __( 'Settings', 'wp-simple-firewall' ), __( 'Security Admin', 'wp-simple-firewall' ) ),
|
445 |
+
'href' => $con->getModule_SecAdmin()->getUrl_DirectLinkToSection( 'section_security_admin_settings' ),
|
446 |
+
],
|
447 |
+
[
|
448 |
+
'slug' => 'users-settings',
|
449 |
+
'title' => sprintf( '%s: %s', __( 'Settings', 'wp-simple-firewall' ), __( 'Sessions', 'wp-simple-firewall' ) ),
|
450 |
+
'href' => $con->getModule_UserManagement()
|
451 |
+
->getUrl_DirectLinkToSection( 'section_user_session_management' ),
|
452 |
+
],
|
453 |
+
[
|
454 |
+
'slug' => 'users-passwords',
|
455 |
+
'title' => sprintf( '%s: %s', __( 'Settings', 'wp-simple-firewall' ), __( 'Password Policies', 'wp-simple-firewall' ) ),
|
456 |
+
'href' => $con->getModule_UserManagement()->getUrl_DirectLinkToSection( 'section_passwords' ),
|
457 |
+
],
|
458 |
+
[
|
459 |
+
'slug' => 'users-suspend',
|
460 |
+
'title' => sprintf( '%s: %s', __( 'Settings', 'wp-simple-firewall' ), __( 'User Suspension', 'wp-simple-firewall' ) ),
|
461 |
+
'href' => $con->getModule_UserManagement()->getUrl_DirectLinkToSection( 'section_suspend' ),
|
462 |
+
],
|
463 |
+
];
|
464 |
+
|
465 |
+
return [
|
466 |
+
'slug' => 'users',
|
467 |
+
'title' => __( 'Users', 'wp-simple-firewall' ),
|
468 |
+
'img' => $this->getCon()->urls->forImage( 'bootstrap/person-badge.svg' ),
|
469 |
+
'introjs' => __( 'View sessions, and configure session timeouts and passwords requirements.', 'wp-simple-firewall' ),
|
470 |
+
'sub_items' => $subItems,
|
471 |
+
];
|
472 |
+
}
|
473 |
+
|
474 |
+
private function getInav() :string {
|
475 |
+
return (string)Services::Request()->query( 'inav' );
|
476 |
+
}
|
477 |
+
}
|
src/lib/src/Modules/Insights/ModCon.php
CHANGED
@@ -18,13 +18,21 @@ class ModCon extends BaseShield\ModCon {
|
|
18 |
|
19 |
protected function onModulesLoaded() {
|
20 |
$this->maybeRedirectToAdmin();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
}
|
22 |
|
23 |
private function maybeRedirectToAdmin() {
|
24 |
$con = $this->getCon();
|
25 |
$activeFor = $con->getModule_Plugin()->getActivateLength();
|
26 |
if ( !Services::WpGeneral()->isAjax() && is_admin() && !$con->isModulePage() && $activeFor < 4 ) {
|
27 |
-
Services::Response()->redirect( $this->
|
28 |
}
|
29 |
}
|
30 |
|
@@ -32,6 +40,14 @@ class ModCon extends BaseShield\ModCon {
|
|
32 |
return add_query_arg( [ 'analyse_ip' => $ip ], $this->getUrl_SubInsightsPage( 'ips' ) );
|
33 |
}
|
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
public function getUrl_SubInsightsPage( string $subPage ) :string {
|
36 |
return add_query_arg(
|
37 |
[ 'inav' => sanitize_key( $subPage ) ],
|
@@ -47,23 +63,34 @@ class ModCon extends BaseShield\ModCon {
|
|
47 |
|
48 |
public function getScriptLocalisations() :array {
|
49 |
$con = $this->getCon();
|
|
|
|
|
50 |
$locals = parent::getScriptLocalisations();
|
51 |
$locals[] = [
|
52 |
'plugin',
|
53 |
'icwp_wpsf_vars_insights',
|
54 |
[
|
55 |
'strings' => [
|
56 |
-
'
|
57 |
-
'
|
58 |
-
'select_action' => __( 'Please select an action to perform.', 'wp-simple-firewall' ),
|
59 |
-
'are_you_sure' => __( 'Are you sure?', 'wp-simple-firewall' ),
|
60 |
],
|
61 |
]
|
62 |
];
|
|
|
63 |
$locals[] = [
|
64 |
$con->prefix( 'ip_detect' ),
|
65 |
'icwp_wpsf_vars_ipdetect',
|
66 |
-
[ 'ajax' => $
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
];
|
68 |
|
69 |
return $locals;
|
@@ -76,10 +103,13 @@ class ModCon extends BaseShield\ModCon {
|
|
76 |
];
|
77 |
|
78 |
$con = $this->getCon();
|
79 |
-
$
|
|
|
|
|
|
|
80 |
|
81 |
-
if ( $con->getIsPage_PluginAdmin() && !empty( $
|
82 |
-
switch ( $
|
83 |
|
84 |
case 'importexport':
|
85 |
$enq[ Enqueue::JS ][] = 'shield/import';
|
@@ -107,22 +137,24 @@ class ModCon extends BaseShield\ModCon {
|
|
107 |
break;
|
108 |
|
109 |
case 'notes':
|
110 |
-
case '
|
|
|
111 |
case 'audit':
|
112 |
case 'traffic':
|
113 |
case 'ips':
|
114 |
case 'debug':
|
115 |
case 'users':
|
|
|
116 |
|
117 |
$enq[ Enqueue::JS ][] = 'shield-tables';
|
118 |
-
if ( $
|
119 |
$enq[ Enqueue::JS ][] = 'shield-scans';
|
120 |
}
|
121 |
-
elseif ( $
|
122 |
$enq[ Enqueue::JS ][] = 'shield/ipanalyse';
|
123 |
}
|
124 |
|
125 |
-
if ( in_array( $
|
126 |
$enq[ Enqueue::JS ][] = 'bootstrap-datepicker';
|
127 |
$enq[ Enqueue::CSS ][] = 'bootstrap-datepicker';
|
128 |
}
|
18 |
|
19 |
protected function onModulesLoaded() {
|
20 |
$this->maybeRedirectToAdmin();
|
21 |
+
$this->maybeRedirectToOverview();
|
22 |
+
}
|
23 |
+
|
24 |
+
private function maybeRedirectToOverview() {
|
25 |
+
$req = Services::Request();
|
26 |
+
if ( $this->isThisModAdminPage() && empty( $req->query( 'inav' ) ) ) {
|
27 |
+
Services::Response()->redirect( $this->getCon()->getPluginUrl_DashboardHome() );
|
28 |
+
}
|
29 |
}
|
30 |
|
31 |
private function maybeRedirectToAdmin() {
|
32 |
$con = $this->getCon();
|
33 |
$activeFor = $con->getModule_Plugin()->getActivateLength();
|
34 |
if ( !Services::WpGeneral()->isAjax() && is_admin() && !$con->isModulePage() && $activeFor < 4 ) {
|
35 |
+
Services::Response()->redirect( $this->getCon()->getPluginUrl_DashboardHome() );
|
36 |
}
|
37 |
}
|
38 |
|
40 |
return add_query_arg( [ 'analyse_ip' => $ip ], $this->getUrl_SubInsightsPage( 'ips' ) );
|
41 |
}
|
42 |
|
43 |
+
public function getUrl_ScansResults() :string {
|
44 |
+
return $this->getUrl_SubInsightsPage( 'scans_results' );
|
45 |
+
}
|
46 |
+
|
47 |
+
public function getUrl_ScansRun() :string {
|
48 |
+
return $this->getUrl_SubInsightsPage( 'scans_run' );
|
49 |
+
}
|
50 |
+
|
51 |
public function getUrl_SubInsightsPage( string $subPage ) :string {
|
52 |
return add_query_arg(
|
53 |
[ 'inav' => sanitize_key( $subPage ) ],
|
63 |
|
64 |
public function getScriptLocalisations() :array {
|
65 |
$con = $this->getCon();
|
66 |
+
$modPlugin = $con->getModule_Plugin();
|
67 |
+
|
68 |
$locals = parent::getScriptLocalisations();
|
69 |
$locals[] = [
|
70 |
'plugin',
|
71 |
'icwp_wpsf_vars_insights',
|
72 |
[
|
73 |
'strings' => [
|
74 |
+
'select_action' => __( 'Please select an action to perform.', 'wp-simple-firewall' ),
|
75 |
+
'are_you_sure' => __( 'Are you sure?', 'wp-simple-firewall' ),
|
|
|
|
|
76 |
],
|
77 |
]
|
78 |
];
|
79 |
+
|
80 |
$locals[] = [
|
81 |
$con->prefix( 'ip_detect' ),
|
82 |
'icwp_wpsf_vars_ipdetect',
|
83 |
+
[ 'ajax' => $modPlugin->getAjaxActionData( 'ipdetect' ) ]
|
84 |
+
];
|
85 |
+
|
86 |
+
$locals[] = [
|
87 |
+
'shield/navigation',
|
88 |
+
'shield_vars_navigation',
|
89 |
+
[
|
90 |
+
'ajax' => [
|
91 |
+
'dynamic_load' => $this->getAjaxActionData( 'dynamic_load' )
|
92 |
+
]
|
93 |
+
]
|
94 |
];
|
95 |
|
96 |
return $locals;
|
103 |
];
|
104 |
|
105 |
$con = $this->getCon();
|
106 |
+
$inav = Services::Request()->query( 'inav' );
|
107 |
+
if ( empty( $inav ) ) {
|
108 |
+
$inav = 'overview';
|
109 |
+
}
|
110 |
|
111 |
+
if ( $con->getIsPage_PluginAdmin() && !empty( $inav ) ) {
|
112 |
+
switch ( $inav ) {
|
113 |
|
114 |
case 'importexport':
|
115 |
$enq[ Enqueue::JS ][] = 'shield/import';
|
137 |
break;
|
138 |
|
139 |
case 'notes':
|
140 |
+
case 'scans_results':
|
141 |
+
case 'scans_run':
|
142 |
case 'audit':
|
143 |
case 'traffic':
|
144 |
case 'ips':
|
145 |
case 'debug':
|
146 |
case 'users':
|
147 |
+
case 'stats':
|
148 |
|
149 |
$enq[ Enqueue::JS ][] = 'shield-tables';
|
150 |
+
if ( in_array( $inav, [ 'scans_results', 'scans_run' ] ) ) {
|
151 |
$enq[ Enqueue::JS ][] = 'shield-scans';
|
152 |
}
|
153 |
+
elseif ( $inav == 'ips' ) {
|
154 |
$enq[ Enqueue::JS ][] = 'shield/ipanalyse';
|
155 |
}
|
156 |
|
157 |
+
if ( in_array( $inav, [ 'audit', 'traffic' ] ) ) {
|
158 |
$enq[ Enqueue::JS ][] = 'bootstrap-datepicker';
|
159 |
$enq[ Enqueue::CSS ][] = 'bootstrap-datepicker';
|
160 |
}
|
src/lib/src/Modules/Insights/UI.php
CHANGED
@@ -52,12 +52,12 @@ class UI extends BaseShield\UI {
|
|
52 |
$mod = $this->getMod();
|
53 |
$req = Services::Request();
|
54 |
|
55 |
-
$
|
56 |
$subNavSection = $req->query( 'subnav' );
|
57 |
|
58 |
$modPlugin = $con->getModule_Plugin();
|
59 |
|
60 |
-
switch ( $
|
61 |
|
62 |
case 'audit':
|
63 |
$modAudit = $con->getModule_AuditTrail();
|
@@ -67,28 +67,6 @@ class UI extends BaseShield\UI {
|
|
67 |
'content' => [
|
68 |
'table_audit' => $auditUI->renderAuditTrailTable(),
|
69 |
],
|
70 |
-
'vars' => [
|
71 |
-
'related_hrefs' => [
|
72 |
-
[
|
73 |
-
'href' => $con->getModule_AuditTrail()->getUrl_AdminPage(),
|
74 |
-
'title' => __( 'Audit Trail Settings', 'wp-simple-firewall' ),
|
75 |
-
],
|
76 |
-
[
|
77 |
-
'href' => 'https://shsec.io/audittrailglossary',
|
78 |
-
'title' => __( 'Audit Trail Glossary', 'wp-simple-firewall' ),
|
79 |
-
'new' => true,
|
80 |
-
],
|
81 |
-
[
|
82 |
-
'href' => $mod->getUrl_SubInsightsPage( 'traffic' ),
|
83 |
-
'title' => __( 'Traffic Log', 'wp-simple-firewall' ),
|
84 |
-
],
|
85 |
-
[
|
86 |
-
'href' => $modAudit->createFileDownloadLink( 'db_audit' ),
|
87 |
-
'classes' => [ 'shield_file_download' ],
|
88 |
-
'title' => sprintf( __( 'Download (as %s)', 'wp-simple-firewall' ), 'CSV' ),
|
89 |
-
],
|
90 |
-
]
|
91 |
-
]
|
92 |
];
|
93 |
break;
|
94 |
|
@@ -100,23 +78,6 @@ class UI extends BaseShield\UI {
|
|
100 |
'content' => [
|
101 |
'table_traffic' => $trafficUI->renderTrafficTable(),
|
102 |
],
|
103 |
-
'vars' => [
|
104 |
-
'related_hrefs' => [
|
105 |
-
[
|
106 |
-
'href' => $con->getModule_Traffic()->getUrl_AdminPage(),
|
107 |
-
'title' => __( 'Traffic Settings', 'wp-simple-firewall' ),
|
108 |
-
],
|
109 |
-
[
|
110 |
-
'href' => $mod->getUrl_SubInsightsPage( 'audit' ),
|
111 |
-
'title' => __( 'Audit Trail', 'wp-simple-firewall' ),
|
112 |
-
],
|
113 |
-
[
|
114 |
-
'href' => $modTraffic->createFileDownloadLink( 'db_traffic' ),
|
115 |
-
'classes' => [ 'shield_file_download' ],
|
116 |
-
'title' => sprintf( __( 'Download (as %s)', 'wp-simple-firewall' ), 'CSV' ),
|
117 |
-
],
|
118 |
-
]
|
119 |
-
]
|
120 |
];
|
121 |
break;
|
122 |
|
@@ -176,7 +137,8 @@ class UI extends BaseShield\UI {
|
|
176 |
$data = $UIReporting->buildInsightsVars();
|
177 |
break;
|
178 |
|
179 |
-
case '
|
|
|
180 |
/** @var Shield\Modules\HackGuard\UI $UIHackGuard */
|
181 |
$UIHackGuard = $con->getModule_HackGuard()->getUIHandler();
|
182 |
$data = $UIHackGuard->buildInsightsVars();
|
@@ -186,6 +148,12 @@ class UI extends BaseShield\UI {
|
|
186 |
$data = $con->modules[ $subNavSection ]->getUIHandler()->getBaseDisplayData();
|
187 |
break;
|
188 |
|
|
|
|
|
|
|
|
|
|
|
|
|
189 |
case 'users':
|
190 |
/** @var Shield\Modules\UserManagement\UI $UIUsers */
|
191 |
$UIUsers = $con->modules[ 'user_management' ]->getUIHandler();
|
@@ -201,21 +169,23 @@ class UI extends BaseShield\UI {
|
|
201 |
}
|
202 |
|
203 |
$availablePages = [
|
204 |
-
'
|
205 |
-
'
|
206 |
-
'
|
207 |
-
'
|
208 |
-
'
|
209 |
-
'
|
210 |
-
'
|
211 |
-
'
|
212 |
-
'
|
213 |
-
'
|
214 |
-
'
|
215 |
-
'
|
216 |
-
'
|
217 |
-
'
|
218 |
-
'
|
|
|
|
|
219 |
];
|
220 |
|
221 |
$modsToSearch = array_filter(
|
@@ -225,7 +195,7 @@ class UI extends BaseShield\UI {
|
|
225 |
}
|
226 |
);
|
227 |
|
228 |
-
$pageTitle = $availablePages[ $
|
229 |
if ( !empty( $subNavSection ) ) {
|
230 |
$pageTitle = sprintf( '%s: %s',
|
231 |
__( 'Settings', 'wp-simple-firewall' ), $modsToSearch[ $subNavSection ][ 'name' ] );
|
@@ -236,17 +206,15 @@ class UI extends BaseShield\UI {
|
|
236 |
$this->getBaseDisplayData(),
|
237 |
[
|
238 |
'classes' => [
|
239 |
-
'page_container' => 'page-insights page-'.$
|
240 |
],
|
241 |
'flags' => [
|
242 |
-
'
|
243 |
-
'is_advanced' => $modPlugin->isShowAdvanced()
|
244 |
],
|
245 |
'hrefs' => [
|
246 |
-
'
|
247 |
-
'
|
248 |
-
'
|
249 |
-
'img_banner' => $con->urls->forImage( 'pluginlogo_banner-170x40.png' )
|
250 |
],
|
251 |
'strings' => [
|
252 |
'page_title' => $pageTitle
|
@@ -255,14 +223,22 @@ class UI extends BaseShield\UI {
|
|
255 |
'changelog_id' => $con->cfg->meta[ 'announcekit_changelog_id' ],
|
256 |
'mods' => $this->buildSelectData_ModuleSettings(),
|
257 |
'search_select' => $this->buildSelectData_OptionsSearch(),
|
258 |
-
'active_module_settings' => $subNavSection
|
|
|
|
|
|
|
259 |
],
|
260 |
],
|
261 |
$data
|
262 |
);
|
263 |
|
|
|
|
|
|
|
|
|
|
|
264 |
return $mod->renderTemplate(
|
265 |
-
sprintf( '/wpadmin_pages/insights/%s/index.twig', $
|
266 |
$data,
|
267 |
true
|
268 |
);
|
@@ -332,14 +308,14 @@ class UI extends BaseShield\UI {
|
|
332 |
|
333 |
private function printGoProFooter() {
|
334 |
$con = $this->getCon();
|
335 |
-
$nav = Services::Request()->query( 'inav', '
|
336 |
echo $this->getMod()->renderTemplate(
|
337 |
'snippets/go_pro_banner.twig',
|
338 |
[
|
339 |
'flags' => [
|
340 |
'show_promo' => $con->isModulePage()
|
341 |
&& !$con->isPremiumActive()
|
342 |
-
&& ( !in_array( $nav, [ '
|
343 |
],
|
344 |
'hrefs' => [
|
345 |
'go_pro' => 'https://shsec.io/shieldgoprofeature',
|
@@ -361,29 +337,4 @@ class UI extends BaseShield\UI {
|
|
361 |
);
|
362 |
}
|
363 |
}
|
364 |
-
|
365 |
-
private function printPluginDeactivateSurvey() {
|
366 |
-
if ( Services::WpPost()->isCurrentPage( 'plugins.php' ) ) {
|
367 |
-
|
368 |
-
$opts = [
|
369 |
-
'reason_confusing' => "It's too confusing",
|
370 |
-
'reason_expected' => "It's not what I expected",
|
371 |
-
'reason_accident' => "I downloaded it accidentally",
|
372 |
-
'reason_alternative' => "I'm already using an alternative",
|
373 |
-
'reason_trust' => "I don't trust the developer :(",
|
374 |
-
'reason_not_work' => "It doesn't work",
|
375 |
-
'reason_errors' => "I'm getting errors",
|
376 |
-
];
|
377 |
-
|
378 |
-
echo $this->getMod()->renderTemplate( 'snippets/plugin-deactivate-survey.php', [
|
379 |
-
'strings' => [
|
380 |
-
'editing_restricted' => __( 'Editing this option is currently restricted.', 'wp-simple-firewall' ),
|
381 |
-
],
|
382 |
-
'inputs' => [
|
383 |
-
'checkboxes' => Services::DataManipulation()->shuffleArray( $opts )
|
384 |
-
],
|
385 |
-
'js_snippets' => []
|
386 |
-
] );
|
387 |
-
}
|
388 |
-
}
|
389 |
}
|
52 |
$mod = $this->getMod();
|
53 |
$req = Services::Request();
|
54 |
|
55 |
+
$inav = $req->query( 'inav', 'overview' );
|
56 |
$subNavSection = $req->query( 'subnav' );
|
57 |
|
58 |
$modPlugin = $con->getModule_Plugin();
|
59 |
|
60 |
+
switch ( $inav ) {
|
61 |
|
62 |
case 'audit':
|
63 |
$modAudit = $con->getModule_AuditTrail();
|
67 |
'content' => [
|
68 |
'table_audit' => $auditUI->renderAuditTrailTable(),
|
69 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
];
|
71 |
break;
|
72 |
|
78 |
'content' => [
|
79 |
'table_traffic' => $trafficUI->renderTrafficTable(),
|
80 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
];
|
82 |
break;
|
83 |
|
137 |
$data = $UIReporting->buildInsightsVars();
|
138 |
break;
|
139 |
|
140 |
+
case 'scans_results':
|
141 |
+
case 'scans_run':
|
142 |
/** @var Shield\Modules\HackGuard\UI $UIHackGuard */
|
143 |
$UIHackGuard = $con->getModule_HackGuard()->getUIHandler();
|
144 |
$data = $UIHackGuard->buildInsightsVars();
|
148 |
$data = $con->modules[ $subNavSection ]->getUIHandler()->getBaseDisplayData();
|
149 |
break;
|
150 |
|
151 |
+
case 'stats':
|
152 |
+
/** @var Shield\Modules\Events\UI $UIEvents */
|
153 |
+
$UIEvents = $con->getModule_Events()->getUIHandler();
|
154 |
+
$data = $UIEvents->buildInsightsVars();
|
155 |
+
break;
|
156 |
+
|
157 |
case 'users':
|
158 |
/** @var Shield\Modules\UserManagement\UI $UIUsers */
|
159 |
$UIUsers = $con->modules[ 'user_management' ]->getUIHandler();
|
169 |
}
|
170 |
|
171 |
$availablePages = [
|
172 |
+
'stats' => __( 'Quick Stats', 'wp-simple-firewall' ),
|
173 |
+
'settings' => __( 'Plugin Settings', 'wp-simple-firewall' ),
|
174 |
+
'dashboard' => __( 'Dashboard', 'wp-simple-firewall' ),
|
175 |
+
'overview' => __( 'Security Overview', 'wp-simple-firewall' ),
|
176 |
+
'scans_results' => __( 'Scan Results', 'wp-simple-firewall' ),
|
177 |
+
'scans_run' => __( 'Run Scans', 'wp-simple-firewall' ),
|
178 |
+
'docs' => __( 'Docs', 'wp-simple-firewall' ),
|
179 |
+
'ips' => __( 'IP Management and Analysis', 'wp-simple-firewall' ),
|
180 |
+
'audit' => __( 'Audit Trail', 'wp-simple-firewall' ),
|
181 |
+
'traffic' => __( 'Traffic', 'wp-simple-firewall' ),
|
182 |
+
'notes' => __( 'Admin Notes', 'wp-simple-firewall' ),
|
183 |
+
'users' => __( 'User Sessions', 'wp-simple-firewall' ),
|
184 |
+
'license' => __( 'ShieldPRO', 'wp-simple-firewall' ),
|
185 |
+
'importexport' => __( 'Import / Export', 'wp-simple-firewall' ),
|
186 |
+
'reports' => __( 'Reports', 'wp-simple-firewall' ),
|
187 |
+
'debug' => __( 'Debug', 'wp-simple-firewall' ),
|
188 |
+
'free_trial' => __( 'Free Trial', 'wp-simple-firewall' ),
|
189 |
];
|
190 |
|
191 |
$modsToSearch = array_filter(
|
195 |
}
|
196 |
);
|
197 |
|
198 |
+
$pageTitle = $availablePages[ $inav ];
|
199 |
if ( !empty( $subNavSection ) ) {
|
200 |
$pageTitle = sprintf( '%s: %s',
|
201 |
__( 'Settings', 'wp-simple-firewall' ), $modsToSearch[ $subNavSection ][ 'name' ] );
|
206 |
$this->getBaseDisplayData(),
|
207 |
[
|
208 |
'classes' => [
|
209 |
+
'page_container' => 'page-insights page-'.$inav
|
210 |
],
|
211 |
'flags' => [
|
212 |
+
'is_advanced' => $modPlugin->isShowAdvanced()
|
|
|
213 |
],
|
214 |
'hrefs' => [
|
215 |
+
'go_pro' => 'https://shsec.io/shieldgoprofeature',
|
216 |
+
'nav_home' => $mod->getUrl_AdminPage(),
|
217 |
+
'img_banner' => $con->urls->forImage( 'pluginlogo_banner-170x40.png' )
|
|
|
218 |
],
|
219 |
'strings' => [
|
220 |
'page_title' => $pageTitle
|
223 |
'changelog_id' => $con->cfg->meta[ 'announcekit_changelog_id' ],
|
224 |
'mods' => $this->buildSelectData_ModuleSettings(),
|
225 |
'search_select' => $this->buildSelectData_OptionsSearch(),
|
226 |
+
'active_module_settings' => $subNavSection,
|
227 |
+
'navbar_menu' => ( new Lib\SideMenuBuilder() )
|
228 |
+
->setMod( $this->getMod() )
|
229 |
+
->build()
|
230 |
],
|
231 |
],
|
232 |
$data
|
233 |
);
|
234 |
|
235 |
+
$templateDir = $inav;
|
236 |
+
if ( strpos( $inav, 'scans_' ) === 0 ) {
|
237 |
+
$templateDir = implode( '/', explode( '_', $inav, 2 ) );
|
238 |
+
}
|
239 |
+
|
240 |
return $mod->renderTemplate(
|
241 |
+
sprintf( '/wpadmin_pages/insights/%s/index.twig', $templateDir ),
|
242 |
$data,
|
243 |
true
|
244 |
);
|
308 |
|
309 |
private function printGoProFooter() {
|
310 |
$con = $this->getCon();
|
311 |
+
$nav = Services::Request()->query( 'inav', 'overview' );
|
312 |
echo $this->getMod()->renderTemplate(
|
313 |
'snippets/go_pro_banner.twig',
|
314 |
[
|
315 |
'flags' => [
|
316 |
'show_promo' => $con->isModulePage()
|
317 |
&& !$con->isPremiumActive()
|
318 |
+
&& ( !in_array( $nav, [ 'scans_results', 'scans_run' ] ) ),
|
319 |
],
|
320 |
'hrefs' => [
|
321 |
'go_pro' => 'https://shsec.io/shieldgoprofeature',
|
337 |
);
|
338 |
}
|
339 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
340 |
}
|
src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/ExtensionSettingsPage.php
CHANGED
@@ -20,8 +20,8 @@ class ExtensionSettingsPage {
|
|
20 |
|
21 |
if ( 'mainwp_page_'.$this->getCon()->mwpVO->extension->page === $hook ) {
|
22 |
|
23 |
-
$enqueues[ Enqueue::JS ][] = 'shield/mainwp
|
24 |
-
$enqueues[ Enqueue::CSS ][] = 'mainwp
|
25 |
|
26 |
// $handle = 'semantic-ui-datatables-select';
|
27 |
// wp_register_script(
|
20 |
|
21 |
if ( 'mainwp_page_'.$this->getCon()->mwpVO->extension->page === $hook ) {
|
22 |
|
23 |
+
$enqueues[ Enqueue::JS ][] = 'shield/mainwp';
|
24 |
+
$enqueues[ Enqueue::CSS ][] = 'shield/mainwp';
|
25 |
|
26 |
// $handle = 'semantic-ui-datatables-select';
|
27 |
// wp_register_script(
|
src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/PageRender/SitesList.php
CHANGED
@@ -132,7 +132,7 @@ class SitesList extends BaseRender {
|
|
132 |
return str_replace(
|
133 |
$WP->getAdminUrl(),
|
134 |
'',
|
135 |
-
$this->getCon()->getModule_Insights()->
|
136 |
);
|
137 |
}
|
138 |
|
132 |
return str_replace(
|
133 |
$WP->getAdminUrl(),
|
134 |
'',
|
135 |
+
$this->getCon()->getModule_Insights()->getUrl_ScansResults()
|
136 |
);
|
137 |
}
|
138 |
|
src/lib/src/Modules/Integrations/Strings.php
CHANGED
@@ -64,6 +64,7 @@ class Strings extends Base\Strings {
|
|
64 |
$name = __( 'MainWP Integration', 'wp-simple-firewall' );
|
65 |
$summary = __( "Turn-On Shield's Built-In Extension For MainWP Server And Client Installations", 'wp-simple-firewall' );
|
66 |
$desc = [
|
|
|
67 |
__( 'Easily integrate Shield Security to help you manage your site security from within MainWP.', 'wp-simple-firewall' ),
|
68 |
__( "You don't need to install a separate extension for MainWP.", 'wp-simple-firewall' ),
|
69 |
sprintf( '%s: %s', __( 'Important', 'wp-simple-firewall' ),
|
64 |
$name = __( 'MainWP Integration', 'wp-simple-firewall' );
|
65 |
$summary = __( "Turn-On Shield's Built-In Extension For MainWP Server And Client Installations", 'wp-simple-firewall' );
|
66 |
$desc = [
|
67 |
+
__( 'This is a ShieldPRO-only feature.', 'wp-simple-firewall' ),
|
68 |
__( 'Easily integrate Shield Security to help you manage your site security from within MainWP.', 'wp-simple-firewall' ),
|
69 |
__( "You don't need to install a separate extension for MainWP.", 'wp-simple-firewall' ),
|
70 |
sprintf( '%s: %s', __( 'Important', 'wp-simple-firewall' ),
|
src/lib/src/Modules/License/UI.php
CHANGED
@@ -56,7 +56,6 @@ class UI extends BaseShield\UI {
|
|
56 |
'license_table' => $aLicenseTableVars,
|
57 |
'activation_url' => $WP->getHomeUrl(),
|
58 |
'error' => $mod->getLastErrors( true ),
|
59 |
-
'related_hrefs' => $this->getSettingsRelatedLinks()
|
60 |
],
|
61 |
'inputs' => [
|
62 |
'license_key' => [
|
@@ -90,26 +89,4 @@ class UI extends BaseShield\UI {
|
|
90 |
$mod = $this->getMod();
|
91 |
return $mod->getLicenseHandler()->hasValidWorkingLicense();
|
92 |
}
|
93 |
-
|
94 |
-
protected function getSettingsRelatedLinks() :array {
|
95 |
-
$modInsights = $this->getCon()->getModule_Insights();
|
96 |
-
$links = [];
|
97 |
-
if ( !$this->getCon()->isPremiumActive() ) {
|
98 |
-
$links[] = [
|
99 |
-
'href' => $modInsights->getUrl_SubInsightsPage( 'free_trial' ),
|
100 |
-
'title' => __( 'Free Trial', 'wp-simple-firewall' ),
|
101 |
-
];
|
102 |
-
}
|
103 |
-
$links[] = [
|
104 |
-
'href' => 'https://shsec.io/c5',
|
105 |
-
'title' => __( 'License Activation', 'wp-simple-firewall' ),
|
106 |
-
'new' => true,
|
107 |
-
];
|
108 |
-
$links[] = [
|
109 |
-
'href' => 'https://shsec.io/gp',
|
110 |
-
'title' => __( 'ShieldPRO Features', 'wp-simple-firewall' ),
|
111 |
-
'new' => true,
|
112 |
-
];
|
113 |
-
return $links;
|
114 |
-
}
|
115 |
}
|
56 |
'license_table' => $aLicenseTableVars,
|
57 |
'activation_url' => $WP->getHomeUrl(),
|
58 |
'error' => $mod->getLastErrors( true ),
|
|
|
59 |
],
|
60 |
'inputs' => [
|
61 |
'license_key' => [
|
89 |
$mod = $this->getMod();
|
90 |
return $mod->getLicenseHandler()->hasValidWorkingLicense();
|
91 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
}
|
src/lib/src/Modules/LoginGuard/Lib/AntiBot/AntibotSetup.php
CHANGED
@@ -57,46 +57,46 @@ class AntibotSetup {
|
|
57 |
if ( !empty( $providers ) ) {
|
58 |
|
59 |
AntiBot\FormProviders\WordPress::SetProviders( $providers );
|
60 |
-
/** @var AntiBot\FormProviders\BaseFormProvider[] $
|
61 |
-
$
|
62 |
new AntiBot\FormProviders\WordPress()
|
63 |
];
|
64 |
|
65 |
if ( $this->getMod()->getIfSupport3rdParty() ) {
|
66 |
if ( @class_exists( 'BuddyPress' ) ) {
|
67 |
-
$
|
68 |
}
|
69 |
if ( @class_exists( 'Easy_Digital_Downloads' ) ) {
|
70 |
-
$
|
71 |
}
|
72 |
if ( @class_exists( 'LearnPress' ) ) {
|
73 |
-
$
|
74 |
}
|
75 |
if ( function_exists( 'mepr_autoloader' ) || @class_exists( 'MeprAccountCtrl' ) ) {
|
76 |
-
$
|
77 |
}
|
78 |
if ( function_exists( 'UM' ) && @class_exists( 'UM' ) && method_exists( 'UM', 'form' ) ) {
|
79 |
-
$
|
80 |
}
|
81 |
if ( @class_exists( 'Paid_Member_Subscriptions' ) && function_exists( 'pms_errors' ) ) {
|
82 |
-
$
|
83 |
}
|
84 |
if ( defined( 'PROFILE_BUILDER_VERSION' ) ) {
|
85 |
-
$
|
86 |
}
|
87 |
if ( @class_exists( 'WooCommerce' ) ) {
|
88 |
-
$
|
89 |
}
|
90 |
if ( defined( 'WPMEM_VERSION' ) && function_exists( 'wpmem_init' ) ) {
|
91 |
-
$
|
92 |
}
|
93 |
if ( false && @class_exists( 'UserRegistration' ) && @function_exists( 'UR' ) ) {
|
94 |
-
$
|
95 |
}
|
96 |
}
|
97 |
|
98 |
-
foreach ( $
|
99 |
-
$
|
100 |
}
|
101 |
}
|
102 |
}
|
57 |
if ( !empty( $providers ) ) {
|
58 |
|
59 |
AntiBot\FormProviders\WordPress::SetProviders( $providers );
|
60 |
+
/** @var AntiBot\FormProviders\BaseFormProvider[] $formProviders */
|
61 |
+
$formProviders = [
|
62 |
new AntiBot\FormProviders\WordPress()
|
63 |
];
|
64 |
|
65 |
if ( $this->getMod()->getIfSupport3rdParty() ) {
|
66 |
if ( @class_exists( 'BuddyPress' ) ) {
|
67 |
+
$formProviders[] = new AntiBot\FormProviders\BuddyPress();
|
68 |
}
|
69 |
if ( @class_exists( 'Easy_Digital_Downloads' ) ) {
|
70 |
+
$formProviders[] = new AntiBot\FormProviders\EasyDigitalDownloads();
|
71 |
}
|
72 |
if ( @class_exists( 'LearnPress' ) ) {
|
73 |
+
$formProviders[] = new AntiBot\FormProviders\LearnPress();
|
74 |
}
|
75 |
if ( function_exists( 'mepr_autoloader' ) || @class_exists( 'MeprAccountCtrl' ) ) {
|
76 |
+
$formProviders[] = new AntiBot\FormProviders\MemberPress();
|
77 |
}
|
78 |
if ( function_exists( 'UM' ) && @class_exists( 'UM' ) && method_exists( 'UM', 'form' ) ) {
|
79 |
+
$formProviders[] = new AntiBot\FormProviders\UltimateMember();
|
80 |
}
|
81 |
if ( @class_exists( 'Paid_Member_Subscriptions' ) && function_exists( 'pms_errors' ) ) {
|
82 |
+
$formProviders[] = new AntiBot\FormProviders\PaidMemberSubscriptions();
|
83 |
}
|
84 |
if ( defined( 'PROFILE_BUILDER_VERSION' ) ) {
|
85 |
+
$formProviders[] = new AntiBot\FormProviders\ProfileBuilder();
|
86 |
}
|
87 |
if ( @class_exists( 'WooCommerce' ) ) {
|
88 |
+
$formProviders[] = new AntiBot\FormProviders\WooCommerce();
|
89 |
}
|
90 |
if ( defined( 'WPMEM_VERSION' ) && function_exists( 'wpmem_init' ) ) {
|
91 |
+
$formProviders[] = new AntiBot\FormProviders\WPMembers();
|
92 |
}
|
93 |
if ( false && @class_exists( 'UserRegistration' ) && @function_exists( 'UR' ) ) {
|
94 |
+
$formProviders[] = new AntiBot\FormProviders\UserRegistration();
|
95 |
}
|
96 |
}
|
97 |
|
98 |
+
foreach ( $formProviders as $form ) {
|
99 |
+
$form->setMod( $mod )->run();
|
100 |
}
|
101 |
}
|
102 |
}
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/MfaController.php
CHANGED
@@ -2,6 +2,7 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Session\Update;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
@@ -12,6 +13,7 @@ class MfaController {
|
|
12 |
|
13 |
use Shield\Modules\ModConsumer;
|
14 |
use Shield\Utilities\Consumer\WpLoginCapture;
|
|
|
15 |
|
16 |
/**
|
17 |
* @var Provider\BaseProvider[]
|
@@ -23,10 +25,11 @@ class MfaController {
|
|
23 |
*/
|
24 |
private $oLoginIntentPageHandler;
|
25 |
|
26 |
-
|
27 |
add_action( 'init', [ $this, 'onWpInit' ], 10, 2 );
|
28 |
add_action( 'wp_loaded', [ $this, 'onWpLoaded' ], 10, 2 );
|
29 |
$this->setupLoginCaptureHooks();
|
|
|
30 |
}
|
31 |
|
32 |
public function onWpInit() {
|
@@ -71,6 +74,49 @@ class MfaController {
|
|
71 |
}
|
72 |
}
|
73 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
private function assessLoginIntent( \WP_User $user ) {
|
75 |
if ( $this->getLoginIntentExpiresAt() > 0 ) {
|
76 |
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor;
|
4 |
|
5 |
+
use FernleafSystems\Utilities\Logic\ExecOnce;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Session\Update;
|
8 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
13 |
|
14 |
use Shield\Modules\ModConsumer;
|
15 |
use Shield\Utilities\Consumer\WpLoginCapture;
|
16 |
+
use ExecOnce;
|
17 |
|
18 |
/**
|
19 |
* @var Provider\BaseProvider[]
|
25 |
*/
|
26 |
private $oLoginIntentPageHandler;
|
27 |
|
28 |
+
protected function run() {
|
29 |
add_action( 'init', [ $this, 'onWpInit' ], 10, 2 );
|
30 |
add_action( 'wp_loaded', [ $this, 'onWpLoaded' ], 10, 2 );
|
31 |
$this->setupLoginCaptureHooks();
|
32 |
+
$this->handleLoginLink();
|
33 |
}
|
34 |
|
35 |
public function onWpInit() {
|
74 |
}
|
75 |
}
|
76 |
|
77 |
+
private function handleLoginLink() {
|
78 |
+
add_action( $this->getCon()->prefix( 'shield_nonce_action' ), function ( string $action ) {
|
79 |
+
if ( strpos( $action, '2fa_verify' ) === 0 ) {
|
80 |
+
try {
|
81 |
+
$this->processEmail2faLink();
|
82 |
+
}
|
83 |
+
catch ( \Exception $e ) {
|
84 |
+
wp_die( $e->getMessage() );
|
85 |
+
}
|
86 |
+
}
|
87 |
+
} );
|
88 |
+
}
|
89 |
+
|
90 |
+
private function processEmail2faLink() {
|
91 |
+
$req = Services::Request();
|
92 |
+
$user = sanitize_user( $req->query( 'user' ) );
|
93 |
+
if ( empty( $user ) ) {
|
94 |
+
throw new \Exception( 'Not valid data.' );
|
95 |
+
}
|
96 |
+
$user = Services::WpUsers()->getUserByUsername( $user );
|
97 |
+
if ( !$user instanceof \WP_User ) {
|
98 |
+
throw new \Exception( 'Not valid data.' );
|
99 |
+
}
|
100 |
+
$providers = $this->getProvidersForUser( $user, true );
|
101 |
+
if ( !isset( $providers[ Provider\Email::SLUG ] ) ) {
|
102 |
+
throw new \Exception( 'Not a support provider' );
|
103 |
+
}
|
104 |
+
if ( !$providers[ Provider\Email::SLUG ]->validateLoginIntent( $user ) ) {
|
105 |
+
throw new \Exception( 'Login validation failed.' );
|
106 |
+
}
|
107 |
+
$providers[ Provider\Email::SLUG ]->postSuccessActions( $user );
|
108 |
+
if ( (int)$user->ID !== (int)Services::WpUsers()->getCurrentWpUserId() ) {
|
109 |
+
throw new \Exception( 'Action completed successfully. Please refresh your browser where you logged-in.' );
|
110 |
+
}
|
111 |
+
|
112 |
+
if ( $req->query( 'redirect_to' ) ) {
|
113 |
+
Services::Response()->redirect( $req->query( 'redirect_to' ) );
|
114 |
+
}
|
115 |
+
else {
|
116 |
+
Services::Response()->redirectToAdmin();
|
117 |
+
}
|
118 |
+
}
|
119 |
+
|
120 |
private function assessLoginIntent( \WP_User $user ) {
|
121 |
if ( $this->getLoginIntentExpiresAt() > 0 ) {
|
122 |
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/Email.php
CHANGED
@@ -149,7 +149,8 @@ class Email extends BaseProvider {
|
|
149 |
'code' => $code
|
150 |
],
|
151 |
'hrefs' => [
|
152 |
-
'login_link' => 'https://shsec.io/96'
|
|
|
153 |
],
|
154 |
'strings' => [
|
155 |
'someone' => __( 'Someone attempted to login into this WordPress site using your account.', 'wp-simple-firewall' ),
|
@@ -223,6 +224,22 @@ class Email extends BaseProvider {
|
|
223 |
&& ( $this->isEnforced( $user ) || $opts->isEnabledEmailAuthAnyUserSet() );
|
224 |
}
|
225 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
226 |
/**
|
227 |
* @param \WP_User $user
|
228 |
* @return string
|
149 |
'code' => $code
|
150 |
],
|
151 |
'hrefs' => [
|
152 |
+
'login_link' => 'https://shsec.io/96',
|
153 |
+
'verify_2fa' => $this->genLoginLink( $user, $code )
|
154 |
],
|
155 |
'strings' => [
|
156 |
'someone' => __( 'Someone attempted to login into this WordPress site using your account.', 'wp-simple-firewall' ),
|
224 |
&& ( $this->isEnforced( $user ) || $opts->isEnabledEmailAuthAnyUserSet() );
|
225 |
}
|
226 |
|
227 |
+
private function genLoginLink( \WP_User $user, string $otp ) :string {
|
228 |
+
/** @var LoginGuard\Options $opts */
|
229 |
+
$opts = $this->getOptions();
|
230 |
+
$action = uniqid( '2fa_verify' );
|
231 |
+
return add_query_arg(
|
232 |
+
[
|
233 |
+
'user' => $user->user_login,
|
234 |
+
$this->getLoginFormParameter() => $otp,
|
235 |
+
'shield_nonce_action' => $action,
|
236 |
+
'shield_nonce' => $this->getCon()
|
237 |
+
->nonce_handler->create( $action, $opts->getLoginIntentMinutes()*60 ),
|
238 |
+
],
|
239 |
+
Services::WpGeneral()->getHomeUrl()
|
240 |
+
);
|
241 |
+
}
|
242 |
+
|
243 |
/**
|
244 |
* @param \WP_User $user
|
245 |
* @return string
|
src/lib/src/Modules/LoginGuard/Processor.php
CHANGED
@@ -26,7 +26,7 @@ class Processor extends BaseShield\Processor {
|
|
26 |
$this->launchAntiBot();
|
27 |
}, -100 );
|
28 |
|
29 |
-
$mod->getLoginIntentController()->
|
30 |
}
|
31 |
}
|
32 |
|
26 |
$this->launchAntiBot();
|
27 |
}, -100 );
|
28 |
|
29 |
+
$mod->getLoginIntentController()->execute();
|
30 |
}
|
31 |
}
|
32 |
|
src/lib/src/Modules/Plugin/AjaxHandler.php
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
|
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
use FernleafSystems\Wordpress\Services\Utilities\Net\FindSourceFromIp;
|
@@ -43,10 +44,6 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
43 |
$response = $this->ajaxExec_SetPluginTrackingPerm();
|
44 |
break;
|
45 |
|
46 |
-
case 'send_deactivate_survey':
|
47 |
-
$response = $this->ajaxExec_SendDeactivateSurvey();
|
48 |
-
break;
|
49 |
-
|
50 |
case 'sgoptimizer_turnoff':
|
51 |
$response = $this->ajaxExec_TurnOffSiteGroundOptions();
|
52 |
break;
|
@@ -66,24 +63,6 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
66 |
return $response;
|
67 |
}
|
68 |
|
69 |
-
private function ajaxExec_SendDeactivateSurvey() :array {
|
70 |
-
/** @var ModCon $mod */
|
71 |
-
$mod = $this->getMod();
|
72 |
-
$results = [];
|
73 |
-
foreach ( $_POST as $sKey => $sValue ) {
|
74 |
-
if ( strpos( $sKey, 'reason_' ) === 0 ) {
|
75 |
-
$results[] = str_replace( 'reason_', '', $sKey ).': '.$sValue;
|
76 |
-
}
|
77 |
-
}
|
78 |
-
$mod->getEmailProcessor()
|
79 |
-
->send(
|
80 |
-
$mod->getSurveyEmail(),
|
81 |
-
'Shield Deactivation Survey',
|
82 |
-
implode( "\n<br/>", $results )
|
83 |
-
);
|
84 |
-
return [ 'success' => true ];
|
85 |
-
}
|
86 |
-
|
87 |
private function ajaxExec_PluginBadgeClose() :array {
|
88 |
/** @var ModCon $mod */
|
89 |
$mod = $this->getMod();
|
@@ -193,22 +172,22 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
193 |
|
194 |
private function ajaxExec_ImportFromSite() :array {
|
195 |
$success = false;
|
196 |
-
$
|
197 |
[
|
198 |
'confirm' => 'N'
|
199 |
],
|
200 |
-
|
201 |
);
|
202 |
|
203 |
// TODO: align with wizard AND combine with file upload errors
|
204 |
-
if ( $
|
205 |
$msg = __( 'Please check the box to confirm your intent to overwrite settings', 'wp-simple-firewall' );
|
206 |
}
|
207 |
else {
|
208 |
-
$sMasterSiteUrl = $
|
209 |
-
$sSecretKey = $
|
210 |
-
$bEnabledNetwork = $
|
211 |
-
$bDisableNetwork = $
|
212 |
$bNetwork = $bEnabledNetwork ? true : ( $bDisableNetwork ? false : null );
|
213 |
|
214 |
/** @var Shield\Databases\AdminNotes\Insert $oInserter */
|
@@ -234,7 +213,7 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
234 |
/** @var ModCon $mod */
|
235 |
$mod = $this->getMod();
|
236 |
$success = false;
|
237 |
-
$formParams =
|
238 |
|
239 |
$note = trim( $formParams[ 'admin_note' ] ?? '' );
|
240 |
if ( !$mod->getCanAdminNotes() ) {
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Lib\Request\FormParams;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
|
8 |
use FernleafSystems\Wordpress\Services\Services;
|
9 |
use FernleafSystems\Wordpress\Services\Utilities\Net\FindSourceFromIp;
|
44 |
$response = $this->ajaxExec_SetPluginTrackingPerm();
|
45 |
break;
|
46 |
|
|
|
|
|
|
|
|
|
47 |
case 'sgoptimizer_turnoff':
|
48 |
$response = $this->ajaxExec_TurnOffSiteGroundOptions();
|
49 |
break;
|
63 |
return $response;
|
64 |
}
|
65 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
private function ajaxExec_PluginBadgeClose() :array {
|
67 |
/** @var ModCon $mod */
|
68 |
$mod = $this->getMod();
|
172 |
|
173 |
private function ajaxExec_ImportFromSite() :array {
|
174 |
$success = false;
|
175 |
+
$formParams = array_merge(
|
176 |
[
|
177 |
'confirm' => 'N'
|
178 |
],
|
179 |
+
FormParams::Retrieve()
|
180 |
);
|
181 |
|
182 |
// TODO: align with wizard AND combine with file upload errors
|
183 |
+
if ( $formParams[ 'confirm' ] !== 'Y' ) {
|
184 |
$msg = __( 'Please check the box to confirm your intent to overwrite settings', 'wp-simple-firewall' );
|
185 |
}
|
186 |
else {
|
187 |
+
$sMasterSiteUrl = $formParams[ 'MasterSiteUrl' ];
|
188 |
+
$sSecretKey = $formParams[ 'MasterSiteSecretKey' ];
|
189 |
+
$bEnabledNetwork = $formParams[ 'ShieldNetwork' ] === 'Y';
|
190 |
+
$bDisableNetwork = $formParams[ 'ShieldNetwork' ] === 'N';
|
191 |
$bNetwork = $bEnabledNetwork ? true : ( $bDisableNetwork ? false : null );
|
192 |
|
193 |
/** @var Shield\Databases\AdminNotes\Insert $oInserter */
|
213 |
/** @var ModCon $mod */
|
214 |
$mod = $this->getMod();
|
215 |
$success = false;
|
216 |
+
$formParams = FormParams::Retrieve();
|
217 |
|
218 |
$note = trim( $formParams[ 'admin_note' ] ?? '' );
|
219 |
if ( !$mod->getCanAdminNotes() ) {
|
src/lib/src/Modules/Plugin/Insights/DashboardCards.php
CHANGED
@@ -56,7 +56,6 @@ class DashboardCards {
|
|
56 |
'c' => [
|
57 |
'title' => __( 'Shield Settings', 'wp-simple-firewall' ),
|
58 |
'img' => $con->urls->forImage( 'bootstrap/sliders.svg' ),
|
59 |
-
'introjs' => sprintf( __( "%s is a big plugin split into modules, and each with their own options - use these jump-off points to find the specific option you need.", 'wp-simple-firewall' ), $name ),
|
60 |
'paras' => [
|
61 |
sprintf( __( "%s settings are arranged into modules.", 'wp-simple-firewall' ), $name )
|
62 |
.' '.__( 'Choose the module you need from the dropdown.', 'wp-simple-firewall' )
|
@@ -113,7 +112,6 @@ class DashboardCards {
|
|
113 |
'overview' => [
|
114 |
'title' => __( 'Security Overview', 'wp-simple-firewall' ),
|
115 |
'img' => $con->urls->forImage( 'bootstrap/binoculars.svg' ),
|
116 |
-
'introjs' => sprintf( __( "Review your entire Shield Security configuration at a glance to see what's working and what's not.", 'wp-simple-firewall' ), $name ),
|
117 |
'paras' => [
|
118 |
sprintf( __( "Review your entire %s security configuration at a glance to see what's working and what's not.", 'wp-simple-firewall' ), $name ),
|
119 |
],
|
@@ -128,7 +126,6 @@ class DashboardCards {
|
|
128 |
'scans' => [
|
129 |
'title' => __( 'Scans and Protection', 'wp-simple-firewall' ),
|
130 |
'img' => $con->urls->forImage( 'bootstrap/shield-shaded.svg' ),
|
131 |
-
'introjs' => sprintf( __( "Run a %s scan at any time, or view the results from the latest scan.", 'wp-simple-firewall' ), $name ),
|
132 |
'paras' => [
|
133 |
sprintf( __( "Use %s Scans to automatically detect and repair intrusions on your site.", 'wp-simple-firewall' ), $name ),
|
134 |
sprintf( __( "%s scans WordPress core files, plugins, themes and will detect Malware (ShieldPRO).", 'wp-simple-firewall' ), $name ),
|
@@ -136,7 +133,7 @@ class DashboardCards {
|
|
136 |
'actions' => [
|
137 |
[
|
138 |
'text' => __( "Run Scans", 'wp-simple-firewall' ),
|
139 |
-
'href' => $modInsights->
|
140 |
],
|
141 |
[
|
142 |
'text' => __( "Scans & Hack Guard Settings", 'wp-simple-firewall' ),
|
@@ -195,7 +192,6 @@ class DashboardCards {
|
|
195 |
'ips' => [
|
196 |
'title' => __( 'IP Blocking and Bypass', 'wp-simple-firewall' ),
|
197 |
'img' => $con->urls->forImage( 'bootstrap/diagram-3.svg' ),
|
198 |
-
'introjs' => __( "Protection begins by detecting bad bots - Review and Analyse all visitor IPs that have an impact on your site.", 'wp-simple-firewall' ),
|
199 |
'paras' => [
|
200 |
__( "Shield automatically detects and blocks bad IP addresses based on your security settings.", 'wp-simple-firewall' ),
|
201 |
__( "The IP Analysis Tool shows you all information for a given IP as it relates to your site.", 'wp-simple-firewall' ),
|
@@ -215,7 +211,6 @@ class DashboardCards {
|
|
215 |
'audit_trail' => [
|
216 |
'title' => __( 'Audit Trail', 'wp-simple-firewall' ),
|
217 |
'img' => $con->urls->forImage( 'bootstrap/person-lines-fill.svg' ),
|
218 |
-
'introjs' => __( "Track and review all important actions taken on your site - see the Who, What and When.", 'wp-simple-firewall' ),
|
219 |
'paras' => [
|
220 |
__( "Provides in-depth logging for all major WordPress events.", 'wp-simple-firewall' ),
|
221 |
],
|
@@ -234,7 +229,6 @@ class DashboardCards {
|
|
234 |
'traffic' => [
|
235 |
'title' => __( 'Traffic Logging', 'wp-simple-firewall' ),
|
236 |
'img' => $con->urls->forImage( 'bootstrap/stoplights.svg' ),
|
237 |
-
'introjs' => __( "Monitor and watch traffic as it hits your site.", 'wp-simple-firewall' ),
|
238 |
'paras' => [
|
239 |
__( "Use traffic logging to monitor visitor requests to your site.", 'wp-simple-firewall' ),
|
240 |
__( "Traffic Rate Limiting lets you throttle requests from any single visitor.", 'wp-simple-firewall' ),
|
@@ -254,7 +248,6 @@ class DashboardCards {
|
|
254 |
'users' => [
|
255 |
'title' => __( 'WordPress Users', 'wp-simple-firewall' ),
|
256 |
'img' => $con->urls->forImage( 'bootstrap/people.svg' ),
|
257 |
-
'introjs' => __( "Set user session timeouts and passwords requirements.", 'wp-simple-firewall' ),
|
258 |
'paras' => [
|
259 |
__( "Adds fine control over user sessions, account re-use, password strength and expiration, and user suspension.", 'wp-simple-firewall' ),
|
260 |
],
|
@@ -367,7 +360,6 @@ class DashboardCards {
|
|
367 |
|
368 |
'integrations' => [
|
369 |
'title' => __( '3rd Party Integrations', 'wp-simple-firewall' ),
|
370 |
-
'introjs' => __( "Integrate with your favourite plugins to block SPAM and manage Shield better.", 'wp-simple-firewall' ),
|
371 |
'img' => $con->urls->forImage( 'bootstrap/link-45deg.svg' ),
|
372 |
'paras' => [
|
373 |
__( "Shield integrates with 3rd party plugins and services.", 'wp-simple-firewall' ),
|
56 |
'c' => [
|
57 |
'title' => __( 'Shield Settings', 'wp-simple-firewall' ),
|
58 |
'img' => $con->urls->forImage( 'bootstrap/sliders.svg' ),
|
|
|
59 |
'paras' => [
|
60 |
sprintf( __( "%s settings are arranged into modules.", 'wp-simple-firewall' ), $name )
|
61 |
.' '.__( 'Choose the module you need from the dropdown.', 'wp-simple-firewall' )
|
112 |
'overview' => [
|
113 |
'title' => __( 'Security Overview', 'wp-simple-firewall' ),
|
114 |
'img' => $con->urls->forImage( 'bootstrap/binoculars.svg' ),
|
|
|
115 |
'paras' => [
|
116 |
sprintf( __( "Review your entire %s security configuration at a glance to see what's working and what's not.", 'wp-simple-firewall' ), $name ),
|
117 |
],
|
126 |
'scans' => [
|
127 |
'title' => __( 'Scans and Protection', 'wp-simple-firewall' ),
|
128 |
'img' => $con->urls->forImage( 'bootstrap/shield-shaded.svg' ),
|
|
|
129 |
'paras' => [
|
130 |
sprintf( __( "Use %s Scans to automatically detect and repair intrusions on your site.", 'wp-simple-firewall' ), $name ),
|
131 |
sprintf( __( "%s scans WordPress core files, plugins, themes and will detect Malware (ShieldPRO).", 'wp-simple-firewall' ), $name ),
|
133 |
'actions' => [
|
134 |
[
|
135 |
'text' => __( "Run Scans", 'wp-simple-firewall' ),
|
136 |
+
'href' => $modInsights->getUrl_ScansResults(),
|
137 |
],
|
138 |
[
|
139 |
'text' => __( "Scans & Hack Guard Settings", 'wp-simple-firewall' ),
|
192 |
'ips' => [
|
193 |
'title' => __( 'IP Blocking and Bypass', 'wp-simple-firewall' ),
|
194 |
'img' => $con->urls->forImage( 'bootstrap/diagram-3.svg' ),
|
|
|
195 |
'paras' => [
|
196 |
__( "Shield automatically detects and blocks bad IP addresses based on your security settings.", 'wp-simple-firewall' ),
|
197 |
__( "The IP Analysis Tool shows you all information for a given IP as it relates to your site.", 'wp-simple-firewall' ),
|
211 |
'audit_trail' => [
|
212 |
'title' => __( 'Audit Trail', 'wp-simple-firewall' ),
|
213 |
'img' => $con->urls->forImage( 'bootstrap/person-lines-fill.svg' ),
|
|
|
214 |
'paras' => [
|
215 |
__( "Provides in-depth logging for all major WordPress events.", 'wp-simple-firewall' ),
|
216 |
],
|
229 |
'traffic' => [
|
230 |
'title' => __( 'Traffic Logging', 'wp-simple-firewall' ),
|
231 |
'img' => $con->urls->forImage( 'bootstrap/stoplights.svg' ),
|
|
|
232 |
'paras' => [
|
233 |
__( "Use traffic logging to monitor visitor requests to your site.", 'wp-simple-firewall' ),
|
234 |
__( "Traffic Rate Limiting lets you throttle requests from any single visitor.", 'wp-simple-firewall' ),
|
248 |
'users' => [
|
249 |
'title' => __( 'WordPress Users', 'wp-simple-firewall' ),
|
250 |
'img' => $con->urls->forImage( 'bootstrap/people.svg' ),
|
|
|
251 |
'paras' => [
|
252 |
__( "Adds fine control over user sessions, account re-use, password strength and expiration, and user suspension.", 'wp-simple-firewall' ),
|
253 |
],
|
360 |
|
361 |
'integrations' => [
|
362 |
'title' => __( '3rd Party Integrations', 'wp-simple-firewall' ),
|
|
|
363 |
'img' => $con->urls->forImage( 'bootstrap/link-45deg.svg' ),
|
364 |
'paras' => [
|
365 |
__( "Shield integrates with 3rd party plugins and services.", 'wp-simple-firewall' ),
|
src/lib/src/Modules/Plugin/Lib/Debug/Collate.php
CHANGED
@@ -218,15 +218,15 @@ class Collate {
|
|
218 |
$licPing->lookup_url_stub = $con->getModule_License()->getOptions()->getDef( 'license_store_url_api' );
|
219 |
$data[ 'Ping License Server' ] = $licPing->ping() ? 'Yes' : 'No';
|
220 |
|
221 |
-
$data[ 'Write TMP/Cache DIR' ] = $con->hasCacheDir() ?'Yes: '.$con->getPluginCachePath() : 'No'
|
222 |
|
223 |
return $data;
|
224 |
}
|
225 |
|
226 |
private function getShieldSummary() :array {
|
227 |
-
$
|
228 |
-
$oModLicense = $
|
229 |
-
$oModPlugin = $
|
230 |
$oWpHashes = $oModLicense->getWpHashesTokenManager();
|
231 |
|
232 |
$nPrevAttempt = $oWpHashes->getPreviousAttemptAt();
|
@@ -241,10 +241,12 @@ class Collate {
|
|
241 |
}
|
242 |
|
243 |
$aD = [
|
244 |
-
'Version' => $
|
245 |
-
'PRO' => $
|
246 |
'WP Hashes Token' => ( $oWpHashes->hasToken() ? $oWpHashes->getToken() : '' ).' ('.$sPrev.')',
|
247 |
-
'Security Admin Enabled' => $
|
|
|
|
|
248 |
];
|
249 |
|
250 |
/** @var Options $oOptsIP */
|
218 |
$licPing->lookup_url_stub = $con->getModule_License()->getOptions()->getDef( 'license_store_url_api' );
|
219 |
$data[ 'Ping License Server' ] = $licPing->ping() ? 'Yes' : 'No';
|
220 |
|
221 |
+
$data[ 'Write TMP/Cache DIR' ] = $con->hasCacheDir() ? 'Yes: '.$con->getPluginCachePath() : 'No';
|
222 |
|
223 |
return $data;
|
224 |
}
|
225 |
|
226 |
private function getShieldSummary() :array {
|
227 |
+
$con = $this->getCon();
|
228 |
+
$oModLicense = $con->getModule_License();
|
229 |
+
$oModPlugin = $con->getModule_Plugin();
|
230 |
$oWpHashes = $oModLicense->getWpHashesTokenManager();
|
231 |
|
232 |
$nPrevAttempt = $oWpHashes->getPreviousAttemptAt();
|
241 |
}
|
242 |
|
243 |
$aD = [
|
244 |
+
'Version' => $con->getVersion(),
|
245 |
+
'PRO' => $con->isPremiumActive() ? 'Yes' : 'No',
|
246 |
'WP Hashes Token' => ( $oWpHashes->hasToken() ? $oWpHashes->getToken() : '' ).' ('.$sPrev.')',
|
247 |
+
'Security Admin Enabled' => $con->getModule_SecAdmin()
|
248 |
+
->getSecurityAdminController()
|
249 |
+
->isEnabledSecAdmin() ? 'Yes' : 'No',
|
250 |
];
|
251 |
|
252 |
/** @var Options $oOptsIP */
|
src/lib/src/Modules/Plugin/Lib/ImportExport/ImportExportController.php
CHANGED
@@ -116,12 +116,6 @@ class ImportExportController {
|
|
116 |
'vars' => [
|
117 |
'file_upload_nonce' => $mod->getNonceActionData( 'import_file_upload' ),
|
118 |
'form_action' => $mod->getUrl_AdminPage(),
|
119 |
-
'related_hrefs' => [
|
120 |
-
[
|
121 |
-
'href' => $mod->getUrl_DirectLinkToSection( 'section_importexport' ),
|
122 |
-
'title' => __( 'Import/Export Settings', 'wp-simple-firewall' ),
|
123 |
-
]
|
124 |
-
]
|
125 |
],
|
126 |
'ajax' => [
|
127 |
'import_from_site' => $mod->getAjaxActionData( 'import_from_site', true ),
|
@@ -146,30 +140,28 @@ class ImportExportController {
|
|
146 |
'title_download_file' => __( 'Download Options Export File', 'wp-simple-firewall' ),
|
147 |
'subtitle_download_file' => __( 'Use this file to copy options from this site into another site', 'wp-simple-firewall' ),
|
148 |
|
149 |
-
'subtitle_import_site'
|
150 |
-
'master_site_url'
|
151 |
-
'remember_include'
|
152 |
__( 'Remember to include %s or %s', 'wp-simple-firewall' ),
|
153 |
'<code>https://</code>',
|
154 |
'<code>http://</code>'
|
155 |
),
|
156 |
-
'secret_key'
|
157 |
-
'master_site_key'
|
158 |
-
'create_network'
|
159 |
-
'key_found_under'
|
160 |
ucwords( sprintf( '%s > %s > %s ', __( 'General Settings', 'wp-simple-firewall' ), __( 'Import/Export', 'wp-simple-firewall' ), __( 'Secret Key', 'wp-simple-firewall' ) ) )
|
161 |
),
|
162 |
-
'turn_on'
|
163 |
-
'turn_off'
|
164 |
-
'no_change'
|
165 |
-
'network_explain'
|
166 |
__( 'Checking this option on will link this site to Master site.', 'wp-simple-firewall' ),
|
167 |
__( 'Options will be automatically imported from the Master site each night', 'wp-simple-firewall' ),
|
168 |
__( 'When you adjust options on the Master site, they will be reflected in this site after the automatic import', 'wp-simple-firewall' ),
|
169 |
],
|
170 |
-
'import_options'
|
171 |
-
'downloading_please_wait' => __( 'Downloading file, please wait...', 'wp-simple-firewall' ),
|
172 |
-
'problem_downloading_file' => __( 'There was a problem downloading the file.', 'wp-simple-firewall' ),
|
173 |
]
|
174 |
];
|
175 |
}
|
116 |
'vars' => [
|
117 |
'file_upload_nonce' => $mod->getNonceActionData( 'import_file_upload' ),
|
118 |
'form_action' => $mod->getUrl_AdminPage(),
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
],
|
120 |
'ajax' => [
|
121 |
'import_from_site' => $mod->getAjaxActionData( 'import_from_site', true ),
|
140 |
'title_download_file' => __( 'Download Options Export File', 'wp-simple-firewall' ),
|
141 |
'subtitle_download_file' => __( 'Use this file to copy options from this site into another site', 'wp-simple-firewall' ),
|
142 |
|
143 |
+
'subtitle_import_site' => __( 'Import options directly from another site', 'wp-simple-firewall' ),
|
144 |
+
'master_site_url' => __( 'Master Site URL', 'wp-simple-firewall' ),
|
145 |
+
'remember_include' => sprintf(
|
146 |
__( 'Remember to include %s or %s', 'wp-simple-firewall' ),
|
147 |
'<code>https://</code>',
|
148 |
'<code>http://</code>'
|
149 |
),
|
150 |
+
'secret_key' => __( 'Secret Key', 'wp-simple-firewall' ),
|
151 |
+
'master_site_key' => __( 'Master Site Secret Key', 'wp-simple-firewall' ),
|
152 |
+
'create_network' => __( 'Create Shield Network', 'wp-simple-firewall' ),
|
153 |
+
'key_found_under' => sprintf( __( 'The secret key is found in: %s', 'wp-simple-firewall' ),
|
154 |
ucwords( sprintf( '%s > %s > %s ', __( 'General Settings', 'wp-simple-firewall' ), __( 'Import/Export', 'wp-simple-firewall' ), __( 'Secret Key', 'wp-simple-firewall' ) ) )
|
155 |
),
|
156 |
+
'turn_on' => __( 'Turn On', 'wp-simple-firewall' ),
|
157 |
+
'turn_off' => __( 'Turn Off', 'wp-simple-firewall' ),
|
158 |
+
'no_change' => __( 'No Change', 'wp-simple-firewall' ),
|
159 |
+
'network_explain' => [
|
160 |
__( 'Checking this option on will link this site to Master site.', 'wp-simple-firewall' ),
|
161 |
__( 'Options will be automatically imported from the Master site each night', 'wp-simple-firewall' ),
|
162 |
__( 'When you adjust options on the Master site, they will be reflected in this site after the automatic import', 'wp-simple-firewall' ),
|
163 |
],
|
164 |
+
'import_options' => __( 'Import Options', 'wp-simple-firewall' ),
|
|
|
|
|
165 |
]
|
166 |
];
|
167 |
}
|
src/lib/src/Modules/Plugin/Lib/ImportExport/Options/BuildTransferableOptions.php
CHANGED
@@ -12,11 +12,11 @@ class BuildTransferableOptions {
|
|
12 |
* @return mixed[]
|
13 |
*/
|
14 |
public function build() {
|
15 |
-
$
|
16 |
return array_merge(
|
17 |
-
array_fill_keys( $
|
18 |
-
array_fill_keys( array_keys( $
|
19 |
-
array_fill_keys( $
|
20 |
);
|
21 |
}
|
22 |
}
|
12 |
* @return mixed[]
|
13 |
*/
|
14 |
public function build() {
|
15 |
+
$opts = $this->getOptions();
|
16 |
return array_merge(
|
17 |
+
array_fill_keys( $opts->getOptionsKeys(), false ),
|
18 |
+
array_fill_keys( array_keys( $opts->getTransferableOptions() ), 'Y' ),
|
19 |
+
array_fill_keys( $opts->getXferExcluded(), 'N' )
|
20 |
);
|
21 |
}
|
22 |
}
|
src/lib/src/Modules/Plugin/Lib/ImportExport/Options/SaveExcludedOptions.php
CHANGED
@@ -11,16 +11,16 @@ class SaveExcludedOptions {
|
|
11 |
/**
|
12 |
* Takes a form submission and if the checkbox isn't checked for a given option,
|
13 |
* it means we are to exclude that option from imports/exports.
|
14 |
-
* @param string[] $
|
15 |
*/
|
16 |
-
public function save( $
|
17 |
-
$
|
18 |
$aExcluded = [];
|
19 |
-
foreach ( array_keys( $
|
20 |
-
if ( empty( $
|
21 |
$aExcluded[] = $sOptKey;
|
22 |
}
|
23 |
}
|
24 |
-
$
|
25 |
}
|
26 |
}
|
11 |
/**
|
12 |
* Takes a form submission and if the checkbox isn't checked for a given option,
|
13 |
* it means we are to exclude that option from imports/exports.
|
14 |
+
* @param string[] $formSubmission
|
15 |
*/
|
16 |
+
public function save( $formSubmission ) {
|
17 |
+
$opts = $this->getOptions();
|
18 |
$aExcluded = [];
|
19 |
+
foreach ( array_keys( $opts->getTransferableOptions() ) as $sOptKey ) {
|
20 |
+
if ( empty( $formSubmission[ 'optxfer-'.$sOptKey ] ) ) {
|
21 |
$aExcluded[] = $sOptKey;
|
22 |
}
|
23 |
}
|
24 |
+
$opts->setOpt( 'xfer_excluded', $aExcluded );
|
25 |
}
|
26 |
}
|
src/lib/src/Modules/Plugin/Lib/TourManager.php
CHANGED
@@ -15,7 +15,8 @@ class TourManager {
|
|
15 |
|
16 |
public function getAllTours() :array {
|
17 |
return [
|
18 |
-
'dashboard_v1'
|
|
|
19 |
];
|
20 |
}
|
21 |
|
15 |
|
16 |
public function getAllTours() :array {
|
17 |
return [
|
18 |
+
'dashboard_v1',
|
19 |
+
'navigation_v1',
|
20 |
];
|
21 |
}
|
22 |
|
src/lib/src/Modules/Plugin/ModCon.php
CHANGED
@@ -489,26 +489,8 @@ class ModCon extends BaseShield\ModCon {
|
|
489 |
}
|
490 |
|
491 |
public function getScriptLocalisations() :array {
|
492 |
-
$con = $this->getCon();
|
493 |
$locals = parent::getScriptLocalisations();
|
494 |
|
495 |
-
if ( Services::WpPost()->isCurrentPage( 'plugins.php' ) ) {
|
496 |
-
$file = $con->base_file;
|
497 |
-
$locals[] = [
|
498 |
-
'global-plugin',
|
499 |
-
'icwp_wpsf_vars_plugin',
|
500 |
-
[
|
501 |
-
'file' => $file,
|
502 |
-
'ajax' => [
|
503 |
-
'send_deactivate_survey' => $this->getAjaxActionData( 'send_deactivate_survey' ),
|
504 |
-
],
|
505 |
-
'hrefs' => [
|
506 |
-
'deactivate' => Services::WpPlugins()->getUrl_Deactivate( $file ),
|
507 |
-
],
|
508 |
-
]
|
509 |
-
];
|
510 |
-
}
|
511 |
-
|
512 |
$tourManager = $this->getTourManager();
|
513 |
$locals[] = [
|
514 |
'shield/tours',
|
@@ -526,7 +508,7 @@ class ModCon extends BaseShield\ModCon {
|
|
526 |
[
|
527 |
'strings' => [
|
528 |
'downloading_file' => __( 'Downloading file, please wait...', 'wp-simple-firewall' ),
|
529 |
-
'
|
530 |
],
|
531 |
]
|
532 |
];
|
@@ -565,11 +547,4 @@ class ModCon extends BaseShield\ModCon {
|
|
565 |
protected function getNamespaceBase() :string {
|
566 |
return 'Plugin';
|
567 |
}
|
568 |
-
|
569 |
-
/**
|
570 |
-
* @return string
|
571 |
-
*/
|
572 |
-
public function getSurveyEmail() {
|
573 |
-
return base64_decode( $this->getDef( 'survey_email' ) );
|
574 |
-
}
|
575 |
}
|
489 |
}
|
490 |
|
491 |
public function getScriptLocalisations() :array {
|
|
|
492 |
$locals = parent::getScriptLocalisations();
|
493 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
494 |
$tourManager = $this->getTourManager();
|
495 |
$locals[] = [
|
496 |
'shield/tours',
|
508 |
[
|
509 |
'strings' => [
|
510 |
'downloading_file' => __( 'Downloading file, please wait...', 'wp-simple-firewall' ),
|
511 |
+
'downloading_file_problem' => __( 'There was a problem downloading the file.', 'wp-simple-firewall' ),
|
512 |
],
|
513 |
]
|
514 |
];
|
547 |
protected function getNamespaceBase() :string {
|
548 |
return 'Plugin';
|
549 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
550 |
}
|
src/lib/src/Modules/Plugin/Strings.php
CHANGED
@@ -196,18 +196,22 @@ class Strings extends Base\Strings {
|
|
196 |
case 'visitor_address_source' :
|
197 |
$name = __( 'IP Source', 'wp-simple-firewall' );
|
198 |
$summary = __( 'Which IP Address Is Yours', 'wp-simple-firewall' );
|
199 |
-
$desc =
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
)
|
|
|
|
|
|
|
|
|
211 |
break;
|
212 |
|
213 |
case 'block_send_email_address' :
|
196 |
case 'visitor_address_source' :
|
197 |
$name = __( 'IP Source', 'wp-simple-firewall' );
|
198 |
$summary = __( 'Which IP Address Is Yours', 'wp-simple-firewall' );
|
199 |
+
$desc = [
|
200 |
+
__( "Knowing the real IP address of your visitors is critical to your security, but many hosts aren't configured correctly to let us find it easily.", 'wp-simple-firewall' ),
|
201 |
+
__( 'There are many possible ways to detect visitor IP addresses. If Auto-Detect is not working, please select yours from the list.', 'wp-simple-firewall' ),
|
202 |
+
__( 'Use the link below to find your correct IP address, then select the option on the list.', 'wp-simple-firewall' ),
|
203 |
+
sprintf(
|
204 |
+
'<p class="mt-2"><a href="%s" target="_blank">%s</a></p>',
|
205 |
+
'https://shsec.io/shieldwhatismyip',
|
206 |
+
__( 'What Is My IP Address?', 'wp-simple-firewall' )
|
207 |
+
),
|
208 |
+
sprintf(
|
209 |
+
__( 'Current source is: %s (%s)', 'wp-simple-firewall' ),
|
210 |
+
'<strong>'.$opts->getIpSource().'</strong>',
|
211 |
+
Services::IP()->getRequestIp()
|
212 |
+
),
|
213 |
+
__( 'If the option you select becomes unavailable at some point, we will revert to auto detection.', 'wp-simple-firewall' ),
|
214 |
+
];
|
215 |
break;
|
216 |
|
217 |
case 'block_send_email_address' :
|
src/lib/src/Modules/Plugin/UI.php
CHANGED
@@ -45,19 +45,20 @@ class UI extends BaseShield\UI {
|
|
45 |
protected function buildOptionForUi( $aOptParams ) {
|
46 |
$aOptParams = parent::buildOptionForUi( $aOptParams );
|
47 |
if ( $aOptParams[ 'key' ] === 'visitor_address_source' ) {
|
48 |
-
$
|
49 |
-
$
|
50 |
-
foreach ( $aOptParams[ 'value_options' ] as $
|
51 |
-
if ( $
|
52 |
-
$
|
53 |
}
|
54 |
else {
|
55 |
-
$
|
56 |
-
|
57 |
-
$
|
|
|
58 |
}
|
59 |
}
|
60 |
-
$aOptParams[ 'value_options' ] = $
|
61 |
}
|
62 |
return $aOptParams;
|
63 |
}
|
@@ -88,14 +89,4 @@ class UI extends BaseShield\UI {
|
|
88 |
|
89 |
return $warnings;
|
90 |
}
|
91 |
-
|
92 |
-
protected function getSettingsRelatedLinks() :array {
|
93 |
-
$modInsights = $this->getCon()->getModule_Insights();
|
94 |
-
return [
|
95 |
-
[
|
96 |
-
'href' => $modInsights->getUrl_SubInsightsPage( 'importexport' ),
|
97 |
-
'title' => __( 'Run Import/Export', 'wp-simple-firewall' ),
|
98 |
-
]
|
99 |
-
];
|
100 |
-
}
|
101 |
}
|
45 |
protected function buildOptionForUi( $aOptParams ) {
|
46 |
$aOptParams = parent::buildOptionForUi( $aOptParams );
|
47 |
if ( $aOptParams[ 'key' ] === 'visitor_address_source' ) {
|
48 |
+
$newOptions = [];
|
49 |
+
$ipDetector = Services::IP()->getIpDetector();
|
50 |
+
foreach ( $aOptParams[ 'value_options' ] as $valKey => $source ) {
|
51 |
+
if ( $valKey == 'AUTO_DETECT_IP' ) {
|
52 |
+
$newOptions[ $valKey ] = $source;
|
53 |
}
|
54 |
else {
|
55 |
+
$IPs = implode( ', ', $ipDetector->getIpsFromSource( $source ) );
|
56 |
+
if ( !empty( $IPs ) ) {
|
57 |
+
$newOptions[ $valKey ] = sprintf( '%s (%s)', $source, $IPs );
|
58 |
+
}
|
59 |
}
|
60 |
}
|
61 |
+
$aOptParams[ 'value_options' ] = $newOptions;
|
62 |
}
|
63 |
return $aOptParams;
|
64 |
}
|
89 |
|
90 |
return $warnings;
|
91 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
}
|
src/lib/src/Modules/Reporting/AjaxHandler.php
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Reporting;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
|
|
6 |
|
7 |
class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
8 |
|
@@ -25,7 +26,7 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
25 |
}
|
26 |
|
27 |
private function ajaxExec_RenderCustomChart() :array {
|
28 |
-
return $this->renderChart(
|
29 |
}
|
30 |
|
31 |
private function ajaxExec_RenderSummaryChart() :array {
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Reporting;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Lib\Request\FormParams;
|
7 |
|
8 |
class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
9 |
|
26 |
}
|
27 |
|
28 |
private function ajaxExec_RenderCustomChart() :array {
|
29 |
+
return $this->renderChart( FormParams::Retrieve() );
|
30 |
}
|
31 |
|
32 |
private function ajaxExec_RenderSummaryChart() :array {
|
src/lib/src/Modules/Reporting/Lib/ReportingController.php
CHANGED
@@ -66,7 +66,7 @@ class ReportingController {
|
|
66 |
* @param Modules\Reporting\Lib\Reports\ReportVO $report
|
67 |
* @return bool
|
68 |
*/
|
69 |
-
private function storeReportRecord( Reports\ReportVO $report ) {
|
70 |
$record = new DBReports\EntryVO();
|
71 |
$record->sent_at = Services::Request()->ts();
|
72 |
$record->rid = $report->rid;
|
@@ -82,10 +82,9 @@ class ReportingController {
|
|
82 |
}
|
83 |
|
84 |
/**
|
85 |
-
* @return Modules\Reporting\Lib\Reports\ReportVO
|
86 |
* @throws \Exception
|
87 |
*/
|
88 |
-
private function buildReportAlerts() {
|
89 |
$report = ( new Reports\CreateReportVO( DBReports\Handler::TYPE_ALERT ) )
|
90 |
->setMod( $this->getMod() )
|
91 |
->create();
|
@@ -96,10 +95,9 @@ class ReportingController {
|
|
96 |
}
|
97 |
|
98 |
/**
|
99 |
-
* @return Modules\Reporting\Lib\Reports\ReportVO
|
100 |
* @throws \Exception
|
101 |
*/
|
102 |
-
private function buildReportInfo() {
|
103 |
$report = ( new Reports\CreateReportVO( DBReports\Handler::TYPE_INFO ) )
|
104 |
->setMod( $this->getMod() )
|
105 |
->create();
|
@@ -110,7 +108,7 @@ class ReportingController {
|
|
110 |
}
|
111 |
|
112 |
/**
|
113 |
-
* @param
|
114 |
*/
|
115 |
private function sendEmail( array $reportVOs ) {
|
116 |
|
66 |
* @param Modules\Reporting\Lib\Reports\ReportVO $report
|
67 |
* @return bool
|
68 |
*/
|
69 |
+
private function storeReportRecord( Reports\ReportVO $report ) :bool {
|
70 |
$record = new DBReports\EntryVO();
|
71 |
$record->sent_at = Services::Request()->ts();
|
72 |
$record->rid = $report->rid;
|
82 |
}
|
83 |
|
84 |
/**
|
|
|
85 |
* @throws \Exception
|
86 |
*/
|
87 |
+
private function buildReportAlerts() :Reports\ReportVO {
|
88 |
$report = ( new Reports\CreateReportVO( DBReports\Handler::TYPE_ALERT ) )
|
89 |
->setMod( $this->getMod() )
|
90 |
->create();
|
95 |
}
|
96 |
|
97 |
/**
|
|
|
98 |
* @throws \Exception
|
99 |
*/
|
100 |
+
private function buildReportInfo() :Reports\ReportVO {
|
101 |
$report = ( new Reports\CreateReportVO( DBReports\Handler::TYPE_INFO ) )
|
102 |
->setMod( $this->getMod() )
|
103 |
->create();
|
108 |
}
|
109 |
|
110 |
/**
|
111 |
+
* @param Reports\ReportVO[] $reportVOs
|
112 |
*/
|
113 |
private function sendEmail( array $reportVOs ) {
|
114 |
|
src/lib/src/Modules/Reporting/Lib/Reports/CreateReportVO.php
CHANGED
@@ -16,9 +16,6 @@ class CreateReportVO {
|
|
16 |
*/
|
17 |
private $rep;
|
18 |
|
19 |
-
/**
|
20 |
-
* @param string $reportType
|
21 |
-
*/
|
22 |
public function __construct( string $reportType ) {
|
23 |
$this->rep = new ReportVO();
|
24 |
$this->rep->type = $reportType;
|
@@ -28,7 +25,7 @@ class CreateReportVO {
|
|
28 |
* @return ReportVO
|
29 |
* @throws \Exception
|
30 |
*/
|
31 |
-
public function create() {
|
32 |
$this->setReportInterval()
|
33 |
->setPreviousReport()
|
34 |
->setIntervalBoundaries()
|
@@ -82,37 +79,38 @@ class CreateReportVO {
|
|
82 |
private function setIntervalBoundaries() {
|
83 |
|
84 |
$carbon = Services::Request()->carbon( true );
|
85 |
-
$
|
86 |
|
87 |
switch ( $this->rep->interval ) {
|
88 |
// case 'realtime':
|
89 |
// break;
|
90 |
-
case '
|
91 |
$start = 0;
|
92 |
$end = $carbon->timestamp;
|
93 |
break;
|
94 |
case 'hourly':
|
95 |
-
$carbon->addHours( $
|
96 |
$start = $carbon->startOfHour()->timestamp;
|
97 |
$end = $carbon->endOfHour()->timestamp;
|
98 |
break;
|
99 |
case 'daily':
|
100 |
-
$carbon->addDays( $
|
101 |
$start = $carbon->startOfDay()->timestamp;
|
102 |
$end = $carbon->endOfDay()->timestamp;
|
103 |
break;
|
104 |
case 'weekly':
|
105 |
-
$carbon->addWeeks( $
|
106 |
$start = $carbon->startOfWeek()->timestamp;
|
107 |
$end = $carbon->endOfWeek()->timestamp;
|
108 |
break;
|
109 |
case 'monthly':
|
110 |
-
$carbon->
|
|
|
111 |
$start = $carbon->startOfMonth()->timestamp;
|
112 |
$end = $carbon->endOfMonth()->timestamp;
|
113 |
break;
|
114 |
case 'yearly':
|
115 |
-
$carbon->addYears( $
|
116 |
$start = $carbon->startOfYear()->timestamp;
|
117 |
$end = $carbon->endOfYear()->timestamp;
|
118 |
break;
|
@@ -138,10 +136,10 @@ class CreateReportVO {
|
|
138 |
private function setReportId() {
|
139 |
/** @var Reporting\ModCon $mod */
|
140 |
$mod = $this->getMod();
|
141 |
-
/** @var Reports\Select $
|
142 |
-
$
|
143 |
-
$
|
144 |
-
$this->rep->rid = is_numeric( $
|
145 |
return $this;
|
146 |
}
|
147 |
|
16 |
*/
|
17 |
private $rep;
|
18 |
|
|
|
|
|
|
|
19 |
public function __construct( string $reportType ) {
|
20 |
$this->rep = new ReportVO();
|
21 |
$this->rep->type = $reportType;
|
25 |
* @return ReportVO
|
26 |
* @throws \Exception
|
27 |
*/
|
28 |
+
public function create() :ReportVO {
|
29 |
$this->setReportInterval()
|
30 |
->setPreviousReport()
|
31 |
->setIntervalBoundaries()
|
79 |
private function setIntervalBoundaries() {
|
80 |
|
81 |
$carbon = Services::Request()->carbon( true );
|
82 |
+
$addition = -1; // the previous hour, day, week, month
|
83 |
|
84 |
switch ( $this->rep->interval ) {
|
85 |
// case 'realtime':
|
86 |
// break;
|
87 |
+
case 'lifetime': // TODO
|
88 |
$start = 0;
|
89 |
$end = $carbon->timestamp;
|
90 |
break;
|
91 |
case 'hourly':
|
92 |
+
$carbon->addHours( $addition );
|
93 |
$start = $carbon->startOfHour()->timestamp;
|
94 |
$end = $carbon->endOfHour()->timestamp;
|
95 |
break;
|
96 |
case 'daily':
|
97 |
+
$carbon->addDays( $addition );
|
98 |
$start = $carbon->startOfDay()->timestamp;
|
99 |
$end = $carbon->endOfDay()->timestamp;
|
100 |
break;
|
101 |
case 'weekly':
|
102 |
+
$carbon->addWeeks( $addition );
|
103 |
$start = $carbon->startOfWeek()->timestamp;
|
104 |
$end = $carbon->endOfWeek()->timestamp;
|
105 |
break;
|
106 |
case 'monthly':
|
107 |
+
$carbon->day( 15 );
|
108 |
+
$carbon->addMonths( $addition );
|
109 |
$start = $carbon->startOfMonth()->timestamp;
|
110 |
$end = $carbon->endOfMonth()->timestamp;
|
111 |
break;
|
112 |
case 'yearly':
|
113 |
+
$carbon->addYears( $addition );
|
114 |
$start = $carbon->startOfYear()->timestamp;
|
115 |
$end = $carbon->endOfYear()->timestamp;
|
116 |
break;
|
136 |
private function setReportId() {
|
137 |
/** @var Reporting\ModCon $mod */
|
138 |
$mod = $this->getMod();
|
139 |
+
/** @var Reports\Select $select */
|
140 |
+
$select = $mod->getDbHandler_Reports()->getQuerySelector();
|
141 |
+
$prevID = $select->getLastReportId();
|
142 |
+
$this->rep->rid = is_numeric( $prevID ) ? $prevID + 1 : 1;
|
143 |
return $this;
|
144 |
}
|
145 |
|
src/lib/src/Modules/Reporting/Options.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<?php
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Reporting;
|
4 |
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Reporting;
|
4 |
|
src/lib/src/Modules/SecurityAdmin/AjaxHandler.php
CHANGED
@@ -37,28 +37,23 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
37 |
private function ajaxExec_SecAdminCheck() :array {
|
38 |
/** @var ModCon $mod */
|
39 |
$mod = $this->getMod();
|
|
|
40 |
return [
|
41 |
-
'
|
42 |
-
'success'
|
43 |
];
|
44 |
}
|
45 |
|
46 |
private function ajaxExec_SecAdminLogin() :array {
|
47 |
/** @var ModCon $mod */
|
48 |
$mod = $this->getMod();
|
49 |
-
$success = false;
|
50 |
-
$html = '';
|
51 |
|
52 |
-
|
|
|
53 |
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
.' '.__( 'Please wait', 'wp-simple-firewall' ).' ...';
|
58 |
-
}
|
59 |
-
else {
|
60 |
-
$msg = __( 'Failed to process key - you may need to re-login to WordPress.', 'wp-simple-firewall' );
|
61 |
-
}
|
62 |
}
|
63 |
else {
|
64 |
$remaining = ( new Shield\Modules\IPs\Components\QueryRemainingOffenses() )
|
@@ -91,7 +86,7 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
91 |
}
|
92 |
|
93 |
private function ajaxExec_SendEmailRemove() :array {
|
94 |
-
( new
|
95 |
->setMod( $this->getMod() )
|
96 |
->sendConfirmationEmail();
|
97 |
return [
|
37 |
private function ajaxExec_SecAdminCheck() :array {
|
38 |
/** @var ModCon $mod */
|
39 |
$mod = $this->getMod();
|
40 |
+
$secAdminCon = $mod->getSecurityAdminController();
|
41 |
return [
|
42 |
+
'time_remaining' => $secAdminCon->getSecAdminTimeRemaining(),
|
43 |
+
'success' => $secAdminCon->isCurrentlySecAdmin()
|
44 |
];
|
45 |
}
|
46 |
|
47 |
private function ajaxExec_SecAdminLogin() :array {
|
48 |
/** @var ModCon $mod */
|
49 |
$mod = $this->getMod();
|
|
|
|
|
50 |
|
51 |
+
$success = $mod->getSecurityAdminController()->verifyPinRequest();
|
52 |
+
$html = '';
|
53 |
|
54 |
+
if ( $success ) {
|
55 |
+
$msg = __( 'Security Admin PIN Accepted.', 'wp-simple-firewall' )
|
56 |
+
.' '.__( 'Please wait', 'wp-simple-firewall' ).' ...';
|
|
|
|
|
|
|
|
|
|
|
57 |
}
|
58 |
else {
|
59 |
$remaining = ( new Shield\Modules\IPs\Components\QueryRemainingOffenses() )
|
86 |
}
|
87 |
|
88 |
private function ajaxExec_SendEmailRemove() :array {
|
89 |
+
( new Lib\SecurityAdmin\Ops\RemoveSecAdmin() )
|
90 |
->setMod( $this->getMod() )
|
91 |
->sendConfirmationEmail();
|
92 |
return [
|
src/lib/src/Modules/SecurityAdmin/Insights/OverviewCards.php
CHANGED
@@ -21,8 +21,8 @@ class OverviewCards extends Shield\Modules\Base\Insights\OverviewCards {
|
|
21 |
|
22 |
$cards = [];
|
23 |
|
24 |
-
$
|
25 |
-
if ( !$
|
26 |
$cards[ 'mod' ] = [
|
27 |
'name' => __( 'Security Admin', 'wp-simple-firewall' ),
|
28 |
'state' => -1,
|
@@ -38,11 +38,11 @@ class OverviewCards extends Shield\Modules\Base\Insights\OverviewCards {
|
|
38 |
'href' => $mod->getUrl_DirectLinkToOption( 'admin_access_key' ),
|
39 |
];
|
40 |
|
41 |
-
$
|
42 |
$cards[ 'wpopts' ] = [
|
43 |
'name' => __( 'Important Options', 'wp-simple-firewall' ),
|
44 |
-
'state' => $
|
45 |
-
'summary' => $
|
46 |
__( 'Important WP options are protected against tampering', 'wp-simple-firewall' )
|
47 |
: __( "Important WP options aren't protected against tampering", 'wp-simple-firewall' ),
|
48 |
'href' => $mod->getUrl_DirectLinkToOption( 'admin_access_restrict_options' ),
|
21 |
|
22 |
$cards = [];
|
23 |
|
24 |
+
$enabled = $mod->getSecurityAdminController()->isEnabledSecAdmin();
|
25 |
+
if ( !$enabled ) {
|
26 |
$cards[ 'mod' ] = [
|
27 |
'name' => __( 'Security Admin', 'wp-simple-firewall' ),
|
28 |
'state' => -1,
|
38 |
'href' => $mod->getUrl_DirectLinkToOption( 'admin_access_key' ),
|
39 |
];
|
40 |
|
41 |
+
$isWPOptsRestricted = $opts->getAdminAccessArea_Options();
|
42 |
$cards[ 'wpopts' ] = [
|
43 |
'name' => __( 'Important Options', 'wp-simple-firewall' ),
|
44 |
+
'state' => $isWPOptsRestricted ? 1 : -1,
|
45 |
+
'summary' => $isWPOptsRestricted ?
|
46 |
__( 'Important WP options are protected against tampering', 'wp-simple-firewall' )
|
47 |
: __( "Important WP options aren't protected against tampering", 'wp-simple-firewall' ),
|
48 |
'href' => $mod->getUrl_DirectLinkToOption( 'admin_access_restrict_options' ),
|
src/lib/src/Modules/SecurityAdmin/Lib/{Actions → SecurityAdmin/Ops}/RemoveSecAdmin.php
RENAMED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Lib\
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin;
|
@@ -40,7 +40,7 @@ class RemoveSecAdmin {
|
|
40 |
sprintf( '%s: %s', __( 'Confirmation link', 'wp-simple-firewall' ),
|
41 |
$mod->buildAdminActionNonceUrl( 'remove_secadmin_confirm' ) ),
|
42 |
'',
|
43 |
-
__( "Please understand that to reinstate the Security Admin features, you'll need to provide a new Security Admin
|
44 |
'',
|
45 |
__( "Thank you.", 'wp-simple-firewall' )
|
46 |
]
|
@@ -58,7 +58,7 @@ class RemoveSecAdmin {
|
|
58 |
__( 'This was done using a confirmation email sent to the Security Administrator email address.', 'wp-simple-firewall' ),
|
59 |
__( 'All restrictions imposed by the Security Admin module have been lifted.', 'wp-simple-firewall' ),
|
60 |
'',
|
61 |
-
__( "Please understand that to reinstate the Security Admin features, you'll need to provide a new Security Admin
|
62 |
'',
|
63 |
__( "Thank you.", 'wp-simple-firewall' )
|
64 |
]
|
1 |
<?php
|
2 |
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Lib\SecurityAdmin\Ops;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin;
|
40 |
sprintf( '%s: %s', __( 'Confirmation link', 'wp-simple-firewall' ),
|
41 |
$mod->buildAdminActionNonceUrl( 'remove_secadmin_confirm' ) ),
|
42 |
'',
|
43 |
+
__( "Please understand that to reinstate the Security Admin features, you'll need to provide a new Security Admin PIN.", 'wp-simple-firewall' ),
|
44 |
'',
|
45 |
__( "Thank you.", 'wp-simple-firewall' )
|
46 |
]
|
58 |
__( 'This was done using a confirmation email sent to the Security Administrator email address.', 'wp-simple-firewall' ),
|
59 |
__( 'All restrictions imposed by the Security Admin module have been lifted.', 'wp-simple-firewall' ),
|
60 |
'',
|
61 |
+
__( "Please understand that to reinstate the Security Admin features, you'll need to provide a new Security Admin PIN.", 'wp-simple-firewall' ),
|
62 |
'',
|
63 |
__( "Thank you.", 'wp-simple-firewall' )
|
64 |
]
|
src/lib/src/Modules/SecurityAdmin/Lib/{Actions → SecurityAdmin/Ops}/SetSecAdminPin.php
RENAMED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Lib\
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
|
1 |
<?php
|
2 |
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Lib\SecurityAdmin\Ops;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
|
src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Ops/ToggleSecAdminStatus.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Lib\SecurityAdmin\Ops;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Session\EntryVO;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Session\Update;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
8 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\ModCon;
|
9 |
+
|
10 |
+
class ToggleSecAdminStatus {
|
11 |
+
|
12 |
+
use ModConsumer;
|
13 |
+
|
14 |
+
public function turnOn() :bool {
|
15 |
+
try {
|
16 |
+
$success = $this->toggle( true );
|
17 |
+
}
|
18 |
+
catch ( \Exception $e ) {
|
19 |
+
$success = false;
|
20 |
+
}
|
21 |
+
return $success;
|
22 |
+
}
|
23 |
+
|
24 |
+
public function turnOff() :bool {
|
25 |
+
try {
|
26 |
+
$success = $this->toggle( false );
|
27 |
+
}
|
28 |
+
catch ( \Exception $e ) {
|
29 |
+
$success = false;
|
30 |
+
}
|
31 |
+
return $success;
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @param bool $onOrOff
|
36 |
+
* @return bool
|
37 |
+
* @throws \Exception
|
38 |
+
*/
|
39 |
+
private function toggle( bool $onOrOff ) :bool {
|
40 |
+
/** @var ModCon $mod */
|
41 |
+
$mod = $this->getMod();
|
42 |
+
$session = $this->getMod()->getSession();
|
43 |
+
if ( !$session instanceof EntryVO ) {
|
44 |
+
throw new \Exception( 'No session' );
|
45 |
+
}
|
46 |
+
/** @var Update $updater */
|
47 |
+
$updater = $mod->getDbHandler_Sessions()->getQueryUpdater();
|
48 |
+
return $onOrOff ? $updater->startSecurityAdmin( $session ) : $updater->terminateSecurityAdmin( $session );
|
49 |
+
}
|
50 |
+
}
|
src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Ops/VerifyPinRequest.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Lib\SecurityAdmin\Ops;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Options;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class VerifyPinRequest {
|
10 |
+
|
11 |
+
use ModConsumer;
|
12 |
+
|
13 |
+
public function run( string $pin = null ) :bool {
|
14 |
+
$valid = false;
|
15 |
+
|
16 |
+
if ( empty( $pin ) ) {
|
17 |
+
$pin = Services::Request()->post( 'sec_admin_key' );
|
18 |
+
}
|
19 |
+
|
20 |
+
if ( !empty( $pin ) ) {
|
21 |
+
/** @var Options $opts */
|
22 |
+
$opts = $this->getOptions();
|
23 |
+
$valid = hash_equals( $opts->getSecurityPIN(), md5( $pin ) );
|
24 |
+
$this->getCon()->fireEvent( $valid ? 'key_success' : 'key_fail' );
|
25 |
+
|
26 |
+
$valid = $valid && ( new ToggleSecAdminStatus() )
|
27 |
+
->setMod( $this->getMod() )
|
28 |
+
->turnOn();
|
29 |
+
}
|
30 |
+
|
31 |
+
return $valid;
|
32 |
+
}
|
33 |
+
}
|
src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/Base.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Lib\SecurityAdmin\Restrictions;
|
4 |
+
|
5 |
+
use FernleafSystems\Utilities\Logic\ExecOnce;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
+
|
8 |
+
class Base {
|
9 |
+
|
10 |
+
use ExecOnce;
|
11 |
+
use ModConsumer;
|
12 |
+
}
|
src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/BaseCapabilitiesRestrict.php
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Lib\SecurityAdmin\Restrictions;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Options;
|
6 |
+
|
7 |
+
class BaseCapabilitiesRestrict extends Base {
|
8 |
+
|
9 |
+
const AREA_SLUG = '';
|
10 |
+
|
11 |
+
protected function canRun() :bool {
|
12 |
+
return $this->hasRestrictedCapabilities();
|
13 |
+
}
|
14 |
+
|
15 |
+
protected function run() {
|
16 |
+
add_filter( 'user_has_cap', [ $this, 'removeCapabilities' ], 0, 3 );
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @param array $allCaps
|
21 |
+
* @param $cap
|
22 |
+
* @param array $args
|
23 |
+
* @return array
|
24 |
+
*/
|
25 |
+
public function removeCapabilities( $allCaps, $cap, $args ) {
|
26 |
+
/** @var string $requestedCap */
|
27 |
+
$requestedCap = $args[ 0 ];
|
28 |
+
|
29 |
+
if ( is_string( $requestedCap ) && $this->isCapabilityToBeRestricted( $requestedCap ) ) {
|
30 |
+
$allCaps[ $requestedCap ] = false;
|
31 |
+
}
|
32 |
+
|
33 |
+
return $allCaps;
|
34 |
+
}
|
35 |
+
|
36 |
+
protected function getApplicableCapabilities() :array {
|
37 |
+
return [];
|
38 |
+
}
|
39 |
+
|
40 |
+
protected function getRestrictedCapabilities() :array {
|
41 |
+
/** @var WpOptions $opts */
|
42 |
+
$opts = $this->getOptions();
|
43 |
+
return $opts->getSecAdminAreaCaps( static::AREA_SLUG );
|
44 |
+
}
|
45 |
+
|
46 |
+
protected function isCapabilityToBeRestricted( string $cap ) :bool {
|
47 |
+
return in_array( $cap, $this->getApplicableCapabilities() )
|
48 |
+
&& in_array( $cap, $this->getRestrictedCapabilities() );
|
49 |
+
}
|
50 |
+
|
51 |
+
protected function hasRestrictedCapabilities() :bool {
|
52 |
+
return !empty( $this->getRestrictedCapabilities() );
|
53 |
+
}
|
54 |
+
}
|
src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/Plugins.php
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Lib\SecurityAdmin\Restrictions;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Services\Services;
|
6 |
+
|
7 |
+
class Plugins extends BaseCapabilitiesRestrict {
|
8 |
+
|
9 |
+
const AREA_SLUG = 'plugins';
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @param array $allCaps
|
13 |
+
* @param $cap
|
14 |
+
* @param array $args
|
15 |
+
* @return array
|
16 |
+
*/
|
17 |
+
public function removeCapabilities( $allCaps, $cap, $args ) {
|
18 |
+
$req = Services::Request();
|
19 |
+
|
20 |
+
/** @var string $requestedCap */
|
21 |
+
$requestedCap = $args[ 0 ];
|
22 |
+
|
23 |
+
// special case for plugin info thickbox for changelog
|
24 |
+
$isChangelog = defined( 'IFRAME_REQUEST' )
|
25 |
+
&& ( $requestedCap === 'install_plugins' )
|
26 |
+
&& ( $req->query( 'section' ) == 'changelog' )
|
27 |
+
&& $req->query( 'plugin' );
|
28 |
+
|
29 |
+
if ( !$isChangelog && is_string( $requestedCap ) && $this->isCapabilityToBeRestricted( $requestedCap ) ) {
|
30 |
+
$allCaps[ $requestedCap ] = false;
|
31 |
+
}
|
32 |
+
|
33 |
+
return $allCaps;
|
34 |
+
}
|
35 |
+
|
36 |
+
protected function getApplicableCapabilities() :array {
|
37 |
+
return [
|
38 |
+
'activate_plugins',
|
39 |
+
'delete_plugins',
|
40 |
+
'install_plugins',
|
41 |
+
'update_plugins'
|
42 |
+
];
|
43 |
+
}
|
44 |
+
}
|
src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/Posts.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Lib\SecurityAdmin\Restrictions;
|
4 |
+
|
5 |
+
class Posts extends BaseCapabilitiesRestrict {
|
6 |
+
|
7 |
+
const AREA_SLUG = 'posts';
|
8 |
+
|
9 |
+
protected function isCapabilityToBeRestricted( string $cap ) :bool {
|
10 |
+
return in_array( $cap, $this->getApplicableCapabilities() )
|
11 |
+
&& in_array(
|
12 |
+
str_replace( [
|
13 |
+
'_posts',
|
14 |
+
'_pages',
|
15 |
+
'_post',
|
16 |
+
'_page'
|
17 |
+
], '', $cap ), //Order of items in this array is important!
|
18 |
+
$this->getRestrictedCapabilities()
|
19 |
+
);
|
20 |
+
}
|
21 |
+
|
22 |
+
protected function getApplicableCapabilities() :array {
|
23 |
+
return [
|
24 |
+
'edit_post',
|
25 |
+
'publish_post',
|
26 |
+
'delete_post',
|
27 |
+
'edit_posts',
|
28 |
+
'publish_posts',
|
29 |
+
'delete_posts',
|
30 |
+
'edit_page',
|
31 |
+
'publish_page',
|
32 |
+
'delete_page',
|
33 |
+
'edit_pages',
|
34 |
+
'publish_pages',
|
35 |
+
'delete_pages'
|
36 |
+
];
|
37 |
+
}
|
38 |
+
}
|
src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/Themes.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Lib\SecurityAdmin\Restrictions;
|
4 |
+
|
5 |
+
class Themes extends BaseCapabilitiesRestrict {
|
6 |
+
|
7 |
+
const AREA_SLUG = 'themes';
|
8 |
+
|
9 |
+
protected function getApplicableCapabilities() :array {
|
10 |
+
return [
|
11 |
+
'switch_themes',
|
12 |
+
'edit_theme_options',
|
13 |
+
'install_themes',
|
14 |
+
'update_themes',
|
15 |
+
'delete_themes'
|
16 |
+
];
|
17 |
+
}
|
18 |
+
}
|
src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/Users.php
ADDED
@@ -0,0 +1,176 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Lib\SecurityAdmin\Restrictions;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Options;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
class Users extends Base {
|
9 |
+
|
10 |
+
protected function canRun() :bool {
|
11 |
+
/** @var Options $opts */
|
12 |
+
$opts = $this->getOptions();
|
13 |
+
return $opts->isSecAdminRestrictUsersEnabled();
|
14 |
+
}
|
15 |
+
|
16 |
+
protected function run() {
|
17 |
+
add_filter( 'editable_roles', [ $this, 'restrictEditableRoles' ], 100, 1 );
|
18 |
+
add_filter( 'user_has_cap', [ $this, 'restrictAdminUserChanges' ], 100, 3 );
|
19 |
+
add_action( 'delete_user', [ $this, 'restrictAdminUserDelete' ], 100, 1 );
|
20 |
+
add_action( 'add_user_role', [ $this, 'restrictAddUserRole' ], 100, 2 );
|
21 |
+
add_action( 'remove_user_role', [ $this, 'restrictRemoveUserRole' ], 100, 2 );
|
22 |
+
add_action( 'set_user_role', [ $this, 'restrictSetUserRole' ], 100, 3 );
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @param int $userId
|
27 |
+
* @param string $role
|
28 |
+
*/
|
29 |
+
public function restrictAddUserRole( $userId, $role ) {
|
30 |
+
$WPU = Services::WpUsers();
|
31 |
+
|
32 |
+
if ( $WPU->getCurrentWpUserId() !== $userId && strtolower( $role ) === 'administrator' ) {
|
33 |
+
$modifiedUser = $WPU->getUserById( $userId );
|
34 |
+
|
35 |
+
remove_action( 'remove_user_role', [ $this, 'restrictRemoveUserRole' ], 100 );
|
36 |
+
$modifiedUser->remove_role( 'administrator' );
|
37 |
+
add_action( 'remove_user_role', [ $this, 'restrictRemoveUserRole' ], 100, 2 );
|
38 |
+
}
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @param int $userId
|
43 |
+
* @param string $role
|
44 |
+
* @param array $oldRoles
|
45 |
+
*/
|
46 |
+
public function restrictSetUserRole( $userId, $role, $oldRoles = [] ) {
|
47 |
+
$WPU = Services::WpUsers();
|
48 |
+
|
49 |
+
$role = strtolower( $role );
|
50 |
+
if ( !is_array( $oldRoles ) ) {
|
51 |
+
$oldRoles = [];
|
52 |
+
}
|
53 |
+
|
54 |
+
if ( $WPU->getCurrentWpUserId() !== $userId ) {
|
55 |
+
$newRoleIsAdmin = $role == 'administrator';
|
56 |
+
|
57 |
+
// 1. Setting administrator role where it doesn't previously exist
|
58 |
+
if ( $newRoleIsAdmin && !in_array( 'administrator', $oldRoles ) ) {
|
59 |
+
$revert = true;
|
60 |
+
}
|
61 |
+
// 2. Setting non-administrator role when previous roles included administrator
|
62 |
+
elseif ( !$newRoleIsAdmin && in_array( 'administrator', $oldRoles ) ) {
|
63 |
+
$revert = true;
|
64 |
+
}
|
65 |
+
else {
|
66 |
+
$revert = false;
|
67 |
+
}
|
68 |
+
|
69 |
+
if ( $revert ) {
|
70 |
+
$modifiedUser = $WPU->getUserById( $userId );
|
71 |
+
remove_action( 'add_user_role', [ $this, 'restrictAddUserRole' ], 100 );
|
72 |
+
remove_action( 'remove_user_role', [ $this, 'restrictRemoveUserRole' ], 100 );
|
73 |
+
$modifiedUser->remove_role( $role );
|
74 |
+
foreach ( $oldRoles as $preExistingRoles ) {
|
75 |
+
$modifiedUser->add_role( $preExistingRoles );
|
76 |
+
}
|
77 |
+
add_action( 'add_user_role', [ $this, 'restrictAddUserRole' ], 100, 2 );
|
78 |
+
add_action( 'remove_user_role', [ $this, 'restrictRemoveUserRole' ], 100, 2 );
|
79 |
+
}
|
80 |
+
}
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* @param int $userId
|
85 |
+
* @param string $role
|
86 |
+
*/
|
87 |
+
public function restrictRemoveUserRole( $userId, $role ) {
|
88 |
+
$WPU = Services::WpUsers();
|
89 |
+
|
90 |
+
if ( $WPU->getCurrentWpUserId() !== $userId && strtolower( $role ) === 'administrator' ) {
|
91 |
+
$modifiedUser = $WPU->getUserById( $userId );
|
92 |
+
|
93 |
+
remove_action( 'add_user_role', [ $this, 'restrictAddUserRole' ], 100 );
|
94 |
+
$modifiedUser->add_role( 'administrator' );
|
95 |
+
add_action( 'add_user_role', [ $this, 'restrictAddUserRole' ], 100, 2 );
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* @param int $userID
|
101 |
+
*/
|
102 |
+
public function restrictAdminUserDelete( $userID ) {
|
103 |
+
$WPU = Services::WpUsers();
|
104 |
+
$userToDelete = $WPU->getUserById( $userID );
|
105 |
+
if ( $userToDelete && $WPU->isUserAdmin( $userToDelete ) ) {
|
106 |
+
Services::WpGeneral()
|
107 |
+
->wpDie( __( 'Sorry, deleting administrators is currently restricted to your Security Admin', 'wp-simple-firewall' ) );
|
108 |
+
}
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* @param array[] $roles
|
113 |
+
* @return array[]
|
114 |
+
*/
|
115 |
+
public function restrictEditableRoles( $roles ) {
|
116 |
+
if ( isset( $roles[ 'administrator' ] ) ) {
|
117 |
+
unset( $roles[ 'administrator' ] );
|
118 |
+
}
|
119 |
+
return $roles;
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* This hooked function captures the attempts to modify the user role using the standard
|
124 |
+
* WordPress profile edit pages. It doesn't sufficiently capture the AJAX request to
|
125 |
+
* modify user roles. (see user role hooks)
|
126 |
+
* @param array $allCaps
|
127 |
+
* @param $cap
|
128 |
+
* @param array $args
|
129 |
+
* @return array
|
130 |
+
*/
|
131 |
+
public function restrictAdminUserChanges( $allCaps, $cap, $args ) {
|
132 |
+
/** @var string $userCap */
|
133 |
+
$userCap = $args[ 0 ];
|
134 |
+
|
135 |
+
if ( in_array( $userCap, [ 'edit_users', 'create_users' ] ) ) {
|
136 |
+
$blockCapability = false;
|
137 |
+
|
138 |
+
$req = Services::Request();
|
139 |
+
$WPU = Services::WpUsers();
|
140 |
+
|
141 |
+
$requestedUser = false;
|
142 |
+
$requestedUsername = $req->post( 'user_login' );
|
143 |
+
|
144 |
+
if ( empty( $requestedUsername ) ) {
|
145 |
+
$requestedUserId = $req->post( 'user_id' );
|
146 |
+
if ( !empty( $requestedUserId ) ) {
|
147 |
+
$requestedUser = $WPU->getUserById( $requestedUserId );
|
148 |
+
}
|
149 |
+
}
|
150 |
+
else {
|
151 |
+
$requestedUser = $WPU->getUserByUsername( $requestedUsername );
|
152 |
+
}
|
153 |
+
|
154 |
+
$requestedRole = strtolower( (string)$req->post( 'role', '' ) );
|
155 |
+
|
156 |
+
if ( $requestedUser instanceof \WP_User ) {
|
157 |
+
// editing an existing user other than yourself?
|
158 |
+
if ( $requestedUser->user_login != $WPU->getCurrentWpUsername() ) {
|
159 |
+
|
160 |
+
if ( $WPU->isUserAdmin( $requestedUser ) || $requestedRole == 'administrator' ) {
|
161 |
+
$blockCapability = true;
|
162 |
+
}
|
163 |
+
}
|
164 |
+
}
|
165 |
+
elseif ( $requestedRole == 'administrator' ) { //creating a new admin user?
|
166 |
+
$blockCapability = true;
|
167 |
+
}
|
168 |
+
|
169 |
+
if ( $blockCapability ) {
|
170 |
+
$allCaps[ $userCap ] = false;
|
171 |
+
}
|
172 |
+
}
|
173 |
+
|
174 |
+
return $allCaps;
|
175 |
+
}
|
176 |
+
}
|
src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/WpOptions.php
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Lib\SecurityAdmin\Restrictions;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Options;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
class WpOptions extends Base {
|
9 |
+
|
10 |
+
protected function canRun() :bool {
|
11 |
+
/** @var Options $opts */
|
12 |
+
$opts = $this->getOptions();
|
13 |
+
return $opts->getAdminAccessArea_Options()
|
14 |
+
&& !$this->getMod()->isUpgrading() && !Services::WpGeneral()->isLoginRequest();
|
15 |
+
}
|
16 |
+
|
17 |
+
protected function run() {
|
18 |
+
add_filter( 'pre_update_option', [ $this, 'blockOptionsSaves' ], 1, 3 );
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Need to always re-test isPluginAdmin() because there's a dynamic filter in there to
|
23 |
+
* permit saving by the plugin itself.
|
24 |
+
*
|
25 |
+
* Right before a plugin option is due to update it will check that we have permissions to do so
|
26 |
+
* and if not, will * revert the option to save to the previous one.
|
27 |
+
* @param mixed $newValue
|
28 |
+
* @param string $key
|
29 |
+
* @param mixed $oldValue
|
30 |
+
* @return mixed
|
31 |
+
* @deprecated 11.1
|
32 |
+
*/
|
33 |
+
public function blockOptionsSaves( $newValue, $key, $oldValue ) {
|
34 |
+
/** @var Options $opts */
|
35 |
+
$opts = $this->getOptions();
|
36 |
+
|
37 |
+
if ( !$this->getCon()->isPluginAdmin() && is_string( $key )
|
38 |
+
&& ( in_array( $key, $opts->getOptionsToRestrict() ) || $this->isPluginOption( $key ) ) ) {
|
39 |
+
$newValue = $oldValue;
|
40 |
+
}
|
41 |
+
|
42 |
+
return $newValue;
|
43 |
+
}
|
44 |
+
|
45 |
+
private function isPluginOption( string $key ) :bool {
|
46 |
+
return preg_match( sprintf( '/^%s.*_options$/', $this->getCon()->getOptionStoragePrefix() ), $key ) > 0;
|
47 |
+
}
|
48 |
+
}
|
src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/SecurityAdminController.php
ADDED
@@ -0,0 +1,185 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Lib\SecurityAdmin;
|
4 |
+
|
5 |
+
use FernleafSystems\Utilities\Logic\ExecOnce;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Controller\Assets\Enqueue;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
8 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\ModCon;
|
9 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Options;
|
10 |
+
use FernleafSystems\Wordpress\Services\Services;
|
11 |
+
|
12 |
+
class SecurityAdminController {
|
13 |
+
|
14 |
+
use ExecOnce;
|
15 |
+
use ModConsumer;
|
16 |
+
|
17 |
+
private $validPinRequest;
|
18 |
+
|
19 |
+
protected function canRun() :bool {
|
20 |
+
return $this->isEnabledSecAdmin();
|
21 |
+
}
|
22 |
+
|
23 |
+
protected function run() {
|
24 |
+
|
25 |
+
add_filter( $this->getCon()->prefix( 'is_plugin_admin' ), [ $this, 'adjustUserAdminPermissions' ] );
|
26 |
+
add_action( 'admin_init', function () {
|
27 |
+
$this->enqueueJS();
|
28 |
+
} );
|
29 |
+
add_action( 'init', function () {
|
30 |
+
if ( !$this->getCon()->isPluginAdmin() ) {
|
31 |
+
( new Restrictions\WpOptions() )
|
32 |
+
->setMod( $this->getMod() )
|
33 |
+
->execute();
|
34 |
+
( new Restrictions\Plugins() )
|
35 |
+
->setMod( $this->getMod() )
|
36 |
+
->execute();
|
37 |
+
( new Restrictions\Themes() )
|
38 |
+
->setMod( $this->getMod() )
|
39 |
+
->execute();
|
40 |
+
( new Restrictions\Posts() )
|
41 |
+
->setMod( $this->getMod() )
|
42 |
+
->execute();
|
43 |
+
( new Restrictions\Users() )
|
44 |
+
->setMod( $this->getMod() )
|
45 |
+
->execute();
|
46 |
+
|
47 |
+
if ( !$this->getCon()->isThisPluginModuleRequest() ) {
|
48 |
+
add_action( 'admin_footer', [ $this, 'printPinLoginForm' ] );
|
49 |
+
}
|
50 |
+
}
|
51 |
+
} );
|
52 |
+
}
|
53 |
+
|
54 |
+
public function isEnabledSecAdmin() :bool {
|
55 |
+
/** @var Options $opts */
|
56 |
+
$opts = $this->getOptions();
|
57 |
+
return $this->getMod()->isModOptEnabled() &&
|
58 |
+
$opts->hasSecurityPIN() && $this->getSecAdminTimeout() > 0;
|
59 |
+
}
|
60 |
+
|
61 |
+
private function enqueueJS() {
|
62 |
+
add_filter( 'shield/custom_enqueues', function ( array $enqueues ) {
|
63 |
+
$enqueues[ Enqueue::JS ][] = 'shield/secadmin';
|
64 |
+
|
65 |
+
add_filter( 'shield/custom_localisations', function ( array $localz ) {
|
66 |
+
/** @var ModCon $mod */
|
67 |
+
$mod = $this->getMod();
|
68 |
+
/** @var Options $opts */
|
69 |
+
$opts = $this->getOptions();
|
70 |
+
|
71 |
+
$isCurrentlySecAdmin = $this->isCurrentlySecAdmin();
|
72 |
+
$localz[] = [
|
73 |
+
'shield/secadmin',
|
74 |
+
'shield_vars_secadmin',
|
75 |
+
[
|
76 |
+
'ajax' => [
|
77 |
+
'sec_admin_check' => $mod->getAjaxActionData( 'sec_admin_check' ),
|
78 |
+
'sec_admin_login' => $mod->getAjaxActionData( 'sec_admin_login' ),
|
79 |
+
'req_email_remove' => $mod->getAjaxActionData( 'req_email_remove' ),
|
80 |
+
],
|
81 |
+
'flags' => [
|
82 |
+
'restrict_options' => !$isCurrentlySecAdmin && $opts->getAdminAccessArea_Options(),
|
83 |
+
'run_checks' => $this->getCon()->getIsPage_PluginAdmin() && $isCurrentlySecAdmin,
|
84 |
+
],
|
85 |
+
'strings' => [
|
86 |
+
'confirm' => __( 'Security Admin session has timed-out.', 'wp-simple-firewall' ).' '.__( 'Click OK to reload and re-authenticate.', 'wp-simple-firewall' ),
|
87 |
+
'nearly' => __( 'Security Admin session has nearly timed-out.', 'wp-simple-firewall' ),
|
88 |
+
'expired' => __( 'Security Admin session has timed-out.', 'wp-simple-firewall' ),
|
89 |
+
'are_you_sure' => __( 'Are you sure?', 'wp-simple-firewall' ),
|
90 |
+
'editing_restricted' => __( 'Editing this option is currently restricted.', 'wp-simple-firewall' ),
|
91 |
+
'unlock_link' => sprintf(
|
92 |
+
'<a href="%1$s" title="%2$s" class="thickbox">%3$s</a>',
|
93 |
+
'#TB_inline?width=400&height=180&inlineId=WpsfAdminAccessLogin',
|
94 |
+
__( 'Security Admin Login', 'wp-simple-firewall' ),
|
95 |
+
__( 'Unlock', 'wp-simple-firewall' )
|
96 |
+
),
|
97 |
+
],
|
98 |
+
'vars' => [
|
99 |
+
'time_remaining' => $this->getSecAdminTimeRemaining(), // JS uses milliseconds
|
100 |
+
'wp_options_to_restrict' => $opts->getOptionsToRestrict(),
|
101 |
+
],
|
102 |
+
]
|
103 |
+
];
|
104 |
+
return $localz;
|
105 |
+
} );
|
106 |
+
|
107 |
+
return $enqueues;
|
108 |
+
} );
|
109 |
+
}
|
110 |
+
|
111 |
+
public function getSecAdminTimeout() :int {
|
112 |
+
return (int)$this->getOptions()->getOpt( 'admin_access_timeout' )*MINUTE_IN_SECONDS;
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Only returns greater than 0 if you have a valid Sec admin session
|
117 |
+
*/
|
118 |
+
public function getSecAdminTimeRemaining() :int {
|
119 |
+
$remaining = 0;
|
120 |
+
if ( $this->getCon()->getModule_Sessions()->getSessionCon()->hasSession() ) {
|
121 |
+
|
122 |
+
$secAdminAt = $this->getMod()->getSession()->getSecAdminAt();
|
123 |
+
if ( $this->isRegisteredSecAdminUser() ) {
|
124 |
+
$remaining = 0;
|
125 |
+
}
|
126 |
+
elseif ( $secAdminAt > 0 ) {
|
127 |
+
$remaining = $this->getSecAdminTimeout() - ( Services::Request()->ts() - $secAdminAt );
|
128 |
+
}
|
129 |
+
}
|
130 |
+
return (int)max( 0, $remaining );
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* @param \WP_User|null $user
|
135 |
+
* @return bool
|
136 |
+
*/
|
137 |
+
public function isRegisteredSecAdminUser( $user = null ) :bool {
|
138 |
+
/** @var Options $opts */
|
139 |
+
$opts = $this->getOptions();
|
140 |
+
if ( !$user instanceof \WP_User ) {
|
141 |
+
$user = Services::WpUsers()->getCurrentWpUser();
|
142 |
+
}
|
143 |
+
return $user instanceof \WP_User && in_array( $user->user_login, $opts->getSecurityAdminUsers() );
|
144 |
+
}
|
145 |
+
|
146 |
+
public function isCurrentlySecAdmin() :bool {
|
147 |
+
return $this->isRegisteredSecAdminUser( Services::WpUsers()->getCurrentWpUser() )
|
148 |
+
|| $this->getSecAdminTimeRemaining() > 0;
|
149 |
+
}
|
150 |
+
|
151 |
+
public function adjustUserAdminPermissions( $isPluginAdmin = true ) :bool {
|
152 |
+
return $isPluginAdmin &&
|
153 |
+
( $this->isCurrentlySecAdmin() || $this->verifyPinRequest() );
|
154 |
+
}
|
155 |
+
|
156 |
+
public function printPinLoginForm() {
|
157 |
+
/** @var ModCon $mod */
|
158 |
+
$mod = $this->getMod();
|
159 |
+
/** @var Options $opts */
|
160 |
+
$opts = $this->getOptions();
|
161 |
+
|
162 |
+
add_thickbox();
|
163 |
+
echo $mod->renderTemplate( '/components/security_admin/login_box.twig', [
|
164 |
+
'flags' => [
|
165 |
+
'restrict_options' => $opts->getAdminAccessArea_Options()
|
166 |
+
],
|
167 |
+
'strings' => [
|
168 |
+
'access_message' => __( 'Enter your Security Admin PIN', 'wp-simple-firewall' ),
|
169 |
+
],
|
170 |
+
'ajax' => [
|
171 |
+
'sec_admin_login' => $mod->getAjaxActionData( 'sec_admin_login', true ),
|
172 |
+
'sec_admin_login_box' => $mod->getAjaxActionData( 'sec_admin_login_box', true )
|
173 |
+
]
|
174 |
+
] );
|
175 |
+
}
|
176 |
+
|
177 |
+
public function verifyPinRequest() :bool {
|
178 |
+
if ( !isset( $this->validPinRequest ) ) {
|
179 |
+
$this->validPinRequest = ( new Ops\VerifyPinRequest() )
|
180 |
+
->setMod( $this->getMod() )
|
181 |
+
->run();
|
182 |
+
}
|
183 |
+
return $this->validPinRequest;
|
184 |
+
}
|
185 |
+
}
|
src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/VerifySecurityAdminList.php
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Lib\SecurityAdmin;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
class VerifySecurityAdminList {
|
9 |
+
|
10 |
+
use ModConsumer;
|
11 |
+
|
12 |
+
public function run( array $users ) :array {
|
13 |
+
$WPU = Services::WpUsers();
|
14 |
+
|
15 |
+
$filtered = [];
|
16 |
+
foreach ( array_map( 'trim', $users ) as $key => $usernameOrEmail ) {
|
17 |
+
$user = null;
|
18 |
+
|
19 |
+
if ( !empty( $usernameOrEmail ) ) {
|
20 |
+
if ( Services::Data()->validEmail( $usernameOrEmail ) ) {
|
21 |
+
$user = $WPU->getUserByEmail( $usernameOrEmail );
|
22 |
+
}
|
23 |
+
else {
|
24 |
+
$user = $WPU->getUserByUsername( $usernameOrEmail );
|
25 |
+
if ( is_null( $user ) && is_numeric( $usernameOrEmail ) ) {
|
26 |
+
$user = $WPU->getUserById( $usernameOrEmail );
|
27 |
+
}
|
28 |
+
}
|
29 |
+
}
|
30 |
+
|
31 |
+
if ( $user instanceof \WP_User && $user->ID > 0 && $WPU->isUserAdmin( $user ) ) {
|
32 |
+
$filtered[] = $user->user_login;
|
33 |
+
}
|
34 |
+
}
|
35 |
+
|
36 |
+
natsort( $filtered );
|
37 |
+
return array_unique( $filtered );
|
38 |
+
}
|
39 |
+
}
|
src/lib/src/Modules/SecurityAdmin/Lib/WhiteLabel/ApplyLabels.php
CHANGED
@@ -65,9 +65,7 @@ class ApplyLabels {
|
|
65 |
}
|
66 |
|
67 |
public function hideFromPluginEditor() {
|
68 |
-
|
69 |
-
$js = Services::Data()->readFileContentsUsingInclude( $con->getPath_AssetJs( 'whitelabel.js' ) );
|
70 |
-
echo sprintf( '<script type="text/javascript">%s</script>', sprintf( $js, $con->base_file ) );
|
71 |
}
|
72 |
|
73 |
/**
|
@@ -81,12 +79,20 @@ class ApplyLabels {
|
|
81 |
$labels = $mod->getWhitelabelOptions();
|
82 |
|
83 |
// these are the old white labelling keys which will be replaced upon final release of white labelling.
|
84 |
-
$
|
85 |
-
$
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
|
91 |
if ( !empty( $labels[ 'description' ] ) ) {
|
92 |
$pluginLabels[ 'Description' ] = $labels[ 'description' ];
|
65 |
}
|
66 |
|
67 |
public function hideFromPluginEditor() {
|
68 |
+
// TODO
|
|
|
|
|
69 |
}
|
70 |
|
71 |
/**
|
79 |
$labels = $mod->getWhitelabelOptions();
|
80 |
|
81 |
// these are the old white labelling keys which will be replaced upon final release of white labelling.
|
82 |
+
$serviceName = $labels[ 'name_main' ];
|
83 |
+
if ( !empty( $serviceName ) ) {
|
84 |
+
$pluginLabels[ 'Name' ] = $serviceName;
|
85 |
+
$pluginLabels[ 'Title' ] = $serviceName;
|
86 |
+
}
|
87 |
+
$companyName = $labels[ 'name_company' ];
|
88 |
+
if ( !empty( $companyName ) ) {
|
89 |
+
$pluginLabels[ 'Author' ] = $labels[ 'name_company' ];
|
90 |
+
$pluginLabels[ 'AuthorName' ] = $labels[ 'name_company' ];
|
91 |
+
}
|
92 |
+
$menuName = empty( $labels[ 'name_menu' ] ) ? $serviceName : $labels[ 'name_menu' ];
|
93 |
+
if ( !empty( $menuName ) ) {
|
94 |
+
$pluginLabels[ 'MenuTitle' ] = $menuName;
|
95 |
+
}
|
96 |
|
97 |
if ( !empty( $labels[ 'description' ] ) ) {
|
98 |
$pluginLabels[ 'Description' ] = $labels[ 'description' ];
|
src/lib/src/Modules/SecurityAdmin/ModCon.php
CHANGED
@@ -20,6 +20,11 @@ class ModCon extends BaseShield\ModCon {
|
|
20 |
*/
|
21 |
private $whitelabelCon;
|
22 |
|
|
|
|
|
|
|
|
|
|
|
23 |
protected function setupCustomHooks() {
|
24 |
add_action( $this->prefix( 'pre_deactivate_plugin' ), [ $this, 'preDeactivatePlugin' ] );
|
25 |
}
|
@@ -32,38 +37,22 @@ class ModCon extends BaseShield\ModCon {
|
|
32 |
return $this->whitelabelCon;
|
33 |
}
|
34 |
|
35 |
-
public function
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
* @throws \Exception
|
42 |
-
*/
|
43 |
-
protected function isReadyToExecute() :bool {
|
44 |
-
return $this->isEnabledSecurityAdmin() && parent::isReadyToExecute();
|
45 |
}
|
46 |
|
47 |
-
|
48 |
-
|
49 |
-
* admin access caps check
|
50 |
-
* @return bool
|
51 |
-
*/
|
52 |
-
public function isRegisteredSecAdminUser() {
|
53 |
-
/** @var Options $opts */
|
54 |
-
$opts = $this->getOptions();
|
55 |
-
$sUser = Services::WpUsers()->getCurrentWpUsername();
|
56 |
-
return !empty( $sUser ) && in_array( $sUser, $opts->getSecurityAdminUsers() );
|
57 |
}
|
58 |
|
59 |
protected function preProcessOptions() {
|
60 |
/** @var Options $opts */
|
61 |
$opts = $this->getOptions();
|
62 |
|
63 |
-
if ( $this->isValidSecAdminRequest() ) {
|
64 |
-
$this->setSecurityAdminStatusOnOff( true );
|
65 |
-
}
|
66 |
-
|
67 |
// Verify whitelabel images
|
68 |
if ( $this->isWlEnabled() ) {
|
69 |
foreach ( [ 'wl_menuiconurl', 'wl_dashboardlogourl', 'wl_login2fa_logourl' ] as $key ) {
|
@@ -73,85 +62,26 @@ class ModCon extends BaseShield\ModCon {
|
|
73 |
}
|
74 |
}
|
75 |
|
76 |
-
$opts->setOpt( 'sec_admin_users',
|
|
|
|
|
|
|
|
|
77 |
|
78 |
if ( hash_equals( $opts->getSecurityPIN(), self::HASH_DELETE ) ) {
|
79 |
$opts->clearSecurityAdminKey();
|
80 |
-
|
|
|
|
|
81 |
// If you delete the PIN, you also delete the sec admins. Prevents a lock out bug.
|
82 |
$opts->setOpt( 'sec_admin_users', [] );
|
83 |
}
|
84 |
}
|
85 |
|
86 |
-
/**
|
87 |
-
* Ensures that all entries are valid users.
|
88 |
-
* @param string[] $aSecUsers
|
89 |
-
* @return string[]
|
90 |
-
*/
|
91 |
-
private function verifySecAdminUsers( $aSecUsers ) {
|
92 |
-
/** @var Options $opts */
|
93 |
-
$opts = $this->getOptions();
|
94 |
-
$DP = Services::Data();
|
95 |
-
$WPU = Services::WpUsers();
|
96 |
-
|
97 |
-
$aFiltered = [];
|
98 |
-
foreach ( $aSecUsers as $nCurrentKey => $usernameOrEmail ) {
|
99 |
-
$user = null;
|
100 |
-
|
101 |
-
if ( !empty( $usernameOrEmail ) ) {
|
102 |
-
if ( $DP->validEmail( $usernameOrEmail ) ) {
|
103 |
-
$user = $WPU->getUserByEmail( $usernameOrEmail );
|
104 |
-
}
|
105 |
-
else {
|
106 |
-
$user = $WPU->getUserByUsername( $usernameOrEmail );
|
107 |
-
if ( is_null( $user ) && is_numeric( $usernameOrEmail ) ) {
|
108 |
-
$user = $WPU->getUserById( $usernameOrEmail );
|
109 |
-
}
|
110 |
-
}
|
111 |
-
}
|
112 |
-
|
113 |
-
if ( $user instanceof \WP_User && $user->ID > 0 && $WPU->isUserAdmin( $user ) ) {
|
114 |
-
$aFiltered[] = $user->user_login;
|
115 |
-
}
|
116 |
-
}
|
117 |
-
|
118 |
-
// We now run a bit of a sanity check to ensure that the current user is
|
119 |
-
// not adding users here that aren't themselves without a key to still gain access
|
120 |
-
$oCurrent = $WPU->getCurrentWpUser();
|
121 |
-
if ( !empty( $aFiltered ) && !$opts->hasSecurityPIN() && !in_array( $oCurrent->user_login, $aFiltered ) ) {
|
122 |
-
$aFiltered[] = $oCurrent->user_login;
|
123 |
-
}
|
124 |
-
|
125 |
-
natsort( $aFiltered );
|
126 |
-
return array_unique( $aFiltered );
|
127 |
-
}
|
128 |
-
|
129 |
-
public function getSecAdminTimeout() :int {
|
130 |
-
return (int)$this->getOptions()->getOpt( 'admin_access_timeout' )*MINUTE_IN_SECONDS;
|
131 |
-
}
|
132 |
-
|
133 |
-
/**
|
134 |
-
* Only returns greater than 0 if you have a valid Sec admin session
|
135 |
-
*/
|
136 |
-
public function getSecAdminTimeLeft() :int {
|
137 |
-
$nLeft = 0;
|
138 |
-
if ( $this->getCon()->getModule_Sessions()->getSessionCon()->hasSession() ) {
|
139 |
-
|
140 |
-
$nSecAdminAt = $this->getSession()->getSecAdminAt();
|
141 |
-
if ( $this->isRegisteredSecAdminUser() ) {
|
142 |
-
$nLeft = 0;
|
143 |
-
}
|
144 |
-
elseif ( $nSecAdminAt > 0 ) {
|
145 |
-
$nLeft = $this->getSecAdminTimeout() - ( Services::Request()->ts() - $nSecAdminAt );
|
146 |
-
}
|
147 |
-
}
|
148 |
-
return (int)max( 0, $nLeft );
|
149 |
-
}
|
150 |
-
|
151 |
protected function handleModAction( string $action ) {
|
152 |
switch ( $action ) {
|
153 |
case 'remove_secadmin_confirm':
|
154 |
-
( new Lib\
|
155 |
->setMod( $this )
|
156 |
->remove();
|
157 |
break;
|
@@ -161,72 +91,10 @@ class ModCon extends BaseShield\ModCon {
|
|
161 |
}
|
162 |
}
|
163 |
|
164 |
-
public function isSecAdminSessionValid() :bool {
|
165 |
-
return $this->getSecAdminTimeLeft() > 0;
|
166 |
-
}
|
167 |
-
|
168 |
-
public function isEnabledSecurityAdmin() :bool {
|
169 |
-
/** @var Options $opts */
|
170 |
-
$opts = $this->getOptions();
|
171 |
-
return $this->isModOptEnabled() &&
|
172 |
-
( count( $opts->getSecurityAdminUsers() ) > 0 ||
|
173 |
-
( $opts->hasSecurityPIN() && $this->getSecAdminTimeout() > 0 )
|
174 |
-
);
|
175 |
-
}
|
176 |
-
|
177 |
/**
|
178 |
-
* @
|
179 |
-
* @
|
180 |
*/
|
181 |
-
public function setSecurityAdminStatusOnOff( $bSetOn = false ) {
|
182 |
-
/** @var Shield\Databases\Session\Update $oUpdater */
|
183 |
-
$oUpdater = $this->getDbHandler_Sessions()->getQueryUpdater();
|
184 |
-
return $bSetOn ?
|
185 |
-
$oUpdater->startSecurityAdmin( $this->getSession() )
|
186 |
-
: $oUpdater->terminateSecurityAdmin( $this->getSession() );
|
187 |
-
}
|
188 |
-
|
189 |
-
public function isValidSecAdminRequest() :bool {
|
190 |
-
return $this->isAccessKeyRequest() && $this->testSecAccessKeyRequest();
|
191 |
-
}
|
192 |
-
|
193 |
-
public function testSecAccessKeyRequest() :bool {
|
194 |
-
if ( !isset( $this->bValidSecAdminRequest ) ) {
|
195 |
-
$bValid = false;
|
196 |
-
$sReqKey = Services::Request()->post( 'sec_admin_key' );
|
197 |
-
if ( !empty( $sReqKey ) ) {
|
198 |
-
/** @var Options $opts */
|
199 |
-
$opts = $this->getOptions();
|
200 |
-
$bValid = hash_equals( $opts->getSecurityPIN(), md5( $sReqKey ) );
|
201 |
-
if ( !$bValid ) {
|
202 |
-
$sEscaped = isset( $_POST[ 'sec_admin_key' ] ) ? $_POST[ 'sec_admin_key' ] : '';
|
203 |
-
if ( !empty( $sEscaped ) ) {
|
204 |
-
// Workaround for escaping of passwords
|
205 |
-
$bValid = hash_equals( $opts->getSecurityPIN(), md5( $sEscaped ) );
|
206 |
-
if ( $bValid ) {
|
207 |
-
$opts->setOpt( 'admin_access_key', md5( $sReqKey ) );
|
208 |
-
}
|
209 |
-
}
|
210 |
-
}
|
211 |
-
|
212 |
-
$this->getCon()->fireEvent( $bValid ? 'key_success' : 'key_fail' );
|
213 |
-
}
|
214 |
-
|
215 |
-
$this->bValidSecAdminRequest = $bValid;
|
216 |
-
}
|
217 |
-
return $this->bValidSecAdminRequest;
|
218 |
-
}
|
219 |
-
|
220 |
-
private function isAccessKeyRequest() :bool {
|
221 |
-
return strlen( Services::Request()->post( 'sec_admin_key', '' ) ) > 0;
|
222 |
-
}
|
223 |
-
|
224 |
-
public function verifyAccessKey( string $key ) :bool {
|
225 |
-
/** @var Options $opts */
|
226 |
-
$opts = $this->getOptions();
|
227 |
-
return !empty( $key ) && hash_equals( $opts->getSecurityPIN(), md5( $key ) );
|
228 |
-
}
|
229 |
-
|
230 |
public function getWhitelabelOptions() :array {
|
231 |
$opts = $this->getOptions();
|
232 |
$main = $opts->getOpt( 'wl_pluginnamemain' );
|
@@ -288,6 +156,7 @@ class ModCon extends BaseShield\ModCon {
|
|
288 |
}
|
289 |
|
290 |
/**
|
|
|
291 |
* @param string $pin
|
292 |
* @return $this
|
293 |
* @throws \Exception
|
@@ -302,44 +171,11 @@ class ModCon extends BaseShield\ModCon {
|
|
302 |
|
303 |
$this->setIsMainFeatureEnabled( true );
|
304 |
$this->getOptions()->setOpt( 'admin_access_key', md5( $pin ) );
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
public function getScriptLocalisations() :array {
|
309 |
-
$locals = parent::getScriptLocalisations();
|
310 |
-
|
311 |
-
if ( $this->getSecAdminTimeLeft() > 0 ) {
|
312 |
-
$data = [
|
313 |
-
'ajax' => [
|
314 |
-
'check' => $this->getSecAdminCheckAjaxData(),
|
315 |
-
],
|
316 |
-
'is_sec_admin' => true, // if $nSecTimeLeft > 0
|
317 |
-
'timeleft' => $this->getSecAdminTimeLeft(), // JS uses milliseconds
|
318 |
-
'strings' => [
|
319 |
-
'confirm' => __( 'Security Admin session has timed-out.', 'wp-simple-firewall' ).' '.__( 'Reload now?', 'wp-simple-firewall' ),
|
320 |
-
'nearly' => __( 'Security Admin session has nearly timed-out.', 'wp-simple-firewall' ),
|
321 |
-
'expired' => __( 'Security Admin session has timed-out.', 'wp-simple-firewall' )
|
322 |
-
]
|
323 |
-
];
|
324 |
-
}
|
325 |
-
else {
|
326 |
-
$data = [
|
327 |
-
'ajax' => [
|
328 |
-
'req_email_remove' => $this->getAjaxActionData( 'req_email_remove' ),
|
329 |
-
],
|
330 |
-
'strings' => [
|
331 |
-
'are_you_sure' => __( 'Are you sure?', 'wp-simple-firewall' )
|
332 |
-
]
|
333 |
-
];
|
334 |
-
}
|
335 |
-
|
336 |
-
$locals[] = [
|
337 |
-
'plugin',
|
338 |
-
'icwp_wpsf_vars_secadmin',
|
339 |
-
$data
|
340 |
-
];
|
341 |
|
342 |
-
return $
|
343 |
}
|
344 |
|
345 |
/**
|
@@ -350,11 +186,11 @@ class ModCon extends BaseShield\ModCon {
|
|
350 |
$opts = $this->getOptions();
|
351 |
|
352 |
// Restricting Activate Plugins also means restricting the rest.
|
353 |
-
$
|
354 |
-
if ( in_array( 'activate_plugins', $
|
355 |
$opts->setOpt(
|
356 |
'admin_access_restrict_plugins',
|
357 |
-
array_unique( array_merge( $
|
358 |
'install_plugins',
|
359 |
'update_plugins',
|
360 |
'delete_plugins'
|
@@ -363,11 +199,11 @@ class ModCon extends BaseShield\ModCon {
|
|
363 |
}
|
364 |
|
365 |
// Restricting Switch (Activate) Themes also means restricting the rest.
|
366 |
-
$
|
367 |
-
if ( in_array( 'switch_themes', $
|
368 |
$opts->setOpt(
|
369 |
'admin_access_restrict_themes',
|
370 |
-
array_unique( array_merge( $
|
371 |
'install_themes',
|
372 |
'update_themes',
|
373 |
'delete_themes'
|
@@ -375,11 +211,11 @@ class ModCon extends BaseShield\ModCon {
|
|
375 |
);
|
376 |
}
|
377 |
|
378 |
-
$
|
379 |
-
if ( in_array( 'edit', $
|
380 |
$opts->setOpt(
|
381 |
'admin_access_restrict_posts',
|
382 |
-
array_unique( array_merge( $
|
383 |
);
|
384 |
}
|
385 |
}
|
@@ -395,4 +231,116 @@ class ModCon extends BaseShield\ModCon {
|
|
395 |
);
|
396 |
}
|
397 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
398 |
}
|
20 |
*/
|
21 |
private $whitelabelCon;
|
22 |
|
23 |
+
/**
|
24 |
+
* @var Lib\SecurityAdmin\SecurityAdminController
|
25 |
+
*/
|
26 |
+
private $securityAdminCon;
|
27 |
+
|
28 |
protected function setupCustomHooks() {
|
29 |
add_action( $this->prefix( 'pre_deactivate_plugin' ), [ $this, 'preDeactivatePlugin' ] );
|
30 |
}
|
37 |
return $this->whitelabelCon;
|
38 |
}
|
39 |
|
40 |
+
public function getSecurityAdminController() :Lib\SecurityAdmin\SecurityAdminController {
|
41 |
+
if ( !$this->securityAdminCon instanceof Lib\SecurityAdmin\SecurityAdminController ) {
|
42 |
+
$this->securityAdminCon = ( new Lib\SecurityAdmin\SecurityAdminController() )
|
43 |
+
->setMod( $this );
|
44 |
+
}
|
45 |
+
return $this->securityAdminCon;
|
|
|
|
|
|
|
|
|
46 |
}
|
47 |
|
48 |
+
public function getSecAdminLoginAjaxData() :array {
|
49 |
+
return $this->getAjaxActionData( 'sec_admin_login' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
}
|
51 |
|
52 |
protected function preProcessOptions() {
|
53 |
/** @var Options $opts */
|
54 |
$opts = $this->getOptions();
|
55 |
|
|
|
|
|
|
|
|
|
56 |
// Verify whitelabel images
|
57 |
if ( $this->isWlEnabled() ) {
|
58 |
foreach ( [ 'wl_menuiconurl', 'wl_dashboardlogourl', 'wl_login2fa_logourl' ] as $key ) {
|
62 |
}
|
63 |
}
|
64 |
|
65 |
+
$opts->setOpt( 'sec_admin_users',
|
66 |
+
( new Lib\SecurityAdmin\VerifySecurityAdminList() )
|
67 |
+
->setMod( $this )
|
68 |
+
->run( $opts->getSecurityAdminUsers() )
|
69 |
+
);
|
70 |
|
71 |
if ( hash_equals( $opts->getSecurityPIN(), self::HASH_DELETE ) ) {
|
72 |
$opts->clearSecurityAdminKey();
|
73 |
+
( new Lib\SecurityAdmin\Ops\ToggleSecAdminStatus() )
|
74 |
+
->setMod( $this )
|
75 |
+
->turnOff();
|
76 |
// If you delete the PIN, you also delete the sec admins. Prevents a lock out bug.
|
77 |
$opts->setOpt( 'sec_admin_users', [] );
|
78 |
}
|
79 |
}
|
80 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
protected function handleModAction( string $action ) {
|
82 |
switch ( $action ) {
|
83 |
case 'remove_secadmin_confirm':
|
84 |
+
( new Lib\SecurityAdmin\Ops\RemoveSecAdmin() )
|
85 |
->setMod( $this )
|
86 |
->remove();
|
87 |
break;
|
91 |
}
|
92 |
}
|
93 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
/**
|
95 |
+
* @return array
|
96 |
+
* @deprecated 11.1
|
97 |
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
public function getWhitelabelOptions() :array {
|
99 |
$opts = $this->getOptions();
|
100 |
$main = $opts->getOpt( 'wl_pluginnamemain' );
|
156 |
}
|
157 |
|
158 |
/**
|
159 |
+
* Used by Wizard. TODO: sort out the wizard requests!
|
160 |
* @param string $pin
|
161 |
* @return $this
|
162 |
* @throws \Exception
|
171 |
|
172 |
$this->setIsMainFeatureEnabled( true );
|
173 |
$this->getOptions()->setOpt( 'admin_access_key', md5( $pin ) );
|
174 |
+
( new Lib\SecurityAdmin\Ops\ToggleSecAdminStatus() )
|
175 |
+
->setMod( $this )
|
176 |
+
->turnOn();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
177 |
|
178 |
+
return $this->saveModOptions();
|
179 |
}
|
180 |
|
181 |
/**
|
186 |
$opts = $this->getOptions();
|
187 |
|
188 |
// Restricting Activate Plugins also means restricting the rest.
|
189 |
+
$pluginsRestrictions = $opts->getAdminAccessArea_Plugins();
|
190 |
+
if ( in_array( 'activate_plugins', $pluginsRestrictions ) ) {
|
191 |
$opts->setOpt(
|
192 |
'admin_access_restrict_plugins',
|
193 |
+
array_unique( array_merge( $pluginsRestrictions, [
|
194 |
'install_plugins',
|
195 |
'update_plugins',
|
196 |
'delete_plugins'
|
199 |
}
|
200 |
|
201 |
// Restricting Switch (Activate) Themes also means restricting the rest.
|
202 |
+
$themesRestrictions = $opts->getAdminAccessArea_Themes();
|
203 |
+
if ( in_array( 'switch_themes', $themesRestrictions ) && in_array( 'edit_theme_options', $themesRestrictions ) ) {
|
204 |
$opts->setOpt(
|
205 |
'admin_access_restrict_themes',
|
206 |
+
array_unique( array_merge( $themesRestrictions, [
|
207 |
'install_themes',
|
208 |
'update_themes',
|
209 |
'delete_themes'
|
211 |
);
|
212 |
}
|
213 |
|
214 |
+
$postRestrictions = $opts->getAdminAccessArea_Posts();
|
215 |
+
if ( in_array( 'edit', $postRestrictions ) ) {
|
216 |
$opts->setOpt(
|
217 |
'admin_access_restrict_posts',
|
218 |
+
array_unique( array_merge( $postRestrictions, [ 'create', 'publish', 'delete' ] ) )
|
219 |
);
|
220 |
}
|
221 |
}
|
231 |
);
|
232 |
}
|
233 |
}
|
234 |
+
|
235 |
+
/**
|
236 |
+
* No checking of admin capabilities in-case of infinite loop with
|
237 |
+
* admin access caps check
|
238 |
+
* @return bool
|
239 |
+
* @deprecated 11.1
|
240 |
+
*/
|
241 |
+
public function isRegisteredSecAdminUser() {
|
242 |
+
/** @var Options $opts */
|
243 |
+
$opts = $this->getOptions();
|
244 |
+
$sUser = Services::WpUsers()->getCurrentWpUsername();
|
245 |
+
return !empty( $sUser ) && in_array( $sUser, $opts->getSecurityAdminUsers() );
|
246 |
+
}
|
247 |
+
|
248 |
+
/**
|
249 |
+
* @return bool
|
250 |
+
* @deprecated 11.1
|
251 |
+
*/
|
252 |
+
public function isEnabledSecurityAdmin() :bool {
|
253 |
+
/** @var Options $opts */
|
254 |
+
$opts = $this->getOptions();
|
255 |
+
return $this->isModOptEnabled() &&
|
256 |
+
( count( $opts->getSecurityAdminUsers() ) > 0 ||
|
257 |
+
( $opts->hasSecurityPIN() && $this->getSecAdminTimeout() > 0 )
|
258 |
+
);
|
259 |
+
}
|
260 |
+
|
261 |
+
/**
|
262 |
+
* @return bool
|
263 |
+
* @deprecated 11.1
|
264 |
+
*/
|
265 |
+
public function isSecAdminSessionValid() :bool {
|
266 |
+
return $this->getSecAdminTimeLeft() > 0;
|
267 |
+
}
|
268 |
+
|
269 |
+
/**
|
270 |
+
* Only returns greater than 0 if you have a valid Sec admin session
|
271 |
+
* @deprecated 11.1
|
272 |
+
*/
|
273 |
+
public function getSecAdminTimeLeft() :int {
|
274 |
+
$nLeft = 0;
|
275 |
+
if ( $this->getCon()->getModule_Sessions()->getSessionCon()->hasSession() ) {
|
276 |
+
|
277 |
+
$nSecAdminAt = $this->getSession()->getSecAdminAt();
|
278 |
+
if ( $this->isRegisteredSecAdminUser() ) {
|
279 |
+
$nLeft = 0;
|
280 |
+
}
|
281 |
+
elseif ( $nSecAdminAt > 0 ) {
|
282 |
+
$nLeft = $this->getSecAdminTimeout() - ( Services::Request()->ts() - $nSecAdminAt );
|
283 |
+
}
|
284 |
+
}
|
285 |
+
return (int)max( 0, $nLeft );
|
286 |
+
}
|
287 |
+
|
288 |
+
/**
|
289 |
+
* @return int
|
290 |
+
* @deprecated 11.1
|
291 |
+
*/
|
292 |
+
public function getSecAdminTimeout() :int {
|
293 |
+
return (int)$this->getOptions()->getOpt( 'admin_access_timeout' )*MINUTE_IN_SECONDS;
|
294 |
+
}
|
295 |
+
|
296 |
+
/**
|
297 |
+
* Ensures that all entries are valid users.
|
298 |
+
* @param string[] $aSecUsers
|
299 |
+
* @return string[]
|
300 |
+
* @deprecated 11.1
|
301 |
+
*/
|
302 |
+
private function verifySecAdminUsers( $aSecUsers ) {
|
303 |
+
return $aSecUsers;
|
304 |
+
}
|
305 |
+
|
306 |
+
/**
|
307 |
+
* @return bool
|
308 |
+
* @deprecated 11.1
|
309 |
+
*/
|
310 |
+
private function isAccessKeyRequest() :bool {
|
311 |
+
return strlen( Services::Request()->post( 'sec_admin_key', '' ) ) > 0;
|
312 |
+
}
|
313 |
+
|
314 |
+
public function verifyAccessKey( string $key ) :bool {
|
315 |
+
/** @var Options $opts */
|
316 |
+
$opts = $this->getOptions();
|
317 |
+
return !empty( $key ) && hash_equals( $opts->getSecurityPIN(), md5( $key ) );
|
318 |
+
}
|
319 |
+
|
320 |
+
/**
|
321 |
+
* @return bool
|
322 |
+
* @deprecated 11.1
|
323 |
+
*/
|
324 |
+
public function testSecAccessKeyRequest() :bool {
|
325 |
+
return ( new Lib\SecurityAdmin\Ops\VerifyPinRequest() )
|
326 |
+
->setMod( $this )
|
327 |
+
->run();
|
328 |
+
}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* @return bool
|
332 |
+
* @deprecated 11.1
|
333 |
+
*/
|
334 |
+
public function isValidSecAdminRequest() :bool {
|
335 |
+
return false;
|
336 |
+
}
|
337 |
+
|
338 |
+
/**
|
339 |
+
* @param bool $bSetOn
|
340 |
+
* @return bool
|
341 |
+
* @deprecated 11.1
|
342 |
+
*/
|
343 |
+
public function setSecurityAdminStatusOnOff( $bSetOn = false ) {
|
344 |
+
return false;
|
345 |
+
}
|
346 |
}
|
src/lib/src/Modules/SecurityAdmin/Options.php
CHANGED
@@ -27,9 +27,20 @@ class Options extends BaseShield\Options {
|
|
27 |
return $this->getAdminAccessArea( 'posts' );
|
28 |
}
|
29 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
/**
|
31 |
* @param string $sArea one of plugins, themes
|
32 |
* @return array
|
|
|
33 |
*/
|
34 |
private function getAdminAccessArea( $sArea = 'plugins' ) :array {
|
35 |
$d = $this->getOpt( 'admin_access_restrict_'.$sArea, [] );
|
@@ -48,8 +59,8 @@ class Options extends BaseShield\Options {
|
|
48 |
*/
|
49 |
public function getOptionsToRestrict( $type = '' ) {
|
50 |
$type = empty( $type ) ? ( Services::WpGeneral()->isMultisite() ? 'wpms' : 'wp' ) : 'wp';
|
51 |
-
$
|
52 |
-
return ( isset( $
|
53 |
}
|
54 |
|
55 |
/**
|
27 |
return $this->getAdminAccessArea( 'posts' );
|
28 |
}
|
29 |
|
30 |
+
/**
|
31 |
+
* @param string $area one of plugins, themes
|
32 |
+
* @return array
|
33 |
+
* @since 11.1
|
34 |
+
*/
|
35 |
+
public function getSecAdminAreaCaps( $area = 'plugins' ) :array {
|
36 |
+
$d = $this->getOpt( 'admin_access_restrict_'.$area, [] );
|
37 |
+
return is_array( $d ) ? $d : [];
|
38 |
+
}
|
39 |
+
|
40 |
/**
|
41 |
* @param string $sArea one of plugins, themes
|
42 |
* @return array
|
43 |
+
* @deprecated 11.1
|
44 |
*/
|
45 |
private function getAdminAccessArea( $sArea = 'plugins' ) :array {
|
46 |
$d = $this->getOpt( 'admin_access_restrict_'.$sArea, [] );
|
59 |
*/
|
60 |
public function getOptionsToRestrict( $type = '' ) {
|
61 |
$type = empty( $type ) ? ( Services::WpGeneral()->isMultisite() ? 'wpms' : 'wp' ) : 'wp';
|
62 |
+
$options = $this->getRestrictedOptions();
|
63 |
+
return ( isset( $options[ $type.'_options' ] ) && is_array( $options[ $type.'_options' ] ) ) ? $options[ $type.'_options' ] : [];
|
64 |
}
|
65 |
|
66 |
/**
|
src/lib/src/Modules/SecurityAdmin/Processor.php
CHANGED
@@ -3,167 +3,72 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield;
|
6 |
-
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
8 |
class Processor extends BaseShield\Processor {
|
9 |
|
10 |
protected function run() {
|
11 |
-
|
|
|
12 |
|
13 |
/** @var Options $opts */
|
14 |
$opts = $this->getOptions();
|
15 |
if ( $opts->isEnabledWhitelabel() ) {
|
16 |
-
/** @var ModCon $mod */
|
17 |
-
$mod = $this->getMod();
|
18 |
$mod->getWhiteLabelController()->execute();
|
19 |
}
|
|
|
|
|
20 |
}
|
21 |
|
22 |
/**
|
23 |
* @param bool $bHasPermission
|
24 |
* @return bool
|
|
|
25 |
*/
|
26 |
public function adjustUserAdminPermissions( $bHasPermission = true ) :bool {
|
27 |
-
|
28 |
-
$mod = $this->getMod();
|
29 |
-
return $bHasPermission &&
|
30 |
-
( $mod->isRegisteredSecAdminUser() || $mod->isSecAdminSessionValid()
|
31 |
-
|| $mod->testSecAccessKeyRequest() );
|
32 |
}
|
33 |
|
34 |
public function onWpInit() {
|
35 |
-
if ( !$this->getCon()->isPluginAdmin() ) {
|
36 |
-
/** @var ModCon $mod */
|
37 |
-
$mod = $this->getMod();
|
38 |
-
/** @var Options $opts */
|
39 |
-
$opts = $this->getOptions();
|
40 |
-
|
41 |
-
if ( !$mod->isUpgrading() && !Services::WpGeneral()->isLoginRequest() ) {
|
42 |
-
add_filter( 'pre_update_option', [ $this, 'blockOptionsSaves' ], 1, 3 );
|
43 |
-
}
|
44 |
-
|
45 |
-
if ( $opts->isSecAdminRestrictUsersEnabled() ) {
|
46 |
-
add_filter( 'editable_roles', [ $this, 'restrictEditableRoles' ], 100, 1 );
|
47 |
-
add_filter( 'user_has_cap', [ $this, 'restrictAdminUserChanges' ], 100, 3 );
|
48 |
-
add_action( 'delete_user', [ $this, 'restrictAdminUserDelete' ], 100, 1 );
|
49 |
-
add_action( 'add_user_role', [ $this, 'restrictAddUserRole' ], 100, 2 );
|
50 |
-
add_action( 'remove_user_role', [ $this, 'restrictRemoveUserRole' ], 100, 2 );
|
51 |
-
add_action( 'set_user_role', [ $this, 'restrictSetUserRole' ], 100, 3 );
|
52 |
-
}
|
53 |
-
|
54 |
-
$aPluginRestrictions = $opts->getAdminAccessArea_Plugins();
|
55 |
-
if ( !empty( $aPluginRestrictions ) ) {
|
56 |
-
add_filter( 'user_has_cap', [ $this, 'disablePluginManipulation' ], 0, 3 );
|
57 |
-
}
|
58 |
-
|
59 |
-
$aThemeRestrictions = $opts->getAdminAccessArea_Themes();
|
60 |
-
if ( !empty( $aThemeRestrictions ) ) {
|
61 |
-
add_filter( 'user_has_cap', [ $this, 'disableThemeManipulation' ], 0, 3 );
|
62 |
-
}
|
63 |
-
|
64 |
-
$aPostRestrictions = $opts->getAdminAccessArea_Posts();
|
65 |
-
if ( !empty( $aPostRestrictions ) ) {
|
66 |
-
add_filter( 'user_has_cap', [ $this, 'disablePostsManipulation' ], 0, 3 );
|
67 |
-
}
|
68 |
-
|
69 |
-
if ( !$this->getCon()->isThisPluginModuleRequest() ) {
|
70 |
-
add_action( 'admin_footer', [ $this, 'printAdminAccessAjaxForm' ] );
|
71 |
-
}
|
72 |
-
}
|
73 |
}
|
74 |
|
75 |
/**
|
76 |
* @param int $nUserId
|
77 |
* @param string $sRole
|
|
|
78 |
*/
|
79 |
public function restrictAddUserRole( $nUserId, $sRole ) {
|
80 |
-
$oWpUsers = Services::WpUsers();
|
81 |
-
|
82 |
-
if ( $oWpUsers->getCurrentWpUserId() !== $nUserId && strtolower( $sRole ) === 'administrator' ) {
|
83 |
-
$oModUser = $oWpUsers->getUserById( $nUserId );
|
84 |
-
remove_action( 'remove_user_role', [ $this, 'restrictRemoveUserRole' ], 100 );
|
85 |
-
$oModUser->remove_role( 'administrator' );
|
86 |
-
add_action( 'remove_user_role', [ $this, 'restrictRemoveUserRole' ], 100, 2 );
|
87 |
-
}
|
88 |
}
|
89 |
|
90 |
/**
|
91 |
* @param int $nUserId
|
92 |
* @param string $sRole
|
93 |
* @param array $aOldRoles
|
|
|
94 |
*/
|
95 |
public function restrictSetUserRole( $nUserId, $sRole, $aOldRoles = [] ) {
|
96 |
-
$oWpUsers = Services::WpUsers();
|
97 |
-
|
98 |
-
$sRole = strtolower( $sRole );
|
99 |
-
if ( !is_array( $aOldRoles ) ) {
|
100 |
-
$aOldRoles = [];
|
101 |
-
}
|
102 |
-
|
103 |
-
if ( $oWpUsers->getCurrentWpUserId() !== $nUserId ) {
|
104 |
-
$bNewRoleIsAdmin = $sRole == 'administrator';
|
105 |
-
|
106 |
-
// 1. Setting administrator role where it doesn't previously exist
|
107 |
-
if ( $bNewRoleIsAdmin && !in_array( 'administrator', $aOldRoles ) ) {
|
108 |
-
$bRevert = true;
|
109 |
-
}
|
110 |
-
// 2. Setting non-administrator role when previous roles included administrator
|
111 |
-
elseif ( !$bNewRoleIsAdmin && in_array( 'administrator', $aOldRoles ) ) {
|
112 |
-
$bRevert = true;
|
113 |
-
}
|
114 |
-
else {
|
115 |
-
$bRevert = false;
|
116 |
-
}
|
117 |
-
|
118 |
-
if ( $bRevert ) {
|
119 |
-
$oModUser = $oWpUsers->getUserById( $nUserId );
|
120 |
-
remove_action( 'add_user_role', [ $this, 'restrictAddUserRole' ], 100 );
|
121 |
-
remove_action( 'remove_user_role', [ $this, 'restrictRemoveUserRole' ], 100 );
|
122 |
-
$oModUser->remove_role( $sRole );
|
123 |
-
foreach ( $aOldRoles as $sPreExistingRoles ) {
|
124 |
-
$oModUser->add_role( $sPreExistingRoles );
|
125 |
-
}
|
126 |
-
add_action( 'add_user_role', [ $this, 'restrictAddUserRole' ], 100, 2 );
|
127 |
-
add_action( 'remove_user_role', [ $this, 'restrictRemoveUserRole' ], 100, 2 );
|
128 |
-
}
|
129 |
-
}
|
130 |
}
|
131 |
|
132 |
/**
|
133 |
* @param int $nUserId
|
134 |
* @param string $sRole
|
|
|
135 |
*/
|
136 |
public function restrictRemoveUserRole( $nUserId, $sRole ) {
|
137 |
-
$oWpUsers = Services::WpUsers();
|
138 |
-
|
139 |
-
if ( $oWpUsers->getCurrentWpUserId() !== $nUserId && strtolower( $sRole ) === 'administrator' ) {
|
140 |
-
$oModUser = $oWpUsers->getUserById( $nUserId );
|
141 |
-
remove_action( 'add_user_role', [ $this, 'restrictAddUserRole' ], 100 );
|
142 |
-
$oModUser->add_role( 'administrator' );
|
143 |
-
add_action( 'add_user_role', [ $this, 'restrictAddUserRole' ], 100, 2 );
|
144 |
-
}
|
145 |
}
|
146 |
|
147 |
/**
|
148 |
* @param int $nId
|
|
|
149 |
*/
|
150 |
public function restrictAdminUserDelete( $nId ) {
|
151 |
-
$WPU = Services::WpUsers();
|
152 |
-
$oUserToDelete = $WPU->getUserById( $nId );
|
153 |
-
if ( $oUserToDelete && $WPU->isUserAdmin( $oUserToDelete ) ) {
|
154 |
-
Services::WpGeneral()
|
155 |
-
->wpDie( __( 'Sorry, deleting administrators is currently restricted to your Security Admin', 'wp-simple-firewall' ) );
|
156 |
-
}
|
157 |
}
|
158 |
|
159 |
/**
|
160 |
* @param array[] $roles
|
161 |
* @return array[]
|
|
|
162 |
*/
|
163 |
public function restrictEditableRoles( $roles ) {
|
164 |
-
if ( isset( $roles[ 'administrator' ] ) ) {
|
165 |
-
unset( $roles[ 'administrator' ] );
|
166 |
-
}
|
167 |
return $roles;
|
168 |
}
|
169 |
|
@@ -175,88 +80,29 @@ class Processor extends BaseShield\Processor {
|
|
175 |
* @param $cap
|
176 |
* @param array $args
|
177 |
* @return array
|
|
|
178 |
*/
|
179 |
public function restrictAdminUserChanges( $allCaps, $cap, $args ) {
|
180 |
-
/** @var string $userCap */
|
181 |
-
$userCap = $args[ 0 ];
|
182 |
-
|
183 |
-
$aRelevantCaps = [ 'edit_users', 'create_users' ];
|
184 |
-
|
185 |
-
// If we're registered with Admin Access we don't modify anything
|
186 |
-
if ( in_array( $userCap, $aRelevantCaps ) ) {
|
187 |
-
$bBlockCapability = false;
|
188 |
-
|
189 |
-
$req = Services::Request();
|
190 |
-
$oWpUsers = Services::WpUsers();
|
191 |
-
|
192 |
-
$oPostUser = false;
|
193 |
-
$sPostUserlogin = $req->post( 'user_login' );
|
194 |
-
if ( empty( $sPostUserlogin ) ) {
|
195 |
-
$nPostUserId = $req->post( 'user_id' );
|
196 |
-
if ( !empty( $nPostUserId ) ) {
|
197 |
-
$oPostUser = $oWpUsers->getUserById( $nPostUserId );
|
198 |
-
}
|
199 |
-
}
|
200 |
-
else {
|
201 |
-
$oPostUser = $oWpUsers->getUserByUsername( $sPostUserlogin );
|
202 |
-
}
|
203 |
-
|
204 |
-
$sRequestRole = strtolower( $req->post( 'role', '' ) );
|
205 |
-
|
206 |
-
if ( $oPostUser instanceof \WP_User ) {
|
207 |
-
// editing an existing user other than yourself?
|
208 |
-
if ( $oPostUser->user_login != $oWpUsers->getCurrentWpUsername() ) {
|
209 |
-
|
210 |
-
if ( $oWpUsers->isUserAdmin( $oPostUser ) || ( $sRequestRole == 'administrator' ) ) {
|
211 |
-
$bBlockCapability = true;
|
212 |
-
}
|
213 |
-
}
|
214 |
-
}
|
215 |
-
elseif ( $sRequestRole == 'administrator' ) { //creating a new admin user?
|
216 |
-
$bBlockCapability = true;
|
217 |
-
}
|
218 |
-
|
219 |
-
if ( $bBlockCapability ) {
|
220 |
-
$allCaps[ $userCap ] = false;
|
221 |
-
}
|
222 |
-
}
|
223 |
-
|
224 |
return $allCaps;
|
225 |
}
|
226 |
|
227 |
-
protected function getUserPagesToRestrict() :array {
|
228 |
-
return [
|
229 |
-
/* 'user-new.php', */
|
230 |
-
'user-edit.php',
|
231 |
-
'users.php',
|
232 |
-
];
|
233 |
-
}
|
234 |
-
|
235 |
/**
|
236 |
-
*
|
237 |
-
* permit saving by the plugin itself.
|
238 |
-
*
|
239 |
-
* Right before a plugin option is due to update it will check that we have permissions to do so
|
240 |
-
* and if not, will * revert the option to save to the previous one.
|
241 |
-
* @param mixed $mNewOptionValue
|
242 |
-
* @param string $key
|
243 |
-
* @param mixed $mOldValue
|
244 |
-
* @return mixed
|
245 |
*/
|
246 |
public function blockOptionsSaves( $mNewOptionValue, $key, $mOldValue ) {
|
247 |
-
|
248 |
-
if ( !$this->getCon()->isPluginAdmin() && is_string( $key )
|
249 |
-
&& ( $this->isOptionForThisPlugin( $key ) || $this->isOptionRestricted( $key ) ) ) {
|
250 |
-
$mNewOptionValue = $mOldValue;
|
251 |
-
}
|
252 |
-
|
253 |
return $mNewOptionValue;
|
254 |
}
|
255 |
|
|
|
|
|
|
|
256 |
private function isOptionForThisPlugin( string $key ) :bool {
|
257 |
return preg_match( $this->getOptionRegexPattern(), $key ) > 0;
|
258 |
}
|
259 |
|
|
|
|
|
|
|
260 |
private function isOptionRestricted( string $key ) :bool {
|
261 |
/** @var Options $opts */
|
262 |
$opts = $this->getOptions();
|
@@ -269,33 +115,9 @@ class Processor extends BaseShield\Processor {
|
|
269 |
* @param $cap
|
270 |
* @param array $aArgs
|
271 |
* @return array
|
|
|
272 |
*/
|
273 |
public function disablePluginManipulation( $aAllCaps, $cap, $aArgs ) {
|
274 |
-
/** @var Options $opts */
|
275 |
-
$opts = $this->getOptions();
|
276 |
-
$req = Services::Request();
|
277 |
-
|
278 |
-
/** @var string $sRequestedCapability */
|
279 |
-
$sRequestedCapability = $aArgs[ 0 ];
|
280 |
-
|
281 |
-
// special case for plugin info thickbox for changelog
|
282 |
-
$bIsChangelog = defined( 'IFRAME_REQUEST' )
|
283 |
-
&& ( $sRequestedCapability === 'install_plugins' )
|
284 |
-
&& ( $req->query( 'section' ) == 'changelog' )
|
285 |
-
&& $req->query( 'plugin' );
|
286 |
-
if ( $bIsChangelog ) {
|
287 |
-
return $aAllCaps;
|
288 |
-
}
|
289 |
-
|
290 |
-
$aEditCapabilities = [ 'activate_plugins', 'delete_plugins', 'install_plugins', 'update_plugins' ];
|
291 |
-
|
292 |
-
if ( in_array( $sRequestedCapability, $aEditCapabilities ) ) {
|
293 |
-
$aAreaRestrictions = $opts->getAdminAccessArea_Plugins();
|
294 |
-
if ( in_array( $sRequestedCapability, $aAreaRestrictions ) ) {
|
295 |
-
$aAllCaps[ $sRequestedCapability ] = false;
|
296 |
-
}
|
297 |
-
}
|
298 |
-
|
299 |
return $aAllCaps;
|
300 |
}
|
301 |
|
@@ -304,6 +126,7 @@ class Processor extends BaseShield\Processor {
|
|
304 |
* @param $cap
|
305 |
* @param array $aArgs
|
306 |
* @return array
|
|
|
307 |
*/
|
308 |
public function disableThemeManipulation( $aAllCaps, $cap, $aArgs ) {
|
309 |
// If we're registered with Admin Access we don't modify anything
|
@@ -311,26 +134,6 @@ class Processor extends BaseShield\Processor {
|
|
311 |
return $aAllCaps;
|
312 |
}
|
313 |
|
314 |
-
/** @var Options $opts */
|
315 |
-
$opts = $this->getOptions();
|
316 |
-
|
317 |
-
/** @var string $sRequestedCapability */
|
318 |
-
$sRequestedCapability = $aArgs[ 0 ];
|
319 |
-
$aEditCapabilities = [
|
320 |
-
'switch_themes',
|
321 |
-
'edit_theme_options',
|
322 |
-
'install_themes',
|
323 |
-
'update_themes',
|
324 |
-
'delete_themes'
|
325 |
-
];
|
326 |
-
|
327 |
-
if ( in_array( $sRequestedCapability, $aEditCapabilities ) ) {
|
328 |
-
$aAreaRestrictions = $opts->getAdminAccessArea_Themes();
|
329 |
-
if ( in_array( $sRequestedCapability, $aAreaRestrictions ) ) {
|
330 |
-
$aAllCaps[ $sRequestedCapability ] = false;
|
331 |
-
}
|
332 |
-
}
|
333 |
-
|
334 |
return $aAllCaps;
|
335 |
}
|
336 |
|
@@ -339,88 +142,31 @@ class Processor extends BaseShield\Processor {
|
|
339 |
* @param $cap
|
340 |
* @param array $args
|
341 |
* @return array
|
|
|
342 |
*/
|
343 |
public function disablePostsManipulation( $aAllCaps, $cap, $args ) {
|
344 |
-
if ( $this->getCon()->isPluginAdmin() ) {
|
345 |
-
return $aAllCaps;
|
346 |
-
}
|
347 |
-
|
348 |
-
/** @var Options $opts */
|
349 |
-
$opts = $this->getOptions();
|
350 |
-
|
351 |
-
/** @var string $sRequestedCapability */
|
352 |
-
$sRequestedCapability = $args[ 0 ];
|
353 |
-
$aEditCapabilities = [
|
354 |
-
'edit_post',
|
355 |
-
'publish_post',
|
356 |
-
'delete_post',
|
357 |
-
'edit_posts',
|
358 |
-
'publish_posts',
|
359 |
-
'delete_posts',
|
360 |
-
'edit_page',
|
361 |
-
'publish_page',
|
362 |
-
'delete_page',
|
363 |
-
'edit_pages',
|
364 |
-
'publish_pages',
|
365 |
-
'delete_pages'
|
366 |
-
];
|
367 |
-
if ( in_array( $sRequestedCapability, $aEditCapabilities ) ) {
|
368 |
-
$sRequestedCapabilityTrimmed = str_replace( [
|
369 |
-
'_posts',
|
370 |
-
'_pages',
|
371 |
-
'_post',
|
372 |
-
'_page'
|
373 |
-
], '', $sRequestedCapability ); //Order of items in this array is important!
|
374 |
-
$aAreaRestrictions = $opts->getAdminAccessArea_Posts();
|
375 |
-
if ( in_array( $sRequestedCapabilityTrimmed, $aAreaRestrictions ) ) {
|
376 |
-
$aAllCaps[ $sRequestedCapability ] = false;
|
377 |
-
}
|
378 |
-
}
|
379 |
return $aAllCaps;
|
380 |
}
|
381 |
|
|
|
|
|
|
|
382 |
private function getOptionRegexPattern() :string {
|
383 |
return sprintf( '/^%s.*_options$/', $this->getCon()->getOptionStoragePrefix() );
|
384 |
}
|
385 |
|
|
|
|
|
|
|
386 |
public function printAdminAccessAjaxForm() {
|
387 |
-
/** @var ModCon $mod */
|
388 |
-
$mod = $this->getMod();
|
389 |
-
/** @var Options $opts */
|
390 |
-
$opts = $this->getOptions();
|
391 |
-
|
392 |
-
$aRenderData = [
|
393 |
-
'flags' => [
|
394 |
-
'restrict_options' => $opts->getAdminAccessArea_Options()
|
395 |
-
],
|
396 |
-
'strings' => [
|
397 |
-
'editing_restricted' => __( 'Editing this option is currently restricted.', 'wp-simple-firewall' ),
|
398 |
-
'unlock_link' => $this->getUnlockLinkHtml(),
|
399 |
-
],
|
400 |
-
'js_snippets' => [
|
401 |
-
'options_to_restrict' => "'".implode( "','", $opts->getOptionsToRestrict() )."'",
|
402 |
-
],
|
403 |
-
'ajax' => [
|
404 |
-
'sec_admin_login_box' => $mod->getAjaxActionData( 'sec_admin_login_box', true )
|
405 |
-
]
|
406 |
-
];
|
407 |
-
add_thickbox();
|
408 |
-
echo $mod->renderTemplate( 'snippets/admin_access_login_box.php', $aRenderData );
|
409 |
}
|
410 |
|
411 |
/**
|
412 |
* @param string $sLinkText
|
413 |
* @return string
|
|
|
414 |
*/
|
415 |
protected function getUnlockLinkHtml( $sLinkText = '' ) {
|
416 |
-
|
417 |
-
$sLinkText = __( 'Unlock', 'wp-simple-firewall' );
|
418 |
-
}
|
419 |
-
return sprintf(
|
420 |
-
'<a href="%1$s" title="%2$s" class="thickbox">%3$s</a>',
|
421 |
-
'#TB_inline?width=400&height=180&inlineId=WpsfAdminAccessLogin',
|
422 |
-
__( 'Security Admin Login', 'wp-simple-firewall' ),
|
423 |
-
$sLinkText
|
424 |
-
);
|
425 |
}
|
426 |
}
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield;
|
|
|
6 |
|
7 |
class Processor extends BaseShield\Processor {
|
8 |
|
9 |
protected function run() {
|
10 |
+
/** @var ModCon $mod */
|
11 |
+
$mod = $this->getMod();
|
12 |
|
13 |
/** @var Options $opts */
|
14 |
$opts = $this->getOptions();
|
15 |
if ( $opts->isEnabledWhitelabel() ) {
|
|
|
|
|
16 |
$mod->getWhiteLabelController()->execute();
|
17 |
}
|
18 |
+
|
19 |
+
$mod->getSecurityAdminController()->execute();
|
20 |
}
|
21 |
|
22 |
/**
|
23 |
* @param bool $bHasPermission
|
24 |
* @return bool
|
25 |
+
* @deprecated 11.1
|
26 |
*/
|
27 |
public function adjustUserAdminPermissions( $bHasPermission = true ) :bool {
|
28 |
+
return $bHasPermission;
|
|
|
|
|
|
|
|
|
29 |
}
|
30 |
|
31 |
public function onWpInit() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
}
|
33 |
|
34 |
/**
|
35 |
* @param int $nUserId
|
36 |
* @param string $sRole
|
37 |
+
* @deprecated 11.1
|
38 |
*/
|
39 |
public function restrictAddUserRole( $nUserId, $sRole ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
}
|
41 |
|
42 |
/**
|
43 |
* @param int $nUserId
|
44 |
* @param string $sRole
|
45 |
* @param array $aOldRoles
|
46 |
+
* @deprecated 11.1
|
47 |
*/
|
48 |
public function restrictSetUserRole( $nUserId, $sRole, $aOldRoles = [] ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
}
|
50 |
|
51 |
/**
|
52 |
* @param int $nUserId
|
53 |
* @param string $sRole
|
54 |
+
* @deprecated 11.1
|
55 |
*/
|
56 |
public function restrictRemoveUserRole( $nUserId, $sRole ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
}
|
58 |
|
59 |
/**
|
60 |
* @param int $nId
|
61 |
+
* @deprecated 11.1
|
62 |
*/
|
63 |
public function restrictAdminUserDelete( $nId ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
}
|
65 |
|
66 |
/**
|
67 |
* @param array[] $roles
|
68 |
* @return array[]
|
69 |
+
* @deprecated 11.1
|
70 |
*/
|
71 |
public function restrictEditableRoles( $roles ) {
|
|
|
|
|
|
|
72 |
return $roles;
|
73 |
}
|
74 |
|
80 |
* @param $cap
|
81 |
* @param array $args
|
82 |
* @return array
|
83 |
+
* @deprecated 11.1
|
84 |
*/
|
85 |
public function restrictAdminUserChanges( $allCaps, $cap, $args ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
return $allCaps;
|
87 |
}
|
88 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
/**
|
90 |
+
* @deprecated 11.1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
*/
|
92 |
public function blockOptionsSaves( $mNewOptionValue, $key, $mOldValue ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
return $mNewOptionValue;
|
94 |
}
|
95 |
|
96 |
+
/**
|
97 |
+
* @deprecated 11.1
|
98 |
+
*/
|
99 |
private function isOptionForThisPlugin( string $key ) :bool {
|
100 |
return preg_match( $this->getOptionRegexPattern(), $key ) > 0;
|
101 |
}
|
102 |
|
103 |
+
/**
|
104 |
+
* @deprecated 11.1
|
105 |
+
*/
|
106 |
private function isOptionRestricted( string $key ) :bool {
|
107 |
/** @var Options $opts */
|
108 |
$opts = $this->getOptions();
|
115 |
* @param $cap
|
116 |
* @param array $aArgs
|
117 |
* @return array
|
118 |
+
* @deprecated 11.1
|
119 |
*/
|
120 |
public function disablePluginManipulation( $aAllCaps, $cap, $aArgs ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
return $aAllCaps;
|
122 |
}
|
123 |
|
126 |
* @param $cap
|
127 |
* @param array $aArgs
|
128 |
* @return array
|
129 |
+
* @deprecated 11.1
|
130 |
*/
|
131 |
public function disableThemeManipulation( $aAllCaps, $cap, $aArgs ) {
|
132 |
// If we're registered with Admin Access we don't modify anything
|
134 |
return $aAllCaps;
|
135 |
}
|
136 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
137 |
return $aAllCaps;
|
138 |
}
|
139 |
|
142 |
* @param $cap
|
143 |
* @param array $args
|
144 |
* @return array
|
145 |
+
* @deprecated 11.1
|
146 |
*/
|
147 |
public function disablePostsManipulation( $aAllCaps, $cap, $args ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
148 |
return $aAllCaps;
|
149 |
}
|
150 |
|
151 |
+
/**
|
152 |
+
* @deprecated 11.1
|
153 |
+
*/
|
154 |
private function getOptionRegexPattern() :string {
|
155 |
return sprintf( '/^%s.*_options$/', $this->getCon()->getOptionStoragePrefix() );
|
156 |
}
|
157 |
|
158 |
+
/**
|
159 |
+
* @deprecated 11.1
|
160 |
+
*/
|
161 |
public function printAdminAccessAjaxForm() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
162 |
}
|
163 |
|
164 |
/**
|
165 |
* @param string $sLinkText
|
166 |
* @return string
|
167 |
+
* @deprecated 11.1
|
168 |
*/
|
169 |
protected function getUnlockLinkHtml( $sLinkText = '' ) {
|
170 |
+
return '';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
171 |
}
|
172 |
}
|
src/lib/src/Modules/SecurityAdmin/Strings.php
CHANGED
@@ -40,7 +40,7 @@ class Strings extends Base\Strings {
|
|
40 |
];
|
41 |
break;
|
42 |
|
43 |
-
case '
|
44 |
$sTitle = __( 'Security Admin Restriction Settings', 'wp-simple-firewall' );
|
45 |
$aSummary = [
|
46 |
sprintf( '%s - %s', __( 'Purpose', 'wp-simple-firewall' ), __( 'Restricts access to this plugin preventing unauthorized changes to your security settings.', 'wp-simple-firewall' ) ),
|
@@ -196,7 +196,7 @@ class Strings extends Base\Strings {
|
|
196 |
case 'whitelabel_enable' :
|
197 |
$name = sprintf( '%s: %s', __( 'Enable', 'wp-simple-firewall' ), __( 'White Label', 'wp-simple-firewall' ) );
|
198 |
$summary = __( 'Activate Your White Label Settings', 'wp-simple-firewall' );
|
199 |
-
$description = __( 'Turn
|
200 |
break;
|
201 |
case 'wl_hide_updates' :
|
202 |
$name = __( 'Hide Updates', 'wp-simple-firewall' );
|
40 |
];
|
41 |
break;
|
42 |
|
43 |
+
case 'section_security_admin_settings' :
|
44 |
$sTitle = __( 'Security Admin Restriction Settings', 'wp-simple-firewall' );
|
45 |
$aSummary = [
|
46 |
sprintf( '%s - %s', __( 'Purpose', 'wp-simple-firewall' ), __( 'Restricts access to this plugin preventing unauthorized changes to your security settings.', 'wp-simple-firewall' ) ),
|
196 |
case 'whitelabel_enable' :
|
197 |
$name = sprintf( '%s: %s', __( 'Enable', 'wp-simple-firewall' ), __( 'White Label', 'wp-simple-firewall' ) );
|
198 |
$summary = __( 'Activate Your White Label Settings', 'wp-simple-firewall' );
|
199 |
+
$description = __( 'Turn your White Label settings on/off.', 'wp-simple-firewall' );
|
200 |
break;
|
201 |
case 'wl_hide_updates' :
|
202 |
$name = __( 'Hide Updates', 'wp-simple-firewall' );
|
src/lib/src/Modules/SecurityAdmin/UI.php
CHANGED
@@ -14,7 +14,7 @@ class UI extends BaseShield\UI {
|
|
14 |
|
15 |
switch ( $section ) {
|
16 |
case 'section_whitelabel':
|
17 |
-
if ( !$mod->
|
18 |
$warning[] = __( 'Please also supply a Security Admin PIN, as whitelabel settings are only applied when the Security Admin feature is active.', 'wp-simple-firewall' );
|
19 |
}
|
20 |
break;
|
@@ -26,6 +26,6 @@ class UI extends BaseShield\UI {
|
|
26 |
public function isEnabledForUiSummary() :bool {
|
27 |
/** @var ModCon $mod */
|
28 |
$mod = $this->getMod();
|
29 |
-
return $mod->
|
30 |
}
|
31 |
}
|
14 |
|
15 |
switch ( $section ) {
|
16 |
case 'section_whitelabel':
|
17 |
+
if ( !$mod->getSecurityAdminController()->isEnabledSecAdmin() ) {
|
18 |
$warning[] = __( 'Please also supply a Security Admin PIN, as whitelabel settings are only applied when the Security Admin feature is active.', 'wp-simple-firewall' );
|
19 |
}
|
20 |
break;
|
26 |
public function isEnabledForUiSummary() :bool {
|
27 |
/** @var ModCon $mod */
|
28 |
$mod = $this->getMod();
|
29 |
+
return $mod->getSecurityAdminController()->isEnabledSecAdmin();
|
30 |
}
|
31 |
}
|
src/lib/src/Modules/SecurityAdmin/WpCli/Pin.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\WpCli;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\WpCli\BaseWpCliCmd;
|
6 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Lib\
|
7 |
use WP_CLI;
|
8 |
|
9 |
class Pin extends BaseWpCliCmd {
|
@@ -51,14 +51,14 @@ class Pin extends BaseWpCliCmd {
|
|
51 |
}
|
52 |
|
53 |
if ( $isRemove ) {
|
54 |
-
( new
|
55 |
->setMod( $this->getMod() )
|
56 |
->remove();
|
57 |
WP_CLI::success( __( 'Security admin pin removed.', 'wp-simple-firewall' ) );
|
58 |
}
|
59 |
else {
|
60 |
try {
|
61 |
-
( new
|
62 |
->setMod( $this->getMod() )
|
63 |
->run( $newPIN );
|
64 |
WP_CLI::success(
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\WpCli;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\WpCli\BaseWpCliCmd;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Lib\SecurityAdmin\Ops;
|
7 |
use WP_CLI;
|
8 |
|
9 |
class Pin extends BaseWpCliCmd {
|
51 |
}
|
52 |
|
53 |
if ( $isRemove ) {
|
54 |
+
( new Ops\RemoveSecAdmin() )
|
55 |
->setMod( $this->getMod() )
|
56 |
->remove();
|
57 |
WP_CLI::success( __( 'Security admin pin removed.', 'wp-simple-firewall' ) );
|
58 |
}
|
59 |
else {
|
60 |
try {
|
61 |
+
( new Ops\SetSecAdminPin() )
|
62 |
->setMod( $this->getMod() )
|
63 |
->run( $newPIN );
|
64 |
WP_CLI::success(
|
src/lib/src/Modules/Sessions/ModCon.php
CHANGED
@@ -22,8 +22,7 @@ class ModCon extends BaseShield\ModCon {
|
|
22 |
}
|
23 |
|
24 |
public function getDbHandler_Sessions() :Databases\Session\Handler {
|
25 |
-
|
26 |
-
return empty( $new ) ? $this->getDbH( 'session' ) : $new;
|
27 |
}
|
28 |
|
29 |
public function isAutoAddSessions() :bool {
|
22 |
}
|
23 |
|
24 |
public function getDbHandler_Sessions() :Databases\Session\Handler {
|
25 |
+
return $this->getDbH( 'sessions' );
|
|
|
26 |
}
|
27 |
|
28 |
public function isAutoAddSessions() :bool {
|
src/lib/src/Modules/Traffic/UI.php
CHANGED
@@ -74,14 +74,4 @@ class UI extends BaseShield\UI {
|
|
74 |
|
75 |
return $warning;
|
76 |
}
|
77 |
-
|
78 |
-
protected function getSettingsRelatedLinks() :array {
|
79 |
-
$modInsights = $this->getCon()->getModule_Insights();
|
80 |
-
return [
|
81 |
-
[
|
82 |
-
'href' => $modInsights->getUrl_SubInsightsPage( 'traffic' ),
|
83 |
-
'title' => __( 'Traffic Log', 'wp-simple-firewall' ),
|
84 |
-
]
|
85 |
-
];
|
86 |
-
}
|
87 |
}
|
74 |
|
75 |
return $warning;
|
76 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
}
|
src/lib/src/Modules/UserManagement/Lib/Registration/EmailValidate.php
CHANGED
@@ -61,7 +61,7 @@ class EmailValidate {
|
|
61 |
}
|
62 |
|
63 |
if ( !empty( $sInvalidBecause ) ) {
|
64 |
-
$
|
65 |
$this->getCon()->fireEvent(
|
66 |
'reg_email_invalid',
|
67 |
[
|
@@ -69,12 +69,12 @@ class EmailValidate {
|
|
69 |
'email' => sanitize_email( $email ),
|
70 |
'reason' => sanitize_key( $sInvalidBecause ),
|
71 |
],
|
72 |
-
'offense_count' => $
|
73 |
-
'block' => $
|
74 |
]
|
75 |
);
|
76 |
|
77 |
-
if ( $
|
78 |
wp_die( 'Attempted user registration with invalid email address has been blocked.' );
|
79 |
}
|
80 |
}
|
61 |
}
|
62 |
|
63 |
if ( !empty( $sInvalidBecause ) ) {
|
64 |
+
$opt = $opts->getValidateEmailOnRegistration();
|
65 |
$this->getCon()->fireEvent(
|
66 |
'reg_email_invalid',
|
67 |
[
|
69 |
'email' => sanitize_email( $email ),
|
70 |
'reason' => sanitize_key( $sInvalidBecause ),
|
71 |
],
|
72 |
+
'offense_count' => $opt == 'log' ? 0 : 1,
|
73 |
+
'block' => $opt == 'block',
|
74 |
]
|
75 |
);
|
76 |
|
77 |
+
if ( $opt == 'block' ) {
|
78 |
wp_die( 'Attempted user registration with invalid email address has been blocked.' );
|
79 |
}
|
80 |
}
|
src/lib/src/Modules/UserManagement/UI.php
CHANGED
@@ -34,23 +34,7 @@ class UI extends BaseShield\UI {
|
|
34 |
'vars' => [
|
35 |
'unique_ips' => $dbSel->getDistinctIps(),
|
36 |
'unique_users' => $dbSel->getDistinctUsernames(),
|
37 |
-
'related_hrefs' => [
|
38 |
-
[
|
39 |
-
'href' => $con->getModule_UserManagement()->getUrl_AdminPage(),
|
40 |
-
'title' => __( 'User Settings', 'wp-simple-firewall' ),
|
41 |
-
]
|
42 |
-
]
|
43 |
],
|
44 |
];
|
45 |
}
|
46 |
-
|
47 |
-
protected function getSettingsRelatedLinks() :array {
|
48 |
-
$modInsights = $this->getCon()->getModule_Insights();
|
49 |
-
return [
|
50 |
-
[
|
51 |
-
'href' => $modInsights->getUrl_SubInsightsPage( 'users' ),
|
52 |
-
'title' => __( 'User Sessions', 'wp-simple-firewall' ),
|
53 |
-
]
|
54 |
-
];
|
55 |
-
}
|
56 |
}
|
34 |
'vars' => [
|
35 |
'unique_ips' => $dbSel->getDistinctIps(),
|
36 |
'unique_users' => $dbSel->getDistinctUsernames(),
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
],
|
38 |
];
|
39 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
}
|
src/lib/src/Scans/Base/Table/BaseEntryFormatter.php
CHANGED
@@ -15,15 +15,12 @@ abstract class BaseEntryFormatter {
|
|
15 |
use Scan\Controller\ScanControllerConsumer;
|
16 |
use ModConsumer;
|
17 |
|
18 |
-
|
19 |
-
* @return array
|
20 |
-
*/
|
21 |
-
abstract public function format();
|
22 |
|
23 |
/**
|
24 |
* @return string[]
|
25 |
*/
|
26 |
-
protected function getSupportedActions() {
|
27 |
return [
|
28 |
'ignore'
|
29 |
];
|
@@ -32,7 +29,7 @@ abstract class BaseEntryFormatter {
|
|
32 |
/**
|
33 |
* @return array[]
|
34 |
*/
|
35 |
-
protected function getActionDefinitions() {
|
36 |
return [
|
37 |
'ignore' => [
|
38 |
'text' => __( 'Ignore', 'wp-simple-firewall' ),
|
@@ -57,10 +54,7 @@ abstract class BaseEntryFormatter {
|
|
57 |
];
|
58 |
}
|
59 |
|
60 |
-
|
61 |
-
* @return array
|
62 |
-
*/
|
63 |
-
protected function getBaseData() {
|
64 |
return $this->getEntryVO()->getRawData();
|
65 |
}
|
66 |
|
@@ -74,15 +68,15 @@ abstract class BaseEntryFormatter {
|
|
74 |
}
|
75 |
|
76 |
/**
|
77 |
-
* @param int $
|
78 |
* @return string
|
79 |
*/
|
80 |
-
protected function formatTimestampField( $
|
81 |
return Services::Request()
|
82 |
->carbon()
|
83 |
-
->setTimestamp( $
|
84 |
->diffForHumans()
|
85 |
.'<br/><span class="timestamp-small">'
|
86 |
-
.Services::WpGeneral()->getTimeStringForDisplay( $
|
87 |
}
|
88 |
}
|
15 |
use Scan\Controller\ScanControllerConsumer;
|
16 |
use ModConsumer;
|
17 |
|
18 |
+
abstract public function format() :array;
|
|
|
|
|
|
|
19 |
|
20 |
/**
|
21 |
* @return string[]
|
22 |
*/
|
23 |
+
protected function getSupportedActions() :array {
|
24 |
return [
|
25 |
'ignore'
|
26 |
];
|
29 |
/**
|
30 |
* @return array[]
|
31 |
*/
|
32 |
+
protected function getActionDefinitions() :array {
|
33 |
return [
|
34 |
'ignore' => [
|
35 |
'text' => __( 'Ignore', 'wp-simple-firewall' ),
|
54 |
];
|
55 |
}
|
56 |
|
57 |
+
protected function getBaseData() :array {
|
|
|
|
|
|
|
58 |
return $this->getEntryVO()->getRawData();
|
59 |
}
|
60 |
|
68 |
}
|
69 |
|
70 |
/**
|
71 |
+
* @param int $ts
|
72 |
* @return string
|
73 |
*/
|
74 |
+
protected function formatTimestampField( $ts ) {
|
75 |
return Services::Request()
|
76 |
->carbon()
|
77 |
+
->setTimestamp( $ts )
|
78 |
->diffForHumans()
|
79 |
.'<br/><span class="timestamp-small">'
|
80 |
+
.Services::WpGeneral()->getTimeStringForDisplay( $ts ).'</span>';
|
81 |
}
|
82 |
}
|
src/lib/src/Scans/Base/Table/BaseFileEntryFormatter.php
CHANGED
@@ -8,45 +8,42 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
8 |
|
9 |
abstract class BaseFileEntryFormatter extends BaseEntryFormatter {
|
10 |
|
11 |
-
|
12 |
-
|
13 |
-
*/
|
14 |
-
protected function getBaseData() {
|
15 |
-
$aData = parent::getBaseData();
|
16 |
$item = $this->getResultItem();
|
17 |
-
$
|
18 |
-
$
|
19 |
-
$
|
20 |
-
$
|
21 |
-
$
|
22 |
-
$
|
23 |
|
24 |
-
$
|
25 |
$this->getActionDefinitions(),
|
26 |
array_flip( array_unique( $this->getSupportedActions() ) )
|
27 |
);
|
28 |
-
foreach ( $
|
29 |
-
$
|
30 |
-
$
|
31 |
[
|
32 |
'rid' => $this->getEntryVO()->id,
|
33 |
-
'item_action' => $
|
34 |
]
|
35 |
);
|
36 |
-
$
|
37 |
-
$
|
38 |
[ 'action', 'item_action' ]
|
39 |
);
|
40 |
}
|
41 |
-
$
|
42 |
|
43 |
-
return $
|
44 |
}
|
45 |
|
46 |
/**
|
47 |
* @return array[]
|
48 |
*/
|
49 |
-
protected function getActionDefinitions() {
|
50 |
return [
|
51 |
'ignore' => [
|
52 |
'text' => sprintf( __( 'Ignore %s', 'wp-simple-firewall' ), __( 'File', 'wp-simple-firewall' ) ),
|
@@ -74,7 +71,7 @@ abstract class BaseFileEntryFormatter extends BaseEntryFormatter {
|
|
74 |
/**
|
75 |
* @return string[]
|
76 |
*/
|
77 |
-
protected function getExplanation() {
|
78 |
return [];
|
79 |
}
|
80 |
}
|
8 |
|
9 |
abstract class BaseFileEntryFormatter extends BaseEntryFormatter {
|
10 |
|
11 |
+
protected function getBaseData() :array {
|
12 |
+
$data = parent::getBaseData();
|
|
|
|
|
|
|
13 |
$item = $this->getResultItem();
|
14 |
+
$data[ 'explanation' ] = $this->getExplanation();
|
15 |
+
$data[ 'path' ] = $item->path_fragment;
|
16 |
+
$data[ 'path_relabs' ] = Services::WpFs()->getPathRelativeToAbsPath( $item->path_full );
|
17 |
+
$data[ 'path_details' ] = [];
|
18 |
+
$data[ 'created_at' ] = $this->formatTimestampField( $this->getEntryVO()->created_at );
|
19 |
+
$data[ 'custom_row' ] = false;
|
20 |
|
21 |
+
$actionDefs = array_intersect_key(
|
22 |
$this->getActionDefinitions(),
|
23 |
array_flip( array_unique( $this->getSupportedActions() ) )
|
24 |
);
|
25 |
+
foreach ( $actionDefs as $key => $actionDef ) {
|
26 |
+
$actionDefs[ $key ][ 'data' ] = array_merge(
|
27 |
+
$actionDef[ 'data' ],
|
28 |
[
|
29 |
'rid' => $this->getEntryVO()->id,
|
30 |
+
'item_action' => $key,
|
31 |
]
|
32 |
);
|
33 |
+
$actionDefs[ $key ][ 'classes' ] = array_merge(
|
34 |
+
$actionDef[ 'classes' ],
|
35 |
[ 'action', 'item_action' ]
|
36 |
);
|
37 |
}
|
38 |
+
$data[ 'actions' ] = $actionDefs;
|
39 |
|
40 |
+
return $data;
|
41 |
}
|
42 |
|
43 |
/**
|
44 |
* @return array[]
|
45 |
*/
|
46 |
+
protected function getActionDefinitions() :array {
|
47 |
return [
|
48 |
'ignore' => [
|
49 |
'text' => sprintf( __( 'Ignore %s', 'wp-simple-firewall' ), __( 'File', 'wp-simple-firewall' ) ),
|
71 |
/**
|
72 |
* @return string[]
|
73 |
*/
|
74 |
+
protected function getExplanation() :array {
|
75 |
return [];
|
76 |
}
|
77 |
}
|
src/lib/src/Scans/Mal/Table/EntryFormatter.php
CHANGED
@@ -8,49 +8,45 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal;
|
|
8 |
|
9 |
class EntryFormatter extends BaseFileEntryFormatter {
|
10 |
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
$aE[ 'status' ] = __( 'Potential Malware Detected', 'wp-simple-firewall' );
|
17 |
-
if ( !array_key_exists( 'repair', $aE[ 'actions' ] ) ) {
|
18 |
-
$aE[ 'explanation' ][] = __( 'Repair Unavailable', 'wp-simple-firewall' );
|
19 |
}
|
20 |
-
|
21 |
-
return $aE;
|
22 |
}
|
23 |
|
24 |
/**
|
25 |
* @return string[]
|
26 |
*/
|
27 |
-
protected function getExplanation() {
|
28 |
-
/** @var Mal\ResultItem $
|
29 |
-
$
|
30 |
|
31 |
-
$
|
32 |
-
sprintf( '%s: %s', __( 'Pattern Detected' ), $this->getPatternForDisplay( base64_decode( $
|
33 |
sprintf( '%s: %s', __( 'Affected line numbers' ),
|
34 |
implode( ', ', array_map(
|
35 |
function ( $nLineNumber ) {
|
36 |
return $nLineNumber + 1;
|
37 |
},
|
38 |
-
$
|
39 |
) )
|
40 |
),
|
41 |
];
|
42 |
|
43 |
-
/** @var HackGuard\Options $
|
44 |
-
$
|
45 |
-
if ( $
|
46 |
-
$
|
47 |
__( 'Likelihood That This Is A False Positive' ),
|
48 |
-
sprintf( '<strong>%s</strong>', (int)$
|
49 |
sprintf( '<a href="%s" target="_blank">%s</a>', 'https://shsec.io/isthismalware', __( 'more info', 'wp-simple-firewall' ) )
|
50 |
);
|
51 |
}
|
52 |
|
53 |
-
return $
|
54 |
}
|
55 |
|
56 |
/**
|
@@ -79,7 +75,7 @@ class EntryFormatter extends BaseFileEntryFormatter {
|
|
79 |
/**
|
80 |
* @inheritDoc
|
81 |
*/
|
82 |
-
protected function getSupportedActions() {
|
83 |
$actions = parent::getSupportedActions();
|
84 |
|
85 |
/** @var Mal\ResultItem $item */
|
8 |
|
9 |
class EntryFormatter extends BaseFileEntryFormatter {
|
10 |
|
11 |
+
public function format() :array {
|
12 |
+
$e = $this->getBaseData();
|
13 |
+
$e[ 'status' ] = __( 'Potential Malware Detected', 'wp-simple-firewall' );
|
14 |
+
if ( !array_key_exists( 'repair', $e[ 'actions' ] ) ) {
|
15 |
+
$e[ 'explanation' ][] = __( 'Repair Unavailable', 'wp-simple-firewall' );
|
|
|
|
|
|
|
16 |
}
|
17 |
+
return $e;
|
|
|
18 |
}
|
19 |
|
20 |
/**
|
21 |
* @return string[]
|
22 |
*/
|
23 |
+
protected function getExplanation() :array {
|
24 |
+
/** @var Mal\ResultItem $item */
|
25 |
+
$item = $this->getResultItem();
|
26 |
|
27 |
+
$expl = [
|
28 |
+
sprintf( '%s: %s', __( 'Pattern Detected' ), $this->getPatternForDisplay( base64_decode( $item->mal_sig ) ) ),
|
29 |
sprintf( '%s: %s', __( 'Affected line numbers' ),
|
30 |
implode( ', ', array_map(
|
31 |
function ( $nLineNumber ) {
|
32 |
return $nLineNumber + 1;
|
33 |
},
|
34 |
+
$item->file_lines // because lines start at ZERO
|
35 |
) )
|
36 |
),
|
37 |
];
|
38 |
|
39 |
+
/** @var HackGuard\Options $opts */
|
40 |
+
$opts = $this->getOptions();
|
41 |
+
if ( $opts->isMalUseNetworkIntelligence() ) {
|
42 |
+
$expl[] = sprintf( '%s: %s/100 [%s]',
|
43 |
__( 'Likelihood That This Is A False Positive' ),
|
44 |
+
sprintf( '<strong>%s</strong>', (int)$item->fp_confidence ),
|
45 |
sprintf( '<a href="%s" target="_blank">%s</a>', 'https://shsec.io/isthismalware', __( 'more info', 'wp-simple-firewall' ) )
|
46 |
);
|
47 |
}
|
48 |
|
49 |
+
return $expl;
|
50 |
}
|
51 |
|
52 |
/**
|
75 |
/**
|
76 |
* @inheritDoc
|
77 |
*/
|
78 |
+
protected function getSupportedActions() :array {
|
79 |
$actions = parent::getSupportedActions();
|
80 |
|
81 |
/** @var Mal\ResultItem $item */
|
src/lib/src/Scans/Ptg/Table/EntryFormatter.php
CHANGED
@@ -8,63 +8,57 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
8 |
|
9 |
class EntryFormatter extends BaseFileEntryFormatter {
|
10 |
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
if ( !empty( $oAsset ) ) {
|
22 |
-
$aData[ 'path_details' ][] = sprintf( '%s: %s v%s',
|
23 |
-
__( 'Plugin', 'wp-simple-firewall' ), $oAsset->Name, $oAsset->version );
|
24 |
}
|
25 |
}
|
26 |
else {
|
27 |
-
$
|
28 |
-
if ( !empty( $
|
29 |
-
$
|
30 |
-
__( 'Theme', 'wp-simple-firewall' ), $
|
31 |
}
|
32 |
}
|
33 |
|
34 |
-
return $
|
35 |
}
|
36 |
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
$
|
43 |
-
|
44 |
-
|
45 |
-
$aE[ 'status' ] = $oIt->is_different ? __( 'Modified', 'wp-simple-firewall' )
|
46 |
-
: ( $oIt->is_missing ? __( 'Missing', 'wp-simple-firewall' ) : __( 'Unrecognised', 'wp-simple-firewall' ) );
|
47 |
-
return $aE;
|
48 |
}
|
49 |
|
50 |
/**
|
51 |
* @inheritDoc
|
52 |
*/
|
53 |
-
protected function getActionDefinitions() {
|
54 |
-
/** @var Ptg\ResultItem $
|
55 |
-
$
|
56 |
-
$
|
57 |
return array_merge(
|
58 |
parent::getActionDefinitions(),
|
59 |
[
|
60 |
'asset_accept' => [
|
61 |
-
'text' => sprintf( __( 'Accept %s', 'wp-simple-firewall' ), $
|
62 |
-
'title' => sprintf( __( 'Accept all current scan results for this %s.' ), $
|
63 |
'classes' => [ 'asset_accept' ],
|
64 |
'data' => [],
|
65 |
],
|
66 |
'asset_reinstall' => [
|
67 |
-
'text' => sprintf( __( 'Re-Install %s', 'wp-simple-firewall' ), $
|
68 |
'classes' => [ 'asset_reinstall' ],
|
69 |
'data' => []
|
70 |
],
|
@@ -75,12 +69,12 @@ class EntryFormatter extends BaseFileEntryFormatter {
|
|
75 |
/**
|
76 |
* @return string[]
|
77 |
*/
|
78 |
-
protected function getExplanation() {
|
79 |
-
/** @var Ptg\ResultItem $
|
80 |
-
$
|
81 |
|
82 |
-
if ( $
|
83 |
-
$
|
84 |
__( "This file appears to have been modified from its original content.", 'wp-simple-firewall' )
|
85 |
.' '.__( "This may be okay if you're editing files directly on your site.", 'wp-simple-firewall' ),
|
86 |
__( "You may want to download it to ensure that the contents are as you expect.", 'wp-simple-firewall' )
|
@@ -88,8 +82,8 @@ class EntryFormatter extends BaseFileEntryFormatter {
|
|
88 |
__( 'Ignore', 'wp-simple-firewall' ) ),
|
89 |
];
|
90 |
}
|
91 |
-
elseif ( $
|
92 |
-
$
|
93 |
__( "This file appears to have been removed from your site.", 'wp-simple-firewall' )
|
94 |
.' '.__( "This may be okay if you're editing files directly on your site.", 'wp-simple-firewall' ),
|
95 |
__( "If you're unsure, you should check whether this is okay.", 'wp-simple-firewall' )
|
@@ -98,7 +92,7 @@ class EntryFormatter extends BaseFileEntryFormatter {
|
|
98 |
];
|
99 |
}
|
100 |
else {
|
101 |
-
$
|
102 |
__( "This file appears to have been added to your site.", 'wp-simple-firewall' ),
|
103 |
__( "This is not normal in the vast majority of cases.", 'wp-simple-firewall' ),
|
104 |
__( "You may want to download it to ensure that the contents are what you expect.", 'wp-simple-firewall' )
|
@@ -107,51 +101,51 @@ class EntryFormatter extends BaseFileEntryFormatter {
|
|
107 |
];
|
108 |
}
|
109 |
|
110 |
-
return $
|
111 |
}
|
112 |
|
113 |
/**
|
114 |
* @inheritDoc
|
115 |
*/
|
116 |
-
protected function getSupportedActions() {
|
117 |
-
/** @var Ptg\ResultItem $
|
118 |
-
$
|
119 |
|
120 |
-
$
|
121 |
'asset_accept'
|
122 |
];
|
123 |
|
124 |
-
if ( $
|
125 |
-
$
|
126 |
}
|
127 |
else {
|
128 |
-
$
|
129 |
}
|
130 |
|
131 |
-
$
|
132 |
-
->setScanItem( $
|
133 |
->canRepair();
|
134 |
-
$
|
135 |
|
136 |
-
if ( $
|
137 |
-
$
|
138 |
}
|
139 |
|
140 |
-
if ( $
|
141 |
-
$
|
142 |
}
|
143 |
-
elseif ( $
|
144 |
-
$
|
145 |
}
|
146 |
|
147 |
-
if ( $
|
148 |
-
$
|
149 |
}
|
150 |
|
151 |
-
if ( !$
|
152 |
-
$
|
153 |
}
|
154 |
|
155 |
-
return array_merge( parent::getSupportedActions(), $
|
156 |
}
|
157 |
}
|
8 |
|
9 |
class EntryFormatter extends BaseFileEntryFormatter {
|
10 |
|
11 |
+
protected function getBaseData() :array {
|
12 |
+
$data = parent::getBaseData();
|
13 |
+
/** @var Ptg\ResultItem $item */
|
14 |
+
$item = $this->getResultItem();
|
15 |
+
|
16 |
+
if ( $item->context == 'plugins' ) {
|
17 |
+
$asset = Services::WpPlugins()->getPluginAsVo( $item->slug );
|
18 |
+
if ( !empty( $asset ) ) {
|
19 |
+
$data[ 'path_details' ][] = sprintf( '%s: %s v%s',
|
20 |
+
__( 'Plugin', 'wp-simple-firewall' ), $asset->Name, $asset->version );
|
|
|
|
|
|
|
21 |
}
|
22 |
}
|
23 |
else {
|
24 |
+
$asset = Services::WpThemes()->getThemeAsVo( $item->slug );
|
25 |
+
if ( !empty( $asset ) ) {
|
26 |
+
$data[ 'path_details' ][] = sprintf( '%s: %s v%s',
|
27 |
+
__( 'Theme', 'wp-simple-firewall' ), $asset->wp_theme->get( 'Name' ), $asset->version );
|
28 |
}
|
29 |
}
|
30 |
|
31 |
+
return $data;
|
32 |
}
|
33 |
|
34 |
+
public function format() :array {
|
35 |
+
/** @var Ptg\ResultItem $item */
|
36 |
+
$item = $this->getResultItem();
|
37 |
+
|
38 |
+
$e = $this->getBaseData();
|
39 |
+
$e[ 'status' ] = $item->is_different ? __( 'Modified', 'wp-simple-firewall' )
|
40 |
+
: ( $item->is_missing ? __( 'Missing', 'wp-simple-firewall' ) : __( 'Unrecognised', 'wp-simple-firewall' ) );
|
41 |
+
return $e;
|
|
|
|
|
|
|
42 |
}
|
43 |
|
44 |
/**
|
45 |
* @inheritDoc
|
46 |
*/
|
47 |
+
protected function getActionDefinitions() :array {
|
48 |
+
/** @var Ptg\ResultItem $item */
|
49 |
+
$item = $this->getResultItem();
|
50 |
+
$assetType = ( $item->context == 'plugins' ? __( 'Plugin', 'wp-simple-firewall' ) : __( 'Theme', 'wp-simple-firewall' ) );
|
51 |
return array_merge(
|
52 |
parent::getActionDefinitions(),
|
53 |
[
|
54 |
'asset_accept' => [
|
55 |
+
'text' => sprintf( __( 'Accept %s', 'wp-simple-firewall' ), $assetType ),
|
56 |
+
'title' => sprintf( __( 'Accept all current scan results for this %s.' ), $assetType ),
|
57 |
'classes' => [ 'asset_accept' ],
|
58 |
'data' => [],
|
59 |
],
|
60 |
'asset_reinstall' => [
|
61 |
+
'text' => sprintf( __( 'Re-Install %s', 'wp-simple-firewall' ), $assetType ),
|
62 |
'classes' => [ 'asset_reinstall' ],
|
63 |
'data' => []
|
64 |
],
|
69 |
/**
|
70 |
* @return string[]
|
71 |
*/
|
72 |
+
protected function getExplanation() :array {
|
73 |
+
/** @var Ptg\ResultItem $item */
|
74 |
+
$item = $this->getResultItem();
|
75 |
|
76 |
+
if ( $item->is_different ) {
|
77 |
+
$expl = [
|
78 |
__( "This file appears to have been modified from its original content.", 'wp-simple-firewall' )
|
79 |
.' '.__( "This may be okay if you're editing files directly on your site.", 'wp-simple-firewall' ),
|
80 |
__( "You may want to download it to ensure that the contents are as you expect.", 'wp-simple-firewall' )
|
82 |
__( 'Ignore', 'wp-simple-firewall' ) ),
|
83 |
];
|
84 |
}
|
85 |
+
elseif ( $item->is_missing ) {
|
86 |
+
$expl = [
|
87 |
__( "This file appears to have been removed from your site.", 'wp-simple-firewall' )
|
88 |
.' '.__( "This may be okay if you're editing files directly on your site.", 'wp-simple-firewall' ),
|
89 |
__( "If you're unsure, you should check whether this is okay.", 'wp-simple-firewall' )
|
92 |
];
|
93 |
}
|
94 |
else {
|
95 |
+
$expl = [
|
96 |
__( "This file appears to have been added to your site.", 'wp-simple-firewall' ),
|
97 |
__( "This is not normal in the vast majority of cases.", 'wp-simple-firewall' ),
|
98 |
__( "You may want to download it to ensure that the contents are what you expect.", 'wp-simple-firewall' )
|
101 |
];
|
102 |
}
|
103 |
|
104 |
+
return $expl;
|
105 |
}
|
106 |
|
107 |
/**
|
108 |
* @inheritDoc
|
109 |
*/
|
110 |
+
protected function getSupportedActions() :array {
|
111 |
+
/** @var Ptg\ResultItem $item */
|
112 |
+
$item = $this->getResultItem();
|
113 |
|
114 |
+
$extras = [
|
115 |
'asset_accept'
|
116 |
];
|
117 |
|
118 |
+
if ( $item->context == 'plugins' ) {
|
119 |
+
$asset = Services::WpPlugins()->getPluginAsVo( $item->slug );
|
120 |
}
|
121 |
else {
|
122 |
+
$asset = Services::WpThemes()->getThemeAsVo( $item->slug );
|
123 |
}
|
124 |
|
125 |
+
$canRepair = ( new Ptg\Utilities\Repair() )
|
126 |
+
->setScanItem( $item )
|
127 |
->canRepair();
|
128 |
+
$hasUpdate = $asset->hasUpdate();
|
129 |
|
130 |
+
if ( $hasUpdate ) {
|
131 |
+
$extras[] = 'update';
|
132 |
}
|
133 |
|
134 |
+
if ( $item->is_unrecognised ) {
|
135 |
+
$extras[] = 'delete';
|
136 |
}
|
137 |
+
elseif ( $canRepair ) {
|
138 |
+
$extras[] = 'repair';
|
139 |
}
|
140 |
|
141 |
+
if ( $canRepair && !$hasUpdate ) {
|
142 |
+
$extras[] = 'asset_reinstall';
|
143 |
}
|
144 |
|
145 |
+
if ( !$item->is_missing ) {
|
146 |
+
$extras[] = 'download';
|
147 |
}
|
148 |
|
149 |
+
return array_merge( parent::getSupportedActions(), $extras );
|
150 |
}
|
151 |
}
|
src/lib/src/Scans/Ufc/BuildScanAction.php
CHANGED
@@ -19,13 +19,13 @@ class BuildScanAction extends Shield\Scans\Base\BaseBuildScanAction {
|
|
19 |
}
|
20 |
|
21 |
protected function setCustomFields() {
|
22 |
-
/** @var ScanActionVO $
|
23 |
-
$
|
24 |
-
/** @var Shield\Modules\HackGuard\Options $
|
25 |
-
$
|
26 |
|
27 |
-
$
|
28 |
-
$
|
29 |
-
$
|
30 |
}
|
31 |
}
|
19 |
}
|
20 |
|
21 |
protected function setCustomFields() {
|
22 |
+
/** @var ScanActionVO $action */
|
23 |
+
$action = $this->getScanActionVO();
|
24 |
+
/** @var Shield\Modules\HackGuard\Options $opts */
|
25 |
+
$opts = $this->getOptions();
|
26 |
|
27 |
+
$exclusions = $opts->getOpt( 'ufc_exclusions', [] );
|
28 |
+
$action->exclusions = is_array( $exclusions ) ? $exclusions : [];
|
29 |
+
$action->scan_dirs = $opts->getUfcScanDirectories();
|
30 |
}
|
31 |
}
|
src/lib/src/Scans/Ufc/FileScanner.php
CHANGED
@@ -5,10 +5,6 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Ufc;
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
8 |
-
/**
|
9 |
-
* Class FileScanner
|
10 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Ufc
|
11 |
-
*/
|
12 |
class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
|
13 |
|
14 |
/**
|
@@ -29,38 +25,34 @@ class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
|
|
29 |
return $item;
|
30 |
}
|
31 |
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
*/
|
36 |
-
private function isExcluded( $sFullPath ) {
|
37 |
-
/** @var ScanActionVO $oAction */
|
38 |
-
$oAction = $this->getScanActionVO();
|
39 |
|
40 |
-
$
|
41 |
-
$
|
42 |
|
43 |
-
$
|
44 |
|
45 |
-
foreach ( $
|
46 |
|
47 |
-
if ( preg_match( '/^#(.+)#[a-z]*$/i', $
|
48 |
-
$
|
49 |
}
|
50 |
else {
|
51 |
-
$
|
52 |
-
if ( strpos( $
|
53 |
-
$
|
54 |
}
|
55 |
else {
|
56 |
-
$
|
57 |
}
|
58 |
}
|
59 |
|
60 |
-
if ( $
|
61 |
break;
|
62 |
}
|
63 |
}
|
64 |
-
return (bool)$
|
65 |
}
|
66 |
}
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
|
|
|
|
|
|
|
|
8 |
class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
|
9 |
|
10 |
/**
|
25 |
return $item;
|
26 |
}
|
27 |
|
28 |
+
private function isExcluded( string $fullPath ) :bool {
|
29 |
+
/** @var ScanActionVO $action */
|
30 |
+
$action = $this->getScanActionVO();
|
|
|
|
|
|
|
|
|
31 |
|
32 |
+
$path = wp_normalize_path( $fullPath );
|
33 |
+
$filename = basename( $path );
|
34 |
|
35 |
+
$excluded = false;
|
36 |
|
37 |
+
foreach ( $action->exclusions as $exclusion ) {
|
38 |
|
39 |
+
if ( preg_match( '/^#(.+)#[a-z]*$/i', $exclusion, $aMatches ) ) { // it's regex
|
40 |
+
$excluded = @preg_match( stripslashes( $exclusion ), $path );
|
41 |
}
|
42 |
else {
|
43 |
+
$exclusion = wp_normalize_path( $exclusion );
|
44 |
+
if ( strpos( $exclusion, '/' ) === false ) { // filename only
|
45 |
+
$excluded = $filename === $exclusion;
|
46 |
}
|
47 |
else {
|
48 |
+
$excluded = strpos( $path, $exclusion ) !== false;
|
49 |
}
|
50 |
}
|
51 |
|
52 |
+
if ( $excluded ) {
|
53 |
break;
|
54 |
}
|
55 |
}
|
56 |
+
return (bool)$excluded;
|
57 |
}
|
58 |
}
|
src/lib/src/Scans/Ufc/Table/EntryFormatter.php
CHANGED
@@ -6,19 +6,16 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\Table\BaseFileEntryFormat
|
|
6 |
|
7 |
class EntryFormatter extends BaseFileEntryFormatter {
|
8 |
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
$aE = $this->getBaseData();
|
14 |
-
$aE[ 'status' ] = __( 'Unrecognised', 'wp-simple-firewall' );
|
15 |
-
return $aE;
|
16 |
}
|
17 |
|
18 |
/**
|
19 |
* @return string[]
|
20 |
*/
|
21 |
-
protected function getExplanation() {
|
22 |
return [
|
23 |
__( 'This file was discovered within one of your core WordPress directories.', 'wp-simple-firewall' ),
|
24 |
__( "But it isn't part of the official WordPress distribution for this version.", 'wp-simple-firewall' ),
|
@@ -31,7 +28,7 @@ class EntryFormatter extends BaseFileEntryFormatter {
|
|
31 |
/**
|
32 |
* @inheritDoc
|
33 |
*/
|
34 |
-
protected function getSupportedActions() {
|
35 |
return array_merge( parent::getSupportedActions(), [ 'delete', 'download' ] );
|
36 |
}
|
37 |
}
|
6 |
|
7 |
class EntryFormatter extends BaseFileEntryFormatter {
|
8 |
|
9 |
+
public function format() :array {
|
10 |
+
$e = $this->getBaseData();
|
11 |
+
$e[ 'status' ] = __( 'Unrecognised', 'wp-simple-firewall' );
|
12 |
+
return $e;
|
|
|
|
|
|
|
13 |
}
|
14 |
|
15 |
/**
|
16 |
* @return string[]
|
17 |
*/
|
18 |
+
protected function getExplanation() :array {
|
19 |
return [
|
20 |
__( 'This file was discovered within one of your core WordPress directories.', 'wp-simple-firewall' ),
|
21 |
__( "But it isn't part of the official WordPress distribution for this version.", 'wp-simple-firewall' ),
|
28 |
/**
|
29 |
* @inheritDoc
|
30 |
*/
|
31 |
+
protected function getSupportedActions() :array {
|
32 |
return array_merge( parent::getSupportedActions(), [ 'delete', 'download' ] );
|
33 |
}
|
34 |
}
|
src/lib/src/Scans/Wcf/Table/EntryFormatter.php
CHANGED
@@ -7,20 +7,17 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Wcf\ResultItem;
|
|
7 |
|
8 |
class EntryFormatter extends BaseFileEntryFormatter {
|
9 |
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
public function format() {
|
14 |
-
/** @var ResultItem $oIt */
|
15 |
-
$oIt = $this->getResultItem();
|
16 |
|
17 |
-
$
|
18 |
|
19 |
-
$
|
20 |
-
: ( $
|
21 |
|
22 |
-
if ( $
|
23 |
-
$
|
24 |
__( 'This file is an official WordPress core file.', 'wp-simple-firewall' ),
|
25 |
__( "But, it appears to have been modified when compared to the official WordPress distribution.", 'wp-simple-firewall' )
|
26 |
.' '.__( "This is not normal in the vast majority of cases.", 'wp-simple-firewall' ),
|
@@ -29,8 +26,8 @@ class EntryFormatter extends BaseFileEntryFormatter {
|
|
29 |
__( 'Ignore', 'wp-simple-firewall' ), __( 'Repair', 'wp-simple-firewall' ) ),
|
30 |
];
|
31 |
}
|
32 |
-
elseif ( $
|
33 |
-
$
|
34 |
__( 'This file is an official WordPress core file.', 'wp-simple-firewall' ),
|
35 |
__( "But, it appears to be missing from your site.", 'wp-simple-firewall' ),
|
36 |
__( "You may want to check why this might be missing.", 'wp-simple-firewall' )
|
@@ -39,18 +36,18 @@ class EntryFormatter extends BaseFileEntryFormatter {
|
|
39 |
];
|
40 |
}
|
41 |
|
42 |
-
return $
|
43 |
}
|
44 |
|
45 |
/**
|
46 |
* @return string[]
|
47 |
*/
|
48 |
-
protected function getExplanation() {
|
49 |
/** @var ResultItem $oIt */
|
50 |
$oIt = $this->getResultItem();
|
51 |
|
52 |
if ( $oIt->is_checksumfail ) {
|
53 |
-
$
|
54 |
__( 'This file is an official WordPress core file.', 'wp-simple-firewall' ),
|
55 |
__( "But, it appears to have been modified when compared to the official WordPress distribution.", 'wp-simple-firewall' )
|
56 |
.' '.__( "This is not normal in the vast majority of cases.", 'wp-simple-firewall' ),
|
@@ -60,7 +57,7 @@ class EntryFormatter extends BaseFileEntryFormatter {
|
|
60 |
];
|
61 |
}
|
62 |
elseif ( $oIt->is_missing ) {
|
63 |
-
$
|
64 |
__( 'This file is an official WordPress core file.', 'wp-simple-firewall' ),
|
65 |
__( "But, it appears to be missing from your site.", 'wp-simple-firewall' ),
|
66 |
__( "You may want to check why this might be missing.", 'wp-simple-firewall' )
|
@@ -69,24 +66,24 @@ class EntryFormatter extends BaseFileEntryFormatter {
|
|
69 |
];
|
70 |
}
|
71 |
else {
|
72 |
-
$
|
73 |
}
|
74 |
|
75 |
-
return $
|
76 |
}
|
77 |
|
78 |
/**
|
79 |
* @inheritDoc
|
80 |
*/
|
81 |
-
protected function getSupportedActions() {
|
82 |
-
$
|
83 |
|
84 |
/** @var ResultItem $oIt */
|
85 |
$oIt = $this->getResultItem();
|
86 |
if ( $oIt->is_checksumfail ) {
|
87 |
-
$
|
88 |
}
|
89 |
|
90 |
-
return array_merge( parent::getSupportedActions(), $
|
91 |
}
|
92 |
}
|
7 |
|
8 |
class EntryFormatter extends BaseFileEntryFormatter {
|
9 |
|
10 |
+
public function format() :array {
|
11 |
+
/** @var ResultItem $item */
|
12 |
+
$item = $this->getResultItem();
|
|
|
|
|
|
|
13 |
|
14 |
+
$e = $this->getBaseData();
|
15 |
|
16 |
+
$e[ 'status' ] = $item->is_checksumfail ? __( 'Modified', 'wp-simple-firewall' )
|
17 |
+
: ( $item->is_missing ? __( 'Missing', 'wp-simple-firewall' ) : __( 'Unknown', 'wp-simple-firewall' ) );
|
18 |
|
19 |
+
if ( $item->is_checksumfail ) {
|
20 |
+
$e[ 'explanation' ] = [
|
21 |
__( 'This file is an official WordPress core file.', 'wp-simple-firewall' ),
|
22 |
__( "But, it appears to have been modified when compared to the official WordPress distribution.", 'wp-simple-firewall' )
|
23 |
.' '.__( "This is not normal in the vast majority of cases.", 'wp-simple-firewall' ),
|
26 |
__( 'Ignore', 'wp-simple-firewall' ), __( 'Repair', 'wp-simple-firewall' ) ),
|
27 |
];
|
28 |
}
|
29 |
+
elseif ( $item->is_missing ) {
|
30 |
+
$e[ 'explanation' ] = [
|
31 |
__( 'This file is an official WordPress core file.', 'wp-simple-firewall' ),
|
32 |
__( "But, it appears to be missing from your site.", 'wp-simple-firewall' ),
|
33 |
__( "You may want to check why this might be missing.", 'wp-simple-firewall' )
|
36 |
];
|
37 |
}
|
38 |
|
39 |
+
return $e;
|
40 |
}
|
41 |
|
42 |
/**
|
43 |
* @return string[]
|
44 |
*/
|
45 |
+
protected function getExplanation() :array {
|
46 |
/** @var ResultItem $oIt */
|
47 |
$oIt = $this->getResultItem();
|
48 |
|
49 |
if ( $oIt->is_checksumfail ) {
|
50 |
+
$expl = [
|
51 |
__( 'This file is an official WordPress core file.', 'wp-simple-firewall' ),
|
52 |
__( "But, it appears to have been modified when compared to the official WordPress distribution.", 'wp-simple-firewall' )
|
53 |
.' '.__( "This is not normal in the vast majority of cases.", 'wp-simple-firewall' ),
|
57 |
];
|
58 |
}
|
59 |
elseif ( $oIt->is_missing ) {
|
60 |
+
$expl = [
|
61 |
__( 'This file is an official WordPress core file.', 'wp-simple-firewall' ),
|
62 |
__( "But, it appears to be missing from your site.", 'wp-simple-firewall' ),
|
63 |
__( "You may want to check why this might be missing.", 'wp-simple-firewall' )
|
66 |
];
|
67 |
}
|
68 |
else {
|
69 |
+
$expl = [];
|
70 |
}
|
71 |
|
72 |
+
return $expl;
|
73 |
}
|
74 |
|
75 |
/**
|
76 |
* @inheritDoc
|
77 |
*/
|
78 |
+
protected function getSupportedActions() :array {
|
79 |
+
$extras = [ 'repair' ];
|
80 |
|
81 |
/** @var ResultItem $oIt */
|
82 |
$oIt = $this->getResultItem();
|
83 |
if ( $oIt->is_checksumfail ) {
|
84 |
+
$extras[] = 'download';
|
85 |
}
|
86 |
|
87 |
+
return array_merge( parent::getSupportedActions(), $extras );
|
88 |
}
|
89 |
}
|
src/lib/src/Scans/Wpv/WpVulnDb/WpVulnVO.php
CHANGED
@@ -40,12 +40,4 @@ class WpVulnVO extends DynPropertiesClass {
|
|
40 |
|
41 |
return $val;
|
42 |
}
|
43 |
-
|
44 |
-
/**
|
45 |
-
* @return string
|
46 |
-
* @deprecated 10.2
|
47 |
-
*/
|
48 |
-
public function getUrl() {
|
49 |
-
return sprintf( 'https://wpvulndb.com/vulnerabilities/%s', $this->id );
|
50 |
-
}
|
51 |
}
|
40 |
|
41 |
return $val;
|
42 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
}
|
src/lib/src/Tables/Build/BaseBuild.php
CHANGED
@@ -157,18 +157,12 @@ class BaseBuild {
|
|
157 |
return $this->aBuildParams;
|
158 |
}
|
159 |
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
private function getFormParams() {
|
164 |
-
parse_str( Services::Request()->post( 'form_params', '' ), $aFormParams );
|
165 |
-
return Services::DataManipulation()->arrayMapRecursive( $aFormParams, 'trim' );
|
166 |
}
|
167 |
|
168 |
-
|
169 |
-
* @return array
|
170 |
-
*/
|
171 |
-
protected function getParamDefaults() {
|
172 |
return array_merge(
|
173 |
[
|
174 |
'paged' => 1,
|
157 |
return $this->aBuildParams;
|
158 |
}
|
159 |
|
160 |
+
private function getFormParams() :array {
|
161 |
+
parse_str( Services::Request()->post( 'form_params', '' ), $formParams );
|
162 |
+
return Services::DataManipulation()->arrayMapRecursive( $formParams, 'trim' );
|
|
|
|
|
|
|
163 |
}
|
164 |
|
165 |
+
protected function getParamDefaults() :array {
|
|
|
|
|
|
|
166 |
return array_merge(
|
167 |
[
|
168 |
'paged' => 1,
|
src/lib/src/Tables/Build/ScanAggregate.php
CHANGED
@@ -3,9 +3,9 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Tables\Build;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner;
|
8 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner\EntryVO;
|
|
|
9 |
|
10 |
/**
|
11 |
* Class ScanAggregate
|
@@ -32,20 +32,20 @@ class ScanAggregate extends ScanBase {
|
|
32 |
*/
|
33 |
public function getEntriesFormatted() :array {
|
34 |
// first filter out PTG results as we process them a bit separately.
|
35 |
-
$
|
36 |
-
|
37 |
-
|
38 |
-
foreach ( $
|
39 |
-
if ( $
|
40 |
-
unset( $
|
41 |
-
$
|
42 |
}
|
43 |
}
|
44 |
|
45 |
-
$aEntries = $this->processEntriesGroup( $
|
46 |
|
47 |
// Group all PTG entries together
|
48 |
-
usort( $
|
49 |
/** @var $oE1 EntryVO */
|
50 |
/** @var $oE2 EntryVO */
|
51 |
return strcasecmp( $oE1->meta[ 'path_full' ], $oE2->meta[ 'path_full' ] );
|
@@ -53,47 +53,44 @@ class ScanAggregate extends ScanBase {
|
|
53 |
|
54 |
return array_merge(
|
55 |
$aEntries,
|
56 |
-
$this->processEntriesGroup( $
|
57 |
);
|
58 |
}
|
59 |
|
60 |
/**
|
61 |
-
* @param Scanner\EntryVO[] $
|
62 |
* @return array[]
|
63 |
*/
|
64 |
-
private function processEntriesGroup( $
|
65 |
-
$
|
66 |
|
67 |
/** @var HackGuard\ModCon $mod */
|
68 |
$mod = $this->getMod();
|
69 |
-
/** @var HackGuard\Strings $
|
70 |
-
$
|
71 |
-
$
|
72 |
|
73 |
$aScanRowTracker = [];
|
74 |
-
foreach ( $
|
75 |
-
if ( empty( $aScanRowTracker[ $
|
76 |
-
$aScanRowTracker[ $
|
77 |
-
$
|
78 |
'custom_row' => true,
|
79 |
-
'title' => $
|
80 |
];
|
81 |
}
|
82 |
-
$
|
83 |
-
->getScanCon( $
|
84 |
->getTableEntryFormatter()
|
85 |
->setMod( $this->getMod() )
|
86 |
-
->setEntryVO( $
|
87 |
->format();
|
88 |
}
|
89 |
|
90 |
-
return $
|
91 |
}
|
92 |
|
93 |
-
|
94 |
-
* @return array
|
95 |
-
*/
|
96 |
-
protected function getParamDefaults() {
|
97 |
return array_merge(
|
98 |
parent::getParamDefaults(),
|
99 |
[ 'orderby' => 'scan', ]
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Tables\Build;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
|
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner\EntryVO;
|
8 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
|
9 |
|
10 |
/**
|
11 |
* Class ScanAggregate
|
32 |
*/
|
33 |
public function getEntriesFormatted() :array {
|
34 |
// first filter out PTG results as we process them a bit separately.
|
35 |
+
$ptgScanEntries = [];
|
36 |
+
/** @var Scanner\EntryVO[] $raw */
|
37 |
+
$raw = $this->getEntriesRaw();
|
38 |
+
foreach ( $raw as $key => $entry ) {
|
39 |
+
if ( $entry->scan == 'ptg' ) {
|
40 |
+
unset( $raw[ $key ] );
|
41 |
+
$ptgScanEntries[ $key ] = $entry;
|
42 |
}
|
43 |
}
|
44 |
|
45 |
+
$aEntries = $this->processEntriesGroup( $raw );
|
46 |
|
47 |
// Group all PTG entries together
|
48 |
+
usort( $ptgScanEntries, function ( $oE1, $oE2 ) {
|
49 |
/** @var $oE1 EntryVO */
|
50 |
/** @var $oE2 EntryVO */
|
51 |
return strcasecmp( $oE1->meta[ 'path_full' ], $oE2->meta[ 'path_full' ] );
|
53 |
|
54 |
return array_merge(
|
55 |
$aEntries,
|
56 |
+
$this->processEntriesGroup( $ptgScanEntries )
|
57 |
);
|
58 |
}
|
59 |
|
60 |
/**
|
61 |
+
* @param Scanner\EntryVO[] $entries
|
62 |
* @return array[]
|
63 |
*/
|
64 |
+
private function processEntriesGroup( array $entries ) {
|
65 |
+
$processed = [];
|
66 |
|
67 |
/** @var HackGuard\ModCon $mod */
|
68 |
$mod = $this->getMod();
|
69 |
+
/** @var HackGuard\Strings $strings */
|
70 |
+
$strings = $mod->getStrings();
|
71 |
+
$scanNames = $strings->getScanNames();
|
72 |
|
73 |
$aScanRowTracker = [];
|
74 |
+
foreach ( $entries as $key => $entry ) {
|
75 |
+
if ( empty( $aScanRowTracker[ $entry->scan ] ) ) {
|
76 |
+
$aScanRowTracker[ $entry->scan ] = $entry->scan;
|
77 |
+
$processed[ $entry->scan ] = [
|
78 |
'custom_row' => true,
|
79 |
+
'title' => $scanNames[ $entry->scan ],
|
80 |
];
|
81 |
}
|
82 |
+
$processed[ $key ] = $mod
|
83 |
+
->getScanCon( $entry->scan )
|
84 |
->getTableEntryFormatter()
|
85 |
->setMod( $this->getMod() )
|
86 |
+
->setEntryVO( $entry )
|
87 |
->format();
|
88 |
}
|
89 |
|
90 |
+
return $processed;
|
91 |
}
|
92 |
|
93 |
+
protected function getParamDefaults() :array {
|
|
|
|
|
|
|
94 |
return array_merge(
|
95 |
parent::getParamDefaults(),
|
96 |
[ 'orderby' => 'scan', ]
|
src/lib/src/Tables/Build/ScanBase.php
CHANGED
@@ -22,19 +22,19 @@ class ScanBase extends BaseBuild {
|
|
22 |
* @return array[]
|
23 |
*/
|
24 |
public function getEntriesFormatted() :array {
|
25 |
-
$
|
26 |
|
27 |
/** @var ModCon $mod */
|
28 |
$mod = $this->getMod();
|
29 |
-
foreach ( $this->getEntriesRaw() as $
|
30 |
-
/** @var Scanner\EntryVO $
|
31 |
-
$
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
}
|
36 |
|
37 |
-
return $
|
38 |
}
|
39 |
|
40 |
/**
|
@@ -63,10 +63,7 @@ class ScanBase extends BaseBuild {
|
|
63 |
];
|
64 |
}
|
65 |
|
66 |
-
|
67 |
-
* @return array
|
68 |
-
*/
|
69 |
-
protected function getParamDefaults() {
|
70 |
return array_merge(
|
71 |
parent::getParamDefaults(),
|
72 |
[ 'limit' => PHP_INT_MAX ]
|
@@ -74,11 +71,11 @@ class ScanBase extends BaseBuild {
|
|
74 |
}
|
75 |
|
76 |
/**
|
77 |
-
* @param Scanner\EntryVO $
|
78 |
* @return string
|
79 |
*/
|
80 |
-
protected function formatIsIgnored( $
|
81 |
-
return ( $
|
82 |
__( 'Yes' ) : __( 'No' );
|
83 |
}
|
84 |
}
|
22 |
* @return array[]
|
23 |
*/
|
24 |
public function getEntriesFormatted() :array {
|
25 |
+
$entries = [];
|
26 |
|
27 |
/** @var ModCon $mod */
|
28 |
$mod = $this->getMod();
|
29 |
+
foreach ( $this->getEntriesRaw() as $key => $entry ) {
|
30 |
+
/** @var Scanner\EntryVO $entry */
|
31 |
+
$entries[ $key ] = $mod->getScanCon( $entry->scan )
|
32 |
+
->getTableEntryFormatter()
|
33 |
+
->setEntryVO( $entry )
|
34 |
+
->format();
|
35 |
}
|
36 |
|
37 |
+
return $entries;
|
38 |
}
|
39 |
|
40 |
/**
|
63 |
];
|
64 |
}
|
65 |
|
66 |
+
protected function getParamDefaults() :array {
|
|
|
|
|
|
|
67 |
return array_merge(
|
68 |
parent::getParamDefaults(),
|
69 |
[ 'limit' => PHP_INT_MAX ]
|
71 |
}
|
72 |
|
73 |
/**
|
74 |
+
* @param Scanner\EntryVO $entry
|
75 |
* @return string
|
76 |
*/
|
77 |
+
protected function formatIsIgnored( $entry ) {
|
78 |
+
return ( $entry->ignored_at > 0 && Services::Request()->ts() > $entry->ignored_at ) ?
|
79 |
__( 'Yes' ) : __( 'No' );
|
80 |
}
|
81 |
}
|
src/lib/src/Tables/Render/WpListTable/ScanAggregate.php
CHANGED
@@ -7,20 +7,20 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
|
7 |
class ScanAggregate extends ScanBase {
|
8 |
|
9 |
/**
|
10 |
-
* @param array $
|
11 |
* @return string
|
12 |
*/
|
13 |
-
public function column_path( $
|
14 |
|
15 |
-
$sContent = parent::column_path( $
|
16 |
|
17 |
-
if ( !empty( $
|
18 |
$sContent .= $this->buildActions(
|
19 |
array_map(
|
20 |
function ( $aActionDef ) {
|
21 |
return $this->buildActionButton_CustomArray( $aActionDef );
|
22 |
},
|
23 |
-
$
|
24 |
)
|
25 |
);
|
26 |
}
|
@@ -29,15 +29,15 @@ class ScanAggregate extends ScanBase {
|
|
29 |
}
|
30 |
|
31 |
/**
|
32 |
-
* @param array $
|
33 |
* @return string
|
34 |
*/
|
35 |
-
public function column_status( $
|
36 |
-
$
|
37 |
-
if ( !empty( $
|
38 |
-
$
|
39 |
}
|
40 |
-
return $
|
41 |
}
|
42 |
|
43 |
/**
|
7 |
class ScanAggregate extends ScanBase {
|
8 |
|
9 |
/**
|
10 |
+
* @param array $item
|
11 |
* @return string
|
12 |
*/
|
13 |
+
public function column_path( $item ) {
|
14 |
|
15 |
+
$sContent = parent::column_path( $item );
|
16 |
|
17 |
+
if ( !empty( $item[ 'actions' ] ) ) {
|
18 |
$sContent .= $this->buildActions(
|
19 |
array_map(
|
20 |
function ( $aActionDef ) {
|
21 |
return $this->buildActionButton_CustomArray( $aActionDef );
|
22 |
},
|
23 |
+
$item[ 'actions' ]
|
24 |
)
|
25 |
);
|
26 |
}
|
29 |
}
|
30 |
|
31 |
/**
|
32 |
+
* @param array $item
|
33 |
* @return string
|
34 |
*/
|
35 |
+
public function column_status( $item ) {
|
36 |
+
$status = sprintf( '<strong>%s</strong>', $item[ 'status' ] );
|
37 |
+
if ( !empty( $item[ 'explanation' ] ) ) {
|
38 |
+
$status .= '<ul><li>'.implode( '</li><li>', $item[ 'explanation' ] ).'</li></ul>';
|
39 |
}
|
40 |
+
return $status;
|
41 |
}
|
42 |
|
43 |
/**
|
src/lib/src/Tables/Render/WpListTable/ScanBase.php
CHANGED
@@ -7,16 +7,16 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
|
7 |
class ScanBase extends Base {
|
8 |
|
9 |
/**
|
10 |
-
* @param array $
|
11 |
* @return string
|
12 |
*/
|
13 |
-
public function column_path( $
|
14 |
$sOut = sprintf( '<code><span class="font-weight-bolder text-dark" style="font-size: larger">%s</span></code><code>[%s]</code>',
|
15 |
-
$
|
16 |
-
sprintf( '%s: %s', __( 'Path', 'wp-simple-firewall' ), trailingslashit( dirname( $
|
17 |
);
|
18 |
-
if ( !empty( $
|
19 |
-
$sOut .= '<p class="mb-0">'.implode( '; ', $
|
20 |
}
|
21 |
return $sOut;
|
22 |
}
|
7 |
class ScanBase extends Base {
|
8 |
|
9 |
/**
|
10 |
+
* @param array $item
|
11 |
* @return string
|
12 |
*/
|
13 |
+
public function column_path( $item ) {
|
14 |
$sOut = sprintf( '<code><span class="font-weight-bolder text-dark" style="font-size: larger">%s</span></code><code>[%s]</code>',
|
15 |
+
$item[ 'path' ],
|
16 |
+
sprintf( '%s: %s', __( 'Path', 'wp-simple-firewall' ), trailingslashit( dirname( $item[ 'path_relabs' ] ) ) )
|
17 |
);
|
18 |
+
if ( !empty( $item[ 'path_details' ] ) ) {
|
19 |
+
$sOut .= '<p class="mb-0">'.implode( '; ', $item[ 'path_details' ] ).'</p>';
|
20 |
}
|
21 |
return $sOut;
|
22 |
}
|
src/lib/src/Tables/Render/WpListTable/ScanMal.php
CHANGED
@@ -7,23 +7,23 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
|
7 |
class ScanMal extends ScanBase {
|
8 |
|
9 |
/**
|
10 |
-
* @param array $
|
11 |
* @return string
|
12 |
*/
|
13 |
-
public function column_path( $
|
14 |
$aButtons = [
|
15 |
-
$this->getActionButton_Ignore( $
|
16 |
];
|
17 |
-
if ( $
|
18 |
-
$aButtons[] = $this->getActionButton_Repair( $
|
19 |
}
|
20 |
else {
|
21 |
-
$aButtons[] = $this->getActionButton_Delete( $
|
22 |
}
|
23 |
-
if ( !empty( $
|
24 |
-
$aButtons[] = $this->getActionButton_DownloadFile( $
|
25 |
}
|
26 |
-
return parent::column_path( $
|
27 |
}
|
28 |
|
29 |
/**
|
7 |
class ScanMal extends ScanBase {
|
8 |
|
9 |
/**
|
10 |
+
* @param array $item
|
11 |
* @return string
|
12 |
*/
|
13 |
+
public function column_path( $item ) {
|
14 |
$aButtons = [
|
15 |
+
$this->getActionButton_Ignore( $item[ 'id' ] ),
|
16 |
];
|
17 |
+
if ( $item[ 'can_repair' ] ) {
|
18 |
+
$aButtons[] = $this->getActionButton_Repair( $item[ 'id' ] );
|
19 |
}
|
20 |
else {
|
21 |
+
$aButtons[] = $this->getActionButton_Delete( $item[ 'id' ] );
|
22 |
}
|
23 |
+
if ( !empty( $item[ 'href_download' ] ) ) {
|
24 |
+
$aButtons[] = $this->getActionButton_DownloadFile( $item[ 'href_download' ] );
|
25 |
}
|
26 |
+
return parent::column_path( $item ).$this->buildActions( $aButtons );
|
27 |
}
|
28 |
|
29 |
/**
|
src/lib/src/Tables/Render/WpListTable/ScanPtg.php
CHANGED
@@ -7,15 +7,15 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
|
7 |
class ScanPtg extends ScanBase {
|
8 |
|
9 |
/**
|
10 |
-
* @param array $
|
11 |
* @return string
|
12 |
*/
|
13 |
-
public function column_path( $
|
14 |
$aButtons = [];
|
15 |
-
if ( !empty( $
|
16 |
-
$aButtons[] = $this->getActionButton_DownloadFile( $
|
17 |
}
|
18 |
-
return parent::column_path( $
|
19 |
}
|
20 |
|
21 |
/**
|
7 |
class ScanPtg extends ScanBase {
|
8 |
|
9 |
/**
|
10 |
+
* @param array $item
|
11 |
* @return string
|
12 |
*/
|
13 |
+
public function column_path( $item ) {
|
14 |
$aButtons = [];
|
15 |
+
if ( !empty( $item[ 'href_download' ] ) ) {
|
16 |
+
$aButtons[] = $this->getActionButton_DownloadFile( $item[ 'href_download' ] );
|
17 |
}
|
18 |
+
return parent::column_path( $item ).$this->buildActions( $aButtons );
|
19 |
}
|
20 |
|
21 |
/**
|
src/lib/src/Tables/Render/WpListTable/ScanUfc.php
CHANGED
@@ -7,18 +7,18 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
|
7 |
class ScanUfc extends ScanBase {
|
8 |
|
9 |
/**
|
10 |
-
* @param array $
|
11 |
* @return string
|
12 |
*/
|
13 |
-
public function column_path( $
|
14 |
$aButtons = [
|
15 |
-
$this->getActionButton_Ignore( $
|
16 |
-
$this->getActionButton_Delete( $
|
17 |
];
|
18 |
-
if ( !empty( $
|
19 |
-
$aButtons[] = $this->getActionButton_DownloadFile( $
|
20 |
}
|
21 |
-
return parent::column_path( $
|
22 |
}
|
23 |
|
24 |
/**
|
7 |
class ScanUfc extends ScanBase {
|
8 |
|
9 |
/**
|
10 |
+
* @param array $item
|
11 |
* @return string
|
12 |
*/
|
13 |
+
public function column_path( $item ) {
|
14 |
$aButtons = [
|
15 |
+
$this->getActionButton_Ignore( $item[ 'id' ] ),
|
16 |
+
$this->getActionButton_Delete( $item[ 'id' ] ),
|
17 |
];
|
18 |
+
if ( !empty( $item[ 'href_download' ] ) ) {
|
19 |
+
$aButtons[] = $this->getActionButton_DownloadFile( $item[ 'href_download' ] );
|
20 |
}
|
21 |
+
return parent::column_path( $item ).$this->buildActions( $aButtons );
|
22 |
}
|
23 |
|
24 |
/**
|
src/lib/src/Tables/Render/WpListTable/ScanWcf.php
CHANGED
@@ -7,18 +7,18 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
|
7 |
class ScanWcf extends ScanBase {
|
8 |
|
9 |
/**
|
10 |
-
* @param array $
|
11 |
* @return string
|
12 |
*/
|
13 |
-
public function column_path( $
|
14 |
$aButtons = [
|
15 |
-
$this->getActionButton_Ignore( $
|
16 |
-
$this->getActionButton_Repair( $
|
17 |
];
|
18 |
-
if ( !empty( $
|
19 |
-
$aButtons[] = $this->getActionButton_DownloadFile( $
|
20 |
}
|
21 |
-
return parent::column_path( $
|
22 |
}
|
23 |
|
24 |
/**
|
7 |
class ScanWcf extends ScanBase {
|
8 |
|
9 |
/**
|
10 |
+
* @param array $item
|
11 |
* @return string
|
12 |
*/
|
13 |
+
public function column_path( $item ) {
|
14 |
$aButtons = [
|
15 |
+
$this->getActionButton_Ignore( $item[ 'id' ] ),
|
16 |
+
$this->getActionButton_Repair( $item[ 'id' ] ),
|
17 |
];
|
18 |
+
if ( !empty( $item[ 'href_download' ] ) ) {
|
19 |
+
$aButtons[] = $this->getActionButton_DownloadFile( $item[ 'href_download' ] );
|
20 |
}
|
21 |
+
return parent::column_path( $item ).$this->buildActions( $aButtons );
|
22 |
}
|
23 |
|
24 |
/**
|
src/lib/src/Utilities/Nonce/Handler.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Utilities\Nonce;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\PluginControllerConsumer;
|
6 |
+
use FernleafSystems\Wordpress\Services\Utilities\Options\Transient;
|
7 |
+
|
8 |
+
class Handler {
|
9 |
+
|
10 |
+
use PluginControllerConsumer;
|
11 |
+
|
12 |
+
public function create( string $action, int $ttl = 0 ) :string {
|
13 |
+
$nonce = hash_hmac( 'sha1', $action, $this->getCon()->getSiteInstallationId() );
|
14 |
+
Transient::Set( 'apto-nonce-'.$action, $nonce, $ttl );
|
15 |
+
return $nonce;
|
16 |
+
}
|
17 |
+
|
18 |
+
public function verify( string $action, string $nonce ) :bool {
|
19 |
+
$valid = hash_equals(
|
20 |
+
(string)Transient::Get( 'apto-nonce-'.$action, '' ),
|
21 |
+
hash_hmac( 'sha1', $action, $this->getCon()->getSiteInstallationId() )
|
22 |
+
);
|
23 |
+
Transient::Delete( 'apto-nonce-'.$action );
|
24 |
+
return $valid;
|
25 |
+
}
|
26 |
+
}
|
src/lib/vendor/composer/autoload_classmap.php
CHANGED
@@ -215,6 +215,7 @@ return array(
|
|
215 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\AjaxHandler' => $baseDir . '/src/Modules/Base/AjaxHandler.php',
|
216 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Debug' => $baseDir . '/src/Modules/Base/Debug.php',
|
217 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Insights\\OverviewCards' => $baseDir . '/src/Modules/Base/Insights/OverviewCards.php',
|
|
|
218 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\ModCon' => $baseDir . '/src/Modules/Base/ModCon.php',
|
219 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Options' => $baseDir . '/src/Modules/Base/Options.php',
|
220 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Options\\OptValueSanitize' => $baseDir . '/src/Modules/Base/Options/OptValueSanitize.php',
|
@@ -264,7 +265,14 @@ return array(
|
|
264 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Processor' => $baseDir . '/src/Modules/Events/Processor.php',
|
265 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Reporting' => $baseDir . '/src/Modules/Events/Reporting.php',
|
266 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Strings' => $baseDir . '/src/Modules/Events/Strings.php',
|
|
|
267 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Insights\\OverviewCards' => $baseDir . '/src/Modules/Firewall/Insights/OverviewCards.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
268 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\ModCon' => $baseDir . '/src/Modules/Firewall/ModCon.php',
|
269 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Options' => $baseDir . '/src/Modules/Firewall/Options.php',
|
270 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Processor' => $baseDir . '/src/Modules/Firewall/Processor.php',
|
@@ -373,11 +381,11 @@ return array(
|
|
373 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\AutoUnblock' => $baseDir . '/src/Modules/IPs/Lib/AutoUnblock.php',
|
374 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\BlacklistHandler' => $baseDir . '/src/Modules/IPs/Lib/BlacklistHandler.php',
|
375 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\BlockRequest' => $baseDir . '/src/Modules/IPs/Lib/BlockRequest.php',
|
|
|
376 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotSignalsController' => $baseDir . '/src/Modules/IPs/Lib/Bots/BotSignalsController.php',
|
377 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotSignalsRecord' => $baseDir . '/src/Modules/IPs/Lib/Bots/BotSignalsRecord.php',
|
378 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\BuildScores' => $baseDir . '/src/Modules/IPs/Lib/Bots/Calculator/BuildScores.php',
|
379 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\CalculateVisitorBotScores' => $baseDir . '/src/Modules/IPs/Lib/Bots/Calculator/CalculateVisitorBotScores.php',
|
380 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\EventListener' => $baseDir . '/src/Modules/IPs/Lib/Bots/EventListener.php',
|
381 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\InsertNotBotJs' => $baseDir . '/src/Modules/IPs/Lib/Bots/NotBot/InsertNotBotJs.php',
|
382 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\NotBotHandler' => $baseDir . '/src/Modules/IPs/Lib/Bots/NotBot/NotBotHandler.php',
|
383 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\BuildDisplay' => $baseDir . '/src/Modules/IPs/Lib/IpAnalyse/BuildDisplay.php',
|
@@ -399,7 +407,10 @@ return array(
|
|
399 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\WpCli\\BaseAddRemove' => $baseDir . '/src/Modules/IPs/WpCli/BaseAddRemove.php',
|
400 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\WpCli\\Enumerate' => $baseDir . '/src/Modules/IPs/WpCli/Enumerate.php',
|
401 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\WpCli\\Remove' => $baseDir . '/src/Modules/IPs/WpCli/Remove.php',
|
|
|
402 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Lib\\OverviewCards' => $baseDir . '/src/Modules/Insights/Lib/OverviewCards.php',
|
|
|
|
|
403 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\ModCon' => $baseDir . '/src/Modules/Insights/ModCon.php',
|
404 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Options' => $baseDir . '/src/Modules/Insights/Options.php',
|
405 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Strings' => $baseDir . '/src/Modules/Insights/Strings.php',
|
@@ -579,8 +590,19 @@ return array(
|
|
579 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\AdminNotices' => $baseDir . '/src/Modules/SecurityAdmin/AdminNotices.php',
|
580 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\AjaxHandler' => $baseDir . '/src/Modules/SecurityAdmin/AjaxHandler.php',
|
581 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Insights\\OverviewCards' => $baseDir . '/src/Modules/SecurityAdmin/Insights/OverviewCards.php',
|
582 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\
|
583 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
584 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\WhiteLabel\\ApplyLabels' => $baseDir . '/src/Modules/SecurityAdmin/Lib/WhiteLabel/ApplyLabels.php',
|
585 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\ModCon' => $baseDir . '/src/Modules/SecurityAdmin/ModCon.php',
|
586 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Options' => $baseDir . '/src/Modules/SecurityAdmin/Options.php',
|
@@ -779,6 +801,7 @@ return array(
|
|
779 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Github\\ListTags' => $baseDir . '/src/Utilities/Github/ListTags.php',
|
780 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\HCaptcha\\TestRequest' => $baseDir . '/src/Utilities/HCaptcha/TestRequest.php',
|
781 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\HumanSpam\\TestContent' => $baseDir . '/src/Utilities/HumanSpam/TestContent.php',
|
|
|
782 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Options\\CleanStorage' => $baseDir . '/src/Utilities/Options/CleanStorage.php',
|
783 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\ReCaptcha\\Enqueue' => $baseDir . '/src/Utilities/ReCaptcha/Enqueue.php',
|
784 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\ReCaptcha\\TestRequest' => $baseDir . '/src/Utilities/ReCaptcha/TestRequest.php',
|
215 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\AjaxHandler' => $baseDir . '/src/Modules/Base/AjaxHandler.php',
|
216 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Debug' => $baseDir . '/src/Modules/Base/Debug.php',
|
217 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Insights\\OverviewCards' => $baseDir . '/src/Modules/Base/Insights/OverviewCards.php',
|
218 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Lib\\Request\\FormParams' => $baseDir . '/src/Modules/Base/Lib/Request/FormParams.php',
|
219 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\ModCon' => $baseDir . '/src/Modules/Base/ModCon.php',
|
220 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Options' => $baseDir . '/src/Modules/Base/Options.php',
|
221 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Options\\OptValueSanitize' => $baseDir . '/src/Modules/Base/Options/OptValueSanitize.php',
|
265 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Processor' => $baseDir . '/src/Modules/Events/Processor.php',
|
266 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Reporting' => $baseDir . '/src/Modules/Events/Reporting.php',
|
267 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Strings' => $baseDir . '/src/Modules/Events/Strings.php',
|
268 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\UI' => $baseDir . '/src/Modules/Events/UI.php',
|
269 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Insights\\OverviewCards' => $baseDir . '/src/Modules/Firewall/Insights/OverviewCards.php',
|
270 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\CanScan' => $baseDir . '/src/Modules/Firewall/Lib/Scan/CanScan.php',
|
271 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Checks\\Base' => $baseDir . '/src/Modules/Firewall/Lib/Scan/Checks/Base.php',
|
272 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Checks\\ExeFiles' => $baseDir . '/src/Modules/Firewall/Lib/Scan/Checks/ExeFiles.php',
|
273 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Checks\\Standard' => $baseDir . '/src/Modules/Firewall/Lib/Scan/Checks/Standard.php',
|
274 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\ParametersToScan' => $baseDir . '/src/Modules/Firewall/Lib/Scan/ParametersToScan.php',
|
275 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\PerformScan' => $baseDir . '/src/Modules/Firewall/Lib/Scan/PerformScan.php',
|
276 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\ModCon' => $baseDir . '/src/Modules/Firewall/ModCon.php',
|
277 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Options' => $baseDir . '/src/Modules/Firewall/Options.php',
|
278 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Processor' => $baseDir . '/src/Modules/Firewall/Processor.php',
|
381 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\AutoUnblock' => $baseDir . '/src/Modules/IPs/Lib/AutoUnblock.php',
|
382 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\BlacklistHandler' => $baseDir . '/src/Modules/IPs/Lib/BlacklistHandler.php',
|
383 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\BlockRequest' => $baseDir . '/src/Modules/IPs/Lib/BlockRequest.php',
|
384 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotEventListener' => $baseDir . '/src/Modules/IPs/Lib/Bots/BotEventListener.php',
|
385 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotSignalsController' => $baseDir . '/src/Modules/IPs/Lib/Bots/BotSignalsController.php',
|
386 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotSignalsRecord' => $baseDir . '/src/Modules/IPs/Lib/Bots/BotSignalsRecord.php',
|
387 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\BuildScores' => $baseDir . '/src/Modules/IPs/Lib/Bots/Calculator/BuildScores.php',
|
388 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\CalculateVisitorBotScores' => $baseDir . '/src/Modules/IPs/Lib/Bots/Calculator/CalculateVisitorBotScores.php',
|
|
|
389 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\InsertNotBotJs' => $baseDir . '/src/Modules/IPs/Lib/Bots/NotBot/InsertNotBotJs.php',
|
390 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\NotBotHandler' => $baseDir . '/src/Modules/IPs/Lib/Bots/NotBot/NotBotHandler.php',
|
391 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\BuildDisplay' => $baseDir . '/src/Modules/IPs/Lib/IpAnalyse/BuildDisplay.php',
|
407 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\WpCli\\BaseAddRemove' => $baseDir . '/src/Modules/IPs/WpCli/BaseAddRemove.php',
|
408 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\WpCli\\Enumerate' => $baseDir . '/src/Modules/IPs/WpCli/Enumerate.php',
|
409 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\WpCli\\Remove' => $baseDir . '/src/Modules/IPs/WpCli/Remove.php',
|
410 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\AjaxHandler' => $baseDir . '/src/Modules/Insights/AjaxHandler.php',
|
411 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Lib\\OverviewCards' => $baseDir . '/src/Modules/Insights/Lib/OverviewCards.php',
|
412 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Lib\\Requests\\DynamicPageLoader' => $baseDir . '/src/Modules/Insights/Lib/Requests/DynamicPageLoader.php',
|
413 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Lib\\SideMenuBuilder' => $baseDir . '/src/Modules/Insights/Lib/SideMenuBuilder.php',
|
414 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\ModCon' => $baseDir . '/src/Modules/Insights/ModCon.php',
|
415 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Options' => $baseDir . '/src/Modules/Insights/Options.php',
|
416 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Strings' => $baseDir . '/src/Modules/Insights/Strings.php',
|
590 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\AdminNotices' => $baseDir . '/src/Modules/SecurityAdmin/AdminNotices.php',
|
591 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\AjaxHandler' => $baseDir . '/src/Modules/SecurityAdmin/AjaxHandler.php',
|
592 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Insights\\OverviewCards' => $baseDir . '/src/Modules/SecurityAdmin/Insights/OverviewCards.php',
|
593 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Ops\\RemoveSecAdmin' => $baseDir . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Ops/RemoveSecAdmin.php',
|
594 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Ops\\SetSecAdminPin' => $baseDir . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Ops/SetSecAdminPin.php',
|
595 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Ops\\ToggleSecAdminStatus' => $baseDir . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Ops/ToggleSecAdminStatus.php',
|
596 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Ops\\VerifyPinRequest' => $baseDir . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Ops/VerifyPinRequest.php',
|
597 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Restrictions\\Base' => $baseDir . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/Base.php',
|
598 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Restrictions\\BaseCapabilitiesRestrict' => $baseDir . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/BaseCapabilitiesRestrict.php',
|
599 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Restrictions\\Plugins' => $baseDir . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/Plugins.php',
|
600 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Restrictions\\Posts' => $baseDir . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/Posts.php',
|
601 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Restrictions\\Themes' => $baseDir . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/Themes.php',
|
602 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Restrictions\\Users' => $baseDir . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/Users.php',
|
603 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Restrictions\\WpOptions' => $baseDir . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/WpOptions.php',
|
604 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\SecurityAdminController' => $baseDir . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/SecurityAdminController.php',
|
605 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\VerifySecurityAdminList' => $baseDir . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/VerifySecurityAdminList.php',
|
606 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\WhiteLabel\\ApplyLabels' => $baseDir . '/src/Modules/SecurityAdmin/Lib/WhiteLabel/ApplyLabels.php',
|
607 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\ModCon' => $baseDir . '/src/Modules/SecurityAdmin/ModCon.php',
|
608 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Options' => $baseDir . '/src/Modules/SecurityAdmin/Options.php',
|
801 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Github\\ListTags' => $baseDir . '/src/Utilities/Github/ListTags.php',
|
802 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\HCaptcha\\TestRequest' => $baseDir . '/src/Utilities/HCaptcha/TestRequest.php',
|
803 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\HumanSpam\\TestContent' => $baseDir . '/src/Utilities/HumanSpam/TestContent.php',
|
804 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Nonce\\Handler' => $baseDir . '/src/Utilities/Nonce/Handler.php',
|
805 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Options\\CleanStorage' => $baseDir . '/src/Utilities/Options/CleanStorage.php',
|
806 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\ReCaptcha\\Enqueue' => $baseDir . '/src/Utilities/ReCaptcha/Enqueue.php',
|
807 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\ReCaptcha\\TestRequest' => $baseDir . '/src/Utilities/ReCaptcha/TestRequest.php',
|
src/lib/vendor/composer/autoload_static.php
CHANGED
@@ -383,6 +383,7 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
383 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\AjaxHandler' => __DIR__ . '/../..' . '/src/Modules/Base/AjaxHandler.php',
|
384 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Debug' => __DIR__ . '/../..' . '/src/Modules/Base/Debug.php',
|
385 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Insights\\OverviewCards' => __DIR__ . '/../..' . '/src/Modules/Base/Insights/OverviewCards.php',
|
|
|
386 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\ModCon' => __DIR__ . '/../..' . '/src/Modules/Base/ModCon.php',
|
387 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Options' => __DIR__ . '/../..' . '/src/Modules/Base/Options.php',
|
388 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Options\\OptValueSanitize' => __DIR__ . '/../..' . '/src/Modules/Base/Options/OptValueSanitize.php',
|
@@ -432,7 +433,14 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
432 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Processor' => __DIR__ . '/../..' . '/src/Modules/Events/Processor.php',
|
433 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Reporting' => __DIR__ . '/../..' . '/src/Modules/Events/Reporting.php',
|
434 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Strings' => __DIR__ . '/../..' . '/src/Modules/Events/Strings.php',
|
|
|
435 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Insights\\OverviewCards' => __DIR__ . '/../..' . '/src/Modules/Firewall/Insights/OverviewCards.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
436 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\ModCon' => __DIR__ . '/../..' . '/src/Modules/Firewall/ModCon.php',
|
437 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Options' => __DIR__ . '/../..' . '/src/Modules/Firewall/Options.php',
|
438 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Processor' => __DIR__ . '/../..' . '/src/Modules/Firewall/Processor.php',
|
@@ -541,11 +549,11 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
541 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\AutoUnblock' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/AutoUnblock.php',
|
542 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\BlacklistHandler' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/BlacklistHandler.php',
|
543 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\BlockRequest' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/BlockRequest.php',
|
|
|
544 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotSignalsController' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/BotSignalsController.php',
|
545 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotSignalsRecord' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/BotSignalsRecord.php',
|
546 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\BuildScores' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/Calculator/BuildScores.php',
|
547 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\CalculateVisitorBotScores' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/Calculator/CalculateVisitorBotScores.php',
|
548 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\EventListener' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/EventListener.php',
|
549 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\InsertNotBotJs' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/NotBot/InsertNotBotJs.php',
|
550 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\NotBotHandler' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/NotBot/NotBotHandler.php',
|
551 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\BuildDisplay' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/IpAnalyse/BuildDisplay.php',
|
@@ -567,7 +575,10 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
567 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\WpCli\\BaseAddRemove' => __DIR__ . '/../..' . '/src/Modules/IPs/WpCli/BaseAddRemove.php',
|
568 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\WpCli\\Enumerate' => __DIR__ . '/../..' . '/src/Modules/IPs/WpCli/Enumerate.php',
|
569 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\WpCli\\Remove' => __DIR__ . '/../..' . '/src/Modules/IPs/WpCli/Remove.php',
|
|
|
570 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Lib\\OverviewCards' => __DIR__ . '/../..' . '/src/Modules/Insights/Lib/OverviewCards.php',
|
|
|
|
|
571 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\ModCon' => __DIR__ . '/../..' . '/src/Modules/Insights/ModCon.php',
|
572 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Options' => __DIR__ . '/../..' . '/src/Modules/Insights/Options.php',
|
573 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Strings' => __DIR__ . '/../..' . '/src/Modules/Insights/Strings.php',
|
@@ -747,8 +758,19 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
747 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\AdminNotices' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/AdminNotices.php',
|
748 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\AjaxHandler' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/AjaxHandler.php',
|
749 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Insights\\OverviewCards' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Insights/OverviewCards.php',
|
750 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\
|
751 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
752 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\WhiteLabel\\ApplyLabels' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Lib/WhiteLabel/ApplyLabels.php',
|
753 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\ModCon' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/ModCon.php',
|
754 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Options' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Options.php',
|
@@ -947,6 +969,7 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
947 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Github\\ListTags' => __DIR__ . '/../..' . '/src/Utilities/Github/ListTags.php',
|
948 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\HCaptcha\\TestRequest' => __DIR__ . '/../..' . '/src/Utilities/HCaptcha/TestRequest.php',
|
949 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\HumanSpam\\TestContent' => __DIR__ . '/../..' . '/src/Utilities/HumanSpam/TestContent.php',
|
|
|
950 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Options\\CleanStorage' => __DIR__ . '/../..' . '/src/Utilities/Options/CleanStorage.php',
|
951 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\ReCaptcha\\Enqueue' => __DIR__ . '/../..' . '/src/Utilities/ReCaptcha/Enqueue.php',
|
952 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\ReCaptcha\\TestRequest' => __DIR__ . '/../..' . '/src/Utilities/ReCaptcha/TestRequest.php',
|
383 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\AjaxHandler' => __DIR__ . '/../..' . '/src/Modules/Base/AjaxHandler.php',
|
384 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Debug' => __DIR__ . '/../..' . '/src/Modules/Base/Debug.php',
|
385 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Insights\\OverviewCards' => __DIR__ . '/../..' . '/src/Modules/Base/Insights/OverviewCards.php',
|
386 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Lib\\Request\\FormParams' => __DIR__ . '/../..' . '/src/Modules/Base/Lib/Request/FormParams.php',
|
387 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\ModCon' => __DIR__ . '/../..' . '/src/Modules/Base/ModCon.php',
|
388 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Options' => __DIR__ . '/../..' . '/src/Modules/Base/Options.php',
|
389 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Options\\OptValueSanitize' => __DIR__ . '/../..' . '/src/Modules/Base/Options/OptValueSanitize.php',
|
433 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Processor' => __DIR__ . '/../..' . '/src/Modules/Events/Processor.php',
|
434 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Reporting' => __DIR__ . '/../..' . '/src/Modules/Events/Reporting.php',
|
435 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Strings' => __DIR__ . '/../..' . '/src/Modules/Events/Strings.php',
|
436 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\UI' => __DIR__ . '/../..' . '/src/Modules/Events/UI.php',
|
437 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Insights\\OverviewCards' => __DIR__ . '/../..' . '/src/Modules/Firewall/Insights/OverviewCards.php',
|
438 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\CanScan' => __DIR__ . '/../..' . '/src/Modules/Firewall/Lib/Scan/CanScan.php',
|
439 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Checks\\Base' => __DIR__ . '/../..' . '/src/Modules/Firewall/Lib/Scan/Checks/Base.php',
|
440 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Checks\\ExeFiles' => __DIR__ . '/../..' . '/src/Modules/Firewall/Lib/Scan/Checks/ExeFiles.php',
|
441 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Checks\\Standard' => __DIR__ . '/../..' . '/src/Modules/Firewall/Lib/Scan/Checks/Standard.php',
|
442 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\ParametersToScan' => __DIR__ . '/../..' . '/src/Modules/Firewall/Lib/Scan/ParametersToScan.php',
|
443 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\PerformScan' => __DIR__ . '/../..' . '/src/Modules/Firewall/Lib/Scan/PerformScan.php',
|
444 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\ModCon' => __DIR__ . '/../..' . '/src/Modules/Firewall/ModCon.php',
|
445 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Options' => __DIR__ . '/../..' . '/src/Modules/Firewall/Options.php',
|
446 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Processor' => __DIR__ . '/../..' . '/src/Modules/Firewall/Processor.php',
|
549 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\AutoUnblock' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/AutoUnblock.php',
|
550 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\BlacklistHandler' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/BlacklistHandler.php',
|
551 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\BlockRequest' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/BlockRequest.php',
|
552 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotEventListener' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/BotEventListener.php',
|
553 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotSignalsController' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/BotSignalsController.php',
|
554 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotSignalsRecord' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/BotSignalsRecord.php',
|
555 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\BuildScores' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/Calculator/BuildScores.php',
|
556 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\CalculateVisitorBotScores' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/Calculator/CalculateVisitorBotScores.php',
|
|
|
557 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\InsertNotBotJs' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/NotBot/InsertNotBotJs.php',
|
558 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\NotBotHandler' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/NotBot/NotBotHandler.php',
|
559 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\BuildDisplay' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/IpAnalyse/BuildDisplay.php',
|
575 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\WpCli\\BaseAddRemove' => __DIR__ . '/../..' . '/src/Modules/IPs/WpCli/BaseAddRemove.php',
|
576 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\WpCli\\Enumerate' => __DIR__ . '/../..' . '/src/Modules/IPs/WpCli/Enumerate.php',
|
577 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\WpCli\\Remove' => __DIR__ . '/../..' . '/src/Modules/IPs/WpCli/Remove.php',
|
578 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\AjaxHandler' => __DIR__ . '/../..' . '/src/Modules/Insights/AjaxHandler.php',
|
579 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Lib\\OverviewCards' => __DIR__ . '/../..' . '/src/Modules/Insights/Lib/OverviewCards.php',
|
580 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Lib\\Requests\\DynamicPageLoader' => __DIR__ . '/../..' . '/src/Modules/Insights/Lib/Requests/DynamicPageLoader.php',
|
581 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Lib\\SideMenuBuilder' => __DIR__ . '/../..' . '/src/Modules/Insights/Lib/SideMenuBuilder.php',
|
582 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\ModCon' => __DIR__ . '/../..' . '/src/Modules/Insights/ModCon.php',
|
583 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Options' => __DIR__ . '/../..' . '/src/Modules/Insights/Options.php',
|
584 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Insights\\Strings' => __DIR__ . '/../..' . '/src/Modules/Insights/Strings.php',
|
758 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\AdminNotices' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/AdminNotices.php',
|
759 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\AjaxHandler' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/AjaxHandler.php',
|
760 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Insights\\OverviewCards' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Insights/OverviewCards.php',
|
761 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Ops\\RemoveSecAdmin' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Ops/RemoveSecAdmin.php',
|
762 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Ops\\SetSecAdminPin' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Ops/SetSecAdminPin.php',
|
763 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Ops\\ToggleSecAdminStatus' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Ops/ToggleSecAdminStatus.php',
|
764 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Ops\\VerifyPinRequest' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Ops/VerifyPinRequest.php',
|
765 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Restrictions\\Base' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/Base.php',
|
766 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Restrictions\\BaseCapabilitiesRestrict' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/BaseCapabilitiesRestrict.php',
|
767 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Restrictions\\Plugins' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/Plugins.php',
|
768 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Restrictions\\Posts' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/Posts.php',
|
769 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Restrictions\\Themes' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/Themes.php',
|
770 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Restrictions\\Users' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/Users.php',
|
771 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\Restrictions\\WpOptions' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/WpOptions.php',
|
772 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\SecurityAdminController' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/SecurityAdminController.php',
|
773 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\SecurityAdmin\\VerifySecurityAdminList' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Lib/SecurityAdmin/VerifySecurityAdminList.php',
|
774 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Lib\\WhiteLabel\\ApplyLabels' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Lib/WhiteLabel/ApplyLabels.php',
|
775 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\ModCon' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/ModCon.php',
|
776 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\Options' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/Options.php',
|
969 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Github\\ListTags' => __DIR__ . '/../..' . '/src/Utilities/Github/ListTags.php',
|
970 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\HCaptcha\\TestRequest' => __DIR__ . '/../..' . '/src/Utilities/HCaptcha/TestRequest.php',
|
971 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\HumanSpam\\TestContent' => __DIR__ . '/../..' . '/src/Utilities/HumanSpam/TestContent.php',
|
972 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Nonce\\Handler' => __DIR__ . '/../..' . '/src/Utilities/Nonce/Handler.php',
|
973 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Options\\CleanStorage' => __DIR__ . '/../..' . '/src/Utilities/Options/CleanStorage.php',
|
974 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\ReCaptcha\\Enqueue' => __DIR__ . '/../..' . '/src/Utilities/ReCaptcha/Enqueue.php',
|
975 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\ReCaptcha\\TestRequest' => __DIR__ . '/../..' . '/src/Utilities/ReCaptcha/TestRequest.php',
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Request.php
CHANGED
@@ -3,38 +3,19 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Services\Core;
|
4 |
|
5 |
use Carbon\Carbon;
|
|
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
8 |
/**
|
9 |
* Class Request
|
10 |
* @package FernleafSystems\Wordpress\Services\Core
|
|
|
|
|
|
|
|
|
|
|
11 |
*/
|
12 |
-
class Request {
|
13 |
-
|
14 |
-
/**
|
15 |
-
* @var array
|
16 |
-
*/
|
17 |
-
private $post;
|
18 |
-
|
19 |
-
/**
|
20 |
-
* @var array
|
21 |
-
*/
|
22 |
-
private $query;
|
23 |
-
|
24 |
-
/**
|
25 |
-
* @var array
|
26 |
-
*/
|
27 |
-
private $cookie;
|
28 |
-
|
29 |
-
/**
|
30 |
-
* @var array
|
31 |
-
*/
|
32 |
-
private $server;
|
33 |
-
|
34 |
-
/**
|
35 |
-
* @var array
|
36 |
-
*/
|
37 |
-
private $env;
|
38 |
|
39 |
/**
|
40 |
* @var int
|
@@ -57,12 +38,7 @@ class Request {
|
|
57 |
public function __construct() {
|
58 |
$this->post = is_array( $_POST ) ? $_POST : [];
|
59 |
$this->query = is_array( $_GET ) ? $_GET : [];
|
60 |
-
|
61 |
-
$this->cookie = &$_COOKIE;
|
62 |
-
}
|
63 |
-
else {
|
64 |
-
$this->cookie = [];
|
65 |
-
}
|
66 |
$this->server = is_array( $_SERVER ) ? $_SERVER : [];
|
67 |
$this->env = is_array( $_ENV ) ? $_ENV : [];
|
68 |
$this->ts();
|
@@ -240,7 +216,7 @@ class Request {
|
|
240 |
}
|
241 |
|
242 |
/**
|
243 |
-
* @param array
|
244 |
* @param string $key
|
245 |
* @param mixed $default
|
246 |
* @return mixed|null
|
3 |
namespace FernleafSystems\Wordpress\Services\Core;
|
4 |
|
5 |
use Carbon\Carbon;
|
6 |
+
use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
9 |
/**
|
10 |
* Class Request
|
11 |
* @package FernleafSystems\Wordpress\Services\Core
|
12 |
+
* @property array $post
|
13 |
+
* @property array $query
|
14 |
+
* @property array $cookie
|
15 |
+
* @property array $server
|
16 |
+
* @property array $env
|
17 |
*/
|
18 |
+
class Request extends DynPropertiesClass {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
|
20 |
/**
|
21 |
* @var int
|
38 |
public function __construct() {
|
39 |
$this->post = is_array( $_POST ) ? $_POST : [];
|
40 |
$this->query = is_array( $_GET ) ? $_GET : [];
|
41 |
+
$this->cookie = is_array( $_COOKIE ) ? $_COOKIE : [];
|
|
|
|
|
|
|
|
|
|
|
42 |
$this->server = is_array( $_SERVER ) ? $_SERVER : [];
|
43 |
$this->env = is_array( $_ENV ) ? $_ENV : [];
|
44 |
$this->ts();
|
216 |
}
|
217 |
|
218 |
/**
|
219 |
+
* @param array $container
|
220 |
* @param string $key
|
221 |
* @param mixed $default
|
222 |
* @return mixed|null
|
src/wizards/base.php
CHANGED
@@ -272,9 +272,7 @@ abstract class ICWP_WPSF_Wizard_Base {
|
|
272 |
'mod_wizards' => $wizards
|
273 |
],
|
274 |
'hrefs' => [
|
275 |
-
'dashboard' => $this->getCon()
|
276 |
-
->getModule_Insights()
|
277 |
-
->getUrl_SubInsightsPage( 'dashboard' ),
|
278 |
'goprofooter' => 'https://shsec.io/goprofooter',
|
279 |
],
|
280 |
'ajax' => [
|
@@ -314,9 +312,7 @@ abstract class ICWP_WPSF_Wizard_Base {
|
|
314 |
'wizard_first_step' => json_encode( $this->getWizardFirstStep() ),
|
315 |
],
|
316 |
'hrefs' => [
|
317 |
-
'dashboard' => $this->getCon()
|
318 |
-
->getModule_Insights()
|
319 |
-
->getUrl_SubInsightsPage( 'dashboard' ),
|
320 |
'goprofooter' => 'https://shsec.io/goprofooter',
|
321 |
],
|
322 |
'ajax' => [
|
@@ -405,9 +401,7 @@ abstract class ICWP_WPSF_Wizard_Base {
|
|
405 |
'has_other_wizards' => false
|
406 |
],
|
407 |
'hrefs' => [
|
408 |
-
'dashboard' => $this->getCon()
|
409 |
-
->getModule_Insights()
|
410 |
-
->getUrl_SubInsightsPage( 'dashboard' ),
|
411 |
'gopro' => 'https://shsec.io/ap',
|
412 |
],
|
413 |
'imgs' => [],
|
272 |
'mod_wizards' => $wizards
|
273 |
],
|
274 |
'hrefs' => [
|
275 |
+
'dashboard' => $this->getCon()->getPluginUrl_DashboardHome(),
|
|
|
|
|
276 |
'goprofooter' => 'https://shsec.io/goprofooter',
|
277 |
],
|
278 |
'ajax' => [
|
312 |
'wizard_first_step' => json_encode( $this->getWizardFirstStep() ),
|
313 |
],
|
314 |
'hrefs' => [
|
315 |
+
'dashboard' => $this->getCon()->getPluginUrl_DashboardHome(),
|
|
|
|
|
316 |
'goprofooter' => 'https://shsec.io/goprofooter',
|
317 |
],
|
318 |
'ajax' => [
|
401 |
'has_other_wizards' => false
|
402 |
],
|
403 |
'hrefs' => [
|
404 |
+
'dashboard' => $this->getCon()->getPluginUrl_DashboardHome(),
|
|
|
|
|
405 |
'gopro' => 'https://shsec.io/ap',
|
406 |
],
|
407 |
'imgs' => [],
|
src/wizards/base_wpsf.php
CHANGED
@@ -93,29 +93,26 @@ abstract class ICWP_WPSF_Wizard_BaseWpsf extends ICWP_WPSF_Wizard_Base {
|
|
93 |
* @return \FernleafSystems\Utilities\Response
|
94 |
*/
|
95 |
private function wizardSecurityAdminVerify() {
|
96 |
-
$
|
97 |
|
98 |
-
$
|
|
|
|
|
99 |
|
100 |
-
$
|
101 |
-
|
102 |
-
|
103 |
-
$sMessage = '';
|
104 |
-
if ( empty( $sKey ) ) {
|
105 |
-
$sMessage = 'Security Admin PIN was empty.';
|
106 |
}
|
107 |
-
elseif ( !$
|
108 |
-
$
|
109 |
}
|
110 |
else {
|
111 |
-
$
|
112 |
-
$
|
113 |
'rerender' => true
|
114 |
-
];
|
115 |
-
$oResponse->setData( $aData );
|
116 |
}
|
117 |
|
118 |
-
return $
|
119 |
-
|
120 |
}
|
121 |
}
|
93 |
* @return \FernleafSystems\Utilities\Response
|
94 |
*/
|
95 |
private function wizardSecurityAdminVerify() {
|
96 |
+
$pin = Services::Request()->post( 'sec_admin_key' );
|
97 |
|
98 |
+
$response = new \FernleafSystems\Utilities\Response();
|
99 |
+
$success = false;
|
100 |
+
$msg = '';
|
101 |
|
102 |
+
if ( empty( $pin ) ) {
|
103 |
+
$msg = 'Security Admin PIN was empty.';
|
|
|
|
|
|
|
|
|
104 |
}
|
105 |
+
elseif ( !$this->getCon()->getModule_SecAdmin()->getSecurityAdminController()->verifyPinRequest() ) {
|
106 |
+
$msg = __( 'Security Admin PIN was not correct.', 'wp-simple-firewall' );
|
107 |
}
|
108 |
else {
|
109 |
+
$success = true;
|
110 |
+
$response->setData( [
|
111 |
'rerender' => true
|
112 |
+
] );
|
|
|
113 |
}
|
114 |
|
115 |
+
return $response->setSuccessful( $success )
|
116 |
+
->setMessageText( $msg );
|
117 |
}
|
118 |
}
|
src/wizards/plugin.php
CHANGED
@@ -370,8 +370,8 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
|
|
370 |
$mod = $this->getCon()->getModule_License();
|
371 |
try {
|
372 |
$success = $mod->getLicenseHandler()
|
373 |
-
|
374 |
-
|
375 |
if ( $success ) {
|
376 |
$msg = __( 'License was found and successfully installed.', 'wp-simple-firewall' );
|
377 |
}
|
@@ -432,33 +432,32 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
|
|
432 |
* @return \FernleafSystems\Utilities\Response
|
433 |
*/
|
434 |
private function wizardSecurityAdmin() {
|
435 |
-
$
|
436 |
-
$pin = $
|
437 |
-
$
|
438 |
|
439 |
-
$
|
440 |
if ( empty( $pin ) ) {
|
441 |
-
$
|
442 |
}
|
443 |
-
elseif ( $pin != $
|
444 |
-
$
|
445 |
}
|
446 |
else {
|
447 |
$mod = $this->getCon()->getModule_SecAdmin();
|
448 |
try {
|
449 |
-
$mod->setNewPinManually( $pin )
|
450 |
-
|
451 |
-
$
|
452 |
-
$sMessage = __( 'Security Admin PIN setup was successful.', 'wp-simple-firewall' );
|
453 |
}
|
454 |
catch ( \Exception $e ) {
|
455 |
-
$
|
456 |
}
|
457 |
}
|
458 |
|
459 |
return ( new \FernleafSystems\Utilities\Response() )
|
460 |
-
->setSuccessful( $
|
461 |
-
->setMessageText( $
|
462 |
}
|
463 |
|
464 |
/**
|
370 |
$mod = $this->getCon()->getModule_License();
|
371 |
try {
|
372 |
$success = $mod->getLicenseHandler()
|
373 |
+
->verify( true )
|
374 |
+
->hasValidWorkingLicense();
|
375 |
if ( $success ) {
|
376 |
$msg = __( 'License was found and successfully installed.', 'wp-simple-firewall' );
|
377 |
}
|
432 |
* @return \FernleafSystems\Utilities\Response
|
433 |
*/
|
434 |
private function wizardSecurityAdmin() {
|
435 |
+
$req = Services::Request();
|
436 |
+
$pin = $req->post( 'sec_admin_key' );
|
437 |
+
$confirm = $req->post( 'AccessKeyConfirm' );
|
438 |
|
439 |
+
$success = false;
|
440 |
if ( empty( $pin ) ) {
|
441 |
+
$msg = __( "Security Admin PIN was empty.", 'wp-simple-firewall' );
|
442 |
}
|
443 |
+
elseif ( $pin != $confirm ) {
|
444 |
+
$msg = __( "Security PINs don't match.", 'wp-simple-firewall' );
|
445 |
}
|
446 |
else {
|
447 |
$mod = $this->getCon()->getModule_SecAdmin();
|
448 |
try {
|
449 |
+
$mod->setNewPinManually( $pin );
|
450 |
+
$success = true;
|
451 |
+
$msg = __( 'Security Admin PIN setup was successful.', 'wp-simple-firewall' );
|
|
|
452 |
}
|
453 |
catch ( \Exception $e ) {
|
454 |
+
$msg = __( $e->getMessage(), 'wp-simple-firewall' );
|
455 |
}
|
456 |
}
|
457 |
|
458 |
return ( new \FernleafSystems\Utilities\Response() )
|
459 |
+
->setSuccessful( $success )
|
460 |
+
->setMessageText( $msg );
|
461 |
}
|
462 |
|
463 |
/**
|
templates/php/snippets/plugin-deactivate-survey.php
DELETED
@@ -1,14 +0,0 @@
|
|
1 |
-
<div id="icwpWpsfSurvey" class="hidden icwp-wpsf-dialog">
|
2 |
-
<p>Deactivating Shield makes us sad, but you can help us improve by letting us know why.</p>
|
3 |
-
<p>This is optional - will you take a second to tell us why you're deactivating Shield?</p>
|
4 |
-
<form id="icwpWpsfSurveyForm">
|
5 |
-
<ul>
|
6 |
-
<?php foreach ( $inputs[ 'checkboxes' ] as $sKey => $sOpt ) : ?>
|
7 |
-
<li><label><input name="<?php echo $sKey; ?>" type="checkbox" value="Y">
|
8 |
-
<?php echo $sOpt; ?></label></li>
|
9 |
-
<?php endforeach; ?>
|
10 |
-
</ul>
|
11 |
-
<textarea name="reason_comments" style="width: 360px;" rows="3"
|
12 |
-
placeholder="If you got errors, for example, could you outline the problems you had?"></textarea>
|
13 |
-
</form>
|
14 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
templates/twig/components/events/stats/stat_box.twig
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="card h-100 stat_box">
|
2 |
+
<div class="card-header">
|
3 |
+
{{ stat.name }}
|
4 |
+
</div>
|
5 |
+
<div class="card-body d-flex flex-row text-center justify-content-center">
|
6 |
+
<div class="stat_count">{{ attribute(stat.counts, stat_to_show|default('lifetime')) }}</div>
|
7 |
+
</div>
|
8 |
+
</div>
|
templates/twig/components/events/stats/stats_collection.twig
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
{% for stats_section in vars.stats %}
|
3 |
+
<div class="row row-cols-md-3 row-cols-lg-4 row-cols-xl-6 ">
|
4 |
+
{% for stat in stats_section %}
|
5 |
+
<div class=" col mb-4">
|
6 |
+
{% include '/components/events/stats/stat_box.twig' %}
|
7 |
+
</div>
|
8 |
+
{% endfor %}
|
9 |
+
</div>
|
10 |
+
{% endfor %}
|
templates/twig/components/options_form/main.twig
CHANGED
@@ -1,5 +1,9 @@
|
|
1 |
-
<form action="{{ form_action }}" method="post"
|
2 |
-
|
|
|
|
|
|
|
|
|
3 |
|
4 |
<div id="ModuleOptionsNav" class="insights-sub-nav" aria-orientation="horizontal">
|
5 |
<ul class="nav nav-tabs" role="tablist">
|
@@ -25,20 +29,25 @@
|
|
25 |
|
26 |
<div class="row">
|
27 |
<div class="col-12">
|
28 |
-
<h5 class="
|
29 |
-
{{ opt_section.title }}
|
30 |
|
31 |
{% if ( opt_section.summary is defined ) and opt_section.summary|length %}
|
32 |
<a class="section_title_info"
|
33 |
-
data-toggle="
|
34 |
-
data-
|
35 |
-
|
36 |
-
<
|
37 |
-
|
38 |
-
|
39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
{% endif %}
|
41 |
-
|
42 |
</h5>
|
43 |
</div>
|
44 |
</div>
|
1 |
+
<form action="{{ form_action }}" method="post"
|
2 |
+
class="icwpOptionsForm form"
|
3 |
+
novalidate="novalidate"
|
4 |
+
autocomplete="off"
|
5 |
+
data-mod_slug="{{ vars.mod_slug }}"
|
6 |
+
>
|
7 |
|
8 |
<div id="ModuleOptionsNav" class="insights-sub-nav" aria-orientation="horizontal">
|
9 |
<ul class="nav nav-tabs" role="tablist">
|
29 |
|
30 |
<div class="row">
|
31 |
<div class="col-12">
|
32 |
+
<h5 class="mt-3">
|
33 |
+
<span class="mb-3 d-inline-block">{{ opt_section.title }}</span>
|
34 |
|
35 |
{% if ( opt_section.summary is defined ) and opt_section.summary|length %}
|
36 |
<a class="section_title_info"
|
37 |
+
data-toggle="collapse"
|
38 |
+
data-target="#collapse-{{ opt_section.slug }}"
|
39 |
+
><span class="dashicons dashicons-info"></span></a>
|
40 |
+
<br />
|
41 |
+
<div class="collapse mb-3" id="collapse-{{ opt_section.slug }}">
|
42 |
+
<div class="card">
|
43 |
+
<div class="card-body">
|
44 |
+
{% for item in opt_section.summary %}
|
45 |
+
<p class="card-text">{{ item|raw }}</p>
|
46 |
+
{% endfor %}
|
47 |
+
</div>
|
48 |
+
</div>
|
49 |
+
</div>
|
50 |
{% endif %}
|
|
|
51 |
</h5>
|
52 |
</div>
|
53 |
</div>
|
templates/twig/components/search/dialog.twig
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="modal fade"
|
2 |
+
role="dialog"
|
3 |
+
id="SearchDialog"
|
4 |
+
tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true"
|
5 |
+
>
|
6 |
+
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
|
7 |
+
<div class="modal-content">
|
8 |
+
<div class="modal-header">
|
9 |
+
<h5 class="modal-title" id="exampleModalLabel">Search The Plugin For Options</h5>
|
10 |
+
</div>
|
11 |
+
<div class="modal-body">
|
12 |
+
<div class="container-fluid">
|
13 |
+
<div class="row no-gutters row-cols-1">
|
14 |
+
<div class="col">
|
15 |
+
{% include '/components/search/options.twig' %}
|
16 |
+
</div>
|
17 |
+
</div>
|
18 |
+
</div>
|
19 |
+
</div>
|
20 |
+
</div>
|
21 |
+
</div>
|
22 |
+
</div>
|
templates/twig/components/search/options.twig
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{% if vars.search_select is defined %}
|
2 |
+
<select class="selectpicker" data-live-search="true"
|
3 |
+
title="Search For Plugin Option"
|
4 |
+
data-size="10"
|
5 |
+
data-header=""
|
6 |
+
onchange="location = this.value;"
|
7 |
+
style="max-width: 100%; width: 100%"
|
8 |
+
>
|
9 |
+
{% for select_section_name,select_section_opts in vars.search_select|default([]) %}
|
10 |
+
<optgroup label="{{ select_section_name }}">
|
11 |
+
{% for select_opt_key,select_opt_data in select_section_opts %}
|
12 |
+
<option value="{{ select_opt_data.href }}"
|
13 |
+
aria-selected="false"
|
14 |
+
data-tokens="{{ select_opt_data.summary }} {{ select_opt_data.description|join(' ') }}"
|
15 |
+
>{{ select_opt_data.name }}
|
16 |
+
</option>
|
17 |
+
{% endfor %}
|
18 |
+
</optgroup>
|
19 |
+
{% endfor %}
|
20 |
+
</select>
|
21 |
+
{% endif %}
|
templates/twig/components/security_admin/login_box.twig
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div id="WpsfAdminAccessLogin" style="display:none;">
|
2 |
+
<div class="bootstrap-wpadmin wpsf-admin-access-login"
|
3 |
+
id="SecAdminDialog">
|
4 |
+
<div class="input-holder" id="SecAdminPinInputContainer">
|
5 |
+
<label>
|
6 |
+
{{ strings.access_message }}
|
7 |
+
<input id="SecAdminPinInput" type="password" name="sec_admin_key" />
|
8 |
+
<button type="submit">Go!</button>
|
9 |
+
</label>
|
10 |
+
</div>
|
11 |
+
|
12 |
+
</div>
|
13 |
+
</div>
|
14 |
+
|
15 |
+
<style type="text/css">
|
16 |
+
.input-holder label {
|
17 |
+
font-size: 24px;
|
18 |
+
}
|
19 |
+
.input-holder label {
|
20 |
+
font-size: inherit;
|
21 |
+
display: block;
|
22 |
+
margin: 6% 107px;
|
23 |
+
vertical-align: middle;
|
24 |
+
}
|
25 |
+
.input-holder input {
|
26 |
+
font-size: inherit;
|
27 |
+
height: 60px;
|
28 |
+
vertical-align: middle;
|
29 |
+
width: 180px;
|
30 |
+
}
|
31 |
+
</style>
|
32 |
+
|
33 |
+
<script type="text/javascript">
|
34 |
+
|
35 |
+
{# let $oThisAAL = jQuery( '#AdminInputHolder' );#}
|
36 |
+
{# let $oInput = jQuery( 'input', $oThisAAL );#}
|
37 |
+
{# jQuery( document ).ready(#}
|
38 |
+
{# function () {#}
|
39 |
+
|
40 |
+
{# jQuery( document ).on( 'click', '#SecAdminDialog button', submit_admin_access );#}
|
41 |
+
{# jQuery( 'input', $oThisAAL ).keypress( function ( e ) {#}
|
42 |
+
{# if ( e.which === 13 ) {#}
|
43 |
+
{# submit_admin_access();#}
|
44 |
+
{# }#}
|
45 |
+
{# } );#}
|
46 |
+
{# }#}
|
47 |
+
{# );#}
|
48 |
+
|
49 |
+
{# function submit_admin_access() {#}
|
50 |
+
{# $oThisAAL.html( '<div class="spinner"></div>' );#}
|
51 |
+
{# jQuery( 'input', $oThisAAL ).prop( 'disabled', true );#}
|
52 |
+
|
53 |
+
{# var requestData = {{ ajax.sec_admin_login|raw }};#}
|
54 |
+
{# requestData[ 'sec_admin_key' ] = $oInput.val();#}
|
55 |
+
|
56 |
+
{# jQuery.post( ajaxurl, requestData, function ( oResponse ) {#}
|
57 |
+
{# if ( oResponse.success ) {#}
|
58 |
+
{# location.reload();#}
|
59 |
+
{# }#}
|
60 |
+
{# if ( oResponse.data ) {#}
|
61 |
+
{# $oThisAAL.html( oResponse.data.html );#}
|
62 |
+
{# }#}
|
63 |
+
{# else {#}
|
64 |
+
{# $oThisAAL.html( 'There was an unknown error' );#}
|
65 |
+
{# }#}
|
66 |
+
{# } );#}
|
67 |
+
{# }#}
|
68 |
+
</script>
|
templates/twig/email/lp_2fa_email_code.twig
CHANGED
@@ -16,6 +16,8 @@
|
|
16 |
<li>{{ body.strings.details_ip }}</li>
|
17 |
</ul>
|
18 |
|
|
|
|
|
19 |
{% if body.flags.show_login_link %}
|
20 |
<a href="{{ body.hrefs.login_link }}" target="_blank">{{ body.strings.login_link }}</a>
|
21 |
{% endif %}
|
16 |
<li>{{ body.strings.details_ip }}</li>
|
17 |
</ul>
|
18 |
|
19 |
+
{# <p>{{ body.hrefs.verify_2fa }}</p>#}
|
20 |
+
|
21 |
{% if body.flags.show_login_link %}
|
22 |
<a href="{{ body.hrefs.login_link }}" target="_blank">{{ body.strings.login_link }}</a>
|
23 |
{% endif %}
|
templates/twig/pages/block/blocklist_die.twig
CHANGED
@@ -9,10 +9,10 @@
|
|
9 |
<style>
|
10 |
#UAU hr {
|
11 |
margin: 40px 40px 30px;
|
12 |
-
color: rgba(0,0,0,0.5);
|
13 |
}
|
14 |
#UAU h3 {
|
15 |
-
margin: 20px 40px
|
16 |
}
|
17 |
.uau {
|
18 |
width: 75%;
|
@@ -22,19 +22,18 @@
|
|
22 |
background-color: rgba(0, 0, 0, 0.02);
|
23 |
}
|
24 |
.uau p {
|
25 |
-
margin:
|
26 |
}
|
27 |
</style>
|
28 |
{% if flags.is_autorecover %}
|
29 |
<div id="UAU">
|
30 |
-
<hr style=""/>
|
31 |
<div class="auto-recover">
|
32 |
<h3 style="">{{ strings.unblock.title }}</h3>
|
33 |
{% if flags.is_uaug_permitted %}
|
34 |
<div class="uaug uau">
|
35 |
<p>{{ strings.unblock.you_can }}</p>
|
36 |
-
<form method="post" action="
|
37 |
-
{{ vars.gasp_element|raw }}
|
38 |
<input type="hidden" name="email" value="" />
|
39 |
<input type="hidden" name="ip" value="{{ vars.ip }}" />
|
40 |
{% for key,val in vars.nonce %}
|
9 |
<style>
|
10 |
#UAU hr {
|
11 |
margin: 40px 40px 30px;
|
12 |
+
color: rgba(0, 0, 0, 0.5);
|
13 |
}
|
14 |
#UAU h3 {
|
15 |
+
margin: 20px 40px 20px;
|
16 |
}
|
17 |
.uau {
|
18 |
width: 75%;
|
22 |
background-color: rgba(0, 0, 0, 0.02);
|
23 |
}
|
24 |
.uau p {
|
25 |
+
margin: 0 0 10px !important;
|
26 |
}
|
27 |
</style>
|
28 |
{% if flags.is_autorecover %}
|
29 |
<div id="UAU">
|
30 |
+
<hr style="" />
|
31 |
<div class="auto-recover">
|
32 |
<h3 style="">{{ strings.unblock.title }}</h3>
|
33 |
{% if flags.is_uaug_permitted %}
|
34 |
<div class="uaug uau">
|
35 |
<p>{{ strings.unblock.you_can }}</p>
|
36 |
+
<form method="post" action="{{ hrefs.home }}">
|
|
|
37 |
<input type="hidden" name="email" value="" />
|
38 |
<input type="hidden" name="ip" value="{{ vars.ip }}" />
|
39 |
{% for key,val in vars.nonce %}
|
templates/twig/snippets/select_search_options.twig
DELETED
@@ -1,21 +0,0 @@
|
|
1 |
-
<select class="select2picker" data-live-search="true"
|
2 |
-
title="Search For Plugin Option"
|
3 |
-
data-size="10"
|
4 |
-
data-header=""
|
5 |
-
onchange="location = this.value;"
|
6 |
-
style="max-width: 100%; width: 100%"
|
7 |
-
>
|
8 |
-
<option value="">
|
9 |
-
-- Search For Plugin Setting --
|
10 |
-
</option>
|
11 |
-
{% for select_section_name,select_section_opts in vars.search_select %}
|
12 |
-
<optgroup label="{{ select_section_name }}">
|
13 |
-
{% for select_opt_key,select_opt_data in select_section_opts %}
|
14 |
-
<option value="{{ select_opt_data.href }}" aria-selected="false"
|
15 |
-
data-tokens="{{ select_opt_data.summary }}"
|
16 |
-
>{{ select_opt_data.name }}
|
17 |
-
</option>
|
18 |
-
{% endfor %}
|
19 |
-
</optgroup>
|
20 |
-
{% endfor %}
|
21 |
-
</select>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
templates/twig/wizard/slides/common/security_admin_verify.twig
CHANGED
@@ -8,7 +8,7 @@
|
|
8 |
<form class="form-horizontal icwp-wizard-form">
|
9 |
{{ icwp_macros.formInput_Hidden( 'current_index', current_index ) }}
|
10 |
{{ icwp_macros.formInput_Hidden( 'wizard-step', 'security_admin_verify' ) }}
|
11 |
-
{{ icwp_macros.formInput_Password( '
|
12 |
{{ icwp_macros.formInput_Submit( 'Submit Key' ) }}
|
13 |
</form>
|
14 |
|
8 |
<form class="form-horizontal icwp-wizard-form">
|
9 |
{{ icwp_macros.formInput_Hidden( 'current_index', current_index ) }}
|
10 |
{{ icwp_macros.formInput_Hidden( 'wizard-step', 'security_admin_verify' ) }}
|
11 |
+
{{ icwp_macros.formInput_Password( 'sec_admin_key', '', 'Security PIN' ) }}
|
12 |
{{ icwp_macros.formInput_Submit( 'Submit Key' ) }}
|
13 |
</form>
|
14 |
|
templates/twig/wizard/slides/welcome/admin_access_restriction.twig
CHANGED
@@ -26,7 +26,7 @@
|
|
26 |
<h6>Supply A New Security Access PIN</h6>
|
27 |
<p><strong>Warning</strong>: You must remember this key to regain access to the Shield plugin.</p>
|
28 |
<form class="form-horizontal icwp-wizard-form">
|
29 |
-
{{ icwp_macros.formInput_Password( '
|
30 |
{{ icwp_macros.formInput_Password( 'AccessKeyConfirm', '', 'Confirm PIN', 'Confirm PIN' ) }}
|
31 |
{{ icwp_macros.formInput_Hidden( 'wizard-step', 'admin_access_restriction' ) }}
|
32 |
{{ icwp_macros.formInput_Submit( 'Turn On Security Admin' ) }}
|
26 |
<h6>Supply A New Security Access PIN</h6>
|
27 |
<p><strong>Warning</strong>: You must remember this key to regain access to the Shield plugin.</p>
|
28 |
<form class="form-horizontal icwp-wizard-form">
|
29 |
+
{{ icwp_macros.formInput_Password( 'sec_admin_key', '', 'Access PIN', '', 'Do not forget this key' ) }}
|
30 |
{{ icwp_macros.formInput_Password( 'AccessKeyConfirm', '', 'Confirm PIN', 'Confirm PIN' ) }}
|
31 |
{{ icwp_macros.formInput_Hidden( 'wizard-step', 'admin_access_restriction' ) }}
|
32 |
{{ icwp_macros.formInput_Submit( 'Turn On Security Admin' ) }}
|
templates/twig/wpadmin_pages/base.twig
CHANGED
@@ -14,7 +14,28 @@
|
|
14 |
|
15 |
<div class="row" id="odp-PageMain">
|
16 |
<div class="col">
|
17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
</div>
|
19 |
</div>
|
20 |
|
@@ -29,5 +50,8 @@
|
|
29 |
</div>
|
30 |
</div>
|
31 |
|
|
|
|
|
32 |
{% block inline_scripts %}
|
|
|
33 |
{% endblock %}
|
14 |
|
15 |
<div class="row" id="odp-PageMain">
|
16 |
<div class="col">
|
17 |
+
|
18 |
+
<div class="row">
|
19 |
+
|
20 |
+
<div id="apto-PageMainSide"
|
21 |
+
class="col-sm-3 col-md-2 col-lg-2 col-xl-2">
|
22 |
+
{% block page_main_side %}
|
23 |
+
{% include '/wpadmin_pages/components/page/nav_sidebar.twig' %}
|
24 |
+
{% endblock %}
|
25 |
+
</div>
|
26 |
+
|
27 |
+
<div id="apto-PageMainBody"
|
28 |
+
class="col-sm-9 col-md-10 col-lg-10 col-xl-10">
|
29 |
+
{% block page_main %}
|
30 |
+
<div class="row">
|
31 |
+
<div class="col">
|
32 |
+
</div>
|
33 |
+
</div>
|
34 |
+
{% endblock %}
|
35 |
+
</div>
|
36 |
+
|
37 |
+
</div>
|
38 |
+
|
39 |
</div>
|
40 |
</div>
|
41 |
|
50 |
</div>
|
51 |
</div>
|
52 |
|
53 |
+
{% include '/components/search/dialog.twig' %}
|
54 |
+
|
55 |
{% block inline_scripts %}
|
56 |
+
{% include '/snippets/js/freshdesk_chatbot.twig' %}
|
57 |
{% endblock %}
|
templates/twig/wpadmin_pages/components/page/nav_sidebar.twig
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div id="NavSideBar" class="tour-navigation_v1">
|
2 |
+
|
3 |
+
<ul class="nav flex-column mt-4">
|
4 |
+
{% for mitem in vars.navbar_menu %}
|
5 |
+
|
6 |
+
<li class="nav-item mb-4 {{ mitem.classes|default([])|join( ' ' ) }}"
|
7 |
+
{% if mitem.id|default('') is not empty %}id="{{ mitem.id }}"{% endif %}
|
8 |
+
>
|
9 |
+
|
10 |
+
<a class="nav-link p-0 {% if mitem.active %}active{% endif %}"
|
11 |
+
href="{{ mitem.href|default('#') }}"
|
12 |
+
{% for data_key,data_val in mitem.data|default([]) %}
|
13 |
+
data-{{ data_key }}="{{ data_val }}"
|
14 |
+
{% endfor %}
|
15 |
+
{% if sub.target|default('') is not empty %}target="{{ sub.target }}"{% endif %}
|
16 |
+
{% if mitem.introjs|default('') is not empty %}data-intro="{{ mitem.introjs }}"{% endif %}
|
17 |
+
>
|
18 |
+
{% if mitem.img|default('') is not empty %}
|
19 |
+
<span class="nav-icon mr-1" style="vertical-align: text-bottom;">
|
20 |
+
<img src="{{ mitem.img }}"
|
21 |
+
class="img-fluid"
|
22 |
+
width="16px"
|
23 |
+
alt="...">
|
24 |
+
</span>
|
25 |
+
{% endif %}
|
26 |
+
<span>{{ mitem.title }}</span>
|
27 |
+
{% if mitem.badge|default([]) is not empty %}
|
28 |
+
<span class="badge badge-{{ mitem.badge.type|default('info') }}">
|
29 |
+
{{ mitem.badge.text }}
|
30 |
+
</span>
|
31 |
+
{% endif %}
|
32 |
+
</a>
|
33 |
+
|
34 |
+
{% if mitem.sub_items|default([]) is not empty %}
|
35 |
+
<div class="collapse {% if mitem.active %}show{% endif %}" id="collapse-{{ mitem.slug }}">
|
36 |
+
<ul class="nav flex-column pt-0 primary_sub_menu pl-4">
|
37 |
+
{% for sub in mitem.sub_items %}
|
38 |
+
<li class="nav-item mb-0 {{ sub.classes|default([])|join( ' ' ) }}">
|
39 |
+
<a class="pl-0 pb-0 pt-2 nav-link {% if sub.active|default(false) %}active{% endif %}"
|
40 |
+
href="{{ sub.href|default('#') }}"
|
41 |
+
{% for data_key,data_val in sub.data|default([]) %}
|
42 |
+
data-{{ data_key }}="{{ data_val }}"
|
43 |
+
{% endfor %}
|
44 |
+
{% if sub.target|default('') is not empty %}target="{{ sub.target }}"{% endif %}
|
45 |
+
>{{ sub.title }}</a>
|
46 |
+
</li>
|
47 |
+
{% endfor %}
|
48 |
+
</ul>
|
49 |
+
</div>
|
50 |
+
{% endif %}
|
51 |
+
|
52 |
+
</li>
|
53 |
+
|
54 |
+
{% endfor %}
|
55 |
+
</ul>
|
56 |
+
</div>
|
templates/twig/wpadmin_pages/insights/audit/audit_table.twig
CHANGED
@@ -1,82 +1,68 @@
|
|
1 |
<div class="row insights_widget" id="SectionAuditTable">
|
2 |
|
3 |
<div class="col">
|
4 |
-
{# <p>#}
|
5 |
-
{# <a href="{{ hrefs.audit_trail_glossary }}" target="_blank">{{ strings.audit_trail_glossary }}</a>#}
|
6 |
-
{# </p>#}
|
7 |
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
{
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
<label class="sr-only" for="SubmitForm" title="{{ strings.exclude_your_ip_tooltip }}">
|
70 |
-
{{ strings.exclude_your_ip }}?</label>
|
71 |
-
<input id="SubmitForm" href="#" class="btn btn-primary"
|
72 |
-
type="submit" value="{{ strings.filters_apply }}" />
|
73 |
-
<a id="ClearForm" href="#"
|
74 |
-
class="btn btn-sm btn-link text-dark">{{ strings.filters_clear }}</a>
|
75 |
-
</div>
|
76 |
-
</div>
|
77 |
-
</form>
|
78 |
-
|
79 |
-
<div id="TableAuditTrail"></div>
|
80 |
|
81 |
</div>
|
82 |
|
1 |
<div class="row insights_widget" id="SectionAuditTable">
|
2 |
|
3 |
<div class="col">
|
|
|
|
|
|
|
4 |
|
5 |
+
<form id="AuditFilterForm" autocomplete="off" class="px-3 pt-3">
|
6 |
+
<div class="form-row">
|
7 |
+
|
8 |
+
<div class="col-auto mb-3">
|
9 |
+
<label class="sr-only" for="_fUsername">{{ strings.username }}</label>
|
10 |
+
<select id="_fUsername" name="fUsername" class="form-control">
|
11 |
+
<option value="">-- {{ strings.username }} --</option>
|
12 |
+
{% for uniq_user in vars.unique_users %}
|
13 |
+
<option value="{{ uniq_user }}">{{ uniq_user }}</option>
|
14 |
+
{% endfor %}
|
15 |
+
</select>
|
16 |
+
</div>
|
17 |
+
|
18 |
+
<div class="col-auto mb-3">
|
19 |
+
<label class="sr-only" for="_fIp">{{ strings.ip_address }}</label>
|
20 |
+
<select id="_fIp" name="fIp" class="form-control select2picker">
|
21 |
+
<option value="">-- {{ strings.ip_address }} --</option>
|
22 |
+
{% for unique_ip in vars.unique_ips %}
|
23 |
+
<option value="{{ unique_ip }}">{{ unique_ip }}</option>
|
24 |
+
{% endfor %}
|
25 |
+
</select>
|
26 |
+
</div>
|
27 |
+
|
28 |
+
<div class="col-auto mb-3">
|
29 |
+
<label class="sr-only" for="_fEvent">{{ strings.event }}</label>
|
30 |
+
<select id="_fEvent" name="fEvent" class="form-control">
|
31 |
+
<option value="">-- {{ strings.event }} --</option>
|
32 |
+
{% for event_key,event_name in vars.events_for_select %}
|
33 |
+
<option value="{{ event_key }}">{{ event_name }}</option>
|
34 |
+
{% endfor %}
|
35 |
+
</select>
|
36 |
+
</div>
|
37 |
+
|
38 |
+
<div class="col-auto mb-3 input-daterange">
|
39 |
+
<label class="form-label sr-only" for="_fDateFrom" title="{{ strings.show_after }}...">
|
40 |
+
{{ strings.time_since }}:</label>
|
41 |
+
<input type="text" class="form-control date-picker" id="_fDateFrom"
|
42 |
+
name="fDateFrom" value=""
|
43 |
+
placeholder="{{ strings.time_since }} {{ strings.yyyymmdd }}">
|
44 |
+
</div>
|
45 |
+
|
46 |
+
<div class="col-auto mb-3 input-daterange">
|
47 |
+
<label class="form-label sr-only" for="_fDateTo" title="{{ strings.show_before }}...">
|
48 |
+
{{ strings.time_until }}:</label>
|
49 |
+
<input type="text" class="form-control date-picker" id="_fDateTo"
|
50 |
+
name="fDateTo" value=""
|
51 |
+
placeholder="{{ strings.time_until }} {{ strings.yyyymmdd }}">
|
52 |
+
</div>
|
53 |
+
|
54 |
+
<div class="col-auto mb-3 text-right">
|
55 |
+
<label class="sr-only" for="SubmitForm" title="{{ strings.exclude_your_ip_tooltip }}">
|
56 |
+
{{ strings.exclude_your_ip }}?</label>
|
57 |
+
<input id="SubmitForm" href="#" class="btn btn-primary"
|
58 |
+
type="submit" value="{{ strings.filters_apply }}" />
|
59 |
+
<a id="ClearForm" href="#"
|
60 |
+
class="btn btn-sm btn-link text-dark">{{ strings.filters_clear }}</a>
|
61 |
+
</div>
|
62 |
+
</div>
|
63 |
+
</form>
|
64 |
+
|
65 |
+
<div id="TableAuditTrail"></div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
|
67 |
</div>
|
68 |
|
templates/twig/wpadmin_pages/insights/base.twig
CHANGED
@@ -6,32 +6,15 @@
|
|
6 |
<div class="row">
|
7 |
|
8 |
<div class="col">
|
9 |
-
<h5 class="mt-3">
|
10 |
{% block page_head_titlemenu %}
|
11 |
-
{
|
12 |
-
{{ strings.dashboard_shield }}
|
13 |
-
{% else %}
|
14 |
-
{{ strings.page_title }}
|
15 |
-
<br />
|
16 |
-
<p class="mb-1 mt-2 d-inline-block" style="font-size: small">
|
17 |
-
<a href="{{ hrefs.back_to_dash }}">« {{ strings.dashboard }}</a>
|
18 |
-
{% if vars.related_hrefs|default([]) is not empty %}
|
19 |
-
{% for related_href in vars.related_hrefs %}
|
20 |
-
| <a href="{{ related_href.href }}"
|
21 |
-
{% if not related_href.id|default('') is empty %}id="{{ related_href.id }}"{% endif %}
|
22 |
-
class="{{ related_href.classes|default([])|join(' ') }}"
|
23 |
-
{% if related_href.new|default(false) %}target="_blank"{% endif %}>
|
24 |
-
{{ related_href.title }}</a>
|
25 |
-
{% endfor %}
|
26 |
-
{% endif %}
|
27 |
-
</p>
|
28 |
-
{% endif %}
|
29 |
{% endblock page_head_titlemenu %}
|
30 |
</h5>
|
31 |
</div>
|
32 |
|
33 |
<div class="col">
|
34 |
-
<a class="navbar-brand float-right
|
35 |
href="{{ hrefs.nav_home }}"
|
36 |
id="navbar-bannerlogo"
|
37 |
style="background-image: url('{{ hrefs.img_banner }}');"
|
@@ -44,17 +27,10 @@
|
|
44 |
{% endblock %}
|
45 |
|
46 |
{% block page_main %}
|
47 |
-
<div class="row">
|
48 |
-
<div class="col">
|
49 |
-
</div>
|
50 |
-
</div>
|
51 |
{% endblock %}
|
52 |
|
53 |
{% block page_foot %}
|
54 |
{% endblock %}
|
55 |
|
56 |
{% block inline_styles %}
|
57 |
-
{% endblock %}
|
58 |
-
|
59 |
-
{% block inline_scripts %}
|
60 |
{% endblock %}
|
6 |
<div class="row">
|
7 |
|
8 |
<div class="col">
|
9 |
+
<h5 class="mt-3" id="PageTitle">
|
10 |
{% block page_head_titlemenu %}
|
11 |
+
{{ strings.page_title }}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
{% endblock page_head_titlemenu %}
|
13 |
</h5>
|
14 |
</div>
|
15 |
|
16 |
<div class="col">
|
17 |
+
<a class="navbar-brand float-right my-2"
|
18 |
href="{{ hrefs.nav_home }}"
|
19 |
id="navbar-bannerlogo"
|
20 |
style="background-image: url('{{ hrefs.img_banner }}');"
|
27 |
{% endblock %}
|
28 |
|
29 |
{% block page_main %}
|
|
|
|
|
|
|
|
|
30 |
{% endblock %}
|
31 |
|
32 |
{% block page_foot %}
|
33 |
{% endblock %}
|
34 |
|
35 |
{% block inline_styles %}
|
|
|
|
|
|
|
36 |
{% endblock %}
|
templates/twig/wpadmin_pages/insights/dashboard/card_settings.twig
CHANGED
@@ -8,7 +8,7 @@
|
|
8 |
</li>
|
9 |
<li class="list-group-item" id="SearchOptionsLaunch">
|
10 |
<div class="text-nowrap">
|
11 |
-
{% include '/
|
12 |
</div>
|
13 |
</li>
|
14 |
</ul>
|
8 |
</li>
|
9 |
<li class="list-group-item" id="SearchOptionsLaunch">
|
10 |
<div class="text-nowrap">
|
11 |
+
{% include '/components/search/options.twig' %}
|
12 |
</div>
|
13 |
</li>
|
14 |
</ul>
|
templates/twig/wpadmin_pages/insights/docs/index.twig
CHANGED
@@ -50,6 +50,7 @@
|
|
50 |
{% endblock %}
|
51 |
|
52 |
{% block inline_scripts %}
|
|
|
53 |
|
54 |
<script type="text/javascript">
|
55 |
window.announcekit = (window.announcekit || {
|
50 |
{% endblock %}
|
51 |
|
52 |
{% block inline_scripts %}
|
53 |
+
{{ parent() }}
|
54 |
|
55 |
<script type="text/javascript">
|
56 |
window.announcekit = (window.announcekit || {
|
templates/twig/wpadmin_pages/insights/overview/cards/shuffle.twig
CHANGED
@@ -102,6 +102,13 @@ document.addEventListener( 'DOMContentLoaded', function () {
|
|
102 |
}
|
103 |
} );
|
104 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
jQuery( function () {
|
106 |
jQuery( '[data-toggle="popover"]' ).popover( {
|
107 |
placement: 'top',
|
102 |
}
|
103 |
} );
|
104 |
|
105 |
+
if ( document.querySelector( '.state-danger' ) !== null ) {
|
106 |
+
document.querySelector('.state-danger').dispatchEvent( new MouseEvent( "click", { bubbles: true, cancellable: true } ) );
|
107 |
+
}
|
108 |
+
if ( document.querySelector( '.state-warning' ) !== null ) {
|
109 |
+
document.querySelector('.state-warning').dispatchEvent( new MouseEvent( "click", { bubbles: true, cancellable: true } ) );
|
110 |
+
}
|
111 |
+
|
112 |
jQuery( function () {
|
113 |
jQuery( '[data-toggle="popover"]' ).popover( {
|
114 |
placement: 'top',
|
templates/twig/wpadmin_pages/insights/scans/index.twig
DELETED
@@ -1,10 +0,0 @@
|
|
1 |
-
{% extends '/wpadmin_pages/insights/base.twig' %}
|
2 |
-
|
3 |
-
{% block page_main %}
|
4 |
-
<div class="row">
|
5 |
-
<div class="col-12 insights_section">
|
6 |
-
{% include '/wpadmin_pages/insights/scans/scan_start.twig' %}
|
7 |
-
</div>
|
8 |
-
</div>
|
9 |
-
{% include '/wpadmin_pages/insights/scans/modal/progress.twig' %}
|
10 |
-
{% endblock %}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
templates/twig/wpadmin_pages/insights/scans/results/index.twig
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{% extends '/wpadmin_pages/insights/base.twig' %}
|
2 |
+
|
3 |
+
{% block page_main %}
|
4 |
+
<div class="row" id="SectionInsightsScans">
|
5 |
+
<div class="col-12 insights-sub-nav" id="ScanResultsTabs">
|
6 |
+
{% include '/wpadmin_pages/insights/scans/results/scan_results.twig' %}
|
7 |
+
</div>
|
8 |
+
</div>
|
9 |
+
{% include '/wpadmin_pages/insights/scans/modal/progress.twig' %}
|
10 |
+
{% endblock %}
|
templates/twig/wpadmin_pages/insights/scans/{realtime → results/realtime}/file_locker/file_diff.twig
RENAMED
@@ -6,6 +6,11 @@
|
|
6 |
<div class="card-body">
|
7 |
<h5 class="card-title">{{ strings.locked_file }}</h5>
|
8 |
|
|
|
|
|
|
|
|
|
|
|
9 |
<dl class="row">
|
10 |
<dt class="col">{{ strings.locked }}</dt>
|
11 |
<dd class="col">{{ vars.locked_at }}</dd>
|
@@ -17,8 +22,8 @@
|
|
17 |
</dl>
|
18 |
|
19 |
<dl class="row">
|
20 |
-
<dt class="col">{{ strings.
|
21 |
-
<dd class="col">{{ vars.file_modified_at }}</dd>
|
22 |
</dl>
|
23 |
|
24 |
<dl class="row">
|
6 |
<div class="card-body">
|
7 |
<h5 class="card-title">{{ strings.locked_file }}</h5>
|
8 |
|
9 |
+
<dl class="row">
|
10 |
+
<dt class="col">{{ strings.relative_path }}</dt>
|
11 |
+
<dd class="col">{{ vars.relative_path }}</dd>
|
12 |
+
</dl>
|
13 |
+
|
14 |
<dl class="row">
|
15 |
<dt class="col">{{ strings.locked }}</dt>
|
16 |
<dd class="col">{{ vars.locked_at }}</dd>
|
22 |
</dl>
|
23 |
|
24 |
<dl class="row">
|
25 |
+
<dt class="col">{{ strings.file_modified }}</dt>
|
26 |
+
<dd class="col">{{ vars.file_modified_ago }}<br/>({{ vars.file_modified_at }})</dd>
|
27 |
</dl>
|
28 |
|
29 |
<dl class="row">
|
templates/twig/wpadmin_pages/insights/scans/{realtime → results/realtime}/file_locker/index.twig
RENAMED
@@ -10,7 +10,7 @@
|
|
10 |
<div class="card-body">
|
11 |
|
12 |
{% if scan.flags.is_restricted %}
|
13 |
-
{% include '/wpadmin_pages/insights/scans/results/common_unavailable.twig' %}
|
14 |
{% else %}
|
15 |
{% if scan.flags.is_enabled %}
|
16 |
<div class="col mt-3 mb-3">
|
@@ -21,12 +21,13 @@
|
|
21 |
</label>
|
22 |
</div>
|
23 |
<select class="custom-select mw-100" id="FileLockerFileSelect">
|
24 |
-
<option selected value="-">--</option>
|
25 |
{% for lock_key, file_lock in scan.vars.file_locks.bad %}
|
26 |
<option value="{{ lock_key }}" class="text-danger">{{ file_lock.file }}</option>
|
27 |
{% endfor %}
|
28 |
{% for lock_key, file_lock in scan.vars.file_locks.good %}
|
29 |
-
<option value="{{ lock_key }}"
|
|
|
30 |
{% endfor %}
|
31 |
</select>
|
32 |
</div>
|
@@ -40,7 +41,7 @@
|
|
40 |
</div>
|
41 |
</div>
|
42 |
{% else %}
|
43 |
-
{% include '/wpadmin_pages/insights/scans/results/common_disabled.twig' %}
|
44 |
{% endif %}
|
45 |
{% endif %}
|
46 |
</div>
|
@@ -61,7 +62,7 @@
|
|
61 |
</div>
|
62 |
|
63 |
{% if not scan.flags.is_restricted %}
|
64 |
-
<script type="text/javascript">
|
65 |
jQuery( '#FileLockerFileSelect' ).on( 'change', function ( e ) {
|
66 |
iCWP_WPSF_BodyOverlay.show();
|
67 |
let ajax_vars ={{ scan.ajax.filelocker_showdiff|raw }};
|
10 |
<div class="card-body">
|
11 |
|
12 |
{% if scan.flags.is_restricted %}
|
13 |
+
{% include '/wpadmin_pages/insights/scans/results/results/common_unavailable.twig' %}
|
14 |
{% else %}
|
15 |
{% if scan.flags.is_enabled %}
|
16 |
<div class="col mt-3 mb-3">
|
21 |
</label>
|
22 |
</div>
|
23 |
<select class="custom-select mw-100" id="FileLockerFileSelect">
|
24 |
+
<option selected value="-" disabled="disabled">--</option>
|
25 |
{% for lock_key, file_lock in scan.vars.file_locks.bad %}
|
26 |
<option value="{{ lock_key }}" class="text-danger">{{ file_lock.file }}</option>
|
27 |
{% endfor %}
|
28 |
{% for lock_key, file_lock in scan.vars.file_locks.good %}
|
29 |
+
<option value="{{ lock_key }}"
|
30 |
+
class="text-success">{{ file_lock.file }}</option>
|
31 |
{% endfor %}
|
32 |
</select>
|
33 |
</div>
|
41 |
</div>
|
42 |
</div>
|
43 |
{% else %}
|
44 |
+
{% include '/wpadmin_pages/insights/scans/results/results/common_disabled.twig' %}
|
45 |
{% endif %}
|
46 |
{% endif %}
|
47 |
</div>
|
62 |
</div>
|
63 |
|
64 |
{% if not scan.flags.is_restricted %}
|
65 |
+
<script type="text/javascript">
|
66 |
jQuery( '#FileLockerFileSelect' ).on( 'change', function ( e ) {
|
67 |
iCWP_WPSF_BodyOverlay.show();
|
68 |
let ajax_vars ={{ scan.ajax.filelocker_showdiff|raw }};
|
templates/twig/wpadmin_pages/insights/scans/results/{aggregate.twig → results/aggregate.twig}
RENAMED
File without changes
|
templates/twig/wpadmin_pages/insights/scans/results/{apc.twig → results/apc.twig}
RENAMED
@@ -20,11 +20,11 @@
|
|
20 |
{% endif %}
|
21 |
|
22 |
{% else %}
|
23 |
-
{% include '/wpadmin_pages/insights/scans/results/common_disabled.twig' %}
|
24 |
{% endif %}
|
25 |
|
26 |
{% else %}
|
27 |
-
{% include '/wpadmin_pages/insights/scans/results/common_unavailable.twig' %}
|
28 |
{% endif %}
|
29 |
|
30 |
</div>
|
20 |
{% endif %}
|
21 |
|
22 |
{% else %}
|
23 |
+
{% include '/wpadmin_pages/insights/scans/results/results/common_disabled.twig' %}
|
24 |
{% endif %}
|
25 |
|
26 |
{% else %}
|
27 |
+
{% include '/wpadmin_pages/insights/scans/results/results/common_unavailable.twig' %}
|
28 |
{% endif %}
|
29 |
|
30 |
</div>
|
templates/twig/wpadmin_pages/insights/scans/results/{common_disabled.twig → results/common_disabled.twig}
RENAMED
File without changes
|
templates/twig/wpadmin_pages/insights/scans/results/{common_unavailable.twig → results/common_unavailable.twig}
RENAMED
File without changes
|
templates/twig/wpadmin_pages/insights/scans/results/{mal.twig → results/mal.twig}
RENAMED
@@ -10,7 +10,7 @@
|
|
10 |
<div class="card-body">
|
11 |
|
12 |
{% if scan.flags.is_restricted %}
|
13 |
-
{% include '/wpadmin_pages/insights/scans/results/common_unavailable.twig' %}
|
14 |
{% else %}
|
15 |
{% if scan.flags.is_available %}
|
16 |
|
@@ -21,7 +21,7 @@
|
|
21 |
{% endif %}
|
22 |
|
23 |
{% else %}
|
24 |
-
{% include '/wpadmin_pages/insights/scans/results/common_disabled.twig' %}
|
25 |
{% endif %}
|
26 |
{% endif %}
|
27 |
|
10 |
<div class="card-body">
|
11 |
|
12 |
{% if scan.flags.is_restricted %}
|
13 |
+
{% include '/wpadmin_pages/insights/scans/results/results/common_unavailable.twig' %}
|
14 |
{% else %}
|
15 |
{% if scan.flags.is_available %}
|
16 |
|
21 |
{% endif %}
|
22 |
|
23 |
{% else %}
|
24 |
+
{% include '/wpadmin_pages/insights/scans/results/results/common_disabled.twig' %}
|
25 |
{% endif %}
|
26 |
{% endif %}
|
27 |
|
templates/twig/wpadmin_pages/insights/scans/results/{ptg.twig → results/ptg.twig}
RENAMED
@@ -9,17 +9,17 @@
|
|
9 |
|
10 |
<div class="card-body">
|
11 |
{% if scan.flags.is_restricted %}
|
12 |
-
{% include '/wpadmin_pages/insights/scans/results/common_unavailable.twig' %}
|
13 |
{% else %}
|
14 |
{% if scan.flags.is_available %}
|
15 |
{% if not scan.flags.has_items %}
|
16 |
<div class="alert alert-success m-0">{{ strings.no_entries_to_display }}</div>
|
17 |
{% else %}
|
18 |
-
{% include '/wpadmin_pages/insights/scans/results/'~scankey~'_table.twig' %}
|
19 |
{% endif %}
|
20 |
|
21 |
{% else %}
|
22 |
-
{% include '/wpadmin_pages/insights/scans/results/common_disabled.twig' %}
|
23 |
{% endif %}
|
24 |
{% endif %}
|
25 |
</div>
|
9 |
|
10 |
<div class="card-body">
|
11 |
{% if scan.flags.is_restricted %}
|
12 |
+
{% include '/wpadmin_pages/insights/scans/results/results/common_unavailable.twig' %}
|
13 |
{% else %}
|
14 |
{% if scan.flags.is_available %}
|
15 |
{% if not scan.flags.has_items %}
|
16 |
<div class="alert alert-success m-0">{{ strings.no_entries_to_display }}</div>
|
17 |
{% else %}
|
18 |
+
{% include '/wpadmin_pages/insights/scans/results/results/'~scankey~'_table.twig' %}
|
19 |
{% endif %}
|
20 |
|
21 |
{% else %}
|
22 |
+
{% include '/wpadmin_pages/insights/scans/results/results/common_disabled.twig' %}
|
23 |
{% endif %}
|
24 |
{% endif %}
|
25 |
</div>
|
templates/twig/wpadmin_pages/insights/scans/results/{ptg_table.twig → results/ptg_table.twig}
RENAMED
File without changes
|
templates/twig/wpadmin_pages/insights/scans/results/{ufc.twig → results/ufc.twig}
RENAMED
File without changes
|
templates/twig/wpadmin_pages/insights/scans/results/{wcf.twig → results/wcf.twig}
RENAMED
@@ -3,8 +3,22 @@
|
|
3 |
<div class="card card-scan_results">
|
4 |
|
5 |
<div class="card-header">
|
6 |
-
<h5 class="card-title">
|
7 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
</div>
|
9 |
|
10 |
<div class="card-body">
|
3 |
<div class="card card-scan_results">
|
4 |
|
5 |
<div class="card-header">
|
6 |
+
<h5 class="card-title">
|
7 |
+
{{ scan.strings.title }}
|
8 |
+
<a data-toggle="collapse"
|
9 |
+
data-target="#MoreInfo-{{ scan.vars.slug }}"
|
10 |
+
><span class="dashicons dashicons-info"></span></a>
|
11 |
+
</h5>
|
12 |
+
<h6 class="card-subtitle text-muted">
|
13 |
+
{{ scan.strings.subtitle }}
|
14 |
+
</h6>
|
15 |
+
<div class="collapse mt-3" id="MoreInfo-{{ scan.vars.slug }}">
|
16 |
+
<div class="alert alert-dark">
|
17 |
+
{% for line in scan.strings.explanation %}
|
18 |
+
<p class="mb-2">{{ line }}</p>
|
19 |
+
{% endfor %}
|
20 |
+
</div>
|
21 |
+
</div>
|
22 |
</div>
|
23 |
|
24 |
<div class="card-body">
|
templates/twig/wpadmin_pages/insights/scans/results/{wpv.twig → results/wpv.twig}
RENAMED
@@ -10,7 +10,7 @@
|
|
10 |
<div class="card-body">
|
11 |
|
12 |
{% if scan.flags.is_restricted %}
|
13 |
-
{% include '/wpadmin_pages/insights/scans/results/common_unavailable.twig' %}
|
14 |
{% else %}
|
15 |
{% if scan.flags.is_available %}
|
16 |
|
@@ -21,7 +21,7 @@
|
|
21 |
{% endif %}
|
22 |
|
23 |
{% else %}
|
24 |
-
{% include '/wpadmin_pages/insights/scans/results/common_disabled.twig' %}
|
25 |
{% endif %}
|
26 |
{% endif %}
|
27 |
|
10 |
<div class="card-body">
|
11 |
|
12 |
{% if scan.flags.is_restricted %}
|
13 |
+
{% include '/wpadmin_pages/insights/scans/results/results/common_unavailable.twig' %}
|
14 |
{% else %}
|
15 |
{% if scan.flags.is_available %}
|
16 |
|
21 |
{% endif %}
|
22 |
|
23 |
{% else %}
|
24 |
+
{% include '/wpadmin_pages/insights/scans/results/results/common_disabled.twig' %}
|
25 |
{% endif %}
|
26 |
{% endif %}
|
27 |
|
templates/twig/wpadmin_pages/insights/scans/{scan_results.twig → results/scan_results.twig}
RENAMED
@@ -12,8 +12,13 @@
|
|
12 |
{% for scankey,scanvars in scans %}
|
13 |
{% if scanvars.flags.show_table %}
|
14 |
<li class="nav-item">
|
15 |
-
<a class="nav-link"
|
16 |
-
|
|
|
|
|
|
|
|
|
|
|
17 |
<span class="badge badge-{% if scanvars.count > 0 %}danger{% endif %}"
|
18 |
>{% if scanvars.count > 0 %}!{% endif %}</span>
|
19 |
{{ scanvars.strings.title }}
|
@@ -31,12 +36,13 @@
|
|
31 |
</a>
|
32 |
</li>
|
33 |
</ul>
|
|
|
34 |
<div class="tab-content mb-5" id="ScanResultsTabsContent">
|
35 |
|
36 |
{% set scan = aggregate %}
|
37 |
<div class="tab-pane show active" id="h-tabs-aggregate" role="tabpanel"
|
38 |
aria-labelledby="h-tabs-aggregate-tab">
|
39 |
-
{% include '/wpadmin_pages/insights/scans/results/aggregate.twig' %}
|
40 |
</div>
|
41 |
|
42 |
{% for scankey,scanvars in scans %}
|
@@ -44,7 +50,7 @@
|
|
44 |
<div class="tab-pane" id="h-tabs-{{ scankey }}" role="tabpanel"
|
45 |
aria-labelledby="h-tabs-{{ scankey }}-tab">
|
46 |
{% set scan = attribute(scans, scankey) %}
|
47 |
-
{% include '/wpadmin_pages/insights/scans/results/'~scankey~'.twig' %}
|
48 |
</div>
|
49 |
{% endif %}
|
50 |
{% endfor %}
|
@@ -52,6 +58,6 @@
|
|
52 |
<div class="tab-pane show" id="h-tabs-file_locker" role="tabpanel"
|
53 |
aria-labelledby="h-tabs-aggregate-tab">
|
54 |
{% set scan = file_locker %}
|
55 |
-
{% include '/wpadmin_pages/insights/scans/realtime/file_locker/index.twig' %}
|
56 |
</div>
|
57 |
</div>
|
12 |
{% for scankey,scanvars in scans %}
|
13 |
{% if scanvars.flags.show_table %}
|
14 |
<li class="nav-item">
|
15 |
+
<a class="nav-link"
|
16 |
+
id="h-tabs-home-tab"
|
17 |
+
data-toggle="tab"
|
18 |
+
href="#h-tabs-{{ scankey }}"
|
19 |
+
role="tab"
|
20 |
+
aria-controls="h-tabs-{{ scankey }}"
|
21 |
+
>
|
22 |
<span class="badge badge-{% if scanvars.count > 0 %}danger{% endif %}"
|
23 |
>{% if scanvars.count > 0 %}!{% endif %}</span>
|
24 |
{{ scanvars.strings.title }}
|
36 |
</a>
|
37 |
</li>
|
38 |
</ul>
|
39 |
+
|
40 |
<div class="tab-content mb-5" id="ScanResultsTabsContent">
|
41 |
|
42 |
{% set scan = aggregate %}
|
43 |
<div class="tab-pane show active" id="h-tabs-aggregate" role="tabpanel"
|
44 |
aria-labelledby="h-tabs-aggregate-tab">
|
45 |
+
{% include '/wpadmin_pages/insights/scans/results/results/aggregate.twig' %}
|
46 |
</div>
|
47 |
|
48 |
{% for scankey,scanvars in scans %}
|
50 |
<div class="tab-pane" id="h-tabs-{{ scankey }}" role="tabpanel"
|
51 |
aria-labelledby="h-tabs-{{ scankey }}-tab">
|
52 |
{% set scan = attribute(scans, scankey) %}
|
53 |
+
{% include '/wpadmin_pages/insights/scans/results/results/'~scankey~'.twig' %}
|
54 |
</div>
|
55 |
{% endif %}
|
56 |
{% endfor %}
|
58 |
<div class="tab-pane show" id="h-tabs-file_locker" role="tabpanel"
|
59 |
aria-labelledby="h-tabs-aggregate-tab">
|
60 |
{% set scan = file_locker %}
|
61 |
+
{% include '/wpadmin_pages/insights/scans/results/realtime/file_locker/index.twig' %}
|
62 |
</div>
|
63 |
</div>
|
templates/twig/wpadmin_pages/insights/scans/run/index.twig
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{% extends '/wpadmin_pages/insights/base.twig' %}
|
2 |
+
|
3 |
+
{% block page_main %}
|
4 |
+
|
5 |
+
<div class="row" id="SectionInsightsScans">
|
6 |
+
<div class="col-12">
|
7 |
+
{% include '/wpadmin_pages/insights/scans/run/scan_areas.twig' %}
|
8 |
+
</div>
|
9 |
+
</div>
|
10 |
+
{% include '/wpadmin_pages/insights/scans/modal/progress.twig' %}
|
11 |
+
{% endblock %}
|
templates/twig/wpadmin_pages/insights/scans/{scan_areas.twig → run/scan_areas.twig}
RENAMED
@@ -163,16 +163,18 @@
|
|
163 |
<script>
|
164 |
jQuery( 'form#StartScans' ).icwpWpsfScansStart(
|
165 |
{
|
166 |
-
'ajax_scans_start':{{ ajax.scans_start|raw }},
|
167 |
-
'ajax_scans_check':{{ ajax.scans_check|raw }}
|
|
|
168 |
}
|
169 |
);
|
170 |
{% if vars.initial_check %}
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
}
|
175 |
-
|
|
|
176 |
{% endif %}
|
177 |
|
178 |
</script>
|
163 |
<script>
|
164 |
jQuery( 'form#StartScans' ).icwpWpsfScansStart(
|
165 |
{
|
166 |
+
'ajax_scans_start': {{ ajax.scans_start|raw }},
|
167 |
+
'ajax_scans_check': {{ ajax.scans_check|raw }},
|
168 |
+
'href_scans_results': "{{ hrefs.scans_results|raw }}"
|
169 |
}
|
170 |
);
|
171 |
{% if vars.initial_check %}
|
172 |
+
jQuery( document ).icwpWpsfScansCheck(
|
173 |
+
{
|
174 |
+
'ajax_scans_check': {{ ajax.scans_check|raw }},
|
175 |
+
'href_scans_results': "{{ hrefs.scans_results|raw }}"
|
176 |
+
}
|
177 |
+
);
|
178 |
{% endif %}
|
179 |
|
180 |
</script>
|
templates/twig/wpadmin_pages/insights/scans/scan_start.twig
DELETED
@@ -1,46 +0,0 @@
|
|
1 |
-
<div class="tab-content" id="ScanResultsTabsContent">
|
2 |
-
|
3 |
-
<div class="tab-pane show active fade" id="ScanPagePaneResults" role="tabpanel"
|
4 |
-
aria-labelledby="h-tabs-scanpage-tab">
|
5 |
-
<div class="row" id="SectionInsightsScans">
|
6 |
-
<div class="col-12 insights-sub-nav" id="ScanResultsTabs">
|
7 |
-
{% include '/wpadmin_pages/insights/scans/scan_results.twig' %}
|
8 |
-
</div>
|
9 |
-
</div>
|
10 |
-
</div>
|
11 |
-
|
12 |
-
<div class="tab-pane fade" id="ScanPagePaneScanNow" role="tabpanel"
|
13 |
-
aria-labelledby="h-tabs-scanpage-tab">
|
14 |
-
<div class="row" id="SectionInsightsScans">
|
15 |
-
<div class="col-12">
|
16 |
-
{% include '/wpadmin_pages/insights/scans/scan_areas.twig' %}
|
17 |
-
</div>
|
18 |
-
</div>
|
19 |
-
</div>
|
20 |
-
</div>
|
21 |
-
<ul class="nav nav-tabs d-block" id="ScanPageTabsNav" role="tablist" style="border-bottom: 0 none;">
|
22 |
-
|
23 |
-
<li id="ScanPageTabsNavResults" class="nav-item hidden footer-form-actions">
|
24 |
-
<a class="nav-link active btn btn-primary btn-lg" data-toggle="tab" href="#ScanPagePaneResults"
|
25 |
-
role="tab" aria-controls="h-tabs-scanpage" aria-selected="true">
|
26 |
-
← {{ strings.select_view_results }}
|
27 |
-
</a>
|
28 |
-
</li>
|
29 |
-
<li id="ScanPageTabsNavScan" class="nav-item footer-form-actions">
|
30 |
-
<a class="nav-link btn btn-primary btn-lg" data-toggle="tab" href="#ScanPagePaneScanNow"
|
31 |
-
role="tab" aria-controls="h-tabs-scanpage" aria-selected="true">
|
32 |
-
{{ strings.run_scans_now }} →
|
33 |
-
</a>
|
34 |
-
</li>
|
35 |
-
</ul>
|
36 |
-
|
37 |
-
<script type="text/javascript">
|
38 |
-
jQuery( '#ScanPageTabsNavResults a[data-toggle="tab"]' ).on( 'shown.bs.tab', function ( e ) {
|
39 |
-
jQuery( '#ScanPageTabsNavScan' ).removeClass( 'hidden' );
|
40 |
-
jQuery( '#ScanPageTabsNavResults' ).addClass( 'hidden' );
|
41 |
-
} );
|
42 |
-
jQuery( '#ScanPageTabsNavScan a[data-toggle="tab"]' ).on( 'shown.bs.tab', function ( e ) {
|
43 |
-
jQuery( '#ScanPageTabsNavResults' ).removeClass( 'hidden' );
|
44 |
-
jQuery( '#ScanPageTabsNavScan' ).addClass( 'hidden' );
|
45 |
-
} );
|
46 |
-
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
templates/twig/wpadmin_pages/insights/settings/index.twig
CHANGED
@@ -2,46 +2,10 @@
|
|
2 |
|
3 |
{% block page_head_titlemenu %}
|
4 |
{{ parent() }}
|
5 |
-
<p class="d-inline">|</p>
|
6 |
-
<div class="d-inline-block" id="ModuleSettingsJump">
|
7 |
-
{% include '/snippets/select_module_settings.twig' %}
|
8 |
-
</div>
|
9 |
{% endblock page_head_titlemenu %}
|
10 |
|
11 |
{% block page_main %}
|
12 |
<div class="row" id="ModulePageTopRow">
|
13 |
-
{# <div class="modules smoothwidth" id="ColumnModules">#}
|
14 |
-
{# <div class="nav flex-column">#}
|
15 |
-
{# <div>#}
|
16 |
-
{# <a id="ModeToggle" href="#" class="btn btn-block btn-outline-primary text-nowrap"#}
|
17 |
-
{# data-txthoverin="{{ strings.mode_switchto }}" data-txthoverout="{{ strings.mode_switchfrom }}"#}
|
18 |
-
{# >#}
|
19 |
-
{# {{ strings.mode }}: <span class="font-weight-bold">#}
|
20 |
-
{# {{ attribute(strings,flags.is_advanced ? 'mode_advanced':'mode_simple') }}#}
|
21 |
-
{# </span>#}
|
22 |
-
{# </a>#}
|
23 |
-
{# </div>#}
|
24 |
-
|
25 |
-
{# <h5 class="mt-3 border-bottom"#}
|
26 |
-
{# style="font-variant: small-caps;font-weight: normal">Shield Modules</h5>#}
|
27 |
-
{# {% for mod_summary in aSummaryData %}#}
|
28 |
-
{# <a class="nav-link module#}
|
29 |
-
{# {% if mod_summary.active %}active{% endif %}#}
|
30 |
-
{# {% if mod_summary.enabled %}enabled{% else %}notenabled{% endif %}"#}
|
31 |
-
{# id="tab-{{ mod_summary.slug }}"#}
|
32 |
-
{# href="{{ mod_summary.href }}" role="tab">#}
|
33 |
-
{# <div>#}
|
34 |
-
{# <span class="module-icon module-icon-{{ mod_summary.slug }}"#}
|
35 |
-
{# id="module-{{ mod_summary.slug }}"></span>#}
|
36 |
-
{# <span class="module-name">#}
|
37 |
-
{# {{ mod_summary.tooltip }}#}
|
38 |
-
{# </span>#}
|
39 |
-
{# </div>#}
|
40 |
-
{# </a>#}
|
41 |
-
{# {% endfor %}#}
|
42 |
-
{# </div>#}
|
43 |
-
{# </div>#}
|
44 |
-
|
45 |
<div class="col" id="ColumnOptions">
|
46 |
<div class="content-options"> {{ strings.loading }} ... </div>
|
47 |
</div>
|
@@ -49,28 +13,5 @@
|
|
49 |
<script>
|
50 |
iCWP_WPSF_OptsPageRender.renderForm( {{ ajax.mod_opts_form_render|raw }} );
|
51 |
iCWP_WPSF_OptionsFormSubmit.updateAjaxReqParams( {{ ajax.mod_options|raw }} );
|
52 |
-
jQuery( 'a.nav-link.module' ).tooltip( {
|
53 |
-
placement: 'right',
|
54 |
-
trigger: 'hover'
|
55 |
-
} );
|
56 |
-
jQuery( 'a.section-help-video' ).tooltip( {
|
57 |
-
placement: 'right',
|
58 |
-
trigger: 'hover'
|
59 |
-
} );
|
60 |
-
|
61 |
-
jQuery( 'a#ModeToggle' ).hover(
|
62 |
-
function ( evt ) {
|
63 |
-
let $this = jQuery( this );
|
64 |
-
$this.text( $this.data( 'txthoverin' ) );
|
65 |
-
$this.addClass( 'btn-warning' )
|
66 |
-
.removeClass( 'btn-outline-primary' );
|
67 |
-
},
|
68 |
-
function ( evt ) {
|
69 |
-
let $this = jQuery( this );
|
70 |
-
$this.text( $this.data( 'txthoverout' ) );
|
71 |
-
$this.addClass( 'btn-outline-primary' )
|
72 |
-
.removeClass( 'btn-warning' );
|
73 |
-
}
|
74 |
-
);
|
75 |
</script>
|
76 |
{% endblock %}
|
2 |
|
3 |
{% block page_head_titlemenu %}
|
4 |
{{ parent() }}
|
|
|
|
|
|
|
|
|
5 |
{% endblock page_head_titlemenu %}
|
6 |
|
7 |
{% block page_main %}
|
8 |
<div class="row" id="ModulePageTopRow">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
<div class="col" id="ColumnOptions">
|
10 |
<div class="content-options"> {{ strings.loading }} ... </div>
|
11 |
</div>
|
13 |
<script>
|
14 |
iCWP_WPSF_OptsPageRender.renderForm( {{ ajax.mod_opts_form_render|raw }} );
|
15 |
iCWP_WPSF_OptionsFormSubmit.updateAjaxReqParams( {{ ajax.mod_options|raw }} );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
</script>
|
17 |
{% endblock %}
|
templates/twig/wpadmin_pages/insights/stats/index.twig
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{% extends '/wpadmin_pages/insights/base.twig' %}
|
2 |
+
|
3 |
+
{% block page_main %}
|
4 |
+
|
5 |
+
{% if flags.has_stats %}
|
6 |
+
|
7 |
+
<div id="StatsNav">
|
8 |
+
<ul class="nav nav-pills">
|
9 |
+
{% for stat_interval_key, stat_interval_name in vars.stat_intervals %}
|
10 |
+
<li class="nav-item">
|
11 |
+
<a class="nav-link {% if stat_interval_key == 'days_1' %}active{% endif %}"
|
12 |
+
data-toggle="pill"
|
13 |
+
href="#statsTab-{{ stat_interval_key }}">
|
14 |
+
{{ stat_interval_name }}</a>
|
15 |
+
</li>
|
16 |
+
{% endfor %}
|
17 |
+
</ul>
|
18 |
+
</div>
|
19 |
+
|
20 |
+
<div class="tab-content mt-3" id="statsTabs">
|
21 |
+
{% for stat_interval_key, stat_interval_name in vars.stat_intervals %}
|
22 |
+
<div class="tab-pane {% if stat_interval_key == 'days_1' %}active{% endif %}" id="statsTab-{{ stat_interval_key }}" role="tabpanel" aria-labelledby="home-tab">
|
23 |
+
{% set stat_to_show = stat_interval_key %}
|
24 |
+
{% include '/components/events/stats/stats_collection.twig' %}
|
25 |
+
</div>
|
26 |
+
{% endfor %}
|
27 |
+
</div>
|
28 |
+
|
29 |
+
{% else %}
|
30 |
+
<div class="alert alert-info">{{ strings.no_stats }}</div>
|
31 |
+
{% endif %}
|
32 |
+
|
33 |
+
{% endblock %}
|
templates/twig/wpadmin_pages/insights/traffic/traffic_table.twig
CHANGED
@@ -13,7 +13,7 @@
|
|
13 |
|
14 |
<div class="col-auto mb-3">
|
15 |
<label class="sr-only" for="_fIp">{{ strings.ip_address }}</label>
|
16 |
-
<select id="_fIp" name="fIp" class="form-control">
|
17 |
<option value="">-- {{ strings.ip_address }} --</option>
|
18 |
{% for unique_ip in vars.unique_ips %}
|
19 |
<option value="{{ unique_ip }}">{{ unique_ip }}</option>
|
13 |
|
14 |
<div class="col-auto mb-3">
|
15 |
<label class="sr-only" for="_fIp">{{ strings.ip_address }}</label>
|
16 |
+
<select id="_fIp" name="fIp" class="form-control select2picker">
|
17 |
<option value="">-- {{ strings.ip_address }} --</option>
|
18 |
{% for unique_ip in vars.unique_ips %}
|
19 |
<option value="{{ unique_ip }}">{{ unique_ip }}</option>
|
templates/twig/wpadmin_pages/security_admin/index.twig
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
{% block h1heading %}<h1 style="display: none;"> </h1>{% endblock %}
|
4 |
{% block page_head %}{% endblock %}
|
5 |
-
{% block
|
6 |
<div class="row justify-content-center">
|
7 |
<div class="col-xl-6 col-lg-7 col-md-8 col-sm-12">
|
8 |
<div class="options-body" id="IcwpWpsfSecurityAdmin">
|
@@ -86,8 +86,4 @@
|
|
86 |
background-color: transparent;
|
87 |
}
|
88 |
</style>
|
89 |
-
{% endblock %}
|
90 |
-
|
91 |
-
{% block inline_scripts %}
|
92 |
-
{% include '/snippets/js/freshdesk_chatbot.twig' %}
|
93 |
{% endblock %}
|
2 |
|
3 |
{% block h1heading %}<h1 style="display: none;"> </h1>{% endblock %}
|
4 |
{% block page_head %}{% endblock %}
|
5 |
+
{% block body %}
|
6 |
<div class="row justify-content-center">
|
7 |
<div class="col-xl-6 col-lg-7 col-md-8 col-sm-12">
|
8 |
<div class="options-body" id="IcwpWpsfSecurityAdmin">
|
86 |
background-color: transparent;
|
87 |
}
|
88 |
</style>
|
|
|
|
|
|
|
|
|
89 |
{% endblock %}
|
unsupported.php
CHANGED
@@ -5,10 +5,10 @@ add_action( 'network_admin_notices', 'icwp_wpsf_unsupported_php' );
|
|
5 |
|
6 |
function icwp_wpsf_unsupported_php() {
|
7 |
global $sIcwpWpsfPluginFile;
|
8 |
-
$
|
9 |
-
'Sorry, your website runs an incredibly old version of PHP that Shield Security no longer supports, as of Shield
|
10 |
"Your PHP no longer gets upgrades and it's difficult to maintain code for.",
|
11 |
-
'We recommend that you contact your website hosting provider on how to upgrade to at least PHP
|
12 |
);
|
13 |
echo sprintf(
|
14 |
'<div class="error"><h4>%s</h4><p>%s</p>' .
|
@@ -16,7 +16,7 @@ function icwp_wpsf_unsupported_php() {
|
|
16 |
'/ <a href="%s">%s</a></p></div>',
|
17 |
|
18 |
sprintf( 'Shield Security Plugin - Unsupported PHP Version: %s', PHP_VERSION ),
|
19 |
-
implode( '<br/>', $
|
20 |
'https://shsec.io/dl',
|
21 |
sprintf( 'Click here for more info' ),
|
22 |
add_query_arg(
|
5 |
|
6 |
function icwp_wpsf_unsupported_php() {
|
7 |
global $sIcwpWpsfPluginFile;
|
8 |
+
$text = array(
|
9 |
+
'Sorry, your website runs an incredibly old version of PHP that Shield Security no longer supports, as of Shield v9.0',
|
10 |
"Your PHP no longer gets upgrades and it's difficult to maintain code for.",
|
11 |
+
'We recommend that you contact your website hosting provider on how to upgrade to at least PHP 7.0'
|
12 |
);
|
13 |
echo sprintf(
|
14 |
'<div class="error"><h4>%s</h4><p>%s</p>' .
|
16 |
'/ <a href="%s">%s</a></p></div>',
|
17 |
|
18 |
sprintf( 'Shield Security Plugin - Unsupported PHP Version: %s', PHP_VERSION ),
|
19 |
+
implode( '<br/>', $text ),
|
20 |
'https://shsec.io/dl',
|
21 |
sprintf( 'Click here for more info' ),
|
22 |
add_query_arg(
|