Shield Security for WordPress - Version 15.1.0

Version Description

Download this release

Release Info

Developer paultgoodchild
Plugin Icon 128x128 Shield Security for WordPress
Version 15.1.0
Comparing to
See all releases

Code changes from version 15.0.13 to 15.1.0

Files changed (156) hide show
  1. cl.json +42 -1
  2. config/audit_trail.json +8 -0
  3. config/comments_filter.json +5 -0
  4. config/deprecated/audit_trail.php +8 -0
  5. config/deprecated/comments_filter.php +5 -0
  6. config/deprecated/firewall.php +1 -0
  7. config/deprecated/hack_protect.php +22 -2
  8. config/deprecated/integrations.php +10 -0
  9. config/deprecated/ips.php +14 -23
  10. config/deprecated/login_protect.php +5 -0
  11. config/deprecated/plugin.php +9 -1
  12. config/deprecated/sessions.php +0 -26
  13. config/deprecated/traffic.php +7 -1
  14. config/deprecated/user_management.php +0 -7
  15. config/firewall.json +1 -0
  16. config/hack_protect.json +22 -2
  17. config/integrations.json +10 -0
  18. config/ips.json +14 -23
  19. config/login_protect.json +5 -0
  20. config/plugin.json +9 -1
  21. config/sessions.json +0 -26
  22. config/traffic.json +7 -1
  23. config/user_management.json +0 -7
  24. icwp-wpsf.php +1 -1
  25. init.php +4 -1
  26. plugin-spec.php +15 -17
  27. plugin.json +15 -17
  28. readme.txt +2 -2
  29. resources/images/{shield/shield-security-1544x500.png → pluginlogo_banner-1544x500.png} +0 -0
  30. resources/js/global-plugin.js +40 -7
  31. resources/js/shield/notbot.js +17 -12
  32. src/lib/src/Controller/Admin/MainAdminMenu.php +11 -7
  33. src/lib/src/Controller/Ajax/Init.php +1 -1
  34. src/lib/src/Controller/Checks/PreModulesBootCheck.php +35 -0
  35. src/lib/src/Controller/Config/ConfigVO.php +0 -1
  36. src/lib/src/Controller/Config/Labels.php +24 -0
  37. src/lib/src/Controller/Config/Ops/Save.php +0 -16
  38. src/lib/src/Controller/Controller.php +221 -231
  39. src/lib/src/Controller/Utilities/Upgrade.php +6 -10
  40. src/lib/src/Crons/StandardCron.php +4 -5
  41. src/lib/src/Databases/Session/Delete.php +0 -38
  42. src/lib/src/Databases/Session/EntryVO.php +0 -38
  43. src/lib/src/Databases/Session/Handler.php +0 -18
  44. src/lib/src/Databases/Session/Insert.php +0 -51
  45. src/lib/src/Databases/Session/Select.php +0 -83
  46. src/lib/src/Databases/Session/Update.php +0 -42
  47. src/lib/src/Modules/Base/AdminNotices.php +0 -9
  48. src/lib/src/Modules/Base/AdminPage.php +0 -14
  49. src/lib/src/Modules/Base/Config/LoadConfig.php +0 -25
  50. src/lib/src/Modules/Base/Config/ModConfigVO.php +23 -0
  51. src/lib/src/Modules/Base/Databases.php +7 -4
  52. src/lib/src/Modules/Base/Lib/CheckModuleRequirements.php +31 -0
  53. src/lib/src/Modules/Base/ModCon.php +33 -68
  54. src/lib/src/Modules/Base/Options.php +0 -48
  55. src/lib/src/Modules/Base/Processor.php +1 -2
  56. src/lib/src/Modules/BaseShield/ModCon.php +0 -61
  57. src/lib/src/Modules/BaseShield/UI.php +1 -2
  58. src/lib/src/Modules/CommentsFilter/ModCon.php +0 -20
  59. src/lib/src/Modules/CommentsFilter/Options.php +0 -28
  60. src/lib/src/Modules/Firewall/Lib/Scan/FirewallHandler.php +0 -173
  61. src/lib/src/Modules/HackGuard/Lib/FileLocker/FileLockerController.php +1 -1
  62. src/lib/src/Modules/HackGuard/ModCon.php +20 -37
  63. src/lib/src/Modules/HackGuard/Options.php +0 -36
  64. src/lib/src/Modules/HackGuard/Scan/Controller/Afs.php +6 -0
  65. src/lib/src/Modules/HackGuard/Scan/Controller/Apc.php +4 -0
  66. src/lib/src/Modules/HackGuard/Scan/Controller/Base.php +4 -0
  67. src/lib/src/Modules/HackGuard/Scan/Init/PopulateScanItems.php +1 -1
  68. src/lib/src/Modules/HackGuard/Scan/ScansController.php +1 -1
  69. src/lib/src/Modules/HackGuard/Strings.php +10 -45
  70. src/lib/src/Modules/IPs/Components/ProcessOffense.php +1 -0
  71. src/lib/src/Modules/IPs/Lib/BlacklistHandler.php +0 -27
  72. src/lib/src/Modules/IPs/Lib/OffenseTracker.php +3 -15
  73. src/lib/src/Modules/IPs/Lib/Ops/AddIp.php +16 -14
  74. src/lib/src/Modules/IPs/ModCon.php +2 -2
  75. src/lib/src/Modules/IPs/Strings.php +1 -1
  76. src/lib/src/Modules/Insights/UI.php +10 -3
  77. src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/Base.php +0 -7
  78. src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/HappyForms.php +23 -0
  79. src/lib/src/Modules/Integrations/Lib/Bots/Spam/SpamController.php +1 -0
  80. src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/EasyDigitalDownloads.php +1 -1
  81. src/lib/src/Modules/Integrations/Lib/MainWP/Client/Actions/ApiActionInit.php +1 -1
  82. src/lib/src/Modules/License/AjaxHandler.php +1 -1
  83. src/lib/src/Modules/License/Lib/LicenseHandler.php +15 -8
  84. src/lib/src/Modules/License/Lib/PluginNameSuffix.php +7 -10
  85. src/lib/src/Modules/License/ModCon.php +6 -8
  86. src/lib/src/Modules/License/Processor.php +0 -3
  87. src/lib/src/Modules/License/WpCli/License.php +1 -1
  88. src/lib/src/Modules/LoginGuard/Lib/AntiBot/FormProviders/EasyDigitalDownloads.php +1 -1
  89. src/lib/src/Modules/LoginGuard/Lib/AntiBot/FormProviders/WooCommerce.php +20 -23
  90. src/lib/src/Modules/LoginGuard/Lib/AntiBot/FormProviders/WordPress.php +11 -11
  91. src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Render/RenderLoginIntentPage.php +6 -10
  92. src/lib/src/Modules/Plugin/AdminNotices.php +37 -6
  93. src/lib/src/Modules/Plugin/AjaxHandler.php +51 -1
  94. src/lib/src/Modules/Plugin/Components/DashboardWidget.php +19 -13
  95. src/lib/src/Modules/Plugin/Debug.php +18 -3
  96. src/lib/src/Modules/Plugin/Lib/ImportExport/ImportExportController.php +7 -7
  97. src/lib/src/Modules/Plugin/ModCon.php +14 -15
  98. src/lib/src/Modules/Plugin/Options.php +0 -7
  99. src/lib/src/Modules/Plugin/Processor.php +0 -7
  100. src/lib/src/Modules/Plugin/Strings.php +0 -1
  101. src/lib/src/Modules/SecurityAdmin/AdminNotices.php +5 -6
  102. src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/BaseCapabilitiesRestrict.php +2 -1
  103. src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/SecurityAdminController.php +9 -4
  104. src/lib/src/Modules/SecurityAdmin/Lib/WhiteLabel/BuildOptions.php +3 -0
  105. src/lib/src/Modules/SecurityAdmin/Lib/WhiteLabel/WhitelabelController.php +91 -30
  106. src/lib/src/Modules/SecurityAdmin/Options.php +10 -18
  107. src/lib/src/Modules/SecurityAdmin/Processor.php +1 -1
  108. src/lib/src/Modules/Sessions/Lib/SessionController.php +0 -54
  109. src/lib/src/Modules/Sessions/ModCon.php +0 -7
  110. src/lib/src/Modules/Sessions/Processor.php +0 -12
  111. src/lib/src/Modules/Traffic/Lib/Limit/Limiter.php +0 -49
  112. src/lib/src/Modules/Traffic/ModCon.php +3 -3
  113. src/lib/src/Modules/Traffic/UI.php +3 -3
  114. src/lib/src/Modules/UserManagement/Processor.php +5 -5
  115. src/lib/src/Modules/UserManagement/WpCli/SessionTerminate.php +0 -73
  116. src/lib/src/Request/ThisRequest.php +2 -1
  117. src/lib/src/Rules/Conditions/IsIpBlocked.php +8 -4
  118. src/lib/src/Rules/RulesStorageHandler.php +10 -6
  119. src/lib/src/Scans/Afs/BuildScanAction.php +7 -1
  120. src/lib/src/Scans/Afs/BuildScanItems.php +65 -29
  121. src/lib/src/Scans/Afs/Processing/FileScanOptimiser.php +173 -0
  122. src/lib/src/Scans/Afs/Scan.php +38 -6
  123. src/lib/src/Scans/Afs/ScanActionVO.php +0 -1
  124. src/lib/src/Scans/Afs/ScanFromFileMap.php +52 -7
  125. src/lib/src/Scans/Apc/BuildScanAction.php +7 -8
  126. src/lib/src/Scans/Apc/ScanActionVO.php +0 -1
  127. src/lib/src/Scans/Base/BaseScanActionVO.php +0 -1
  128. src/lib/src/Scans/Base/BuildScanAction.php +1 -22
  129. src/lib/src/Scans/Mal/ScanActionVO.php +0 -1
  130. src/lib/src/Scans/Ptg/ScanActionVO.php +0 -1
  131. src/lib/src/Scans/Ufc/ScanActionVO.php +0 -1
  132. src/lib/src/Scans/Wcf/ScanActionVO.php +0 -1
  133. src/lib/src/Scans/Wpv/BuildScanAction.php +7 -4
  134. src/lib/src/Tables/Build/Sessions.php +0 -9
  135. src/lib/src/Utilities/MU/MUHandler.php +2 -2
  136. src/lib/src/Utilities/Render/BasePageDisplay.php +9 -2
  137. src/lib/vendor/composer/autoload_classmap.php +8 -19
  138. src/lib/vendor/composer/autoload_static.php +8 -19
  139. src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Handler.php +106 -99
  140. src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/AlignTableWithSchema.php +4 -4
  141. src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/TableReadyCache.php +14 -4
  142. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Request.php +47 -29
  143. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Arrays.php +10 -0
  144. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Data.php +4 -4
  145. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/File/Search/SearchFile.php +97 -0
  146. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/IpUtils.php +12 -14
  147. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Net/BaseIP.php +19 -0
  148. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Net/FindSourceFromIp.php +1 -1
  149. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Net/IpID.php +34 -27
  150. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Net/RequestIpDetect.php +145 -0
  151. src/wizards/plugin.php +3 -27
  152. templates/twig/notices/base.twig +2 -2
  153. templates/twig/notices/databases-not-ready.twig +11 -0
  154. templates/twig/notices/override-forceoff.twig +3 -19
  155. templates/twig/pages/block/block_page_ip.twig +8 -6
  156. templates/twig/pages/block/block_page_standard.twig +1 -2
cl.json CHANGED
@@ -1,4 +1,46 @@
1
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  "15.0": {
3
  "version": "15.0",
4
  "released_at": 1652090000,
@@ -14,7 +56,6 @@
14
  "items": [
15
  {
16
  "type": "new",
17
- "pro_only": true,
18
  "title": "Rules Engine",
19
  "description": [
20
  "Massive performance and processing optimisations with a brand new core Shield Rules Engine.",
1
  {
2
+ "15.1": {
3
+ "version": "15.1",
4
+ "released_at": 1652090000,
5
+ "hrefs": {
6
+ "release": "https://shsec.io/shieldrelease151",
7
+ "upgrade": "https://shsec.io/shieldupgradeguide151"
8
+ },
9
+ "title": "Optimisations",
10
+ "description": [
11
+ ],
12
+ "items": [
13
+ {
14
+ "type": "new",
15
+ "pro_only": false,
16
+ "title": "Optimised File Scanning",
17
+ "description": [
18
+ "Significant optimisation in file scanning with reduction of full file scan times by up to 66%.",
19
+ "For example, if a file scan would have normally lasted for 3 minutes, it'll now take less than 1 minute.",
20
+ "This means faster scanning, less waiting, and much lighter load on your servers by using fewer resources."
21
+ ]
22
+ },
23
+ {
24
+ "type": "new",
25
+ "pro_only": true,
26
+ "title": "Happy Forms",
27
+ "description": [
28
+ "Full support available for SPAM protection on Happy Forms."
29
+ ]
30
+ },
31
+ {
32
+ "type": "improved",
33
+ "pro_only": true,
34
+ "title": "Automatic Visitor IP Detection",
35
+ "description": [
36
+ "The 100% fully automatic detection of visitor IP addresses is a lofty goal and with each release we get a bit closer.",
37
+ "You can always help Shield by manually setting your Visitor IP source option: Shield > Config > General IP Source."
38
+ ]
39
+ }
40
+ ],
41
+ "patches": [
42
+ ]
43
+ },
44
  "15.0": {
45
  "version": "15.0",
46
  "released_at": 1652090000,
56
  "items": [
57
  {
58
  "type": "new",
 
59
  "title": "Rules Engine",
60
  "description": [
61
  "Massive performance and processing optimisations with a brand new core Shield Rules Engine.",
config/audit_trail.json CHANGED
@@ -18,6 +18,14 @@
18
  "run_if_wpcli": true,
19
  "order": 110
20
  },
 
 
 
 
 
 
 
 
21
  "menus": {
22
  "config_menu_priority": 35
23
  },
18
  "run_if_wpcli": true,
19
  "order": 110
20
  },
21
+ "reqs": {
22
+ "dbs": [
23
+ "at_logs",
24
+ "at_meta",
25
+ "ips",
26
+ "req_logs"
27
+ ]
28
+ },
29
  "menus": {
30
  "config_menu_priority": 35
31
  },
config/comments_filter.json CHANGED
@@ -17,6 +17,11 @@
17
  "run_if_wpcli": false,
18
  "order": 50
19
  },
 
 
 
 
 
20
  "menus": {
21
  "config_menu_priority": 40
22
  },
17
  "run_if_wpcli": false,
18
  "order": 50
19
  },
20
+ "reqs": {
21
+ "dbs": [
22
+ "botsignal"
23
+ ]
24
+ },
25
  "menus": {
26
  "config_menu_priority": 40
27
  },
config/deprecated/audit_trail.php CHANGED
@@ -18,6 +18,14 @@
18
  "run_if_wpcli": true,
19
  "order": 110
20
  },
 
 
 
 
 
 
 
 
21
  "menus": {
22
  "config_menu_priority": 35
23
  },
18
  "run_if_wpcli": true,
19
  "order": 110
20
  },
21
+ "reqs": {
22
+ "dbs": [
23
+ "at_logs",
24
+ "at_meta",
25
+ "ips",
26
+ "req_logs"
27
+ ]
28
+ },
29
  "menus": {
30
  "config_menu_priority": 35
31
  },
config/deprecated/comments_filter.php CHANGED
@@ -17,6 +17,11 @@
17
  "run_if_wpcli": false,
18
  "order": 50
19
  },
 
 
 
 
 
20
  "menus": {
21
  "config_menu_priority": 40
22
  },
17
  "run_if_wpcli": false,
18
  "order": 50
19
  },
20
+ "reqs": {
21
+ "dbs": [
22
+ "botsignal"
23
+ ]
24
+ },
25
  "menus": {
26
  "config_menu_priority": 40
27
  },
config/deprecated/firewall.php CHANGED
@@ -314,6 +314,7 @@
314
  "pwd",
315
  "url",
316
  "referredby",
 
317
  "redirect_to",
318
  "jetpack_sso_original_request",
319
  "jetpack_sso_redirect_to",
314
  "pwd",
315
  "url",
316
  "referredby",
317
+ "return",
318
  "redirect_to",
319
  "jetpack_sso_original_request",
320
  "jetpack_sso_redirect_to",
config/deprecated/hack_protect.php CHANGED
@@ -19,7 +19,16 @@
19
  "run_if_verified_bot": true,
20
  "run_if_wpcli": true
21
  },
22
- "menus": {
 
 
 
 
 
 
 
 
 
23
  "config_menu_priority": 25
24
  },
25
  "wpcli": {
@@ -307,6 +316,18 @@
307
  "summary": "Show Re-Install Links For Plugins",
308
  "description": "Show links to re-install plugins and offer re-install when activating plugins."
309
  },
 
 
 
 
 
 
 
 
 
 
 
 
310
  {
311
  "key": "scans_to_build",
312
  "section": "section_non_ui",
@@ -571,7 +592,6 @@
571
  "*/mail.log",
572
  "*/php_mail.log"
573
  ],
574
- "cron_all_scans": "all-scans",
575
  "wcf_exclusions": [
576
  "readme.html",
577
  "license.txt",
19
  "run_if_verified_bot": true,
20
  "run_if_wpcli": true
21
  },
22
+ "reqs": {
23
+ "dbs": [
24
+ "scans",
25
+ "scanitems",
26
+ "resultitems",
27
+ "resultitem_meta",
28
+ "scanresults"
29
+ ]
30
+ },
31
+ "menus": {
32
  "config_menu_priority": 25
33
  },
34
  "wpcli": {
316
  "summary": "Show Re-Install Links For Plugins",
317
  "description": "Show links to re-install plugins and offer re-install when activating plugins."
318
  },
319
+ {
320
+ "key": "optimise_scan_speed",
321
+ "section": "section_scan_options",
322
+ "premium": true,
323
+ "type": "checkbox",
324
+ "default": "Y",
325
+ "link_info": "",
326
+ "link_blog": "",
327
+ "name": "Optimise File Scans",
328
+ "summary": "Optimise File Scans",
329
+ "description": "Optimise file scans wherever possible."
330
+ },
331
  {
332
  "key": "scans_to_build",
333
  "section": "section_non_ui",
592
  "*/mail.log",
593
  "*/php_mail.log"
594
  ],
 
595
  "wcf_exclusions": [
596
  "readme.html",
597
  "license.txt",
config/deprecated/integrations.php CHANGED
@@ -19,6 +19,12 @@
19
  "skip_processor": false,
20
  "tracking_exclude": false
21
  },
 
 
 
 
 
 
22
  "menus": {
23
  "config_menu_priority": 50
24
  },
@@ -99,6 +105,10 @@
99
  "value_key": "groundhogg",
100
  "text": "Groundhogg"
101
  },
 
 
 
 
102
  {
103
  "value_key": "kaliforms",
104
  "text": "Kali Forms"
19
  "skip_processor": false,
20
  "tracking_exclude": false
21
  },
22
+ "reqs": {
23
+ "dbs": [
24
+ "botsignal",
25
+ "ips"
26
+ ]
27
+ },
28
  "menus": {
29
  "config_menu_priority": 50
30
  },
105
  "value_key": "groundhogg",
106
  "text": "Groundhogg"
107
  },
108
+ {
109
+ "value_key": "happyforms",
110
+ "text": "HappyForms"
111
+ },
112
  {
113
  "value_key": "kaliforms",
114
  "text": "Kali Forms"
config/deprecated/ips.php CHANGED
@@ -19,9 +19,14 @@
19
  "run_if_wpcli": false,
20
  "order": 100
21
  },
22
- "menus": {
23
  "config_menu_priority": 20
24
  },
 
 
 
 
 
25
  "wpcli": {
26
  "enabled": true
27
  },
@@ -49,20 +54,6 @@
49
  "type": "info"
50
  }
51
  },
52
- "requirements": {
53
- "php": {
54
- "functions": [
55
- "filter_var"
56
- ],
57
- "constants": [
58
- "FILTER_VALIDATE_IP",
59
- "FILTER_FLAG_IPV4",
60
- "FILTER_FLAG_IPV6",
61
- "FILTER_FLAG_NO_PRIV_RANGE",
62
- "FILTER_FLAG_NO_RES_RANGE"
63
- ]
64
- }
65
- },
66
  "sections": [
67
  {
68
  "slug": "section_auto_black_list",
@@ -300,7 +291,7 @@
300
  },
301
  {
302
  "value_key": "log",
303
- "text": "Audit Log Only"
304
  },
305
  {
306
  "value_key": "transgression-single",
@@ -335,7 +326,7 @@
335
  },
336
  {
337
  "value_key": "log",
338
- "text": "Audit Log Only"
339
  },
340
  {
341
  "value_key": "transgression-single",
@@ -370,7 +361,7 @@
370
  },
371
  {
372
  "value_key": "log",
373
- "text": "Audit Log Only"
374
  },
375
  {
376
  "value_key": "transgression-single",
@@ -405,7 +396,7 @@
405
  },
406
  {
407
  "value_key": "log",
408
- "text": "Audit Log Only"
409
  },
410
  {
411
  "value_key": "transgression-single",
@@ -439,7 +430,7 @@
439
  },
440
  {
441
  "value_key": "log",
442
- "text": "Audit Log Only"
443
  },
444
  {
445
  "value_key": "transgression-single",
@@ -474,7 +465,7 @@
474
  },
475
  {
476
  "value_key": "log",
477
- "text": "Audit Log Only"
478
  },
479
  {
480
  "value_key": "transgression-single",
@@ -509,7 +500,7 @@
509
  },
510
  {
511
  "value_key": "log",
512
- "text": "Audit Log Only"
513
  },
514
  {
515
  "value_key": "transgression-single",
@@ -544,7 +535,7 @@
544
  },
545
  {
546
  "value_key": "log",
547
- "text": "Audit Log Only"
548
  },
549
  {
550
  "value_key": "transgression-single",
19
  "run_if_wpcli": false,
20
  "order": 100
21
  },
22
+ "menus": {
23
  "config_menu_priority": 20
24
  },
25
+ "reqs": {
26
+ "dbs": [
27
+ "ips"
28
+ ]
29
+ },
30
  "wpcli": {
31
  "enabled": true
32
  },
54
  "type": "info"
55
  }
56
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  "sections": [
58
  {
59
  "slug": "section_auto_black_list",
291
  },
292
  {
293
  "value_key": "log",
294
+ "text": "Activity Log Only"
295
  },
296
  {
297
  "value_key": "transgression-single",
326
  },
327
  {
328
  "value_key": "log",
329
+ "text": "Activity Log Only"
330
  },
331
  {
332
  "value_key": "transgression-single",
361
  },
362
  {
363
  "value_key": "log",
364
+ "text": "Activity Log Only"
365
  },
366
  {
367
  "value_key": "transgression-single",
396
  },
397
  {
398
  "value_key": "log",
399
+ "text": "Activity Log Only"
400
  },
401
  {
402
  "value_key": "transgression-single",
430
  },
431
  {
432
  "value_key": "log",
433
+ "text": "Activity Log Only"
434
  },
435
  {
436
  "value_key": "transgression-single",
465
  },
466
  {
467
  "value_key": "log",
468
+ "text": "Activity Log Only"
469
  },
470
  {
471
  "value_key": "transgression-single",
500
  },
501
  {
502
  "value_key": "log",
503
+ "text": "Activity Log Only"
504
  },
505
  {
506
  "value_key": "transgression-single",
535
  },
536
  {
537
  "value_key": "log",
538
+ "text": "Activity Log Only"
539
  },
540
  {
541
  "value_key": "transgression-single",
config/deprecated/login_protect.php CHANGED
@@ -18,6 +18,11 @@
18
  "run_if_wpcli": false,
19
  "order": 40
20
  },
 
 
 
 
 
21
  "menus": {
22
  "config_menu_priority": 30
23
  },
18
  "run_if_wpcli": false,
19
  "order": 40
20
  },
21
+ "reqs": {
22
+ "dbs": [
23
+ "botsignal"
24
+ ]
25
+ },
26
  "menus": {
27
  "config_menu_priority": 30
28
  },
config/deprecated/plugin.php CHANGED
@@ -25,6 +25,14 @@
25
  "enabled": true
26
  },
27
  "admin_notices": {
 
 
 
 
 
 
 
 
28
  "plugin-too-old": {
29
  "id": "plugin-too-old",
30
  "schedule": "conditions",
@@ -33,7 +41,7 @@
33
  "can_dismiss": true,
34
  "type": "error"
35
  },
36
- "rules-not-running": {
37
  "id": "rules-not-running",
38
  "schedule": "conditions",
39
  "valid_admin": false,
25
  "enabled": true
26
  },
27
  "admin_notices": {
28
+ "databases-not-ready": {
29
+ "id": "databases-not-ready",
30
+ "schedule": "conditions",
31
+ "valid_admin": true,
32
+ "plugin_page_only": false,
33
+ "can_dismiss": false,
34
+ "type": "error"
35
+ },
36
  "plugin-too-old": {
37
  "id": "plugin-too-old",
38
  "schedule": "conditions",
41
  "can_dismiss": true,
42
  "type": "error"
43
  },
44
+ "rules-not-running": {
45
  "id": "rules-not-running",
46
  "schedule": "conditions",
47
  "valid_admin": false,
config/deprecated/sessions.php CHANGED
@@ -46,35 +46,9 @@
46
  "name": "Enable Sessions",
47
  "summary": "Enable (or Disable) The Sessions module",
48
  "description": "Un-Checking this option will completely disable the Sessions module"
49
- },
50
- {
51
- "key": "autoadd_sessions_started_at",
52
- "section": "section_non_ui",
53
- "type": "integer",
54
- "default": 0,
55
- "transferable": false
56
  }
57
  ],
58
  "definitions": {
59
- "db_classes": {
60
- "sessions": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Session\\Handler"
61
- },
62
- "sessions_table_name": "sessions",
63
- "db_table_sessions": {
64
- "slug": "sessions",
65
- "cols_custom": {
66
- "session_id": "varchar(32) NOT NULL DEFAULT ''",
67
- "wp_username": "varchar(255) NOT NULL DEFAULT ''",
68
- "ip": "varchar(60) NOT NULL DEFAULT ''",
69
- "browser": "varchar(32) NOT NULL DEFAULT ''",
70
- "last_activity_uri": "text NOT NULL DEFAULT ''"
71
- },
72
- "cols_timestamps": {
73
- "logged_in_at": "Session Started",
74
- "last_activity_at": "Last Seen At",
75
- "secadmin_at": "Security Admin Authenticated"
76
- }
77
- },
78
  "events": {
79
  "session_start": {
80
  "audit_params": [
46
  "name": "Enable Sessions",
47
  "summary": "Enable (or Disable) The Sessions module",
48
  "description": "Un-Checking this option will completely disable the Sessions module"
 
 
 
 
 
 
 
49
  }
50
  ],
51
  "definitions": {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  "events": {
53
  "session_start": {
54
  "audit_params": [
config/deprecated/traffic.php CHANGED
@@ -18,7 +18,13 @@
18
  "run_if_wpcli": false,
19
  "order": 110
20
  },
21
- "menus": {
 
 
 
 
 
 
22
  "config_menu_priority": 35
23
  },
24
  "wpcli": {
18
  "run_if_wpcli": false,
19
  "order": 110
20
  },
21
+ "reqs": {
22
+ "dbs": [
23
+ "ips",
24
+ "req_logs"
25
+ ]
26
+ },
27
+ "menus": {
28
  "config_menu_priority": 35
29
  },
30
  "wpcli": {
config/deprecated/user_management.php CHANGED
@@ -398,13 +398,6 @@
398
  "name": "Auto-Suspend Idle Users",
399
  "summary": "Automatically Suspend Idle User Accounts",
400
  "description": "Prevent login by idle users and require password reset to unsuspend."
401
- },
402
- {
403
- "key": "autoadd_sessions_started_at",
404
- "section": "section_non_ui",
405
- "type": "integer",
406
- "default": 0,
407
- "transferable": false
408
  }
409
  ],
410
  "definitions": {
398
  "name": "Auto-Suspend Idle Users",
399
  "summary": "Automatically Suspend Idle User Accounts",
400
  "description": "Prevent login by idle users and require password reset to unsuspend."
 
 
 
 
 
 
 
401
  }
402
  ],
403
  "definitions": {
config/firewall.json CHANGED
@@ -314,6 +314,7 @@
314
  "pwd",
315
  "url",
316
  "referredby",
 
317
  "redirect_to",
318
  "jetpack_sso_original_request",
319
  "jetpack_sso_redirect_to",
314
  "pwd",
315
  "url",
316
  "referredby",
317
+ "return",
318
  "redirect_to",
319
  "jetpack_sso_original_request",
320
  "jetpack_sso_redirect_to",
config/hack_protect.json CHANGED
@@ -19,7 +19,16 @@
19
  "run_if_verified_bot": true,
20
  "run_if_wpcli": true
21
  },
22
- "menus": {
 
 
 
 
 
 
 
 
 
23
  "config_menu_priority": 25
24
  },
25
  "wpcli": {
@@ -307,6 +316,18 @@
307
  "summary": "Show Re-Install Links For Plugins",
308
  "description": "Show links to re-install plugins and offer re-install when activating plugins."
309
  },
 
 
 
 
 
 
 
 
 
 
 
 
310
  {
311
  "key": "scans_to_build",
312
  "section": "section_non_ui",
@@ -571,7 +592,6 @@
571
  "*/mail.log",
572
  "*/php_mail.log"
573
  ],
574
- "cron_all_scans": "all-scans",
575
  "wcf_exclusions": [
576
  "readme.html",
577
  "license.txt",
19
  "run_if_verified_bot": true,
20
  "run_if_wpcli": true
21
  },
22
+ "reqs": {
23
+ "dbs": [
24
+ "scans",
25
+ "scanitems",
26
+ "resultitems",
27
+ "resultitem_meta",
28
+ "scanresults"
29
+ ]
30
+ },
31
+ "menus": {
32
  "config_menu_priority": 25
33
  },
34
  "wpcli": {
316
  "summary": "Show Re-Install Links For Plugins",
317
  "description": "Show links to re-install plugins and offer re-install when activating plugins."
318
  },
319
+ {
320
+ "key": "optimise_scan_speed",
321
+ "section": "section_scan_options",
322
+ "premium": true,
323
+ "type": "checkbox",
324
+ "default": "Y",
325
+ "link_info": "",
326
+ "link_blog": "",
327
+ "name": "Optimise File Scans",
328
+ "summary": "Optimise File Scans",
329
+ "description": "Optimise file scans wherever possible."
330
+ },
331
  {
332
  "key": "scans_to_build",
333
  "section": "section_non_ui",
592
  "*/mail.log",
593
  "*/php_mail.log"
594
  ],
 
595
  "wcf_exclusions": [
596
  "readme.html",
597
  "license.txt",
config/integrations.json CHANGED
@@ -19,6 +19,12 @@
19
  "skip_processor": false,
20
  "tracking_exclude": false
21
  },
 
 
 
 
 
 
22
  "menus": {
23
  "config_menu_priority": 50
24
  },
@@ -99,6 +105,10 @@
99
  "value_key": "groundhogg",
100
  "text": "Groundhogg"
101
  },
 
 
 
 
102
  {
103
  "value_key": "kaliforms",
104
  "text": "Kali Forms"
19
  "skip_processor": false,
20
  "tracking_exclude": false
21
  },
22
+ "reqs": {
23
+ "dbs": [
24
+ "botsignal",
25
+ "ips"
26
+ ]
27
+ },
28
  "menus": {
29
  "config_menu_priority": 50
30
  },
105
  "value_key": "groundhogg",
106
  "text": "Groundhogg"
107
  },
108
+ {
109
+ "value_key": "happyforms",
110
+ "text": "HappyForms"
111
+ },
112
  {
113
  "value_key": "kaliforms",
114
  "text": "Kali Forms"
config/ips.json CHANGED
@@ -19,9 +19,14 @@
19
  "run_if_wpcli": false,
20
  "order": 100
21
  },
22
- "menus": {
23
  "config_menu_priority": 20
24
  },
 
 
 
 
 
25
  "wpcli": {
26
  "enabled": true
27
  },
@@ -49,20 +54,6 @@
49
  "type": "info"
50
  }
51
  },
52
- "requirements": {
53
- "php": {
54
- "functions": [
55
- "filter_var"
56
- ],
57
- "constants": [
58
- "FILTER_VALIDATE_IP",
59
- "FILTER_FLAG_IPV4",
60
- "FILTER_FLAG_IPV6",
61
- "FILTER_FLAG_NO_PRIV_RANGE",
62
- "FILTER_FLAG_NO_RES_RANGE"
63
- ]
64
- }
65
- },
66
  "sections": [
67
  {
68
  "slug": "section_auto_black_list",
@@ -300,7 +291,7 @@
300
  },
301
  {
302
  "value_key": "log",
303
- "text": "Audit Log Only"
304
  },
305
  {
306
  "value_key": "transgression-single",
@@ -335,7 +326,7 @@
335
  },
336
  {
337
  "value_key": "log",
338
- "text": "Audit Log Only"
339
  },
340
  {
341
  "value_key": "transgression-single",
@@ -370,7 +361,7 @@
370
  },
371
  {
372
  "value_key": "log",
373
- "text": "Audit Log Only"
374
  },
375
  {
376
  "value_key": "transgression-single",
@@ -405,7 +396,7 @@
405
  },
406
  {
407
  "value_key": "log",
408
- "text": "Audit Log Only"
409
  },
410
  {
411
  "value_key": "transgression-single",
@@ -439,7 +430,7 @@
439
  },
440
  {
441
  "value_key": "log",
442
- "text": "Audit Log Only"
443
  },
444
  {
445
  "value_key": "transgression-single",
@@ -474,7 +465,7 @@
474
  },
475
  {
476
  "value_key": "log",
477
- "text": "Audit Log Only"
478
  },
479
  {
480
  "value_key": "transgression-single",
@@ -509,7 +500,7 @@
509
  },
510
  {
511
  "value_key": "log",
512
- "text": "Audit Log Only"
513
  },
514
  {
515
  "value_key": "transgression-single",
@@ -544,7 +535,7 @@
544
  },
545
  {
546
  "value_key": "log",
547
- "text": "Audit Log Only"
548
  },
549
  {
550
  "value_key": "transgression-single",
19
  "run_if_wpcli": false,
20
  "order": 100
21
  },
22
+ "menus": {
23
  "config_menu_priority": 20
24
  },
25
+ "reqs": {
26
+ "dbs": [
27
+ "ips"
28
+ ]
29
+ },
30
  "wpcli": {
31
  "enabled": true
32
  },
54
  "type": "info"
55
  }
56
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  "sections": [
58
  {
59
  "slug": "section_auto_black_list",
291
  },
292
  {
293
  "value_key": "log",
294
+ "text": "Activity Log Only"
295
  },
296
  {
297
  "value_key": "transgression-single",
326
  },
327
  {
328
  "value_key": "log",
329
+ "text": "Activity Log Only"
330
  },
331
  {
332
  "value_key": "transgression-single",
361
  },
362
  {
363
  "value_key": "log",
364
+ "text": "Activity Log Only"
365
  },
366
  {
367
  "value_key": "transgression-single",
396
  },
397
  {
398
  "value_key": "log",
399
+ "text": "Activity Log Only"
400
  },
401
  {
402
  "value_key": "transgression-single",
430
  },
431
  {
432
  "value_key": "log",
433
+ "text": "Activity Log Only"
434
  },
435
  {
436
  "value_key": "transgression-single",
465
  },
466
  {
467
  "value_key": "log",
468
+ "text": "Activity Log Only"
469
  },
470
  {
471
  "value_key": "transgression-single",
500
  },
501
  {
502
  "value_key": "log",
503
+ "text": "Activity Log Only"
504
  },
505
  {
506
  "value_key": "transgression-single",
535
  },
536
  {
537
  "value_key": "log",
538
+ "text": "Activity Log Only"
539
  },
540
  {
541
  "value_key": "transgression-single",
config/login_protect.json CHANGED
@@ -18,6 +18,11 @@
18
  "run_if_wpcli": false,
19
  "order": 40
20
  },
 
 
 
 
 
21
  "menus": {
22
  "config_menu_priority": 30
23
  },
18
  "run_if_wpcli": false,
19
  "order": 40
20
  },
21
+ "reqs": {
22
+ "dbs": [
23
+ "botsignal"
24
+ ]
25
+ },
26
  "menus": {
27
  "config_menu_priority": 30
28
  },
config/plugin.json CHANGED
@@ -25,6 +25,14 @@
25
  "enabled": true
26
  },
27
  "admin_notices": {
 
 
 
 
 
 
 
 
28
  "plugin-too-old": {
29
  "id": "plugin-too-old",
30
  "schedule": "conditions",
@@ -33,7 +41,7 @@
33
  "can_dismiss": true,
34
  "type": "error"
35
  },
36
- "rules-not-running": {
37
  "id": "rules-not-running",
38
  "schedule": "conditions",
39
  "valid_admin": false,
25
  "enabled": true
26
  },
27
  "admin_notices": {
28
+ "databases-not-ready": {
29
+ "id": "databases-not-ready",
30
+ "schedule": "conditions",
31
+ "valid_admin": true,
32
+ "plugin_page_only": false,
33
+ "can_dismiss": false,
34
+ "type": "error"
35
+ },
36
  "plugin-too-old": {
37
  "id": "plugin-too-old",
38
  "schedule": "conditions",
41
  "can_dismiss": true,
42
  "type": "error"
43
  },
44
+ "rules-not-running": {
45
  "id": "rules-not-running",
46
  "schedule": "conditions",
47
  "valid_admin": false,
config/sessions.json CHANGED
@@ -46,35 +46,9 @@
46
  "name": "Enable Sessions",
47
  "summary": "Enable (or Disable) The Sessions module",
48
  "description": "Un-Checking this option will completely disable the Sessions module"
49
- },
50
- {
51
- "key": "autoadd_sessions_started_at",
52
- "section": "section_non_ui",
53
- "type": "integer",
54
- "default": 0,
55
- "transferable": false
56
  }
57
  ],
58
  "definitions": {
59
- "db_classes": {
60
- "sessions": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Session\\Handler"
61
- },
62
- "sessions_table_name": "sessions",
63
- "db_table_sessions": {
64
- "slug": "sessions",
65
- "cols_custom": {
66
- "session_id": "varchar(32) NOT NULL DEFAULT ''",
67
- "wp_username": "varchar(255) NOT NULL DEFAULT ''",
68
- "ip": "varchar(60) NOT NULL DEFAULT ''",
69
- "browser": "varchar(32) NOT NULL DEFAULT ''",
70
- "last_activity_uri": "text NOT NULL DEFAULT ''"
71
- },
72
- "cols_timestamps": {
73
- "logged_in_at": "Session Started",
74
- "last_activity_at": "Last Seen At",
75
- "secadmin_at": "Security Admin Authenticated"
76
- }
77
- },
78
  "events": {
79
  "session_start": {
80
  "audit_params": [
46
  "name": "Enable Sessions",
47
  "summary": "Enable (or Disable) The Sessions module",
48
  "description": "Un-Checking this option will completely disable the Sessions module"
 
 
 
 
 
 
 
49
  }
50
  ],
51
  "definitions": {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  "events": {
53
  "session_start": {
54
  "audit_params": [
config/traffic.json CHANGED
@@ -18,7 +18,13 @@
18
  "run_if_wpcli": false,
19
  "order": 110
20
  },
21
- "menus": {
 
 
 
 
 
 
22
  "config_menu_priority": 35
23
  },
24
  "wpcli": {
18
  "run_if_wpcli": false,
19
  "order": 110
20
  },
21
+ "reqs": {
22
+ "dbs": [
23
+ "ips",
24
+ "req_logs"
25
+ ]
26
+ },
27
+ "menus": {
28
  "config_menu_priority": 35
29
  },
30
  "wpcli": {
config/user_management.json CHANGED
@@ -398,13 +398,6 @@
398
  "name": "Auto-Suspend Idle Users",
399
  "summary": "Automatically Suspend Idle User Accounts",
400
  "description": "Prevent login by idle users and require password reset to unsuspend."
401
- },
402
- {
403
- "key": "autoadd_sessions_started_at",
404
- "section": "section_non_ui",
405
- "type": "integer",
406
- "default": 0,
407
- "transferable": false
408
  }
409
  ],
410
  "definitions": {
398
  "name": "Auto-Suspend Idle Users",
399
  "summary": "Automatically Suspend Idle User Accounts",
400
  "description": "Prevent login by idle users and require password reset to unsuspend."
 
 
 
 
 
 
 
401
  }
402
  ],
403
  "definitions": {
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: 15.0.13
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: 15.1.0
7
  * Text Domain: wp-simple-firewall
8
  * Domain Path: /languages
9
  * Author: Shield Security
init.php CHANGED
@@ -28,8 +28,11 @@ class ICWP_WPSF_Shield_Security {
28
  $this->con = $controller;
29
  }
30
 
 
 
 
31
  public function start() {
32
- $this->con->loadAllFeatures();
33
  }
34
 
35
  /**
28
  $this->con = $controller;
29
  }
30
 
31
+ /**
32
+ * @throws Exception
33
+ */
34
  public function start() {
35
+ $this->con->boot();
36
  }
37
 
38
  /**
plugin-spec.php CHANGED
@@ -1,12 +1,10 @@
1
  {
2
  "properties": {
3
- "version": "15.0.13",
4
- "release_timestamp": 1652947091,
5
- "build": "202205.1901",
6
  "slug_parent": "icwp",
7
  "slug_plugin": "wpsf",
8
- "human_name": "Shield Security",
9
- "menu_title": "Shield",
10
  "text_domain": "wp-simple-firewall",
11
  "base_permissions": "manage_options",
12
  "wpms_network_admin_only": true,
@@ -423,23 +421,23 @@
423
  },
424
  "menu": {
425
  "show": true,
426
- "title": "Shield Security",
427
  "top_level": true,
428
  "do_submenu_fix": true,
429
- "icon_image": "pluginlogo_16x16.png",
430
  "has_submenu": true
431
  },
432
  "labels": {
433
- "Name": "Shield Security",
434
- "Description": "Ultimate WP Security Protection - Scans, 2FA, Firewall, SPAM, Activity Log, Security Admin, and so much more.",
435
- "Title": "Shield Security",
436
- "Author": "Shield Security",
437
- "AuthorName": "Shield Security",
438
- "PluginURI": "https://shsec.io/2f",
439
- "AuthorURI": "https://shsec.io/bv",
440
- "icon_url_16x16": "pluginlogo_16x16.png",
441
- "icon_url_32x32": "pluginlogo_32x32.png",
442
- "icon_url_128x128": "pluginlogo_128x128.png"
 
 
443
  },
444
  "meta": {
445
  "url_repo_home": "https://shsec.io/eh",
1
  {
2
  "properties": {
3
+ "version": "15.1.0",
4
+ "release_timestamp": 1654505519,
5
+ "build": "202206.0601",
6
  "slug_parent": "icwp",
7
  "slug_plugin": "wpsf",
 
 
8
  "text_domain": "wp-simple-firewall",
9
  "base_permissions": "manage_options",
10
  "wpms_network_admin_only": true,
421
  },
422
  "menu": {
423
  "show": true,
 
424
  "top_level": true,
425
  "do_submenu_fix": true,
 
426
  "has_submenu": true
427
  },
428
  "labels": {
429
+ "Name": "Shield Security",
430
+ "MenuTitle": "Shield Security",
431
+ "Description": "Ultimate WP Security Protection - Scans, 2FA, Firewall, SPAM, Activity Log, Security Admin, and so much more.",
432
+ "Title": "Shield Security",
433
+ "Author": "Shield Security",
434
+ "AuthorName": "Shield Security",
435
+ "PluginURI": "https://shsec.io/2f",
436
+ "AuthorURI": "https://shsec.io/bv",
437
+ "url_img_pagebanner": "pluginlogo_banner-1544x500.png",
438
+ "icon_url_16x16": "pluginlogo_16x16.png",
439
+ "icon_url_32x32": "pluginlogo_32x32.png",
440
+ "icon_url_128x128": "pluginlogo_128x128.png"
441
  },
442
  "meta": {
443
  "url_repo_home": "https://shsec.io/eh",
plugin.json CHANGED
@@ -1,12 +1,10 @@
1
  {
2
  "properties": {
3
- "version": "15.0.13",
4
- "release_timestamp": 1652947091,
5
- "build": "202205.1901",
6
  "slug_parent": "icwp",
7
  "slug_plugin": "wpsf",
8
- "human_name": "Shield Security",
9
- "menu_title": "Shield",
10
  "text_domain": "wp-simple-firewall",
11
  "base_permissions": "manage_options",
12
  "wpms_network_admin_only": true,
@@ -423,23 +421,23 @@
423
  },
424
  "menu": {
425
  "show": true,
426
- "title": "Shield Security",
427
  "top_level": true,
428
  "do_submenu_fix": true,
429
- "icon_image": "pluginlogo_16x16.png",
430
  "has_submenu": true
431
  },
432
  "labels": {
433
- "Name": "Shield Security",
434
- "Description": "Ultimate WP Security Protection - Scans, 2FA, Firewall, SPAM, Activity Log, Security Admin, and so much more.",
435
- "Title": "Shield Security",
436
- "Author": "Shield Security",
437
- "AuthorName": "Shield Security",
438
- "PluginURI": "https://shsec.io/2f",
439
- "AuthorURI": "https://shsec.io/bv",
440
- "icon_url_16x16": "pluginlogo_16x16.png",
441
- "icon_url_32x32": "pluginlogo_32x32.png",
442
- "icon_url_128x128": "pluginlogo_128x128.png"
 
 
443
  },
444
  "meta": {
445
  "url_repo_home": "https://shsec.io/eh",
1
  {
2
  "properties": {
3
+ "version": "15.1.0",
4
+ "release_timestamp": 1654505519,
5
+ "build": "202206.0601",
6
  "slug_parent": "icwp",
7
  "slug_plugin": "wpsf",
 
 
8
  "text_domain": "wp-simple-firewall",
9
  "base_permissions": "manage_options",
10
  "wpms_network_admin_only": true,
421
  },
422
  "menu": {
423
  "show": true,
 
424
  "top_level": true,
425
  "do_submenu_fix": true,
 
426
  "has_submenu": true
427
  },
428
  "labels": {
429
+ "Name": "Shield Security",
430
+ "MenuTitle": "Shield Security",
431
+ "Description": "Ultimate WP Security Protection - Scans, 2FA, Firewall, SPAM, Activity Log, Security Admin, and so much more.",
432
+ "Title": "Shield Security",
433
+ "Author": "Shield Security",
434
+ "AuthorName": "Shield Security",
435
+ "PluginURI": "https://shsec.io/2f",
436
+ "AuthorURI": "https://shsec.io/bv",
437
+ "url_img_pagebanner": "pluginlogo_banner-1544x500.png",
438
+ "icon_url_16x16": "pluginlogo_16x16.png",
439
+ "icon_url_32x32": "pluginlogo_32x32.png",
440
+ "icon_url_128x128": "pluginlogo_128x128.png"
441
  },
442
  "meta": {
443
  "url_repo_home": "https://shsec.io/eh",
readme.txt CHANGED
@@ -8,9 +8,9 @@ Requires at least: 3.7
8
  Requires PHP: 7.0
9
  Recommended PHP: 7.4
10
  Tested up to: 6.0
11
- Stable tag: 15.0.13
12
 
13
- Bad Bots Are Your #1 Security Risk. Malware is a symptom of poor security, not its cause. Discover the advantage of powerful security over marketing.
14
 
15
  == Description ==
16
 
8
  Requires PHP: 7.0
9
  Recommended PHP: 7.4
10
  Tested up to: 6.0
11
+ Stable tag: 15.1.0
12
 
13
+ Bad Bots Are Your #1 Security Risk. Malware is a symptom of poor security, not the cause. Discover the advantage of powerful security over marketing.
14
 
15
  == Description ==
16
 
resources/images/{shield/shield-security-1544x500.png → pluginlogo_banner-1544x500.png} RENAMED
File without changes
resources/js/global-plugin.js CHANGED
@@ -1,3 +1,6 @@
 
 
 
1
  var iCWP_WPSF_JSErrorTrack = new function () {
2
  var bHasError = false;
3
  this.initialise = function () {
@@ -304,12 +307,42 @@ var iCWP_WPSF_BodyOverlay = new function () {
304
 
305
  }();
306
 
307
- jQuery( document ).ready( function () {
308
- iCWP_WPSF_BodyOverlay.initialise();
309
 
310
- if ( typeof icwp_wpsf_vars_globalplugin !== 'undefined' ) {
311
- if ( typeof icwp_wpsf_vars_globalplugin.vars.dashboard_widget !== 'undefined' ) {
312
- Shield_WP_Dashboard_Widget.initialise( icwp_wpsf_vars_globalplugin.vars.dashboard_widget );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
313
  }
314
- }
315
- } );
 
1
+ /**
2
+ * @var ajaxurl string
3
+ */
4
  var iCWP_WPSF_JSErrorTrack = new function () {
5
  var bHasError = false;
6
  this.initialise = function () {
307
 
308
  }();
309
 
310
+ (function ( $ ) {
 
311
 
312
+ let Shield_WP_Admin_notices = new function () {
313
+ let self = this;
314
+ let data;
315
+ this.fireNoticeReq = function ( notice_action ) {
316
+ iCWP_WPSF_StandardAjax.send_ajax_req( data.ajax[ notice_action ] );
317
+ };
318
+
319
+ this.initialise = function ( workingData ) {
320
+ data = workingData;
321
+
322
+ $( document ).on( 'click', 'a.shield_admin_notice_action', function ( evt ) {
323
+ evt.preventDefault();
324
+ self.fireNoticeReq( $( evt.currentTarget ).data( 'notice_action' ) );
325
+ return false;
326
+ } );
327
+ };
328
+ }();
329
+
330
+ $( document ).ready( function () {
331
+ iCWP_WPSF_BodyOverlay.initialise();
332
+
333
+ if ( typeof icwp_wpsf_vars_globalplugin !== 'undefined' ) {
334
+
335
+ let globalVars = icwp_wpsf_vars_globalplugin;
336
+
337
+ /** Dashboard Widget **/
338
+ if ( typeof globalVars.vars.dashboard_widget !== 'undefined' ) {
339
+ Shield_WP_Dashboard_Widget.initialise( globalVars.vars.dashboard_widget );
340
+ }
341
+
342
+ if ( typeof globalVars.vars.notices !== 'undefined' ) {
343
+ Shield_WP_Admin_notices.initialise( globalVars.vars.notices );
344
+ }
345
  }
346
+
347
+ } );
348
+ })( jQuery );
resources/js/shield/notbot.js CHANGED
@@ -8,7 +8,7 @@ if ( typeof Shield_Antibot === typeof undefined && typeof shield_vars_notbotjs !
8
  let can_send_request = true;
9
  let nonce_cook = '';
10
  let ajaxurl = shield_vars_notbotjs.ajax.not_bot.ajaxurl;
11
- let use_fetch = false;
12
 
13
  this.initialise = function () {
14
  /**
@@ -30,8 +30,7 @@ if ( typeof Shield_Antibot === typeof undefined && typeof shield_vars_notbotjs !
30
  };
31
 
32
  /**
33
- * @since 12.0.10 - rather than auto send request every page load, check for cookie repeatedly and send if
34
- * absent.
35
  */
36
  let fire = function () {
37
  if ( can_send_request && request_count < 10 ) {
@@ -50,7 +49,7 @@ if ( typeof Shield_Antibot === typeof undefined && typeof shield_vars_notbotjs !
50
  request_count++;
51
 
52
  if ( use_fetch ) {
53
- return sendReqWithFetch();
54
  }
55
 
56
  let xhr = new XMLHttpRequest();
@@ -80,9 +79,9 @@ if ( typeof Shield_Antibot === typeof undefined && typeof shield_vars_notbotjs !
80
  xhr.send( (new URLSearchParams( shield_vars_notbotjs.ajax.not_bot )).toString() );
81
  };
82
 
83
- async function sendReqWithFetch() {
84
  try {
85
- let resp = await fetch( ajaxurl, {
86
  method: 'POST',
87
  body: (new URLSearchParams( shield_vars_notbotjs.ajax.not_bot )).toString(),
88
  headers: {
@@ -90,17 +89,23 @@ if ( typeof Shield_Antibot === typeof undefined && typeof shield_vars_notbotjs !
90
  'X-Requested-With': 'XMLHttpRequest',
91
  }
92
  } )
 
93
  .then( response => response.json() )
 
 
 
 
 
 
 
 
 
 
 
94
  .catch( error => {
95
  console.log( error );
96
  use_fetch = false;
97
  } );
98
- if ( resp ) {
99
- can_send_request = resp && resp.success;
100
- }
101
- else {
102
- use_fetch = false;
103
- }
104
  }
105
  catch ( error ) {
106
  use_fetch = false;
8
  let can_send_request = true;
9
  let nonce_cook = '';
10
  let ajaxurl = shield_vars_notbotjs.ajax.not_bot.ajaxurl;
11
+ let use_fetch = typeof fetch !== typeof undefined;
12
 
13
  this.initialise = function () {
14
  /**
30
  };
31
 
32
  /**
33
+ * @since 12.0.10 - rather than auto send each page load, check for cookie repeatedly and send if absent.
 
34
  */
35
  let fire = function () {
36
  if ( can_send_request && request_count < 10 ) {
49
  request_count++;
50
 
51
  if ( use_fetch ) {
52
+ return notBotSendReqWithFetch();
53
  }
54
 
55
  let xhr = new XMLHttpRequest();
79
  xhr.send( (new URLSearchParams( shield_vars_notbotjs.ajax.not_bot )).toString() );
80
  };
81
 
82
+ async function notBotSendReqWithFetch() {
83
  try {
84
+ fetch( ajaxurl, {
85
  method: 'POST',
86
  body: (new URLSearchParams( shield_vars_notbotjs.ajax.not_bot )).toString(),
87
  headers: {
89
  'X-Requested-With': 'XMLHttpRequest',
90
  }
91
  } )
92
+
93
  .then( response => response.json() )
94
+
95
+ .then( response_data => {
96
+ if ( response_data ) {
97
+ can_send_request = response_data && response_data.success;
98
+ }
99
+ else {
100
+ use_fetch = false;
101
+ }
102
+ return response_data;
103
+ } )
104
+
105
  .catch( error => {
106
  console.log( error );
107
  use_fetch = false;
108
  } );
 
 
 
 
 
 
109
  }
110
  catch ( error ) {
111
  use_fetch = false;
src/lib/src/Controller/Admin/MainAdminMenu.php CHANGED
@@ -30,14 +30,18 @@ class MainAdminMenu {
30
  $menu = $con->cfg->menu;
31
  if ( $menu[ 'top_level' ] ) {
32
 
33
- $labels = $con->getLabels();
34
- $menuTitle = empty( $labels[ 'MenuTitle' ] ) ? $menu[ 'title' ] : $labels[ 'MenuTitle' ];
35
- if ( is_null( $menuTitle ) ) {
36
- $menuTitle = $con->getHumanName();
 
 
 
 
 
 
 
37
  }
38
-
39
- $menuIcon = $con->urls->forImage( $menu[ 'icon_image' ] );
40
- $iconUrl = empty( $labels[ 'icon_url_16x16' ] ) ? $menuIcon : $labels[ 'icon_url_16x16' ];
41
 
42
  $parentMenuID = $con->getPluginPrefix();
43
  add_menu_page(
30
  $menu = $con->cfg->menu;
31
  if ( $menu[ 'top_level' ] ) {
32
 
33
+ if ( empty( $con->labels ) ) {
34
+ $labels = $con->getLabels();
35
+ $menuTitle = empty( $labels[ 'MenuTitle' ] ) ? $menu[ 'title' ] : $labels[ 'MenuTitle' ];
36
+ if ( is_null( $menuTitle ) ) {
37
+ $menuTitle = $con->getHumanName();
38
+ }
39
+ $iconUrl = $labels[ 'icon_url_16x16' ];
40
+ }
41
+ else {
42
+ $menuTitle = $con->labels->MenuTitle;
43
+ $iconUrl = $con->labels->icon_url_16x16;
44
  }
 
 
 
45
 
46
  $parentMenuID = $con->getPluginPrefix();
47
  add_menu_page(
src/lib/src/Controller/Ajax/Init.php CHANGED
@@ -71,7 +71,7 @@ class Init {
71
  [
72
  'success' => false,
73
  'page_reload' => false,
74
- 'message' => 'Unknown',
75
  'html' => '',
76
  ],
77
  $ajaxResponse
71
  [
72
  'success' => false,
73
  'page_reload' => false,
74
+ 'message' => 'No AJAX Message provided',
75
  'html' => '',
76
  ],
77
  $ajaxResponse
src/lib/src/Controller/Checks/PreModulesBootCheck.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Controller\Checks;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\PluginControllerConsumer;
6
+
7
+ /**
8
+ * All Plugin Modules have been created at this stage.
9
+ * We now run some pre-checks to ensure we're ok to do full modules boot.
10
+ */
11
+ class PreModulesBootCheck {
12
+
13
+ use PluginControllerConsumer;
14
+
15
+ public function run( bool $ensureFreshResults = false ) :array {
16
+ $con = $this->getCon();
17
+
18
+ $checks = [
19
+ 'dbs' => [
20
+ ]
21
+ ];
22
+
23
+ foreach ( $con->modules as $mod ) {
24
+ try {
25
+ foreach ( $mod->getDbHandler()->loadAllDbHandlers( $ensureFreshResults ) as $dbh ) {
26
+ $checks[ 'dbs' ][ $dbh->getTableSchema()->slug ] = $dbh->isReady();
27
+ }
28
+ }
29
+ catch ( \Exception $e ) {
30
+ }
31
+ }
32
+
33
+ return $checks;
34
+ }
35
+ }
src/lib/src/Controller/Config/ConfigVO.php CHANGED
@@ -49,7 +49,6 @@ class ConfigVO extends DynPropertiesClass {
49
  'has_submenu' => true,
50
  'title' => 'undefined menu title',
51
  'callback' => 'undefinedMenuCallback',
52
- 'icon_image' => 'pluginlogo_16x16.png',
53
  ],
54
  is_array( $val ) ? $val : []
55
  );
49
  'has_submenu' => true,
50
  'title' => 'undefined menu title',
51
  'callback' => 'undefinedMenuCallback',
 
52
  ],
53
  is_array( $val ) ? $val : []
54
  );
src/lib/src/Controller/Config/Labels.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Controller\Config;
4
+
5
+ use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
6
+
7
+ /**
8
+ * @property string $Name
9
+ * @property string $Description
10
+ * @property string $Title
11
+ * @property string $Author
12
+ * @property string $AuthorName
13
+ * @property string $MenuTitle
14
+ * @property string $PluginURI
15
+ * @property string $AuthorURI
16
+ * @property string $url_secadmin_forgotten_key
17
+ * @property string $url_img_pagebanner
18
+ * @property string $icon_url_16x16
19
+ * @property string $icon_url_32x32
20
+ * @property string $icon_url_128x128
21
+ */
22
+ class Labels extends DynPropertiesClass {
23
+
24
+ }
src/lib/src/Controller/Config/Ops/Save.php DELETED
@@ -1,16 +0,0 @@
1
- <?php declare( strict_types=1 );
2
-
3
- namespace FernleafSystems\Wordpress\Plugin\Shield\Controller\Config\Ops;
4
-
5
- use FernleafSystems\Wordpress\Plugin\Shield\Controller\Config\ConfigVO;
6
- use FernleafSystems\Wordpress\Services\Utilities\Options\Transient;
7
-
8
- /**
9
- * @deprecated 15.0
10
- */
11
- class Save {
12
-
13
- public static function ToWp( ConfigVO $cfg, string $key ) :bool {
14
- return Transient::Set( $key, $cfg->getRawData() );
15
- }
16
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/src/Controller/Controller.php CHANGED
@@ -6,24 +6,28 @@ use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
6
  use FernleafSystems\Wordpress\Plugin\Shield;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Controller\Exceptions;
8
  use FernleafSystems\Wordpress\Plugin\Shield\Controller\Plugin\PluginDeactivate;
 
9
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Config\LoadConfig;
10
  use FernleafSystems\Wordpress\Services\Services;
11
  use FernleafSystems\Wordpress\Services\Utilities\Options\Transient;
12
 
13
  /**
14
- * @property Config\ConfigVO $cfg
15
- * @property Shield\Controller\Assets\Urls $urls
16
- * @property Shield\Controller\Assets\Paths $paths
17
- * @property Shield\Controller\Assets\Svgs $svgs
18
- * @property Shield\Request\ThisRequest $this_req
19
- * @property bool $is_activating
20
- * @property bool $is_mode_debug
21
- * @property bool $is_mode_staging
22
- * @property bool $is_mode_live
23
- * @property bool $is_my_upgrade
24
- * @property bool $is_rest_enabled
25
- * @property bool $modules_loaded
26
- * @property bool $plugin_deactivating
 
 
 
27
  * @property bool $plugin_deleting
28
  * @property bool $plugin_reset
29
  * @property Shield\Utilities\CacheDir $cache_dir_handler
@@ -106,7 +110,6 @@ class Controller extends DynPropertiesClass {
106
  }
107
  $this->loadConfig();
108
  $this->checkMinimumRequirements();
109
- $this->doRegisterHooks();
110
 
111
  ( new Shield\Controller\I18n\LoadTextDomain() )
112
  ->setCon( $this )
@@ -121,17 +124,24 @@ class Controller extends DynPropertiesClass {
121
 
122
  switch ( $key ) {
123
 
124
- case 'this_req':
 
 
 
 
 
 
 
125
  if ( is_null( $val ) ) {
126
- $val = new Shield\Request\ThisRequest( $this );
127
- $this->this_req = $val;
128
  }
129
  break;
130
 
131
- case 'rules':
132
  if ( is_null( $val ) ) {
133
- $val = ( new Shield\Rules\RulesController() )->setCon( $this );
134
- $this->rules = $val;
135
  }
136
  break;
137
 
@@ -161,25 +171,6 @@ class Controller extends DynPropertiesClass {
161
  }
162
  break;
163
 
164
- case 'urls':
165
- if ( !$val instanceof Shield\Controller\Assets\Urls ) {
166
- $val = ( new Shield\Controller\Assets\Urls() )->setCon( $this );
167
- }
168
- break;
169
-
170
- case 'svgs':
171
- if ( !$val instanceof Shield\Controller\Assets\Svgs ) {
172
- $val = ( new Shield\Controller\Assets\Svgs() )->setCon( $this );
173
- }
174
- break;
175
-
176
- case 'paths':
177
- if ( !$val instanceof Shield\Controller\Assets\Paths ) {
178
- $val = ( new Shield\Controller\Assets\Paths() )->setCon( $this );
179
- $this->paths = $val;
180
- }
181
- break;
182
-
183
  case 'is_mode_debug':
184
  if ( is_null( $val ) ) {
185
  $val = ( new Shield\Controller\Modes\DebugMode() )
@@ -220,6 +211,25 @@ class Controller extends DynPropertiesClass {
220
  }
221
  break;
222
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  case 'reqs_not_met':
224
  if ( !is_array( $val ) ) {
225
  $val = [];
@@ -233,6 +243,7 @@ class Controller extends DynPropertiesClass {
233
  }
234
  break;
235
 
 
236
  default:
237
  break;
238
  }
@@ -333,9 +344,76 @@ class Controller extends DynPropertiesClass {
333
  }
334
 
335
  /**
336
- * @deprecated 15.0
 
 
 
 
 
337
  */
338
- public function adminNoticePluginFailedToLoad() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
  }
340
 
341
  /**
@@ -391,18 +469,15 @@ class Controller extends DynPropertiesClass {
391
  add_action( 'wp_loaded', [ $this, 'onWpLoaded' ], 5 );
392
  add_action( 'admin_init', [ $this, 'onWpAdminInit' ] );
393
 
394
- add_filter( 'all_plugins', [ $this, 'filter_hidePluginFromTableList' ] );
395
  add_filter( 'all_plugins', [ $this, 'doPluginLabels' ] );
396
  add_filter( 'plugin_action_links_'.$this->base_file, [ $this, 'onWpPluginActionLinks' ], 50 );
397
  add_filter( 'plugin_row_meta', [ $this, 'onPluginRowMeta' ], 50, 2 );
398
- add_filter( 'site_transient_update_plugins', [ $this, 'filter_hidePluginUpdatesFromUI' ] );
399
  add_action( 'in_plugin_update_message-'.$this->base_file, [ $this, 'onWpPluginUpdateMessage' ] );
400
  add_filter( 'site_transient_update_plugins', [ $this, 'blockIncompatibleUpdates' ] );
401
  add_filter( 'auto_update_plugin', [ $this, 'onWpAutoUpdate' ], 500, 2 );
402
  add_filter( 'set_site_transient_update_plugins', [ $this, 'setUpdateFirstDetectedAt' ] );
403
 
404
  add_action( 'shutdown', [ $this, 'onWpShutdown' ], PHP_INT_MIN );
405
- add_action( 'wp_logout', [ $this, 'onWpLogout' ] );
406
 
407
  // GDPR
408
  add_filter( 'wp_privacy_personal_data_exporters', [ $this, 'onWpPrivacyRegisterExporter' ] );
@@ -548,7 +623,7 @@ class Controller extends DynPropertiesClass {
548
  /**
549
  * @return Shield\Utilities\AdminNotices\Controller
550
  */
551
- public function getAdminNotices() {
552
  if ( !isset( $this->oNotices ) ) {
553
  if ( $this->getIsPage_PluginAdmin() ) {
554
  remove_all_filters( 'admin_notices' );
@@ -777,22 +852,26 @@ class Controller extends DynPropertiesClass {
777
  * @return array
778
  */
779
  public function doPluginLabels( $plugins ) {
780
- $labels = $this->getLabels();
781
- if ( empty( $labels ) ) {
782
- return $plugins;
783
- }
784
-
785
  $file = $this->base_file;
786
- // For this plugin, overwrite any specified settings
787
- if ( array_key_exists( $file, $plugins ) ) {
788
- foreach ( $labels as $sLabelKey => $sLabel ) {
789
- $plugins[ $file ][ $sLabelKey ] = $sLabel;
790
- }
791
  }
792
-
793
  return $plugins;
794
  }
795
 
 
 
 
 
 
 
 
 
 
 
796
  public function getLabels() :array {
797
 
798
  $labels = array_map(
@@ -811,17 +890,10 @@ class Controller extends DynPropertiesClass {
811
  return $labels;
812
  }
813
 
814
- public function onWpShutdown() {
815
- do_action( $this->prefix( 'pre_plugin_shutdown' ) );
816
- do_action( $this->prefix( 'plugin_shutdown' ) );
817
- $this->saveCurrentPluginControllerOptions();
818
- $this->deleteFlags();
819
- }
820
-
821
  public function onWpLogout() {
822
- if ( $this->hasSessionId() ) {
823
- $this->clearSession();
824
- }
825
  }
826
 
827
  protected function deleteFlags() {
@@ -834,40 +906,7 @@ class Controller extends DynPropertiesClass {
834
  }
835
  }
836
 
837
- /**
838
- * Added to a WordPress filter ('all_plugins') which will remove this particular plugin from the
839
- * list of all plugins based on the "plugin file" name.
840
- * @param array $plugins
841
- * @return array
842
- */
843
- public function filter_hidePluginFromTableList( $plugins ) {
844
- if ( apply_filters( $this->prefix( 'hide_plugin' ), false ) ) {
845
- unset( $plugins[ $this->base_file ] );
846
- }
847
- return $plugins;
848
- }
849
-
850
- /**
851
- * Added to the WordPress filter ('site_transient_update_plugins') in order to remove visibility of updates
852
- * from the WordPress Admin UI.
853
- * In order to ensure that WordPress still checks for plugin updates it will not remove this plugin from
854
- * the list of plugins if DOING_CRON is set to true.
855
- * @param \stdClass $plugins
856
- * @return \stdClass
857
- */
858
- public function filter_hidePluginUpdatesFromUI( $plugins ) {
859
- if ( !Services::WpGeneral()->isCron() && apply_filters( $this->prefix( 'hide_plugin_updates' ), false ) ) {
860
- unset( $plugins->response[ $this->base_file ] );
861
- }
862
- return $plugins;
863
- }
864
-
865
- /**
866
- * @param string $suffix
867
- * @param string $glue
868
- * @return string
869
- */
870
- public function prefix( $suffix = '', $glue = '-' ) {
871
  $prefix = $this->getPluginPrefix( $glue );
872
 
873
  if ( $suffix == $prefix || strpos( $suffix, $prefix.$glue ) === 0 ) { //it already has the full prefix
@@ -884,7 +923,7 @@ class Controller extends DynPropertiesClass {
884
  /**
885
  * @throws \Exception
886
  */
887
- private function loadConfig() :Config\ConfigVO {
888
  try {
889
  $this->cfg = ( new Config\Ops\LoadConfig( $this->getPathPluginSpec( true ), $this->getConfigStoreKey() ) )
890
  ->setCon( $this )
@@ -895,12 +934,8 @@ class Controller extends DynPropertiesClass {
895
  ->setCon( $this )
896
  ->run();
897
  }
898
-
899
  $this->loadModConfigs();
900
-
901
  $this->saveCurrentPluginControllerOptions();
902
-
903
- return $this->cfg;
904
  }
905
 
906
  /**
@@ -1024,8 +1059,7 @@ class Controller extends DynPropertiesClass {
1024
  * @return string
1025
  */
1026
  public function getHumanName() {
1027
- $labels = $this->getLabels();
1028
- return empty( $labels[ 'Name' ] ) ? $this->getCfgProperty( 'human_name' ) : $labels[ 'Name' ];
1029
  }
1030
 
1031
  public function getIsPage_PluginAdmin() :bool {
@@ -1144,11 +1178,6 @@ class Controller extends DynPropertiesClass {
1144
  return 'aptoweb_controller_'.substr( md5( get_class() ), 0, 6 );
1145
  }
1146
 
1147
- public function clearSession() {
1148
- Services::Response()->cookieDelete( $this->getSessionCookieID() );
1149
- self::$sSessionId = null;
1150
- }
1151
-
1152
  public function deleteForceOffFile() {
1153
  if ( $this->this_req->is_force_off && !empty( $this->file_forceoff ) ) {
1154
  Services::WpFs()->deleteFile( $this->file_forceoff );
@@ -1157,130 +1186,17 @@ class Controller extends DynPropertiesClass {
1157
  }
1158
  }
1159
 
1160
- /**
1161
- * @deprecated 15.0
1162
- */
1163
- public function getIfForceOffActive() :bool {
1164
- return (bool)$this->this_req->is_force_off;
1165
- }
1166
-
1167
- /**
1168
- * @return false|string
1169
- * @deprecated 15.0
1170
- */
1171
- protected function getForceOffFilePath() {
1172
- if ( !isset( $this->file_forceoff ) ) {
1173
- $FS = Services::WpFs();
1174
- $file = $FS->findFileInDir( 'forceoff', $this->getRootDir(), false, false );
1175
- $this->file_forceoff = empty( $file ) ? false : $file;
1176
- }
1177
- return $this->file_forceoff;
1178
- }
1179
-
1180
- /**
1181
- * @param bool $setIfNeeded
1182
- * @return string
1183
- */
1184
- public function getSessionId( $setIfNeeded = true ) {
1185
- if ( empty( self::$sSessionId ) ) {
1186
- $req = Services::Request();
1187
- self::$sSessionId = $req->cookie( $this->getSessionCookieID(), '' );
1188
- if ( empty( self::$sSessionId ) && $setIfNeeded ) {
1189
- self::$sSessionId = md5( uniqid( $this->getPluginPrefix() ) );
1190
- $this->setSessionCookie();
1191
- }
1192
- }
1193
- return self::$sSessionId;
1194
- }
1195
-
1196
- public function hasSessionId() :bool {
1197
- return !empty( $this->getSessionId( false ) );
1198
- }
1199
-
1200
- protected function setSessionCookie() {
1201
- Services::Response()->cookieSet(
1202
- $this->getSessionCookieID(),
1203
- $this->getSessionId(),
1204
- Services::Request()->ts() + DAY_IN_SECONDS*30,
1205
- Services::WpGeneral()->getCookiePath(),
1206
- Services::WpGeneral()->getCookieDomain()
1207
- );
1208
- }
1209
-
1210
- private function getSessionCookieID() :string {
1211
- return 'wp-'.$this->getPluginPrefix();
1212
- }
1213
-
1214
- /**
1215
- * We let the \Exception from the core plugin feature to bubble up because it's critical.
1216
- * @return Shield\Modules\Plugin\ModCon
1217
- * @throws \Exception from loadFeatureHandler()
1218
- * @deprecated 15.0
1219
- */
1220
- public function loadCorePluginFeatureHandler() {
1221
- $plugin = $this->modules[ 'plugin' ] ?? null;
1222
- if ( !$plugin instanceof Shield\Modules\Plugin\ModCon ) {
1223
- $this->getModule_Plugin();
1224
- }
1225
- return $this->modules[ 'plugin' ];
1226
- }
1227
-
1228
- /**
1229
- * @throws \Exception
1230
- */
1231
- public function loadAllFeatures() :bool {
1232
-
1233
- foreach ( $this->cfg->mods_cfg as $cfg ) {
1234
- try {
1235
- $this->getModule( $cfg->slug );
1236
- }
1237
- catch ( \Exception $e ) {
1238
- }
1239
- }
1240
-
1241
- $this->modules_loaded = true;
1242
-
1243
- // Upgrade modules
1244
- ( new Shield\Controller\Utilities\Upgrade() )
1245
- ->setCon( $this )
1246
- ->execute();
1247
-
1248
- do_action( $this->prefix( 'modules_loaded' ) );
1249
-
1250
- $this->rules->execute();
1251
-
1252
- if ( !$this->cfg->rebuilt && $this->rules->isRulesEngineReady() ) {
1253
-
1254
- $this->rules->processRules();
1255
-
1256
- foreach ( $this->modules as $module ) {
1257
- $module->onRunProcessors();
1258
- }
1259
-
1260
- // This is where any rules responses will execute (i.e. after processors are run):
1261
- do_action( $this->prefix( 'after_run_processors' ) );
1262
- }
1263
-
1264
- return true;
1265
  }
1266
 
1267
  /**
1268
  * @return Shield\Modules\Base\ModCon|null|mixed
1269
  */
1270
  public function getModule( string $slug ) {
1271
- $mod = $this->modules[ $slug ] ?? null;
1272
- if ( !$mod instanceof Shield\Modules\Base\ModCon ) {
1273
- try {
1274
- if ( empty( $this->cfg->mods_cfg[ $slug ] ) ) {
1275
- throw new \Exception( 'No config available for module: '.$slug );
1276
- }
1277
- $mod = $this->loadFeatureHandler( $this->cfg->mods_cfg[ $slug ] );
1278
- }
1279
- catch ( \Exception $e ) {
1280
- error_log( $e->getMessage() );
1281
- }
1282
- }
1283
- return $mod;
1284
  }
1285
 
1286
  public function getModule_AuditTrail() :Shield\Modules\AuditTrail\ModCon {
@@ -1501,7 +1417,7 @@ class Controller extends DynPropertiesClass {
1501
  try {
1502
  if ( $this->getModule_SecAdmin()->getWhiteLabelController()->isEnabled() ) {
1503
  $name = $this->getHumanName();
1504
- $href = $this->getLabels()[ 'PluginURI' ];
1505
  }
1506
  else {
1507
  $name = $this->cfg->menu[ 'title' ];
@@ -1529,6 +1445,20 @@ class Controller extends DynPropertiesClass {
1529
  return empty( $content ) ? '' : wp_kses_post( wpautop( $content, false ) );
1530
  }
1531
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1532
  private function runTests() {
1533
  die();
1534
  ( new Shield\Tests\VerifyUniqueEvents() )->setCon( $this )->run();
@@ -1538,4 +1468,64 @@ class Controller extends DynPropertiesClass {
1538
  ->run();
1539
  }
1540
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1541
  }
6
  use FernleafSystems\Wordpress\Plugin\Shield;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Controller\Exceptions;
8
  use FernleafSystems\Wordpress\Plugin\Shield\Controller\Plugin\PluginDeactivate;
9
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
10
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Config\LoadConfig;
11
  use FernleafSystems\Wordpress\Services\Services;
12
  use FernleafSystems\Wordpress\Services\Utilities\Options\Transient;
13
 
14
  /**
15
+ * @property Config\ConfigVO $cfg
16
+ * @property Shield\Controller\Assets\Urls $urls
17
+ * @property Shield\Controller\Assets\Paths $paths
18
+ * @property Shield\Controller\Assets\Svgs $svgs
19
+ * @property Shield\Request\ThisRequest $this_req
20
+ * @property Config\Labels $labels
21
+ * @property array $prechecks
22
+ * @property array $flags
23
+ * @property bool $is_activating
24
+ * @property bool $is_mode_debug
25
+ * @property bool $is_mode_staging
26
+ * @property bool $is_mode_live
27
+ * @property bool $is_my_upgrade
28
+ * @property bool $is_rest_enabled
29
+ * @property bool $modules_loaded
30
+ * @property bool $plugin_deactivating
31
  * @property bool $plugin_deleting
32
  * @property bool $plugin_reset
33
  * @property Shield\Utilities\CacheDir $cache_dir_handler
110
  }
111
  $this->loadConfig();
112
  $this->checkMinimumRequirements();
 
113
 
114
  ( new Shield\Controller\I18n\LoadTextDomain() )
115
  ->setCon( $this )
124
 
125
  switch ( $key ) {
126
 
127
+ case 'flags':
128
+ if ( !is_array( $val ) ) {
129
+ $val = [];
130
+ $this->flags = $val;
131
+ }
132
+ break;
133
+
134
+ case 'labels':
135
  if ( is_null( $val ) ) {
136
+ $val = $this->labels();
137
+ $this->labels = $val;
138
  }
139
  break;
140
 
141
+ case 'this_req':
142
  if ( is_null( $val ) ) {
143
+ $val = new Shield\Request\ThisRequest( $this );
144
+ $this->this_req = $val;
145
  }
146
  break;
147
 
171
  }
172
  break;
173
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
  case 'is_mode_debug':
175
  if ( is_null( $val ) ) {
176
  $val = ( new Shield\Controller\Modes\DebugMode() )
211
  }
212
  break;
213
 
214
+ case 'paths':
215
+ if ( !$val instanceof Shield\Controller\Assets\Paths ) {
216
+ $val = ( new Shield\Controller\Assets\Paths() )->setCon( $this );
217
+ $this->paths = $val;
218
+ }
219
+ break;
220
+
221
+ case 'svgs':
222
+ if ( !$val instanceof Shield\Controller\Assets\Svgs ) {
223
+ $val = ( new Shield\Controller\Assets\Svgs() )->setCon( $this );
224
+ }
225
+ break;
226
+
227
+ case 'urls':
228
+ if ( !$val instanceof Shield\Controller\Assets\Urls ) {
229
+ $val = ( new Shield\Controller\Assets\Urls() )->setCon( $this );
230
+ }
231
+ break;
232
+
233
  case 'reqs_not_met':
234
  if ( !is_array( $val ) ) {
235
  $val = [];
243
  }
244
  break;
245
 
246
+ case 'rules':
247
  default:
248
  break;
249
  }
344
  }
345
 
346
  /**
347
+ * This is where everything happens that runs the plugin.
348
+ * 1) Modules are all loaded.
349
+ * 2) Upgrades are run.
350
+ * 3) Rules Engine is initiated
351
+ * 4) If Rules Engine is ready, they're executed and then processors are kicked off.
352
+ * @throws \Exception
353
  */
354
+ public function boot() {
355
+ $this->loadModules();
356
+
357
+ // Upgrade modules
358
+ ( new Shield\Controller\Utilities\Upgrade() )
359
+ ->setCon( $this )
360
+ ->execute();
361
+
362
+ do_action( $this->prefix( 'modules_loaded' ) );
363
+
364
+ $this->rules = ( new Shield\Rules\RulesController() )->setCon( $this );
365
+ $this->rules->execute();
366
+
367
+ if ( !$this->cfg->rebuilt && $this->rules->isRulesEngineReady() ) {
368
+
369
+ $this->rules->processRules();
370
+
371
+ foreach ( $this->modules as $module ) {
372
+ $module->onRunProcessors();
373
+ }
374
+
375
+ $this->labels; // Ensures labels are created.
376
+
377
+ // This is where any rules responses will execute (i.e. after processors are run):
378
+ do_action( $this->prefix( 'after_run_processors' ) );
379
+ }
380
+ }
381
+
382
+ /**
383
+ * @throws \Exception
384
+ */
385
+ private function loadModules() {
386
+ if ( !$this->modules_loaded ) {
387
+
388
+ $this->modules_loaded = true;
389
+
390
+ $modules = $this->modules ?? [];
391
+ foreach ( $this->cfg->mods_cfg as $cfg ) {
392
+
393
+ $slug = $cfg->properties[ 'slug' ];
394
+
395
+ $className = $this->getModulesNamespace().sprintf( '\\%s\\ModCon',
396
+ $cfg->properties[ 'namespace' ] ?? str_replace( ' ', '', ucwords( str_replace( '_', ' ', $slug ) ) ) );
397
+ if ( !class_exists( $className ) ) {
398
+ // All this to prevent fatal errors if the plugin doesn't install/upgrade correctly
399
+ throw new \Exception( sprintf( 'Class for module "%s" is missing', $className ) );
400
+ }
401
+
402
+ $modules[ $slug ] = new $className( $this, $cfg );
403
+ $this->modules = $modules;
404
+ }
405
+
406
+ $this->prechecks = ( new Checks\PreModulesBootCheck() )
407
+ ->setCon( $this )
408
+ ->run();
409
+
410
+ // Register the Controller hooks
411
+ $this->doRegisterHooks();
412
+
413
+ foreach ( $this->modules as $module ) {
414
+ $module->boot();
415
+ }
416
+ }
417
  }
418
 
419
  /**
469
  add_action( 'wp_loaded', [ $this, 'onWpLoaded' ], 5 );
470
  add_action( 'admin_init', [ $this, 'onWpAdminInit' ] );
471
 
 
472
  add_filter( 'all_plugins', [ $this, 'doPluginLabels' ] );
473
  add_filter( 'plugin_action_links_'.$this->base_file, [ $this, 'onWpPluginActionLinks' ], 50 );
474
  add_filter( 'plugin_row_meta', [ $this, 'onPluginRowMeta' ], 50, 2 );
 
475
  add_action( 'in_plugin_update_message-'.$this->base_file, [ $this, 'onWpPluginUpdateMessage' ] );
476
  add_filter( 'site_transient_update_plugins', [ $this, 'blockIncompatibleUpdates' ] );
477
  add_filter( 'auto_update_plugin', [ $this, 'onWpAutoUpdate' ], 500, 2 );
478
  add_filter( 'set_site_transient_update_plugins', [ $this, 'setUpdateFirstDetectedAt' ] );
479
 
480
  add_action( 'shutdown', [ $this, 'onWpShutdown' ], PHP_INT_MIN );
 
481
 
482
  // GDPR
483
  add_filter( 'wp_privacy_personal_data_exporters', [ $this, 'onWpPrivacyRegisterExporter' ] );
623
  /**
624
  * @return Shield\Utilities\AdminNotices\Controller
625
  */
626
+ public function getAdminNotices() :Shield\Utilities\AdminNotices\Controller {
627
  if ( !isset( $this->oNotices ) ) {
628
  if ( $this->getIsPage_PluginAdmin() ) {
629
  remove_all_filters( 'admin_notices' );
852
  * @return array
853
  */
854
  public function doPluginLabels( $plugins ) {
 
 
 
 
 
855
  $file = $this->base_file;
856
+ if ( is_array( $plugins[ $file ] ?? null ) ) {
857
+ $plugins[ $file ] = array_merge(
858
+ $plugins[ $file ],
859
+ empty( $this->labels ) ? $this->getLabels() : $this->labels->getRawData()
860
+ );
861
  }
 
862
  return $plugins;
863
  }
864
 
865
+ public function onWpShutdown() {
866
+ do_action( $this->prefix( 'pre_plugin_shutdown' ) );
867
+ do_action( $this->prefix( 'plugin_shutdown' ) );
868
+ $this->saveCurrentPluginControllerOptions();
869
+ $this->deleteFlags();
870
+ }
871
+
872
+ /**
873
+ * @deprecated 15.1
874
+ */
875
  public function getLabels() :array {
876
 
877
  $labels = array_map(
890
  return $labels;
891
  }
892
 
893
+ /**
894
+ * @deprecated 15.1
895
+ */
 
 
 
 
896
  public function onWpLogout() {
 
 
 
897
  }
898
 
899
  protected function deleteFlags() {
906
  }
907
  }
908
 
909
+ public function prefix( string $suffix = '', string $glue = '-' ) :string {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
910
  $prefix = $this->getPluginPrefix( $glue );
911
 
912
  if ( $suffix == $prefix || strpos( $suffix, $prefix.$glue ) === 0 ) { //it already has the full prefix
923
  /**
924
  * @throws \Exception
925
  */
926
+ private function loadConfig() {
927
  try {
928
  $this->cfg = ( new Config\Ops\LoadConfig( $this->getPathPluginSpec( true ), $this->getConfigStoreKey() ) )
929
  ->setCon( $this )
934
  ->setCon( $this )
935
  ->run();
936
  }
 
937
  $this->loadModConfigs();
 
938
  $this->saveCurrentPluginControllerOptions();
 
 
939
  }
940
 
941
  /**
1059
  * @return string
1060
  */
1061
  public function getHumanName() {
1062
+ return empty( $this->labels ) ? $this->getLabels()[ 'Name' ] : $this->labels->Name;
 
1063
  }
1064
 
1065
  public function getIsPage_PluginAdmin() :bool {
1178
  return 'aptoweb_controller_'.substr( md5( get_class() ), 0, 6 );
1179
  }
1180
 
 
 
 
 
 
1181
  public function deleteForceOffFile() {
1182
  if ( $this->this_req->is_force_off && !empty( $this->file_forceoff ) ) {
1183
  Services::WpFs()->deleteFile( $this->file_forceoff );
1186
  }
1187
  }
1188
 
1189
+ public function setFlag( string $flag, $value ) {
1190
+ $flags = $this->flags;
1191
+ $flags[ $flag ] = $value;
1192
+ $this->flags = $flags;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1193
  }
1194
 
1195
  /**
1196
  * @return Shield\Modules\Base\ModCon|null|mixed
1197
  */
1198
  public function getModule( string $slug ) {
1199
+ return $this->modules[ $slug ] ?? null;
 
 
 
 
 
 
 
 
 
 
 
 
1200
  }
1201
 
1202
  public function getModule_AuditTrail() :Shield\Modules\AuditTrail\ModCon {
1417
  try {
1418
  if ( $this->getModule_SecAdmin()->getWhiteLabelController()->isEnabled() ) {
1419
  $name = $this->getHumanName();
1420
+ $href = $this->labels->PluginURI;
1421
  }
1422
  else {
1423
  $name = $this->cfg->menu[ 'title' ];
1445
  return empty( $content ) ? '' : wp_kses_post( wpautop( $content, false ) );
1446
  }
1447
 
1448
+ private function labels() :Config\Labels {
1449
+ $labels = array_map( 'stripslashes', $this->cfg->labels );
1450
+
1451
+ foreach ( [ 'icon_url_16x16', 'icon_url_32x32', 'icon_url_128x128', 'url_img_pagebanner' ] as $img ) {
1452
+ if ( !empty( $labels[ $img ] ) && !Services::Data()->isValidWebUrl( $labels[ $img ] ) ) {
1453
+ $labels[ $img ] = $this->urls->forImage( $labels[ $img ] );
1454
+ }
1455
+ }
1456
+
1457
+ $labels = ( new Config\Labels() )->applyFromArray( $labels );
1458
+ $labels->url_secadmin_forgotten_key = 'https://shsec.io/gc';
1459
+ return $this->isPremiumActive() ? apply_filters( $this->prefix( 'labels' ), $labels ) : $labels;
1460
+ }
1461
+
1462
  private function runTests() {
1463
  die();
1464
  ( new Shield\Tests\VerifyUniqueEvents() )->setCon( $this )->run();
1468
  ->run();
1469
  }
1470
  }
1471
+
1472
+ /**
1473
+ * @deprecated 15.1
1474
+ */
1475
+ public function clearSession() {
1476
+ }
1477
+
1478
+ /**
1479
+ * @deprecated 15.1
1480
+ */
1481
+ private function getSessionCookieID() :string {
1482
+ return 'wp-null';
1483
+ }
1484
+
1485
+ /**
1486
+ * @param bool $setIfNeeded
1487
+ * @return string
1488
+ * @deprecated 15.1
1489
+ */
1490
+ public function getSessionId() {
1491
+ return '';
1492
+ }
1493
+
1494
+ /**
1495
+ * @deprecated 15.1
1496
+ */
1497
+ public function hasSessionId() :bool {
1498
+ return false;
1499
+ }
1500
+
1501
+ protected function setSessionCookie() {
1502
+ }
1503
+
1504
+ /**
1505
+ * Added to the WordPress filter ('site_transient_update_plugins') in order to remove visibility of updates
1506
+ * from the WordPress Admin UI.
1507
+ * In order to ensure that WordPress still checks for plugin updates it will not remove this plugin from
1508
+ * the list of plugins if DOING_CRON is set to true.
1509
+ * @param \stdClass $plugins
1510
+ * @return \stdClass
1511
+ * @deprecated 15.1
1512
+ */
1513
+ public function filter_hidePluginUpdatesFromUI( $plugins ) {
1514
+ return $plugins;
1515
+ }
1516
+
1517
+ /**
1518
+ * @deprecated 15.1
1519
+ */
1520
+ public function filter_hidePluginFromTableList( $plugins ) {
1521
+ return $plugins;
1522
+ }
1523
+
1524
+ /**
1525
+ * @throws \Exception
1526
+ * @deprecated 15.0
1527
+ */
1528
+ public function loadAllFeatures() :bool {
1529
+ return true;
1530
+ }
1531
  }
src/lib/src/Controller/Utilities/Upgrade.php CHANGED
@@ -31,9 +31,6 @@ class Upgrade {
31
  Services::WpFs()->touch( $con->getPluginCachePath( 'upgrading.flag' ), Services::Request()->ts() );
32
 
33
  $this->upgradeModules();
34
- do_action( $con->prefix( 'plugin_shutdown' ), function () {
35
- $this->deleteOldModConfigs();
36
- } );
37
 
38
  $con->cfg->previous_version = $con->getVersion();
39
 
@@ -42,13 +39,6 @@ class Upgrade {
42
  } );
43
  }
44
 
45
- private function deleteOldModConfigs() {
46
- $DB = Services::WpDb();
47
- $DB->doSql(
48
- sprintf( 'DELETE from `%s` where `option_name` LIKE "shield_mod_config_%%"', $DB->getTable_Options() )
49
- );
50
- }
51
-
52
  private function upgradeModules() {
53
  foreach ( $this->getCon()->modules as $mod ) {
54
  $H = $mod->getUpgradeHandler();
@@ -57,4 +47,10 @@ class Upgrade {
57
  }
58
  }
59
  }
 
 
 
 
 
 
60
  }
31
  Services::WpFs()->touch( $con->getPluginCachePath( 'upgrading.flag' ), Services::Request()->ts() );
32
 
33
  $this->upgradeModules();
 
 
 
34
 
35
  $con->cfg->previous_version = $con->getVersion();
36
 
39
  } );
40
  }
41
 
 
 
 
 
 
 
 
42
  private function upgradeModules() {
43
  foreach ( $this->getCon()->modules as $mod ) {
44
  $H = $mod->getUpgradeHandler();
47
  }
48
  }
49
  }
50
+
51
+ /**
52
+ * @deprecated 15.1
53
+ */
54
+ private function deleteOldModConfigs() {
55
+ }
56
  }
src/lib/src/Crons/StandardCron.php CHANGED
@@ -27,11 +27,10 @@ trait StandardCron {
27
  * @return string
28
  */
29
  protected function getCronRecurrence() {
30
- $sFreq = $this->getCronFrequency();
31
- $aStdIntervals = array_keys( wp_get_schedules() );
32
- return in_array( $sFreq, $aStdIntervals ) ?
33
- $sFreq
34
- : $this->getCon()->prefix( sprintf( 'per-day-%s', $sFreq ) );
35
  }
36
 
37
  /**
27
  * @return string
28
  */
29
  protected function getCronRecurrence() {
30
+ $frequency = $this->getCronFrequency();
31
+ return in_array( $frequency, array_keys( wp_get_schedules() ) ) ?
32
+ $frequency
33
+ : $this->getCon()->prefix( sprintf( 'per-day-%s', $frequency ) );
 
34
  }
35
 
36
  /**
src/lib/src/Databases/Session/Delete.php DELETED
@@ -1,38 +0,0 @@
1
- <?php
2
-
3
- namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\Session;
4
-
5
- use FernleafSystems\Wordpress\Plugin\Shield\Databases\Base;
6
-
7
- class Delete extends Base\Delete {
8
-
9
- /**
10
- * @param int $olderThan
11
- * @return bool
12
- */
13
- public function forExpiredLoginAt( int $olderThan ) {
14
- return $this->reset()
15
- ->addWhereOlderThan( $olderThan, 'logged_in_at' )
16
- ->query();
17
- }
18
-
19
- /**
20
- * @param int $olderThan
21
- * @return bool
22
- */
23
- public function forExpiredLoginIdle( int $olderThan ) {
24
- return $this->reset()
25
- ->addWhereOlderThan( $olderThan, 'last_activity_at' )
26
- ->query();
27
- }
28
-
29
- /**
30
- * @param string $username
31
- * @return false|int
32
- */
33
- public function forUsername( string $username ) {
34
- return $this->reset()
35
- ->addWhereEquals( 'wp_username', $username )
36
- ->query();
37
- }
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/src/Databases/Session/EntryVO.php DELETED
@@ -1,38 +0,0 @@
1
- <?php
2
-
3
- namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\Session;
4
-
5
- use FernleafSystems\Wordpress\Plugin\Shield\Databases\Base;
6
-
7
- /**
8
- * @property string ip
9
- * @property string browser
10
- * @property string wp_username
11
- * @property int last_activity_at
12
- * @property int logged_in_at
13
- * @property string session_id
14
- * @property int secadmin_at
15
- */
16
- class EntryVO extends Base\EntryVO {
17
-
18
- /**
19
- * @return string
20
- */
21
- public function getSessionId() {
22
- return (string)$this->session_id;
23
- }
24
-
25
- /**
26
- * @return int
27
- */
28
- public function getSecAdminAt() {
29
- return (int)$this->secadmin_at;
30
- }
31
-
32
- /**
33
- * @return string
34
- */
35
- public function getUsername() {
36
- return (string)$this->wp_username;
37
- }
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/src/Databases/Session/Handler.php DELETED
@@ -1,18 +0,0 @@
1
- <?php declare( strict_types=1 );
2
-
3
- namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\Session;
4
-
5
- use FernleafSystems\Wordpress\Plugin\Shield\Databases\Base;
6
- use FernleafSystems\Wordpress\Services\Services;
7
-
8
- class Handler extends Base\Handler {
9
-
10
- public function autoCleanDb() {
11
- $this->tableCleanExpired( 30 );
12
- // Remove soft-deleted sessions after 3 days
13
- $this->getQueryDeleter()
14
- ->addWhereNewerThan( 0, 'deleted_at' )
15
- ->addWhereOlderThan( Services::Request()->carbon()->subDays( 5 )->timestamp, 'deleted_at' )
16
- ->query();
17
- }
18
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/src/Databases/Session/Insert.php DELETED
@@ -1,51 +0,0 @@
1
- <?php
2
-
3
- namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\Session;
4
-
5
- use FernleafSystems\Wordpress\Plugin\Shield\Databases\Base;
6
- use FernleafSystems\Wordpress\Services\Services;
7
-
8
- class Insert extends Base\Insert {
9
-
10
- public function create( string $ID, string $username ) :bool {
11
- return $this->setInsertData( [
12
- 'session_id' => $ID,
13
- 'wp_username' => $username,
14
- 'ip' => Services::IP()->getRequestIp()
15
- ] )->query() === 1;
16
- }
17
-
18
- /**
19
- * @return $this
20
- * @throws \Exception
21
- */
22
- protected function verifyInsertData() {
23
- parent::verifyInsertData();
24
-
25
- $data = $this->getInsertData();
26
- if ( empty( $data[ 'session_id' ] ) ) {
27
- throw new \Exception( 'Session ID not provided.' );
28
- }
29
- if ( empty( $data[ 'wp_username' ] ) ) {
30
- throw new \Exception( 'WP Username not provided' );
31
- }
32
-
33
- $srvIP = Services::IP();
34
- if ( empty( $data[ 'ip' ] ) || !$srvIP->isValidIp( $data[ 'ip' ] ) ) {
35
- $reqIP = $srvIP->getRequestIp();
36
- $data[ 'ip' ] = $srvIP->isValidIp( $reqIP ) ? $reqIP: '';
37
- }
38
-
39
- $req = Services::Request();
40
- return $this->setInsertData( array_merge(
41
- [
42
- 'browser' => md5( $req->getUserAgent() ),
43
- 'logged_in_at' => $req->ts(),
44
- 'last_activity_at' => $req->ts(),
45
- 'last_activity_uri' => $req->getUri(),
46
- 'secadmin_at' => 0,
47
- ],
48
- $data
49
- ) );
50
- }
51
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/src/Databases/Session/Select.php DELETED
@@ -1,83 +0,0 @@
1
- <?php
2
-
3
- namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\Session;
4
-
5
- use FernleafSystems\Wordpress\Plugin\Shield\Databases\Base;
6
- use FernleafSystems\Wordpress\Plugin\Shield\Utilities\Tool\IpListSort;
7
- use FernleafSystems\Wordpress\Services\Services;
8
-
9
- class Select extends Base\Select {
10
-
11
- use Base\Traits\Select_IPTable;
12
-
13
- /**
14
- * @return string[]
15
- */
16
- public function getDistinctUsernames() :array {
17
- return $this->getDistinct_FilterAndSort( 'wp_username' );
18
- }
19
-
20
- /**
21
- * @param string $ip
22
- * @return $this
23
- */
24
- public function filterByIp( string $ip ) {
25
- if ( Services::IP()->isValidIp( $ip ) ) {
26
- $this->addWhereEquals( 'ip', trim( $ip ) );
27
- }
28
- return $this;
29
- }
30
-
31
- /**
32
- * @return EntryVO[]|\stdClass[]
33
- */
34
- public function all() {
35
- return $this->selectForUserSession();
36
- }
37
-
38
- /**
39
- * @param int $nExpiredBoundary
40
- * @return $this
41
- */
42
- public function filterByLoginNotExpired( $nExpiredBoundary ) {
43
- return $this->addWhereNewerThan( $nExpiredBoundary, 'logged_in_at' );
44
- }
45
-
46
- /**
47
- * @param int $nExpiredBoundary
48
- * @return $this
49
- */
50
- public function filterByLoginNotIdleExpired( $nExpiredBoundary ) {
51
- return $this->addWhereNewerThan( $nExpiredBoundary, 'last_activity_at' );
52
- }
53
-
54
- public function filterByUsername( string $username ) :self {
55
- return $this->addWhereEquals( 'wp_username', trim( $username ) );
56
- }
57
-
58
- /**
59
- * @param string $ID
60
- * @param string $username
61
- * @return EntryVO|null
62
- */
63
- public function retrieveUserSession( string $ID, $username = '' ) {
64
- $data = $this->selectForUserSession( $ID, $username );
65
- return ( count( $data ) == 1 ) ? array_shift( $data ) : null;
66
- }
67
-
68
- /**
69
- * @param string $ID
70
- * @param string $username
71
- * @return EntryVO[]
72
- */
73
- protected function selectForUserSession( $ID = '', $username = '' ) {
74
- if ( !empty( $username ) ) {
75
- $this->addWhereEquals( 'wp_username', $username );
76
- }
77
- if ( !empty( $ID ) ) {
78
- $this->addWhereEquals( 'session_id', $ID );
79
- }
80
-
81
- return $this->setOrderBy( 'last_activity_at', 'DESC' )->query();
82
- }
83
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/src/Databases/Session/Update.php DELETED
@@ -1,42 +0,0 @@
1
- <?php
2
-
3
- namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\Session;
4
-
5
- use FernleafSystems\Wordpress\Plugin\Shield\Databases\Base;
6
- use FernleafSystems\Wordpress\Services\Services;
7
-
8
- class Update extends Base\Update {
9
-
10
- /**
11
- * @param EntryVO $session
12
- * @return bool
13
- */
14
- public function startSecurityAdmin( EntryVO $session ) {
15
- return $this->updateSession( $session, [ 'secadmin_at' => Services::Request()->ts() ] );
16
- }
17
-
18
- /**
19
- * @param EntryVO $session
20
- * @return bool
21
- */
22
- public function terminateSecurityAdmin( EntryVO $session ) {
23
- return $this->updateSession( $session, [ 'secadmin_at' => 0 ] );
24
- }
25
-
26
- /**
27
- * @param EntryVO $session
28
- * @return bool
29
- */
30
- public function updateLastActivity( $session ) {
31
- return true;
32
- }
33
-
34
- /**
35
- * @param EntryVO $session
36
- * @param array $updateData
37
- * @return bool
38
- */
39
- public function updateSession( $session, $updateData = [] ) {
40
- return parent::updateEntry( $session, $updateData );
41
- }
42
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/src/Modules/Base/AdminNotices.php CHANGED
@@ -18,15 +18,6 @@ class AdminNotices extends Shield\Modules\Base\Common\ExecOnceModConsumer {
18
  return $this->buildNotices();
19
  }
20
 
21
- /**
22
- * @param Shield\Utilities\AdminNotices\NoticeVO[] $notices
23
- * @return Shield\Utilities\AdminNotices\NoticeVO[]
24
- * @deprecated 15.0
25
- */
26
- public function addNotices( $notices ) {
27
- return array_merge( $notices, $this->buildNotices() );
28
- }
29
-
30
  /**
31
  * @return Shield\Utilities\AdminNotices\NoticeVO[]
32
  */
18
  return $this->buildNotices();
19
  }
20
 
 
 
 
 
 
 
 
 
 
21
  /**
22
  * @return Shield\Utilities\AdminNotices\NoticeVO[]
23
  */
src/lib/src/Modules/Base/AdminPage.php CHANGED
@@ -100,24 +100,10 @@ class AdminPage extends ExecOnceModConsumer {
100
  );
101
  }
102
 
103
- /**
104
- * @deprecated 15.0
105
- */
106
- protected function getMenuPriority() :int {
107
- return $this->getMod()->cfg->properties[ 'menu_priority' ] ?? 100;
108
- }
109
-
110
  public function getCap() :string {
111
  return $this->getCon()->getBasePermissions();
112
  }
113
 
114
- /**
115
- * @deprecated 15.0
116
- */
117
- public function isShowMenu() :bool {
118
- return $this->getMod()->cfg->properties[ 'show_module_menu_item' ] ?? false;
119
- }
120
-
121
  public function isCurrentPage() :bool {
122
  $req = Services::Request();
123
  return !Services::WpGeneral()->isAjax() && $req->isGet()
100
  );
101
  }
102
 
 
 
 
 
 
 
 
103
  public function getCap() :string {
104
  return $this->getCon()->getBasePermissions();
105
  }
106
 
 
 
 
 
 
 
 
107
  public function isCurrentPage() :bool {
108
  $req = Services::Request();
109
  return !Services::WpGeneral()->isAjax() && $req->isGet()
src/lib/src/Modules/Base/Config/LoadConfig.php CHANGED
@@ -30,13 +30,6 @@ class LoadConfig {
30
  return empty( $this->configSourceFile ) ? $this->getPathCfg() : $this->configSourceFile;
31
  }
32
 
33
- /**
34
- * @deprecated 15.0
35
- */
36
- public function isBuiltFromFile() :bool {
37
- return $this->isBuiltFromFile;
38
- }
39
-
40
  /**
41
  * @throws \Exception
42
  */
@@ -50,24 +43,6 @@ class LoadConfig {
50
  return $rebuild ? ( new ModConfigVO() )->applyFromArray( $this->fromFile() ) : $this->cfg;
51
  }
52
 
53
- /**
54
- * @throws \Exception
55
- * @deprecated 15.0
56
- */
57
- public function fromWP() :array {
58
- $FS = Services::WpFs();
59
- $cfg = Transient::Get( $this->storeKey() );
60
-
61
- if ( empty( $cfg ) || !is_array( $cfg ) || ( $FS->getModifiedTime( $this->getConfigSourceFile() ) > $cfg[ 'meta' ][ 'ts_mod' ] ) ) {
62
- throw new \Exception( 'WP store is expired or non-existent' );
63
- }
64
- return $cfg;
65
- }
66
-
67
- public function storeKey() :string {
68
- return 'shield_mod_config_'.$this->slug;
69
- }
70
-
71
  /**
72
  * @throws \Exception
73
  */
30
  return empty( $this->configSourceFile ) ? $this->getPathCfg() : $this->configSourceFile;
31
  }
32
 
 
 
 
 
 
 
 
33
  /**
34
  * @throws \Exception
35
  */
43
  return $rebuild ? ( new ModConfigVO() )->applyFromArray( $this->fromFile() ) : $this->cfg;
44
  }
45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  /**
47
  * @throws \Exception
48
  */
src/lib/src/Modules/Base/Config/ModConfigVO.php CHANGED
@@ -6,6 +6,7 @@ use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
6
 
7
  /**
8
  * @property array $properties
 
9
  * @property array $menus
10
  * @property array $meta
11
  * @property array $options
@@ -15,4 +16,26 @@ use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
15
  */
16
  class ModConfigVO extends DynPropertiesClass {
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  }
6
 
7
  /**
8
  * @property array $properties
9
+ * @property array $reqs
10
  * @property array $menus
11
  * @property array $meta
12
  * @property array $options
16
  */
17
  class ModConfigVO extends DynPropertiesClass {
18
 
19
+ /**
20
+ * @inheritDoc
21
+ */
22
+ public function __get( string $key ) {
23
+
24
+ $value = parent::__get( $key );
25
+
26
+ switch ( $key ) {
27
+ case 'reqs':
28
+ $value = array_merge(
29
+ [
30
+ 'dbs' => [],
31
+ ],
32
+ is_array( $value ) ? $value : []
33
+ );
34
+ break;
35
+ default:
36
+ break;
37
+ }
38
+
39
+ return $value;
40
+ }
41
  }
src/lib/src/Modules/Base/Databases.php CHANGED
@@ -23,9 +23,9 @@ class Databases {
23
  * @return Core\Databases\Base\Handler[]
24
  * @throws \Exception
25
  */
26
- public function loadAllDbHandlers() :array {
27
  foreach ( array_keys( $this->getDbHandlerClasses() ) as $dbKey ) {
28
- $this->loadDbH( $dbKey );
29
  }
30
  return $this->dbHandlers;
31
  }
@@ -34,10 +34,10 @@ class Databases {
34
  * @return Core\Databases\Base\Handler|mixed|null
35
  * @throws \Exception
36
  */
37
- public function loadDbH( string $dbKey ) {
38
  $dbh = $this->dbHandlers[ $dbKey ] ?? null;
39
 
40
- if ( empty( $dbh ) ) {
41
 
42
  $dbDef = $this->getOptions()->getDef( 'db_table_'.$dbKey );
43
  if ( empty( $dbDef ) ) {
@@ -57,6 +57,9 @@ class Databases {
57
  $dbDef[ 'table_prefix' ] = $this->getCon()->getPluginPrefix( '_' );
58
  /** @var Core\Databases\Base\Handler|mixed $dbh */
59
  $dbh = new $dbClass( $dbDef );
 
 
 
60
  $dbh->execute();
61
 
62
  $this->dbHandlers[ $dbKey ] = $dbh;
23
  * @return Core\Databases\Base\Handler[]
24
  * @throws \Exception
25
  */
26
+ public function loadAllDbHandlers( bool $reload = false ) :array {
27
  foreach ( array_keys( $this->getDbHandlerClasses() ) as $dbKey ) {
28
+ $this->loadDbH( $dbKey, $reload );
29
  }
30
  return $this->dbHandlers;
31
  }
34
  * @return Core\Databases\Base\Handler|mixed|null
35
  * @throws \Exception
36
  */
37
+ public function loadDbH( string $dbKey, bool $reload = false ) {
38
  $dbh = $this->dbHandlers[ $dbKey ] ?? null;
39
 
40
+ if ( $reload || empty( $dbh ) ) {
41
 
42
  $dbDef = $this->getOptions()->getDef( 'db_table_'.$dbKey );
43
  if ( empty( $dbDef ) ) {
57
  $dbDef[ 'table_prefix' ] = $this->getCon()->getPluginPrefix( '_' );
58
  /** @var Core\Databases\Base\Handler|mixed $dbh */
59
  $dbh = new $dbClass( $dbDef );
60
+ if ( $this->getCon()->flags[ 'db_bypass_ready_check_cache' ] ?? false ) {
61
+ $dbh->bypassReadyCheckCache();
62
+ }
63
  $dbh->execute();
64
 
65
  $this->dbHandlers[ $dbKey ] = $dbh;
src/lib/src/Modules/Base/Lib/CheckModuleRequirements.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Lib;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Shield;
6
+
7
+ class CheckModuleRequirements {
8
+
9
+ use Shield\Modules\ModConsumer;
10
+
11
+ /**
12
+ * @throws \Exception
13
+ */
14
+ public function run() :bool {
15
+ $preChecks = $this->getCon()->prechecks;
16
+ $modReqs = $this->getMod()->cfg->reqs;
17
+
18
+ $modChecks = [
19
+ // all DBs that this mod requires but that aren't ready.
20
+ 'dbs' => array_filter(
21
+ array_intersect_key( $preChecks[ 'dbs' ], array_flip( $modReqs[ 'dbs' ] ) ),
22
+ function ( $dbState ) {
23
+ return $dbState === false;
24
+ }
25
+ )
26
+ ];
27
+
28
+ // We're ready to run if all our DBs are ready.
29
+ return empty( $modChecks[ 'dbs' ] );
30
+ }
31
+ }
src/lib/src/Modules/Base/ModCon.php CHANGED
@@ -2,13 +2,15 @@
2
 
3
  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\Plugin\Shield\Modules\Base\Lib\Request\FormParams;
8
- use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Options\RenderOptionsForm;
9
  use FernleafSystems\Wordpress\Services\Services;
10
 
11
- abstract class ModCon {
 
 
 
12
 
13
  use Modules\PluginControllerConsumer;
14
  use Shield\Crons\PluginCronsConsumer;
@@ -74,18 +76,35 @@ abstract class ModCon {
74
  private $adminNotices;
75
 
76
  /**
77
- * @param Shield\Controller\Controller $pluginCon
78
- * @param Config\ModConfigVO $cfg
79
  * @throws \Exception
80
  */
81
  public function __construct( Shield\Controller\Controller $pluginCon, Config\ModConfigVO $cfg ) {
82
  $this->setCon( $pluginCon );
83
  $this->cfg = $cfg;
84
- if ( $this->verifyModuleMeetRequirements() ) {
 
 
 
 
 
 
 
85
  $this->handleAutoPageRedirects();
86
- $this->setupHooks();
87
  $this->doPostConstruction();
 
 
 
 
 
 
 
 
 
88
  }
 
 
 
 
89
  }
90
 
91
  protected function setupHooks() {
@@ -96,7 +115,7 @@ abstract class ModCon {
96
  } );
97
 
98
  add_action( 'init', [ $this, 'onWpInit' ], 1 );
99
- add_action( 'init', [ $this, 'onWpLoaded' ] );
100
 
101
  add_action( $con->prefix( 'plugin_shutdown' ), [ $this, 'onPluginShutdown' ] );
102
  add_action( $con->prefix( 'deactivate_plugin' ), [ $this, 'onPluginDeactivate' ] );
@@ -211,31 +230,6 @@ abstract class ModCon {
211
  return $this->loadModElement( 'Upgrade' );
212
  }
213
 
214
- private function verifyModuleMeetRequirements() :bool {
215
- $meetReqs = true;
216
-
217
- $reqPHP = $this->getOptions()->getFeatureRequirement( 'php' );
218
- if ( !empty( $reqPHP ) ) {
219
-
220
- if ( !empty( $reqPHP[ 'version' ] ) ) {
221
- $meetReqs = Services::Data()->getPhpVersionIsAtLeast( $reqPHP[ 'version' ] );
222
- }
223
-
224
- if ( !empty( $reqPHP[ 'functions' ] ) && is_array( $reqPHP[ 'functions' ] ) ) {
225
- foreach ( $reqPHP[ 'functions' ] as $func ) {
226
- $meetReqs = $meetReqs && function_exists( $func );
227
- }
228
- }
229
- if ( !empty( $reqPHP[ 'constants' ] ) && is_array( $reqPHP[ 'constants' ] ) ) {
230
- foreach ( $reqPHP[ 'constants' ] as $constant ) {
231
- $meetReqs = $meetReqs && defined( $constant );
232
- }
233
- }
234
- }
235
-
236
- return $meetReqs;
237
- }
238
-
239
  protected function onModulesLoaded() {
240
  }
241
 
@@ -388,13 +382,6 @@ abstract class ModCon {
388
  );
389
  }
390
 
391
- /**
392
- * @deprecated 15.0
393
- */
394
- public function isUpgrading() :bool {
395
- return $this->getCon()->cfg->rebuilt;
396
- }
397
-
398
  /**
399
  * Hooked to the plugin's main plugin_shutdown action
400
  */
@@ -522,7 +509,10 @@ abstract class ModCon {
522
  /** @var Shield\Modules\Plugin\Options $pluginOpts */
523
  $pluginOpts = $this->getCon()->getModule_Plugin()->getOptions();
524
 
525
- if ( $this->cfg->properties[ 'auto_enabled' ] ) {
 
 
 
526
  // Auto enabled modules always run regardless
527
  $enabled = true;
528
  }
@@ -573,8 +563,8 @@ abstract class ModCon {
573
  $cfg = $this->getOptions()->getRawData_FullFeatureConfig();
574
  if ( !empty( $cfg[ 'custom_redirects' ] ) && $this->getCon()->isValidAdminArea() ) {
575
  foreach ( $cfg[ 'custom_redirects' ] as $redirect ) {
576
- if ( Services::Request()->query( 'page' ) == $this->getCon()
577
- ->prefix( $redirect[ 'source_mod_page' ] ) ) {
578
  Services::Response()->redirect(
579
  $this->getCon()->getModule( $redirect[ 'target_mod_page' ] )->getUrl_AdminPage(),
580
  $redirect[ 'query_args' ],
@@ -590,13 +580,6 @@ abstract class ModCon {
590
  return $this->cfg->properties[ 'show_module_menu_item' ];
591
  }
592
 
593
- /**
594
- * @deprecated 15.0
595
- */
596
- public function getIfShowModuleOpts() :bool {
597
- return $this->cfg->properties[ 'show_module_options' ];
598
- }
599
-
600
  /**
601
  * @return $this
602
  */
@@ -824,28 +807,10 @@ abstract class ModCon {
824
  && Services::Request()->query( 'inav' ) == $this->getSlug();
825
  }
826
 
827
- /**
828
- * @deprecated 15.0
829
- */
830
- protected function isModuleOptionsRequest() :bool {
831
- return false;
832
- }
833
-
834
  protected function isWizardPage() :bool {
835
  return $this->getCon()->getShieldAction() == 'wizard' && $this->isThisModulePage();
836
  }
837
 
838
- /**
839
- * Will prefix and return any string with the unique plugin prefix.
840
- * @param string $suffix
841
- * @param string $glue
842
- * @return string
843
- * @deprecated 15.0
844
- */
845
- public function prefix( $suffix = '', $glue = '-' ) {
846
- return $this->getCon()->prefix( $suffix, $glue );
847
- }
848
-
849
  protected function buildContextualHelp() {
850
  if ( !function_exists( 'get_current_screen' ) ) {
851
  require_once( ABSPATH.'wp-admin/includes/screen.php' );
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
4
 
5
+ use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
6
  use FernleafSystems\Wordpress\Plugin\Shield;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules;
 
 
8
  use FernleafSystems\Wordpress\Services\Services;
9
 
10
+ /**
11
+ * @property bool $is_booted
12
+ */
13
+ abstract class ModCon extends DynPropertiesClass {
14
 
15
  use Modules\PluginControllerConsumer;
16
  use Shield\Crons\PluginCronsConsumer;
76
  private $adminNotices;
77
 
78
  /**
 
 
79
  * @throws \Exception
80
  */
81
  public function __construct( Shield\Controller\Controller $pluginCon, Config\ModConfigVO $cfg ) {
82
  $this->setCon( $pluginCon );
83
  $this->cfg = $cfg;
84
+ }
85
+
86
+ /**
87
+ * @throws \Exception
88
+ */
89
+ public function boot() {
90
+ if ( !$this->is_booted ) {
91
+ $this->is_booted = true;
92
  $this->handleAutoPageRedirects();
 
93
  $this->doPostConstruction();
94
+ $this->setupHooks();
95
+ }
96
+ }
97
+
98
+ protected function moduleReadyCheck() :bool {
99
+ try {
100
+ $ready = ( new Lib\CheckModuleRequirements() )
101
+ ->setMod( $this )
102
+ ->run();
103
  }
104
+ catch ( \Exception $e ) {
105
+ $ready = false;
106
+ }
107
+ return $ready;
108
  }
109
 
110
  protected function setupHooks() {
115
  } );
116
 
117
  add_action( 'init', [ $this, 'onWpInit' ], 1 );
118
+ add_action( 'wp_loaded', [ $this, 'onWpLoaded' ] );
119
 
120
  add_action( $con->prefix( 'plugin_shutdown' ), [ $this, 'onPluginShutdown' ] );
121
  add_action( $con->prefix( 'deactivate_plugin' ), [ $this, 'onPluginDeactivate' ] );
230
  return $this->loadModElement( 'Upgrade' );
231
  }
232
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  protected function onModulesLoaded() {
234
  }
235
 
382
  );
383
  }
384
 
 
 
 
 
 
 
 
385
  /**
386
  * Hooked to the plugin's main plugin_shutdown action
387
  */
509
  /** @var Shield\Modules\Plugin\Options $pluginOpts */
510
  $pluginOpts = $this->getCon()->getModule_Plugin()->getOptions();
511
 
512
+ if ( !$this->moduleReadyCheck() ) {
513
+ $enabled = false;
514
+ }
515
+ elseif ( $this->cfg->properties[ 'auto_enabled' ] ) {
516
  // Auto enabled modules always run regardless
517
  $enabled = true;
518
  }
563
  $cfg = $this->getOptions()->getRawData_FullFeatureConfig();
564
  if ( !empty( $cfg[ 'custom_redirects' ] ) && $this->getCon()->isValidAdminArea() ) {
565
  foreach ( $cfg[ 'custom_redirects' ] as $redirect ) {
566
+ if ( Services::Request()->query( 'page' )
567
+ == $this->getCon()->prefix( $redirect[ 'source_mod_page' ] ) ) {
568
  Services::Response()->redirect(
569
  $this->getCon()->getModule( $redirect[ 'target_mod_page' ] )->getUrl_AdminPage(),
570
  $redirect[ 'query_args' ],
580
  return $this->cfg->properties[ 'show_module_menu_item' ];
581
  }
582
 
 
 
 
 
 
 
 
583
  /**
584
  * @return $this
585
  */
807
  && Services::Request()->query( 'inav' ) == $this->getSlug();
808
  }
809
 
 
 
 
 
 
 
 
810
  protected function isWizardPage() :bool {
811
  return $this->getCon()->getShieldAction() == 'wizard' && $this->isThisModulePage();
812
  }
813
 
 
 
 
 
 
 
 
 
 
 
 
814
  protected function buildContextualHelp() {
815
  if ( !function_exists( 'get_current_screen' ) ) {
816
  require_once( ABSPATH.'wp-admin/includes/screen.php' );
src/lib/src/Modules/Base/Options.php CHANGED
@@ -169,13 +169,6 @@ class Options {
169
  return $this->getRawData_FullFeatureConfig()[ 'admin_notices' ] ?? [];
170
  }
171
 
172
- /**
173
- * @deprecated 15.0
174
- */
175
- public function getFeatureTagline() {
176
- return $this->getFeatureProperty( 'tagline' );
177
- }
178
-
179
  public function isValidOptionKey( string $key ) :bool {
180
  return in_array( $key, $this->getOptionsKeys() );
181
  }
@@ -439,37 +432,6 @@ class Options {
439
  return $text;
440
  }
441
 
442
- /**
443
- * @deprecated 15.0
444
- */
445
- public function isAccessRestricted() :bool {
446
- $state = $this->getFeatureProperty( 'access_restricted' );
447
- return is_null( $state ) || $state;
448
- }
449
-
450
- /**
451
- * @deprecated 15.0
452
- */
453
- public function isModuleRunIfWhitelisted() :bool {
454
- $state = $this->getFeatureProperty( 'run_if_whitelisted' );
455
- return is_null( $state ) || $state;
456
- }
457
-
458
- /**
459
- * @deprecated 15.0
460
- */
461
- public function isModuleRunUnderWpCli() :bool {
462
- $state = $this->getFeatureProperty( 'run_if_wpcli' );
463
- return is_null( $state ) || $state;
464
- }
465
-
466
- /**
467
- * @deprecated 15.0
468
- */
469
- public function isModuleRunIfVerifiedBot() :bool {
470
- return (bool)$this->getFeatureProperty( 'run_if_verified_bot' );
471
- }
472
-
473
  public function isOptAdvanced( string $key ) :bool {
474
  return (bool)$this->getOptProperty( $key, 'advanced' );
475
  }
@@ -680,16 +642,6 @@ class Options {
680
  }
681
  }
682
 
683
- /**
684
- * @deprecated 15.0
685
- */
686
- public function getConfigLoader() :Config\LoadConfig {
687
- if ( empty( $this->cfgLoader ) ) {
688
- $this->cfgLoader = new Config\LoadConfig( $this->getMod()->getSlug() );
689
- }
690
- return $this->cfgLoader;
691
- }
692
-
693
  private function getOptsStorage() :Options\Storage {
694
  if ( empty( $this->optsStorage ) ) {
695
  $this->optsStorage = ( new Options\Storage() )->setMod( $this->getMod() );
169
  return $this->getRawData_FullFeatureConfig()[ 'admin_notices' ] ?? [];
170
  }
171
 
 
 
 
 
 
 
 
172
  public function isValidOptionKey( string $key ) :bool {
173
  return in_array( $key, $this->getOptionsKeys() );
174
  }
432
  return $text;
433
  }
434
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
435
  public function isOptAdvanced( string $key ) :bool {
436
  return (bool)$this->getOptProperty( $key, 'advanced' );
437
  }
642
  }
643
  }
644
 
 
 
 
 
 
 
 
 
 
 
645
  private function getOptsStorage() :Options\Storage {
646
  if ( empty( $this->optsStorage ) ) {
647
  $this->optsStorage = ( new Options\Storage() )->setMod( $this->getMod() );
src/lib/src/Modules/Base/Processor.php CHANGED
@@ -31,8 +31,7 @@ abstract class Processor {
31
  public function onWpAdminInit() {
32
  /** @var Shield\Modules\Plugin\Options $optsPlugin */
33
  $optsPlugin = $this->getCon()->getModule_Plugin()->getOptions();
34
- // @deprecated 14.1.8
35
- if ( method_exists( $optsPlugin, 'isShowPluginNotices' ) && $optsPlugin->isShowPluginNotices() ) {
36
  add_filter( $this->getCon()->prefix( 'admin_bar_menu_groups' ), [ $this, 'addAdminBarMenuGroup' ] );
37
  }
38
  }
31
  public function onWpAdminInit() {
32
  /** @var Shield\Modules\Plugin\Options $optsPlugin */
33
  $optsPlugin = $this->getCon()->getModule_Plugin()->getOptions();
34
+ if ( $optsPlugin->isShowPluginNotices() ) {
 
35
  add_filter( $this->getCon()->prefix( 'admin_bar_menu_groups' ), [ $this, 'addAdminBarMenuGroup' ] );
36
  }
37
  }
src/lib/src/Modules/BaseShield/ModCon.php CHANGED
@@ -10,27 +10,6 @@ use FernleafSystems\Wordpress\Services\Utilities;
10
 
11
  class ModCon extends Base\ModCon {
12
 
13
- /**
14
- * @var bool
15
- * @deprecated 15.0
16
- */
17
- protected static $bIsVerifiedBot;
18
-
19
- /**
20
- * @var bool
21
- * @deprecated 15.0
22
- */
23
- private static $bVisitorIsWhitelisted;
24
-
25
- /**
26
- * @deprecated 15.0
27
- */
28
- public function getDbHandler_Sessions() :Shield\Databases\Session\Handler {
29
- return $this->getCon()
30
- ->getModule_Sessions()
31
- ->getDbHandler_Sessions();
32
- }
33
-
34
  public function getSessionWP() :Shield\Modules\Sessions\Lib\SessionVO {
35
  return $this->getCon()
36
  ->getModule_Sessions()
@@ -38,17 +17,6 @@ class ModCon extends Base\ModCon {
38
  ->getCurrentWP();
39
  }
40
 
41
- /**
42
- * @return Shield\Databases\Session\EntryVO|null
43
- * @deprecated 15.0
44
- */
45
- public function getSession() :array {
46
- return $this->getCon()
47
- ->getModule_Sessions()
48
- ->getSessionCon()
49
- ->getCurrent();
50
- }
51
-
52
  public function onWpInit() {
53
  parent::onWpInit();
54
  if ( $this->isThisModulePage() && !$this->isWizardPage() && ( $this->getSlug() != 'insights' ) ) {
@@ -110,35 +78,6 @@ class ModCon extends Base\ModCon {
110
  && parent::isReadyToExecute();
111
  }
112
 
113
- /**
114
- * @deprecated 15.0
115
- */
116
- public function isVisitorWhitelisted() :bool {
117
- return $this->getCon()->this_req->is_ip_whitelisted;
118
- }
119
-
120
- /**
121
- * @deprecated 15.0
122
- */
123
- public function isTrustedVerifiedBot() :bool {
124
- return $this->getCon()->this_req->is_trusted_bot;
125
- }
126
-
127
- /**
128
- * @deprecated 15.0
129
- */
130
- protected function getUntrustedProviders() :array {
131
- $untrustedProviders = apply_filters( 'shield/untrusted_service_providers', [] );
132
- return is_array( $untrustedProviders ) ? $untrustedProviders : [];
133
- }
134
-
135
- /**
136
- * @deprecated 15.0
137
- */
138
- public function isVerifiedBot() :bool {
139
- return $this->isTrustedVerifiedBot();
140
- }
141
-
142
  public function isXmlrpcBypass() :bool {
143
  return $this->getCon()
144
  ->getModule_Plugin()
10
 
11
  class ModCon extends Base\ModCon {
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  public function getSessionWP() :Shield\Modules\Sessions\Lib\SessionVO {
14
  return $this->getCon()
15
  ->getModule_Sessions()
17
  ->getCurrentWP();
18
  }
19
 
 
 
 
 
 
 
 
 
 
 
 
20
  public function onWpInit() {
21
  parent::onWpInit();
22
  if ( $this->isThisModulePage() && !$this->isWizardPage() && ( $this->getSlug() != 'insights' ) ) {
78
  && parent::isReadyToExecute();
79
  }
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  public function isXmlrpcBypass() :bool {
82
  return $this->getCon()
83
  ->getModule_Plugin()
src/lib/src/Modules/BaseShield/UI.php CHANGED
@@ -57,8 +57,7 @@ class UI extends Base\UI {
57
  'is_whitelabelled' => $isWhitelabelled
58
  ],
59
  'hrefs' => [
60
- 'aar_forget_key' => $isWhitelabelled ?
61
- $this->getCon()->getLabels()[ 'AuthorURI' ] : 'https://shsec.io/gc'
62
  ],
63
  'vars' => [
64
  ],
57
  'is_whitelabelled' => $isWhitelabelled
58
  ],
59
  'hrefs' => [
60
+ 'aar_forget_key' => empty( $con->labels ) ? $con->getLabels()[ 'AuthorURI' ] : $con->labels->url_secadmin_forgotten_key
 
61
  ],
62
  'vars' => [
63
  ],
src/lib/src/Modules/CommentsFilter/ModCon.php CHANGED
@@ -24,24 +24,4 @@ class ModCon extends BaseShield\ModCon {
24
  public function getSpamBlacklistFile() :string {
25
  return $this->getCon()->paths->forCacheItem( 'spamblacklist.txt' );
26
  }
27
-
28
- /**
29
- * @deprecated 15.0
30
- */
31
- public function isEnabledCaptcha() :bool {
32
- return false;
33
- }
34
-
35
- /**
36
- * @deprecated 15.0
37
- */
38
- public function ensureCorrectCaptchaConfig() {
39
- }
40
-
41
- /**
42
- * @deprecated 15.0
43
- */
44
- public function getCaptchaCfg() :\FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin\Lib\Captcha\CaptchaConfigVO {
45
- return parent::getCaptchaCfg();
46
- }
47
  }
24
  public function getSpamBlacklistFile() :string {
25
  return $this->getCon()->paths->forCacheItem( 'spamblacklist.txt' );
26
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  }
src/lib/src/Modules/CommentsFilter/Options.php CHANGED
@@ -42,32 +42,4 @@ class Options extends BaseShield\Options {
42
  public function setEnabledAntiBot( bool $enabled = true ) {
43
  $this->setOpt( 'enable_antibot_comments', $enabled ? 'Y' : 'N' );
44
  }
45
-
46
- /**
47
- * @deprecated 15.0
48
- */
49
- public function isEnabledGaspCheck() :bool {
50
- return false;
51
- }
52
-
53
- /**
54
- * @deprecated 15.0
55
- */
56
- public function isEnabledCaptcha() :bool {
57
- return false;
58
- }
59
-
60
- /**
61
- * @deprecated 15.0
62
- */
63
- public function getTokenExpireInterval() :int {
64
- return 0;
65
- }
66
-
67
- /**
68
- * @deprecated 15.0
69
- */
70
- public function getTokenCooldown() :int {
71
- return 0;
72
- }
73
  }
42
  public function setEnabledAntiBot( bool $enabled = true ) {
43
  $this->setOpt( 'enable_antibot_comments', $enabled ? 'Y' : 'N' );
44
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  }
src/lib/src/Modules/Firewall/Lib/Scan/FirewallHandler.php DELETED
@@ -1,173 +0,0 @@
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\Base\Common\ExecOnceModConsumer;
6
- use FernleafSystems\Wordpress\Plugin\Shield\Modules\Firewall\{
7
- Lib\Scan\Handlers\Base,
8
- ModCon,
9
- Options
10
- };
11
- use FernleafSystems\Wordpress\Services\Services;
12
-
13
- /**
14
- * @deprecated 15.0
15
- */
16
- class FirewallHandler extends ExecOnceModConsumer {
17
-
18
- /**
19
- * @var false|\WP_Error
20
- */
21
- private $result = false;
22
-
23
- protected function canRun() :bool {
24
- return ( new CanScan() )
25
- ->setMod( $this->getMod() )
26
- ->run();
27
- }
28
-
29
- public function getResult() :\WP_Error {
30
- return is_wp_error( $this->result ) ? $this->result : new \WP_Error();
31
- }
32
-
33
- protected function run() {
34
- $this->runScans();
35
-
36
- $result = $this->getResult();
37
- $block = (bool)apply_filters( 'shield/do_firewall_block', !empty( $result->get_error_codes() ) );
38
- if ( $block ) {
39
- $this->doBlock();
40
- }
41
- }
42
-
43
- private function runScans() {
44
- $opts = $this->getOptions();
45
-
46
- $this->result = new \WP_Error();
47
- foreach ( $this->enumHandlers() as $opt => $handlerInit ) {
48
- if ( $opts->isOpt( 'block_'.$opt, 'Y' ) ) {
49
- /** @var Base $handler */
50
- $handler = $handlerInit();
51
- $result = $handler->setMod( $this->getMod() )->runCheck();
52
- if ( !empty( $result->get_error_codes() ) ) {
53
- $this->result = $result;
54
- break;
55
- }
56
- }
57
- }
58
- }
59
-
60
- private function doBlock() {
61
- /** @var ModCon $mod */
62
- $mod = $this->getMod();
63
-
64
- $this->preBlock();
65
-
66
- switch ( $mod->getBlockResponse() ) {
67
- case 'redirect_die':
68
- Services::WpGeneral()->wpDie( 'Firewall Triggered' );
69
- break;
70
- case 'redirect_die_message':
71
- Services::WpGeneral()->wpDie( implode( ' ', $this->getFirewallDieMessage() ) );
72
- break;
73
- case 'redirect_home':
74
- Services::Response()->redirectToHome();
75
- break;
76
- case 'redirect_404':
77
- header( 'Cache-Control: no-store, no-cache' );
78
- Services::WpGeneral()->turnOffCache();
79
- Services::Response()->sendApache404();
80
- break;
81
- default:
82
- break;
83
- }
84
- die();
85
- }
86
-
87
- private function preBlock() {
88
- /** @var Options $opts */
89
- $opts = $this->getOptions();
90
- if ( $opts->isSendBlockEmail() ) {
91
- $this->getCon()->fireEvent(
92
- $this->sendBlockEmail() ? 'fw_email_success' : 'fw_email_fail',
93
- [ 'audit_params' => [ 'to' => $this->getMod()->getPluginReportEmail() ] ]
94
- );
95
- }
96
- $this->getCon()->fireEvent( 'firewall_block', [ 'audit_params' => $this->getResult()->get_error_data() ] );
97
- }
98
-
99
- protected function getFirewallDieMessage() :array {
100
- return [
101
- __( "Something in the request URL or Form data triggered the firewall.", 'wp-simple-firewall' )
102
- ];
103
- }
104
-
105
- private function sendBlockEmail() :bool {
106
- $ip = Services::IP()->getRequestIp();
107
- $resultData = $this->getResult()->get_error_data( 'shield-firewall' );
108
-
109
- return $this->getMod()
110
- ->getEmailProcessor()
111
- ->sendEmailWithTemplate(
112
- '/email/firewall_block.twig',
113
- $this->getMod()->getPluginReportEmail(),
114
- __( 'Firewall Block Alert', 'wp-simple-firewall' ),
115
- [
116
- 'strings' => [
117
- 'shield_blocked' => sprintf( __( '%s Firewall has blocked a request to your WordPress site.', 'wp-simple-firewall' ),
118
- $this->getCon()->getHumanName() ),
119
- 'details_below' => __( 'Details for the request are given below:', 'wp-simple-firewall' ),
120
- 'details' => __( 'Request Details', 'wp-simple-firewall' ),
121
- 'ip_lookup' => __( 'IP Address Lookup' ),
122
- 'this_is_info' => __( 'This is for informational purposes only.' ),
123
- 'already_blocked' => sprintf( __( '%s has already taken the necessary action of blocking the request.' ),
124
- $this->getCon()->getHumanName() ),
125
- ],
126
- 'hrefs' => [
127
- 'ip_lookup' => add_query_arg( [ 'ip' => $ip ], 'https://shsec.io/botornot' )
128
- ],
129
- 'vars' => [
130
- 'req_details' => [
131
- __( 'Visitor IP Address', 'wp-simple-firewall' ) => $ip,
132
- __( 'Firewall Rule', 'wp-simple-firewall' ) => $resultData[ 'name' ],
133
- __( 'Request Path', 'wp-simple-firewall' ) => Services::Request()->getPath(),
134
- __( 'Request Parameter', 'wp-simple-firewall' ) => $resultData[ 'param' ],
135
- __( 'Request Value', 'wp-simple-firewall' ) => $resultData[ 'value' ],
136
- ]
137
- ]
138
- ]
139
- );
140
- }
141
-
142
- /**
143
- * @return callable[]
144
- */
145
- private function enumHandlers() :array {
146
- return [
147
- // 'dir_traversal' => function () {
148
- // return new Handlers\DirTraversal();
149
- // },
150
- // 'sql_queries' => function () {
151
- // return new Handlers\SqlQueries();
152
- // },
153
- // 'wordpress_terms' => function () {
154
- // return new Handlers\WpTerms();
155
- // },
156
- // 'field_truncation' => function () {
157
- // return new Handlers\FieldTruncation();
158
- // },
159
- // 'php_code' => function () {
160
- // return new Handlers\PhpCode();
161
- // },
162
- // 'leading_schema' => function () {
163
- // return new Handlers\LeadingSchema();
164
- // },
165
- // 'aggressive' => function () {
166
- // return new Handlers\Aggressive();
167
- // },
168
- 'exe_file_uploads' => function () {
169
- return new Handlers\ExeFiles();
170
- },
171
- ];
172
- }
173
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/src/Modules/HackGuard/Lib/FileLocker/FileLockerController.php CHANGED
@@ -166,7 +166,7 @@ class FileLockerController {
166
  }
167
  }
168
 
169
- add_action( $this->getCon()->prefix( 'create_file_locks' ), function () {
170
  $this->runLocksCreation();
171
  } );
172
  }
166
  }
167
  }
168
 
169
+ add_action( $con->prefix( 'create_file_locks' ), function () {
170
  $this->runLocksCreation();
171
  } );
172
  }
src/lib/src/Modules/HackGuard/ModCon.php CHANGED
@@ -112,12 +112,16 @@ class ModCon extends BaseShield\ModCon {
112
  /** @var Options $opts */
113
  $opts = $this->getOptions();
114
 
115
- $this->cleanFileExclusions();
116
-
117
  if ( $opts->isOptChanged( 'scan_frequency' ) ) {
118
  $this->getScansCon()->deleteCron();
119
  }
120
 
 
 
 
 
 
 
121
  if ( count( $opts->getFilesToLock() ) === 0 || !$this->getCon()
122
  ->getModule_Plugin()
123
  ->getShieldNetApiController()
@@ -126,12 +130,6 @@ class ModCon extends BaseShield\ModCon {
126
  $this->getFileLocker()->purge();
127
  }
128
 
129
- $lockFiles = $opts->getFilesToLock();
130
- if ( in_array( 'root_webconfig', $lockFiles ) && !Services::Data()->isWindows() ) {
131
- unset( $lockFiles[ array_search( 'root_webconfig', $lockFiles ) ] );
132
- $opts->setOpt( 'file_locker', $lockFiles );
133
- }
134
-
135
  foreach ( $this->getScansCon()->getAllScanCons() as $con ) {
136
  if ( !$con->isEnabled() ) {
137
  $con->purge();
@@ -182,36 +180,10 @@ class ModCon extends BaseShield\ModCon {
182
  return $this;
183
  }
184
 
 
 
 
185
  protected function cleanFileExclusions() {
186
- /** @var Options $opts */
187
- $opts = $this->getOptions();
188
- $excl = [];
189
-
190
- $toClean = $opts->getOpt( 'ufc_exclusions', [] );
191
- if ( is_array( $toClean ) ) {
192
- foreach ( $toClean as $exclusion ) {
193
-
194
- if ( preg_match( '/^#(.+)#$/', $exclusion, $matches ) ) { // it's not regex
195
- $exclusion = str_replace( '\\', '\\\\', $exclusion );
196
- }
197
- else {
198
- $exclusion = wp_normalize_path( trim( $exclusion ) );
199
- if ( strpos( $exclusion, '/' ) === false ) { // filename only
200
- $exclusion = trim( preg_replace( '#[^.\da-z_-]#i', '', $exclusion ) );
201
- }
202
- }
203
-
204
- if ( !empty( $exclusion ) ) {
205
- $excl[] = $exclusion;
206
- }
207
- }
208
- }
209
-
210
- $opts->setOpt( 'ufc_exclusions', array_unique( $excl ) );
211
- }
212
-
213
- public function hasWizard() :bool {
214
- return false;
215
  }
216
 
217
  public function getScansTempDir() :string {
@@ -251,6 +223,17 @@ class ModCon extends BaseShield\ModCon {
251
  $this->getFileLocker()->purge();
252
  }
253
 
 
 
 
 
 
 
 
 
 
 
 
254
  /**
255
  * @inheritDoc
256
  * @deprecated 13.1
112
  /** @var Options $opts */
113
  $opts = $this->getOptions();
114
 
 
 
115
  if ( $opts->isOptChanged( 'scan_frequency' ) ) {
116
  $this->getScansCon()->deleteCron();
117
  }
118
 
119
+ $lockFiles = $opts->getFilesToLock();
120
+ if ( in_array( 'root_webconfig', $lockFiles ) && !Services::Data()->isWindows() ) {
121
+ unset( $lockFiles[ array_search( 'root_webconfig', $lockFiles ) ] );
122
+ $opts->setOpt( 'file_locker', $lockFiles );
123
+ }
124
+
125
  if ( count( $opts->getFilesToLock() ) === 0 || !$this->getCon()
126
  ->getModule_Plugin()
127
  ->getShieldNetApiController()
130
  $this->getFileLocker()->purge();
131
  }
132
 
 
 
 
 
 
 
133
  foreach ( $this->getScansCon()->getAllScanCons() as $con ) {
134
  if ( !$con->isEnabled() ) {
135
  $con->purge();
180
  return $this;
181
  }
182
 
183
+ /**
184
+ * @deprecated 15.1
185
+ */
186
  protected function cleanFileExclusions() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  }
188
 
189
  public function getScansTempDir() :string {
223
  $this->getFileLocker()->purge();
224
  }
225
 
226
+ public function runDailyCron() {
227
+ parent::runDailyCron();
228
+
229
+ $carbon = Services::Request()->carbon();
230
+ if ( $carbon->isSunday() ) {
231
+ ( new Shield\Scans\Afs\Processing\FileScanOptimiser() )
232
+ ->setMod( $this )
233
+ ->cleanStaleHashesOlderThan( $carbon->subWeek()->timestamp );
234
+ }
235
+ }
236
+
237
  /**
238
  * @inheritDoc
239
  * @deprecated 13.1
src/lib/src/Modules/HackGuard/Options.php CHANGED
@@ -185,42 +185,6 @@ class Options extends BaseShield\Options {
185
  return $this;
186
  }
187
 
188
- /**
189
- * Provides an array where the key is the root dir, and the value is the specific file types.
190
- * An empty array means all files.
191
- * @return array[]
192
- */
193
- public function getUfcScanDirectories() :array {
194
- $dirs = [
195
- path_join( ABSPATH, 'wp-admin' ) => [],
196
- path_join( ABSPATH, 'wp-includes' ) => []
197
- ];
198
-
199
- if ( $this->isOpt( 'ufc_scan_uploads', 'Y' ) ) { // include uploads
200
- $uploadsDir = Services::WpGeneral()->getDirUploads();
201
- if ( !empty( $uploadsDir ) ) {
202
- $dirs[ $uploadsDir ] = [
203
- 'php',
204
- 'php5',
205
- 'js',
206
- ];
207
- }
208
- }
209
-
210
- return $dirs;
211
- }
212
-
213
- /**
214
- * @return string
215
- */
216
- public function getUnrecognisedFileScannerOption() {
217
- return $this->getOpt( 'enable_unrecognised_file_cleaner_scan', 'disabled' );
218
- }
219
-
220
- public function isUfsDeleteFiles() :bool {
221
- return $this->getUnrecognisedFileScannerOption() === 'enabled_delete_only';
222
- }
223
-
224
  public function isScanCron() :bool {
225
  return (bool)$this->getOpt( 'is_scan_cron' );
226
  }
185
  return $this;
186
  }
187
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  public function isScanCron() :bool {
189
  return (bool)$this->getOpt( 'is_scan_cron' );
190
  }
src/lib/src/Modules/HackGuard/Scan/Controller/Afs.php CHANGED
@@ -185,6 +185,12 @@ class Afs extends BaseForFiles {
185
  }
186
  }
187
 
 
 
 
 
 
 
188
  /**
189
  * @return Scans\Afs\Utilities\ItemActionHandler
190
  */
185
  }
186
  }
187
 
188
+ public function getQueueGroupSize() :int {
189
+ /** @var Options $opts */
190
+ $opts = $this->getOptions();
191
+ return $opts->isOpt( 'optimise_scan_speed', 'Y' ) ? 80 : 45;
192
+ }
193
+
194
  /**
195
  * @return Scans\Afs\Utilities\ItemActionHandler
196
  */
src/lib/src/Modules/HackGuard/Scan/Controller/Apc.php CHANGED
@@ -29,6 +29,10 @@ class Apc extends BaseForAssets {
29
  return $items;
30
  }
31
 
 
 
 
 
32
  /**
33
  * @return Scans\Apc\Utilities\ItemActionHandler
34
  */
29
  return $items;
30
  }
31
 
32
+ public function getQueueGroupSize() :int {
33
+ return 3;
34
+ }
35
+
36
  /**
37
  * @return Scans\Apc\Utilities\ItemActionHandler
38
  */
src/lib/src/Modules/HackGuard/Scan/Controller/Base.php CHANGED
@@ -51,6 +51,10 @@ abstract class Base extends ExecOnceModConsumer {
51
  return [];
52
  }
53
 
 
 
 
 
54
  public function cleanStalesResults() {
55
  foreach ( $this->getAllResults()->getItems() as $item ) {
56
  $this->cleanStaleResultItem( $item );
51
  return [];
52
  }
53
 
54
+ public function getQueueGroupSize() :int {
55
+ return 1;
56
+ }
57
+
58
  public function cleanStalesResults() {
59
  foreach ( $this->getAllResults()->getItems() as $item ) {
60
  $this->cleanStaleResultItem( $item );
src/lib/src/Modules/HackGuard/Scan/Init/PopulateScanItems.php CHANGED
@@ -36,7 +36,7 @@ class PopulateScanItems {
36
  'meta' => $scanRecord->getRawData()[ 'meta' ]
37
  ] );
38
 
39
- $sliceSize = $scanAction::QUEUE_GROUP_SIZE_LIMIT;
40
 
41
  /** @var ScanItemsDB\Ops\Record $newRecord */
42
  $newRecord = $dbhItems->getRecord();
36
  'meta' => $scanRecord->getRawData()[ 'meta' ]
37
  ] );
38
 
39
+ $sliceSize = $scanCon->getQueueGroupSize();
40
 
41
  /** @var ScanItemsDB\Ops\Record $newRecord */
42
  $newRecord = $dbhItems->getRecord();
src/lib/src/Modules/HackGuard/Scan/ScansController.php CHANGED
@@ -227,6 +227,6 @@ class ScansController extends ExecOnceModConsumer {
227
  }
228
 
229
  protected function getCronName() :string {
230
- return $this->getCon()->prefix( $this->getOptions()->getDef( 'cron_all_scans' ) );
231
  }
232
  }
227
  }
228
 
229
  protected function getCronName() :string {
230
+ return $this->getCon()->prefix( 'all-scans' );
231
  }
232
  }
src/lib/src/Modules/HackGuard/Strings.php CHANGED
@@ -258,56 +258,21 @@ class Strings extends Base\Strings {
258
  }
259
  break;
260
 
261
- case 'enable_unrecognised_file_cleaner_scan' :
262
- $name = __( 'Unrecognised Files Scanner', 'wp-simple-firewall' );
263
- $summary = __( 'Automatically Scans For Unrecognised Files In Core Directories', 'wp-simple-firewall' );
264
- $desc = __( 'Scans for, and automatically deletes, any files in your core WordPress folders that are not part of your WordPress installation.', 'wp-simple-firewall' );
265
- break;
266
-
267
- case 'ufc_scan_uploads' :
268
- $name = __( 'Scan Uploads', 'wp-simple-firewall' );
269
- $summary = __( 'Scan Uploads Folder For PHP and Javascript', 'wp-simple-firewall' );
270
- $desc = sprintf( '%s - %s', __( 'Warning', 'wp-simple-firewall' ), __( 'Take care when turning on this option - if you are unsure, leave it disabled.', 'wp-simple-firewall' ) )
271
- .'<br />'.__( 'The Uploads folder is primarily for media, but could be used to store nefarious files.', 'wp-simple-firewall' );
272
- break;
273
-
274
- case 'ufc_exclusions' :
275
- $name = __( 'File Exclusions', 'wp-simple-firewall' );
276
- $summary = __( 'Provide A List Of Files To Be Excluded From The Scan', 'wp-simple-firewall' );
277
- $sDefaults = implode( ', ', $this->getOptions()->getOptDefault( 'ufc_exclusions' ) );
278
- $desc = __( 'Take a new line for each file you wish to exclude from the scan.', 'wp-simple-firewall' )
279
- .'<br/><strong>'.__( 'No commas are necessary.', 'wp-simple-firewall' ).'</strong>'
280
- .'<br/>'.sprintf( '%s: %s', __( 'Default', 'wp-simple-firewall' ), $sDefaults );
281
- break;
282
-
283
- case 'ic_enabled' :
284
- $name = __( 'Enable Integrity Scan', 'wp-simple-firewall' );
285
- $summary = __( 'Scans For Critical Changes Made To Your WordPress Site', 'wp-simple-firewall' );
286
- $desc = __( 'Detects changes made to your WordPress site outside of WordPress.', 'wp-simple-firewall' );
287
- break;
288
-
289
- case 'ic_users' :
290
- $name = __( 'Monitor User Accounts', 'wp-simple-firewall' );
291
- $summary = __( 'Scans For Critical Changes Made To User Accounts', 'wp-simple-firewall' );
292
- $desc = sprintf( __( 'Detects changes made to critical user account information that were made directly on the database and outside of the WordPress system.', 'wp-simple-firewall' ), 'author=' )
293
- .'<br />'.__( 'An example of this might be some form of SQL Injection attack.', 'wp-simple-firewall' )
294
- .'<br />'.sprintf( '%s: %s', __( 'Warning', 'wp-simple-firewall' ), __( 'Enabling this option for every page low may slow down your site with large numbers of users.', 'wp-simple-firewall' ) )
295
- .'<br />'.sprintf( '%s: %s', __( 'Warning', 'wp-simple-firewall' ), __( 'This option may cause critical problem with 3rd party plugins that manage user accounts.', 'wp-simple-firewall' ) );
296
- break;
297
-
298
- case 'ptg_depth' : /* DELETED */
299
- $name = __( 'Guard/Scan Depth', 'wp-simple-firewall' );
300
- $summary = __( 'How Deep Into The Plugin Directories To Scan And Guard', 'wp-simple-firewall' );
301
- $desc = __( 'The Guard normally scans only the top level of a folder. Increasing depth will increase scan times.', 'wp-simple-firewall' )
302
- .'<br/>'.sprintf( __( 'Setting it to %s will remove this limit and all sub-folders will be scanned - not recommended', 'wp-simple-firewall' ), 0 );
303
- break;
304
-
305
- case 'ptg_reinstall_links' :
306
  $name = __( 'Show Re-Install Links', 'wp-simple-firewall' );
307
  $summary = __( 'Show Re-Install Links For Plugins', 'wp-simple-firewall' );
308
  $desc = __( "Show links to re-install plugins and offer re-install when activating plugins.", 'wp-simple-firewall' );
309
  break;
310
 
 
 
 
 
 
 
 
 
 
311
  case 'scan_path_exclusions' :
312
  $name = __( 'Scan Exclusions', 'wp-simple-firewall' );
313
  $summary = __( 'Scan File And Folder Exclusions', 'wp-simple-firewall' );
258
  }
259
  break;
260
 
261
+ case 'ptg_reinstall_links':
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
262
  $name = __( 'Show Re-Install Links', 'wp-simple-firewall' );
263
  $summary = __( 'Show Re-Install Links For Plugins', 'wp-simple-firewall' );
264
  $desc = __( "Show links to re-install plugins and offer re-install when activating plugins.", 'wp-simple-firewall' );
265
  break;
266
 
267
+ case 'optimise_scan_speed':
268
+ $name = __( 'Optimise File Scans', 'wp-simple-firewall' );
269
+ $summary = __( 'Optimise File Scans', 'wp-simple-firewall' );
270
+ $desc = [
271
+ __( 'Optimise file scans to run much faster.', 'wp-simple-firewall' ),
272
+ __( 'If you experience any errors in your logs or strange scanning behaviour, disable this option.', 'wp-simple-firewall' )
273
+ ];
274
+ break;
275
+
276
  case 'scan_path_exclusions' :
277
  $name = __( 'Scan Exclusions', 'wp-simple-firewall' );
278
  $summary = __( 'Scan File And Folder Exclusions', 'wp-simple-firewall' );
src/lib/src/Modules/IPs/Components/ProcessOffense.php CHANGED
@@ -59,6 +59,7 @@ class ProcessOffense {
59
  * so we fire ip_offense but suppress the audit
60
  */
61
  if ( $toBlock ) {
 
62
  $updater = $mod->getDbHandler_IPs()->getQueryUpdater();
63
  $updater->setBlocked( $IP );
64
  $con->fireEvent( 'ip_offense',
59
  * so we fire ip_offense but suppress the audit
60
  */
61
  if ( $toBlock ) {
62
+ /** @var Databases\IPs\Update $updater */
63
  $updater = $mod->getDbHandler_IPs()->getQueryUpdater();
64
  $updater->setBlocked( $IP );
65
  $con->fireEvent( 'ip_offense',
src/lib/src/Modules/IPs/Lib/BlacklistHandler.php CHANGED
@@ -37,31 +37,4 @@ class BlacklistHandler extends Modules\Base\Common\ExecOnceModConsumer {
37
  ->setMod( $this->getMod() )
38
  ->execute();
39
  }
40
-
41
- /**
42
- * @deprecated 15.0
43
- */
44
- private function isRequestWhitelisted() :bool {
45
- /** @var IPs\Options $opts */
46
- $opts = $this->getOptions();
47
- $isWhitelisted = false;
48
-
49
- $whitelistPaths = array_map(
50
- function ( $value ) {
51
- return ( new WildCardOptions() )->buildFullRegexValue( $value, WildCardOptions::URL_PATH );
52
- },
53
- $this->getCon()->isPremiumActive() ? $opts->getOpt( 'request_whitelist', [] ) : []
54
- );
55
-
56
- if ( !empty( $whitelistPaths ) ) {
57
- $path = strtolower( '/'.ltrim( Services::Request()->getPath(), '/' ) );
58
- foreach ( $whitelistPaths as $rule ) {
59
- if ( preg_match( $rule, $path ) ) {
60
- $isWhitelisted = true;
61
- break;
62
- }
63
- }
64
- }
65
- return $isWhitelisted;
66
- }
67
  }
37
  ->setMod( $this->getMod() )
38
  ->execute();
39
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  }
src/lib/src/Modules/IPs/Lib/OffenseTracker.php CHANGED
@@ -11,23 +11,11 @@ class OffenseTracker extends EventsListener {
11
  */
12
  private $isBlocked = false;
13
 
14
- /**
15
- * @var bool
16
- * @deprecated 15.0
17
- */
18
- private $bIsBlocked = false;
19
-
20
  /**
21
  * @var int
22
  */
23
  private $offenseCount = 0;
24
 
25
- /**
26
- * @var int
27
- * @deprecated 15.0
28
- */
29
- private $nOffenseCount = 0;
30
-
31
  protected function captureEvent( string $evt, array $meta = [], array $def = [] ) {
32
  if ( !empty( $def[ 'offense' ] ) && empty( $meta[ 'suppress_offense' ] ) ) {
33
  $this->incrementCount( (int)( $meta[ 'offense_count' ] ?? 1 ) );
@@ -42,11 +30,11 @@ class OffenseTracker extends EventsListener {
42
  }
43
 
44
  public function isBlocked() :bool {
45
- return (bool)( $this->isBlocked ?? $this->bIsBlocked );
46
  }
47
 
48
  public function getOffenseCount() :int {
49
- return (int)( $this->offenseCount ?? $this->nOffenseCount );
50
  }
51
 
52
  /**
@@ -68,7 +56,7 @@ class OffenseTracker extends EventsListener {
68
  * @return $this
69
  */
70
  public function setOffenseCount( int $offenseCount ) {
71
- $this->offenseCount = max( $offenseCount, $this->getOffenseCount() );
72
  return $this;
73
  }
74
  }
11
  */
12
  private $isBlocked = false;
13
 
 
 
 
 
 
 
14
  /**
15
  * @var int
16
  */
17
  private $offenseCount = 0;
18
 
 
 
 
 
 
 
19
  protected function captureEvent( string $evt, array $meta = [], array $def = [] ) {
20
  if ( !empty( $def[ 'offense' ] ) && empty( $meta[ 'suppress_offense' ] ) ) {
21
  $this->incrementCount( (int)( $meta[ 'offense_count' ] ?? 1 ) );
30
  }
31
 
32
  public function isBlocked() :bool {
33
+ return $this->isBlocked;
34
  }
35
 
36
  public function getOffenseCount() :int {
37
+ return $this->offenseCount;
38
  }
39
 
40
  /**
56
  * @return $this
57
  */
58
  public function setOffenseCount( int $offenseCount ) {
59
+ $this->offenseCount = (int)max( $offenseCount, $this->getOffenseCount() );
60
  return $this;
61
  }
62
  }
src/lib/src/Modules/IPs/Lib/Ops/AddIp.php CHANGED
@@ -21,20 +21,16 @@ class AddIp {
21
  $mod = $this->getMod();
22
  $req = Services::Request();
23
 
24
- $ip = $this->getIP();
25
- if ( !Services::IP()->isValidIp( $ip ) ) {
26
  throw new \Exception( "IP address isn't valid." );
27
  }
28
- if ( in_array( $ip, Services::IP()->getServerPublicIPs() ) ) {
29
- throw new \Exception( 'Will not black mark our own server IP' );
30
- }
31
 
32
  $IP = ( new LookupIpOnList() )
33
  ->setDbHandler( $mod->getDbHandler_IPs() )
34
  ->setListTypeBlock()
35
- ->setIP( $ip )
36
  ->lookup( false );
37
- if ( !$IP instanceof Databases\IPs\EntryVO ) {
38
  $IP = $this->add( $mod::LIST_AUTO_BLACK, 'auto', $req->ts() );
39
  if ( !empty( $IP ) ) {
40
  $this->getCon()->fireEvent( 'ip_block_auto', [ 'audit_params' => [ 'ip' => $this->getIP() ] ] );
@@ -46,7 +42,7 @@ class AddIp {
46
  // We just reset the transgressions
47
  /** @var Modules\IPs\Options $opts */
48
  $opts = $this->getOptions();
49
- if ( $IP->transgressions > 0 && ( $req->ts() - $opts->getAutoExpireTime() > (int)$IP->last_access_at ) ) {
50
  $mod->getDbHandler_IPs()
51
  ->getQueryUpdater()
52
  ->updateEntry( $IP, [
@@ -180,28 +176,34 @@ class AddIp {
180
  * @throws \Exception
181
  */
182
  private function add( string $list, string $label = '', int $accessAt = 0 ) {
183
- $IP = null;
184
-
185
  /** @var ModCon $mod */
186
  $mod = $this->getMod();
187
-
188
- // Never add a reserved IP to any black list
189
  $dbh = $mod->getDbHandler_IPs();
 
 
 
190
 
191
  /** @var Databases\IPs\EntryVO $tmp */
192
  $tmp = $dbh->getVo();
193
  $tmp->ip = $this->getIP();
194
  $tmp->list = $list;
195
- $tmp->label = (string)$label;
196
  $tmp->last_access_at = $accessAt;
197
 
 
 
 
 
 
 
 
198
  if ( $dbh->getQueryInserter()->insert( $tmp ) ) {
199
  /** @var Databases\IPs\EntryVO $IP */
200
  $IP = $dbh->getQuerySelector()
201
  ->byId( Services::WpDb()->getVar( 'SELECT LAST_INSERT_ID()' ) );
202
  }
203
 
204
- if ( !$IP instanceof Databases\IPs\EntryVO ) {
205
  throw new \Exception( "IP couldn't be added to the database." );
206
  }
207
 
21
  $mod = $this->getMod();
22
  $req = Services::Request();
23
 
24
+ if ( !Services::IP()->isValidIp( $this->getIP() ) ) {
 
25
  throw new \Exception( "IP address isn't valid." );
26
  }
 
 
 
27
 
28
  $IP = ( new LookupIpOnList() )
29
  ->setDbHandler( $mod->getDbHandler_IPs() )
30
  ->setListTypeBlock()
31
+ ->setIP( $this->getIP() )
32
  ->lookup( false );
33
+ if ( empty( $IP ) ) {
34
  $IP = $this->add( $mod::LIST_AUTO_BLACK, 'auto', $req->ts() );
35
  if ( !empty( $IP ) ) {
36
  $this->getCon()->fireEvent( 'ip_block_auto', [ 'audit_params' => [ 'ip' => $this->getIP() ] ] );
42
  // We just reset the transgressions
43
  /** @var Modules\IPs\Options $opts */
44
  $opts = $this->getOptions();
45
+ if ( !empty( $IP ) && $IP->transgressions > 0 && ( $req->ts() - $opts->getAutoExpireTime() > $IP->last_access_at ) ) {
46
  $mod->getDbHandler_IPs()
47
  ->getQueryUpdater()
48
  ->updateEntry( $IP, [
176
  * @throws \Exception
177
  */
178
  private function add( string $list, string $label = '', int $accessAt = 0 ) {
 
 
179
  /** @var ModCon $mod */
180
  $mod = $this->getMod();
 
 
181
  $dbh = $mod->getDbHandler_IPs();
182
+ $srvIP = Services::IP();
183
+
184
+ $IP = null;
185
 
186
  /** @var Databases\IPs\EntryVO $tmp */
187
  $tmp = $dbh->getVo();
188
  $tmp->ip = $this->getIP();
189
  $tmp->list = $list;
190
+ $tmp->label = $label;
191
  $tmp->last_access_at = $accessAt;
192
 
193
+ // Never add a reserved IP to any black list
194
+ if ( in_array( $tmp->list, [ $mod::LIST_AUTO_BLACK, $mod::LIST_MANUAL_BLACK ] ) ) {
195
+ if ( $srvIP->checkIp( $tmp->ip, $srvIP->getServerPublicIPs() ) ) {
196
+ throw new \Exception( "Forbidden to blacklist server's public IP." );
197
+ }
198
+ }
199
+
200
  if ( $dbh->getQueryInserter()->insert( $tmp ) ) {
201
  /** @var Databases\IPs\EntryVO $IP */
202
  $IP = $dbh->getQuerySelector()
203
  ->byId( Services::WpDb()->getVar( 'SELECT LAST_INSERT_ID()' ) );
204
  }
205
 
206
+ if ( empty( $IP ) ) {
207
  throw new \Exception( "IP couldn't be added to the database." );
208
  }
209
 
src/lib/src/Modules/IPs/ModCon.php CHANGED
@@ -70,8 +70,8 @@ class ModCon extends BaseShield\ModCon {
70
  * @throws \Exception
71
  */
72
  protected function isReadyToExecute() :bool {
73
- $oIp = Services::IP();
74
- return $oIp->isValidIp_PublicRange( $oIp->getRequestIp() )
75
  && ( $this->getDbHandler_IPs() instanceof Shield\Databases\IPs\Handler )
76
  && $this->getDbHandler_IPs()->isReady()
77
  && parent::isReadyToExecute();
70
  * @throws \Exception
71
  */
72
  protected function isReadyToExecute() :bool {
73
+ $con = $this->getCon();
74
+ return $con->this_req->ip_is_public
75
  && ( $this->getDbHandler_IPs() instanceof Shield\Databases\IPs\Handler )
76
  && $this->getDbHandler_IPs()->isReady()
77
  && parent::isReadyToExecute();
src/lib/src/Modules/IPs/Strings.php CHANGED
@@ -387,7 +387,7 @@ class Strings extends Base\Strings {
387
  __( "Detect when a bot tries to load WordPress directly from a file that isn't normally used to load WordPress.", 'wp-simple-firewall' ),
388
  __( 'WordPress should only be loaded in a limited number of ways.', 'wp-simple-firewall' ),
389
  sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ),
390
- sprintf( __( 'Set this option to "%s" and monitor the Activity Log, since some plugins, themes, or custom integrations may trigger this.', 'wp-simple-firewall' ), __( 'Audit Log Only', 'wp-simple-firewall' ) ) )
391
  ];
392
  break;
393
 
387
  __( "Detect when a bot tries to load WordPress directly from a file that isn't normally used to load WordPress.", 'wp-simple-firewall' ),
388
  __( 'WordPress should only be loaded in a limited number of ways.', 'wp-simple-firewall' ),
389
  sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ),
390
+ sprintf( __( 'Set this option to "%s" and monitor the Activity Log, since some plugins, themes, or custom integrations may trigger this.', 'wp-simple-firewall' ), __( 'Activity Log Only', 'wp-simple-firewall' ) ) )
391
  ];
392
  break;
393
 
src/lib/src/Modules/Insights/UI.php CHANGED
@@ -223,9 +223,16 @@ class UI extends BaseShield\UI {
223
  }
224
 
225
  if ( $con->getModule_SecAdmin()->getWhiteLabelController()->isEnabled() ) {
226
- $dashboardLogo = ( new Shield\Modules\SecurityAdmin\Lib\WhiteLabel\BuildOptions() )
227
- ->setMod( $con->getModule_SecAdmin() )
228
- ->build()[ 'url_login2fa_logourl' ];
 
 
 
 
 
 
 
229
  }
230
  else {
231
  $dashboardLogo = $con->urls->forImage( 'pluginlogo_banner-170x40.png' );
223
  }
224
 
225
  if ( $con->getModule_SecAdmin()->getWhiteLabelController()->isEnabled() ) {
226
+
227
+ if ( !empty( $con->labels ) ) {
228
+ $dashboardLogo = $con->labels->url_img_pagebanner;
229
+ }
230
+ else {
231
+ /** @deprecated 15.1 */
232
+ $dashboardLogo = ( new Shield\Modules\SecurityAdmin\Lib\WhiteLabel\BuildOptions() )
233
+ ->setMod( $con->getModule_SecAdmin() )
234
+ ->build()[ 'url_login2fa_logourl' ];
235
+ }
236
  }
237
  else {
238
  $dashboardLogo = $con->urls->forImage( 'pluginlogo_banner-170x40.png' );
src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/Base.php CHANGED
@@ -13,13 +13,6 @@ abstract class Base extends BaseHandler {
13
  return $mod->getController_SpamForms();
14
  }
15
 
16
- /**
17
- * @deprecated 15.0
18
- */
19
- public function isSpam() :bool {
20
- return parent::isBot();
21
- }
22
-
23
  protected function fireBotEvent() {
24
  $this->getCon()->fireEvent(
25
  sprintf( 'spam_form_%s', $this->isBot() ? 'fail' : 'pass' ),
13
  return $mod->getController_SpamForms();
14
  }
15
 
 
 
 
 
 
 
 
16
  protected function fireBotEvent() {
17
  $this->getCon()->fireEvent(
18
  sprintf( 'spam_form_%s', $this->isBot() ? 'fail' : 'pass' ),
src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/HappyForms.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\Bots\Spam\Handlers;
4
+
5
+ class HappyForms extends Base {
6
+
7
+ protected function run() {
8
+ add_filter( 'happyforms_validate_submission',
9
+ function ( $is_valid, $request = null, $form = null ) {
10
+ if ( $is_valid ) {
11
+ $is_valid = !$this->isBotBlockRequired();
12
+ }
13
+ return $is_valid;
14
+ },
15
+ 1000, 3
16
+ );
17
+ }
18
+
19
+ public static function IsProviderInstalled() :bool {
20
+ return function_exists( '\HappyForms' ) && @class_exists( '\HappyForms' )
21
+ && function_exists( 'happyforms_get_version' ) && version_compare( (string)happyforms_get_version(), '1.15', '>=' );
22
+ }
23
+ }
src/lib/src/Modules/Integrations/Lib/Bots/Spam/SpamController.php CHANGED
@@ -22,6 +22,7 @@ class SpamController extends BaseBotDetectionController {
22
  'forminator' => Handlers\Forminator::class,
23
  'gravityforms' => Handlers\GravityForms::class,
24
  'groundhogg' => Handlers\Groundhogg::class,
 
25
  'kaliforms' => Handlers\KaliForms::class,
26
  'ninjaforms' => Handlers\NinjaForms::class,
27
  'superforms' => Handlers\SuperForms::class,
22
  'forminator' => Handlers\Forminator::class,
23
  'gravityforms' => Handlers\GravityForms::class,
24
  'groundhogg' => Handlers\Groundhogg::class,
25
+ 'happyforms' => Handlers\HappyForms::class,
26
  'kaliforms' => Handlers\KaliForms::class,
27
  'ninjaforms' => Handlers\NinjaForms::class,
28
  'superforms' => Handlers\SuperForms::class,
src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/EasyDigitalDownloads.php CHANGED
@@ -11,7 +11,7 @@ class EasyDigitalDownloads extends Base {
11
  public function checkRegister_EDD() {
12
  if ( $this->setAuditAction( 'register' )->isBotBlockRequired() ) {
13
  $this->fireEventBlockRegister();
14
- edd_set_error( $this->getCon()->prefix( rand() ), $this->getErrorMessage() );
15
  }
16
  }
17
 
11
  public function checkRegister_EDD() {
12
  if ( $this->setAuditAction( 'register' )->isBotBlockRequired() ) {
13
  $this->fireEventBlockRegister();
14
+ edd_set_error( uniqid(), $this->getErrorMessage() );
15
  }
16
  }
17
 
src/lib/src/Modules/Integrations/Lib/MainWP/Client/Actions/ApiActionInit.php CHANGED
@@ -15,7 +15,7 @@ class ApiActionInit {
15
  $valid = $this->getCon()
16
  ->getModule_License()
17
  ->getLicenseHandler()
18
- ->verify()
19
  ->hasValidWorkingLicense();
20
  $response = [
21
  'success' => $valid,
15
  $valid = $this->getCon()
16
  ->getModule_License()
17
  ->getLicenseHandler()
18
+ ->verify( true )
19
  ->hasValidWorkingLicense();
20
  $response = [
21
  'success' => $valid,
src/lib/src/Modules/License/AjaxHandler.php CHANGED
@@ -67,7 +67,7 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
67
  }
68
  else {
69
  try {
70
- $success = $licHandler->verify()->hasValidWorkingLicense();
71
  $msg = $success ? __( 'Valid license found.', 'wp-simple-firewall' ) : __( "Valid license couldn't be found.", 'wp-simple-firewall' );
72
  }
73
  catch ( \Exception $e ) {
67
  }
68
  else {
69
  try {
70
+ $success = $licHandler->verify( true )->hasValidWorkingLicense();
71
  $msg = $success ? __( 'Valid license found.', 'wp-simple-firewall' ) : __( "Valid license couldn't be found.", 'wp-simple-firewall' );
72
  }
73
  catch ( \Exception $e ) {
src/lib/src/Modules/License/Lib/LicenseHandler.php CHANGED
@@ -64,7 +64,7 @@ class LicenseHandler extends Modules\Base\Common\ExecOnceModConsumer {
64
  $reqHost = Services::Request()->getHost();
65
  if ( !$this->hasValidWorkingLicense() || empty( $licHost ) || empty( $reqHost ) || ( $licHost === $reqHost ) ) {
66
  try {
67
- $mod->getLicenseHandler()->verify();
68
  }
69
  catch ( \Exception $e ) {
70
  }
@@ -197,17 +197,24 @@ class LicenseHandler extends Modules\Base\Common\ExecOnceModConsumer {
197
  * @return $this
198
  * @throws \Exception
199
  */
200
- public function verify( bool $force = true ) {
201
- if ( $force || ( $this->isVerifyRequired() && $this->canCheck() ) ) {
202
- ( new Verify() )
203
- ->setMod( $this->getMod() )
204
- ->run();
 
 
 
 
 
 
205
  }
 
206
  return $this;
207
  }
208
 
209
- private function getIsLicenseNotCheckedFor( $nTimePeriod ) :bool {
210
- return $this->getLicenseNotCheckedForInterval() > $nTimePeriod;
211
  }
212
 
213
  private function canLicenseCheck_FileFlag() :bool {
64
  $reqHost = Services::Request()->getHost();
65
  if ( !$this->hasValidWorkingLicense() || empty( $licHost ) || empty( $reqHost ) || ( $licHost === $reqHost ) ) {
66
  try {
67
+ $mod->getLicenseHandler()->verify( true );
68
  }
69
  catch ( \Exception $e ) {
70
  }
197
  * @return $this
198
  * @throws \Exception
199
  */
200
+ public function verify( bool $onDemand = false ) {
201
+ if ( $this->canCheck() ) {
202
+ if ( $onDemand ) {
203
+ Services::WpCron()->deleteCronJob( $this->getCon()->prefix( 'adhoc_cron_license_check' ) );
204
+ ( new Verify() )
205
+ ->setMod( $this->getMod() )
206
+ ->run();
207
+ }
208
+ elseif ( $this->isVerifyRequired() ) {
209
+ $this->scheduleAdHocCheck( rand( MINUTE_IN_SECONDS, MINUTE_IN_SECONDS*30 ) );
210
+ }
211
  }
212
+
213
  return $this;
214
  }
215
 
216
+ private function getIsLicenseNotCheckedFor( int $interval ) :bool {
217
+ return $this->getLicenseNotCheckedForInterval() > $interval;
218
  }
219
 
220
  private function canLicenseCheck_FileFlag() :bool {
src/lib/src/Modules/License/Lib/PluginNameSuffix.php CHANGED
@@ -1,14 +1,11 @@
1
- <?php
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\License\Lib;
4
 
5
- use FernleafSystems\Utilities\Logic\ExecOnce;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules;
7
 
8
- class PluginNameSuffix {
9
-
10
- use Modules\ModConsumer;
11
- use ExecOnce;
12
 
13
  protected function canRun() :bool {
14
  $con = $this->getCon();
@@ -17,10 +14,10 @@ class PluginNameSuffix {
17
  }
18
 
19
  protected function run() {
20
- add_filter( $this->getCon()->prefix( 'plugin_labels' ), function ( $labels ) {
21
- $labels[ 'Name' ] = 'ShieldPRO';
22
- $labels[ 'Title' ] = 'ShieldPRO';
23
- $labels[ 'MenuTitle' ] = 'ShieldPRO';
24
  return $labels;
25
  } );
26
  }
1
+ <?php declare( strict_types=1 );
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\License\Lib;
4
 
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Controller\Config\Labels;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules;
7
 
8
+ class PluginNameSuffix extends Modules\Base\Common\ExecOnceModConsumer {
 
 
 
9
 
10
  protected function canRun() :bool {
11
  $con = $this->getCon();
14
  }
15
 
16
  protected function run() {
17
+ add_filter( $this->getCon()->prefix( 'labels' ), function ( Labels $labels ) {
18
+ $labels->Name = 'ShieldPRO';
19
+ $labels->Title = 'ShieldPRO';
20
+ $labels->MenuTitle = 'ShieldPRO';
21
  return $labels;
22
  } );
23
  }
src/lib/src/Modules/License/ModCon.php CHANGED
@@ -55,14 +55,12 @@ class ModCon extends BaseShield\ModCon {
55
  return parent::getIfShowModuleMenuItem() && !$this->isPremium();
56
  }
57
 
58
- public function onPluginShutdown() {
59
- if ( !$this->getCon()->plugin_deleting ) {
60
- try {
61
- $this->getLicenseHandler()->verify( false );
62
- }
63
- catch ( \Exception $e ) {
64
- }
65
  }
66
- parent::onPluginShutdown();
67
  }
68
  }
55
  return parent::getIfShowModuleMenuItem() && !$this->isPremium();
56
  }
57
 
58
+ public function onWpLoaded() {
59
+ parent::onWpLoaded();
60
+ try {
61
+ $this->getLicenseHandler()->verify( false );
62
+ }
63
+ catch ( \Exception $e ) {
 
64
  }
 
65
  }
66
  }
src/lib/src/Modules/License/Processor.php CHANGED
@@ -10,9 +10,6 @@ class Processor extends BaseShield\Processor {
10
  /** @var ModCon $mod */
11
  $mod = $this->getMod();
12
  $mod->getLicenseHandler()->execute();
13
- }
14
-
15
- public function onWpLoaded() {
16
  ( new Lib\PluginNameSuffix() )
17
  ->setMod( $this->getMod() )
18
  ->execute();
10
  /** @var ModCon $mod */
11
  $mod = $this->getMod();
12
  $mod->getLicenseHandler()->execute();
 
 
 
13
  ( new Lib\PluginNameSuffix() )
14
  ->setMod( $this->getMod() )
15
  ->execute();
src/lib/src/Modules/License/WpCli/License.php CHANGED
@@ -100,7 +100,7 @@ class License extends Base\WpCli\BaseWpCliCmd {
100
  }
101
  $success = $mod
102
  ->getLicenseHandler()
103
- ->verify()
104
  ->hasValidWorkingLicense();
105
  $msg = $success ? __( 'Valid license found and installed.', 'wp-simple-firewall' )
106
  : __( "Valid license couldn't be found.", 'wp-simple-firewall' );
100
  }
101
  $success = $mod
102
  ->getLicenseHandler()
103
+ ->verify( true )
104
  ->hasValidWorkingLicense();
105
  $msg = $success ? __( 'Valid license found and installed.', 'wp-simple-firewall' )
106
  : __( "Valid license couldn't be found.", 'wp-simple-firewall' );
src/lib/src/Modules/LoginGuard/Lib/AntiBot/FormProviders/EasyDigitalDownloads.php CHANGED
@@ -20,7 +20,7 @@ class EasyDigitalDownloads extends BaseFormProvider {
20
  }
21
  catch ( \Exception $e ) {
22
  if ( function_exists( 'edd_set_error' ) ) {
23
- edd_set_error( $this->getCon()->prefix( rand() ), $e->getMessage() );
24
  }
25
  }
26
  }
20
  }
21
  catch ( \Exception $e ) {
22
  if ( function_exists( 'edd_set_error' ) ) {
23
+ edd_set_error( $this->getCon()->prefix( uniqid() ), $e->getMessage() );
24
  }
25
  }
26
  }
src/lib/src/Modules/LoginGuard/Lib/AntiBot/FormProviders/WooCommerce.php CHANGED
@@ -36,12 +36,9 @@ class WooCommerce extends BaseFormProvider {
36
  add_action( 'woocommerce_after_checkout_validation', [ $this, 'checkCheckout' ], 10, 2 );
37
  }
38
 
39
- /**
40
- * @return string
41
- */
42
- private function getCheckoutHookLocation() {
43
  return apply_filters(
44
- $this->getCon()->prefix( 'woocommerce_checkout_hook_location' ),
45
  'woocommerce_after_checkout_registration_form'
46
  );
47
  }
@@ -86,58 +83,58 @@ class WooCommerce extends BaseFormProvider {
86
  /**
87
  * Should be a filter added to WordPress's "authenticate" filter, but before WordPress performs
88
  * it's own authentication (theirs is priority 30, so we could go in at around 20).
89
- * @param null|\WP_User|\WP_Error $oUserOrError
90
  * @param string $sUsername
91
  * @return \WP_User|\WP_Error
92
  */
93
- public function checkLogin( $oUserOrError, $sUsername ) {
94
  try {
95
- if ( !is_wp_error( $oUserOrError ) && !empty( $sUsername ) ) {
96
  $this->setUserToAudit( $sUsername )
97
  ->setActionToAudit( 'woo-register' )
98
  ->checkProviders();
99
  }
100
  }
101
  catch ( \Exception $e ) {
102
- $oUserOrError = $this->giveMeWpError( $oUserOrError );
103
- $oUserOrError->add( $this->getCon()->prefix( rand() ), $e->getMessage() );
104
  }
105
- return $oUserOrError;
106
  }
107
 
108
  /**
109
- * @param \WP_Error $oWpError
110
- * @param string $sUsername
111
  * @return \WP_Error
112
  */
113
- public function checkRegister( $oWpError, $sUsername ) {
114
  try {
115
- $this->setUserToAudit( $sUsername )
116
  ->setActionToAudit( 'woo-register' )
117
  ->checkProviders();
118
  }
119
  catch ( \Exception $e ) {
120
- $oWpError = $this->giveMeWpError( $oWpError );
121
- $oWpError->add( $this->getCon()->prefix( rand() ), $e->getMessage() );
122
  }
123
- return $oWpError;
124
  }
125
 
126
  /**
127
  * see class-wc-checkout.php
128
- * @param \WP_Error $oWpError
129
  * @param array $aPostedData
130
  * @return \WP_Error
131
  */
132
- public function checkCheckout( $aPostedData, $oWpError ) {
133
  try {
134
  $this->setActionToAudit( 'woo-checkout' )
135
  ->checkProviders();
136
  }
137
  catch ( \Exception $e ) {
138
- $oWpError = $this->giveMeWpError( $oWpError );
139
- $oWpError->add( $this->getCon()->prefix( rand() ), $e->getMessage() );
140
  }
141
- return $oWpError;
142
  }
143
  }
36
  add_action( 'woocommerce_after_checkout_validation', [ $this, 'checkCheckout' ], 10, 2 );
37
  }
38
 
39
+ private function getCheckoutHookLocation() :string {
 
 
 
40
  return apply_filters(
41
+ 'shield/woocommerce_checkout_hook_location',
42
  'woocommerce_after_checkout_registration_form'
43
  );
44
  }
83
  /**
84
  * Should be a filter added to WordPress's "authenticate" filter, but before WordPress performs
85
  * it's own authentication (theirs is priority 30, so we could go in at around 20).
86
+ * @param null|\WP_User|\WP_Error $userOrError
87
  * @param string $sUsername
88
  * @return \WP_User|\WP_Error
89
  */
90
+ public function checkLogin( $userOrError, $sUsername ) {
91
  try {
92
+ if ( !is_wp_error( $userOrError ) && !empty( $sUsername ) ) {
93
  $this->setUserToAudit( $sUsername )
94
  ->setActionToAudit( 'woo-register' )
95
  ->checkProviders();
96
  }
97
  }
98
  catch ( \Exception $e ) {
99
+ $userOrError = $this->giveMeWpError( $userOrError );
100
+ $userOrError->add( $this->getCon()->prefix( uniqid() ), $e->getMessage() );
101
  }
102
+ return $userOrError;
103
  }
104
 
105
  /**
106
+ * @param \WP_Error $wpError
107
+ * @param string $username
108
  * @return \WP_Error
109
  */
110
+ public function checkRegister( $wpError, $username ) {
111
  try {
112
+ $this->setUserToAudit( $username )
113
  ->setActionToAudit( 'woo-register' )
114
  ->checkProviders();
115
  }
116
  catch ( \Exception $e ) {
117
+ $wpError = $this->giveMeWpError( $wpError );
118
+ $wpError->add( $this->getCon()->prefix( uniqid() ), $e->getMessage() );
119
  }
120
+ return $wpError;
121
  }
122
 
123
  /**
124
  * see class-wc-checkout.php
125
+ * @param \WP_Error $wpError
126
  * @param array $aPostedData
127
  * @return \WP_Error
128
  */
129
+ public function checkCheckout( $aPostedData, $wpError ) {
130
  try {
131
  $this->setActionToAudit( 'woo-checkout' )
132
  ->checkProviders();
133
  }
134
  catch ( \Exception $e ) {
135
+ $wpError = $this->giveMeWpError( $wpError );
136
+ $wpError->add( $this->getCon()->prefix( uniqid() ), $e->getMessage() );
137
  }
138
+ return $wpError;
139
  }
140
  }
src/lib/src/Modules/LoginGuard/Lib/AntiBot/FormProviders/WordPress.php CHANGED
@@ -26,23 +26,23 @@ class WordPress extends BaseFormProvider {
26
  /**
27
  * Should be a filter added to WordPress's "authenticate" filter, but before WordPress performs
28
  * it's own authentication (theirs is priority 30, so we could go in at around 20).
29
- * @param null|\WP_User|\WP_Error $oUserOrError
30
  * @param string $username
31
  * @return \WP_User|\WP_Error
32
  */
33
- public function checkLogin( $oUserOrError, $username ) {
34
  try {
35
- if ( !is_wp_error( $oUserOrError ) && !empty( $username ) ) {
36
  $this->setUserToAudit( $username )
37
  ->setActionToAudit( 'login' )
38
  ->checkProviders();
39
  }
40
  }
41
  catch ( \Exception $e ) {
42
- $oUserOrError = $this->giveMeWpError( $oUserOrError );
43
- $oUserOrError->add( $this->getCon()->prefix( rand() ), $e->getMessage() );
44
  }
45
- return $oUserOrError;
46
  }
47
 
48
  /**
@@ -57,25 +57,25 @@ class WordPress extends BaseFormProvider {
57
  }
58
  catch ( \Exception $e ) {
59
  $wpError = $this->giveMeWpError( $wpError );
60
- $wpError->add( $this->getCon()->prefix( rand() ), $e->getMessage() );
61
  }
62
  return $wpError;
63
  }
64
 
65
  /**
66
  * @param \WP_Error $wpError
67
- * @param string $sUsername
68
  * @return \WP_Error
69
  */
70
- public function checkRegister( $wpError, $sUsername ) {
71
  try {
72
- $this->setUserToAudit( $sUsername )
73
  ->setActionToAudit( 'register' )
74
  ->checkProviders();
75
  }
76
  catch ( \Exception $e ) {
77
  $wpError = $this->giveMeWpError( $wpError );
78
- $wpError->add( $this->getCon()->prefix( rand() ), $e->getMessage() );
79
  }
80
  return $wpError;
81
  }
26
  /**
27
  * Should be a filter added to WordPress's "authenticate" filter, but before WordPress performs
28
  * it's own authentication (theirs is priority 30, so we could go in at around 20).
29
+ * @param null|\WP_User|\WP_Error $userOrError
30
  * @param string $username
31
  * @return \WP_User|\WP_Error
32
  */
33
+ public function checkLogin( $userOrError, $username ) {
34
  try {
35
+ if ( !is_wp_error( $userOrError ) && !empty( $username ) ) {
36
  $this->setUserToAudit( $username )
37
  ->setActionToAudit( 'login' )
38
  ->checkProviders();
39
  }
40
  }
41
  catch ( \Exception $e ) {
42
+ $userOrError = $this->giveMeWpError( $userOrError );
43
+ $userOrError->add( $this->getCon()->prefix( uniqid() ), $e->getMessage() );
44
  }
45
+ return $userOrError;
46
  }
47
 
48
  /**
57
  }
58
  catch ( \Exception $e ) {
59
  $wpError = $this->giveMeWpError( $wpError );
60
+ $wpError->add( $this->getCon()->prefix( uniqid() ), $e->getMessage() );
61
  }
62
  return $wpError;
63
  }
64
 
65
  /**
66
  * @param \WP_Error $wpError
67
+ * @param string $username
68
  * @return \WP_Error
69
  */
70
+ public function checkRegister( $wpError, $username ) {
71
  try {
72
+ $this->setUserToAudit( $username )
73
  ->setActionToAudit( 'register' )
74
  ->checkProviders();
75
  }
76
  catch ( \Exception $e ) {
77
  $wpError = $this->giveMeWpError( $wpError );
78
+ $wpError->add( $this->getCon()->prefix( uniqid() ), $e->getMessage() );
79
  }
80
  return $wpError;
81
  }
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Render/RenderLoginIntentPage.php CHANGED
@@ -15,10 +15,6 @@ class RenderLoginIntentPage extends RenderBase {
15
  $con = $this->getCon();
16
  /** @var LoginGuard\ModCon $mod */
17
  $mod = $this->getMod();
18
-
19
- $labels = $con->getLabels();
20
- $bannerURL = empty( $labels[ 'url_login2fa_logourl' ] ) ? $con->urls->forImage( 'shield/banner-2FA.png' ) : $labels[ 'url_login2fa_logourl' ];
21
-
22
  $data = [
23
  'strings' => [
24
  'what_is_this' => __( 'What is this?', 'wp-simple-firewall' ),
@@ -27,12 +23,11 @@ class RenderLoginIntentPage extends RenderBase {
27
  'hrefs' => [
28
  'css_bootstrap' => $con->urls->forCss( 'bootstrap' ),
29
  'js_bootstrap' => $con->urls->forJs( 'bootstrap' ),
30
- 'shield_logo' => 'https://ps.w.org/wp-simple-firewall/assets/banner-772x250.png',
31
  'what_is_this' => 'https://help.getshieldsecurity.com/article/322-what-is-the-login-authentication-portal',
32
  ],
33
  'imgs' => [
34
- 'banner' => $bannerURL,
35
- 'favicon' => $con->urls->forImage( 'pluginlogo_24x24.png' ),
36
  ],
37
  'flags' => [
38
  'show_branded_links' => !$con->getModule_SecAdmin()->getWhiteLabelController()->isEnabled(),
@@ -59,9 +54,10 @@ class RenderLoginIntentPage extends RenderBase {
59
  ]
60
  ];
61
 
62
- return $mod->renderTemplate( '/pages/login_intent/index.twig',
63
- Services::DataManipulation()->mergeArraysRecursive(
64
- $mod->getUIHandler()->getBaseDisplayData(), $data ) );
 
65
  }
66
 
67
  private function renderForm() :string {
15
  $con = $this->getCon();
16
  /** @var LoginGuard\ModCon $mod */
17
  $mod = $this->getMod();
 
 
 
 
18
  $data = [
19
  'strings' => [
20
  'what_is_this' => __( 'What is this?', 'wp-simple-firewall' ),
23
  'hrefs' => [
24
  'css_bootstrap' => $con->urls->forCss( 'bootstrap' ),
25
  'js_bootstrap' => $con->urls->forJs( 'bootstrap' ),
 
26
  'what_is_this' => 'https://help.getshieldsecurity.com/article/322-what-is-the-login-authentication-portal',
27
  ],
28
  'imgs' => [
29
+ 'banner' => empty( $con->labels ) ? $con->getLabels()[ 'url_login2fa_logourl' ] : $con->labels->url_img_pagebanner,
30
+ 'favicon' => $con->labels->icon_url_32x32,
31
  ],
32
  'flags' => [
33
  'show_branded_links' => !$con->getModule_SecAdmin()->getWhiteLabelController()->isEnabled(),
54
  ]
55
  ];
56
 
57
+ return $mod->renderTemplate(
58
+ '/pages/login_intent/index.twig',
59
+ Services::DataManipulation()->mergeArraysRecursive( $mod->getUIHandler()->getBaseDisplayData(), $data )
60
+ );
61
  }
62
 
63
  private function renderForm() :string {
src/lib/src/Modules/Plugin/AdminNotices.php CHANGED
@@ -17,6 +17,10 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
17
 
18
  switch ( $notice->id ) {
19
 
 
 
 
 
20
  case 'rules-not-running':
21
  $this->buildNotice_RulesNotRunning( $notice );
22
  break;
@@ -63,6 +67,27 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
63
  }
64
  }
65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  private function buildNotice_RulesNotRunning( NoticeVO $notice ) {
67
  $name = $this->getCon()->getHumanName();
68
 
@@ -120,9 +145,6 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
120
  ),
121
  'delete' => __( 'Click here to automatically delete the file', 'wp-simple-firewall' )
122
  ],
123
- 'ajax' => [
124
- 'delete_forceoff' => $this->getMod()->getAjaxActionData( 'delete_forceoff', true )
125
- ]
126
  ];
127
  }
128
 
@@ -280,6 +302,10 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
280
 
281
  switch ( $notice->id ) {
282
 
 
 
 
 
283
  case 'wizard_welcome':
284
  $needed = false;
285
  break;
@@ -319,9 +345,9 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
319
  return $needed;
320
  }
321
 
322
- private function isNeeded_RulesNotRunning() :bool {
323
- $con = $this->getCon();
324
- return !$con->rules->isRulesEngineReady() || !$con->rules->processComplete;
325
  }
326
 
327
  private function isNeeded_PluginTooOld() :bool {
@@ -348,4 +374,9 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
348
  }
349
  return $needed;
350
  }
 
 
 
 
 
351
  }
17
 
18
  switch ( $notice->id ) {
19
 
20
+ case 'databases-not-ready':
21
+ $this->buildNotice_DatabasesNotReady( $notice );
22
+ break;
23
+
24
  case 'rules-not-running':
25
  $this->buildNotice_RulesNotRunning( $notice );
26
  break;
67
  }
68
  }
69
 
70
+ private function buildNotice_DatabasesNotReady( NoticeVO $notice ) {
71
+ $name = $this->getCon()->getHumanName();
72
+
73
+ $notice->render_data = [
74
+ 'notice_attributes' => [],
75
+ 'strings' => [
76
+ 'title' => sprintf( '%s: %s', __( 'Warning', 'wp-simple-firewall' ),
77
+ sprintf( __( "%s Databases May Need To Be Repaired", 'wp-simple-firewall' ), $name ) ),
78
+ 'lines' => [
79
+ __( 'To save you manual work, the plugin tries to manage its database tables automatically for you. But sometimes the automated process may run into trouble.', 'wp-simple-firewall' ),
80
+ __( "If this message persists for more than ~30 seconds, please use the link below to repair the plugin's database tables.", 'wp-simple-firewall' )
81
+ .' '.__( "This will result in a loss of all activity and traffic logs.", 'wp-simple-firewall' )
82
+ ],
83
+ 'click_repair' => __( 'Click here to repair the database tables', 'wp-simple-firewall' )
84
+ ],
85
+ 'ajax' => [
86
+ 'auto_db_repair' => $this->getMod()->getAjaxActionData( 'auto_db_repair', true )
87
+ ]
88
+ ];
89
+ }
90
+
91
  private function buildNotice_RulesNotRunning( NoticeVO $notice ) {
92
  $name = $this->getCon()->getHumanName();
93
 
145
  ),
146
  'delete' => __( 'Click here to automatically delete the file', 'wp-simple-firewall' )
147
  ],
 
 
 
148
  ];
149
  }
150
 
302
 
303
  switch ( $notice->id ) {
304
 
305
+ case 'databases-not-ready':
306
+ $needed = $this->isNeeded_DatabasesNotReady();
307
+ break;
308
+
309
  case 'wizard_welcome':
310
  $needed = false;
311
  break;
345
  return $needed;
346
  }
347
 
348
+ private function isNeeded_DatabasesNotReady() :bool {
349
+ $dbs = $this->getCon()->prechecks[ 'dbs' ];
350
+ return count( $dbs ) !== count( array_filter( $dbs ) );
351
  }
352
 
353
  private function isNeeded_PluginTooOld() :bool {
374
  }
375
  return $needed;
376
  }
377
+
378
+ private function isNeeded_RulesNotRunning() :bool {
379
+ $con = $this->getCon();
380
+ return !$con->rules->isRulesEngineReady() || !$con->rules->processComplete;
381
+ }
382
  }
src/lib/src/Modules/Plugin/AjaxHandler.php CHANGED
@@ -2,6 +2,8 @@
2
 
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;
@@ -16,6 +18,7 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
16
  ] );
17
  if ( $isAuth ) {
18
  $map = array_merge( $map, [
 
19
  'mod_options_save' => [ $this, 'ajaxExec_ModOptionsSave' ],
20
  'bulk_action' => [ $this, 'ajaxExec_BulkItemAction' ],
21
  'delete_forceoff' => [ $this, 'ajaxExec_DeleteForceOff' ],
@@ -35,6 +38,49 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
35
  return $map;
36
  }
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  public function ajaxExec_ModOptionsSave() :array {
39
  $name = $this->getCon()->getHumanName();
40
 
@@ -126,7 +172,11 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
126
 
127
  public function ajaxExec_DeleteForceOff() :array {
128
  $this->getCon()->deleteForceOffFile();
129
- return [ 'success' => true ];
 
 
 
 
130
  }
131
 
132
  public function ajaxExec_RenderTableAdminNotes() :array {
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
4
 
5
+ use FernleafSystems\Wordpress\Plugin\Core\Databases\Base\Handler;
6
+ use FernleafSystems\Wordpress\Plugin\Core\Databases\Common\TableSchema;
7
  use FernleafSystems\Wordpress\Plugin\Shield;
8
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Lib\Request\FormParams;
9
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
18
  ] );
19
  if ( $isAuth ) {
20
  $map = array_merge( $map, [
21
+ 'auto_db_repair' => [ $this, 'ajaxExec_AutoDbRepair' ],
22
  'mod_options_save' => [ $this, 'ajaxExec_ModOptionsSave' ],
23
  'bulk_action' => [ $this, 'ajaxExec_BulkItemAction' ],
24
  'delete_forceoff' => [ $this, 'ajaxExec_DeleteForceOff' ],
38
  return $map;
39
  }
40
 
41
+ public function ajaxExec_AutoDbRepair() :array {
42
+ $con = $this->getCon();
43
+
44
+ // 1. Forcefully re-run all checks:
45
+ $checks = ( new Shield\Controller\Checks\PreModulesBootCheck() )
46
+ ->setCon( $con )
47
+ ->run( true );
48
+ $dbMisconfigured = count( $checks[ 'dbs' ] ) !== count( array_filter( $checks[ 'dbs' ] ) );
49
+
50
+ if ( $dbMisconfigured ) {
51
+ /** @var Handler[] $allHandlers */
52
+ $allHandlers = [
53
+ $con->getModule_AuditTrail()->getDbH_Logs(),
54
+ $con->getModule_AuditTrail()->getDbH_Meta(),
55
+ $con->getModule_Data()->getDbH_IPs(),
56
+ $con->getModule_Data()->getDbH_ReqLogs(),
57
+ $con->getModule_Data()->getDbH_UserMeta(),
58
+ $con->getModule_IPs()->getDbH_BotSignal(),
59
+ ];
60
+ Services::WpDb()->doSql(
61
+ sprintf( 'DROP TABLE IF EXISTS `%s`', implode( '`,`', array_map(
62
+ function ( $schema ) {
63
+ return $schema->getTableSchema()->table;
64
+ },
65
+ $allHandlers
66
+ ) ) )
67
+ );
68
+ foreach ( $allHandlers as $handler ) {
69
+ $handler::GetTableReadyCache()->setReady( $handler->getTableSchema(), false );
70
+ }
71
+ $msg = "Tables deleted and they'll now be recreated.";
72
+ }
73
+ else {
74
+ $msg = "Tables appear to be valid and haven't been repaired.";
75
+ }
76
+
77
+ return [
78
+ 'success' => true,
79
+ 'page_reload' => true,
80
+ 'message' => $msg
81
+ ];
82
+ }
83
+
84
  public function ajaxExec_ModOptionsSave() :array {
85
  $name = $this->getCon()->getHumanName();
86
 
172
 
173
  public function ajaxExec_DeleteForceOff() :array {
174
  $this->getCon()->deleteForceOffFile();
175
+ return [
176
+ 'success' => true,
177
+ 'page_reload' => true,
178
+ 'message' => __( 'Removed the forceoff file.', 'wp-simple-firewall' ),
179
+ ];
180
  }
181
 
182
  public function ajaxExec_RenderTableAdminNotes() :array {
src/lib/src/Modules/Plugin/Components/DashboardWidget.php CHANGED
@@ -7,6 +7,7 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Insights\Lib\MeterAnalysis\C
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
8
  use FernleafSystems\Wordpress\Plugin\Shield\Utilities\Collate\RecentStats;
9
  use FernleafSystems\Wordpress\Services\Services;
 
10
  use FernleafSystems\Wordpress\Services\Utilities\Options\Transient;
11
 
12
  class DashboardWidget {
@@ -16,26 +17,18 @@ class DashboardWidget {
16
  public function render( bool $forceRefresh = false ) :string {
17
  $con = $this->getCon();
18
  $modInsights = $con->getModule_Insights();
19
- $labels = $con->getLabels();
20
-
21
  $vars = $this->getVars( $forceRefresh );
22
  $vars[ 'generated_at' ] = Services::Request()
23
  ->carbon()
24
  ->setTimestamp( $vars[ 'generated_at' ] )
25
  ->diffForHumans();
26
-
27
- $logoSrc = $con->urls->forImage( 'pluginlogo_banner-772x250.png' );
28
- if ( $con->getModule_SecAdmin()->getWhiteLabelController()->isEnabled() ) {
29
- $logoSrc = $con->getLabels()[ 'url_login2fa_logourl' ] ?? ( $con->getLabels()[ 'url_dashboardlogourl' ] ?? '' );
30
- }
31
-
32
  return $this->getMod()
33
  ->getRenderer()
34
  ->setTemplate( '/admin/admin_dashboard_widget.twig' )
35
  ->setRenderData( [
36
  'hrefs' => [
37
  'overview' => $modInsights->getUrl_SubInsightsPage( 'overview' ),
38
- 'logo' => $labels[ 'PluginURI' ],
39
  'audit_trail' => $modInsights->getUrl_SubInsightsPage( 'audit_trail' ),
40
  'sessions' => $modInsights->getUrl_SubInsightsPage( 'users' ),
41
  'ips' => $modInsights->getUrl_SubInsightsPage( 'ips' ),
@@ -44,7 +37,7 @@ class DashboardWidget {
44
  'show_internal_links' => $con->isPluginAdmin()
45
  ],
46
  'imgs' => [
47
- 'logo' => $logoSrc,
48
  ],
49
  'strings' => [
50
  'security_level' => __( 'Level', 'wp-simple-firewall' ),
@@ -169,10 +162,19 @@ class DashboardWidget {
169
  ),
170
  'recent_users' => array_map(
171
  function ( $sess ) use ( $modInsights ) {
 
 
 
 
 
 
 
 
 
 
172
  return [
173
- 'user' => $sess[ 'user_login' ],
174
- 'user_href' => Services::WpUsers()
175
- ->getAdminUrl_ProfileEdit( $sess[ 'user_id' ] ),
176
  'ip' => $sess[ 'ip' ],
177
  'ip_href' => $modInsights->getUrl_IpAnalysis( $sess[ 'ip' ] ),
178
  'at' => Services::Request()
@@ -189,4 +191,8 @@ class DashboardWidget {
189
 
190
  return $vars;
191
  }
 
 
 
 
192
  }
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
8
  use FernleafSystems\Wordpress\Plugin\Shield\Utilities\Collate\RecentStats;
9
  use FernleafSystems\Wordpress\Services\Services;
10
+ use FernleafSystems\Wordpress\Services\Utilities\Obfuscate;
11
  use FernleafSystems\Wordpress\Services\Utilities\Options\Transient;
12
 
13
  class DashboardWidget {
17
  public function render( bool $forceRefresh = false ) :string {
18
  $con = $this->getCon();
19
  $modInsights = $con->getModule_Insights();
 
 
20
  $vars = $this->getVars( $forceRefresh );
21
  $vars[ 'generated_at' ] = Services::Request()
22
  ->carbon()
23
  ->setTimestamp( $vars[ 'generated_at' ] )
24
  ->diffForHumans();
 
 
 
 
 
 
25
  return $this->getMod()
26
  ->getRenderer()
27
  ->setTemplate( '/admin/admin_dashboard_widget.twig' )
28
  ->setRenderData( [
29
  'hrefs' => [
30
  'overview' => $modInsights->getUrl_SubInsightsPage( 'overview' ),
31
+ 'logo' => empty( $con->labels ) ? $con->getLabels()[ 'PluginURI' ] : $con->labels->PluginURI,
32
  'audit_trail' => $modInsights->getUrl_SubInsightsPage( 'audit_trail' ),
33
  'sessions' => $modInsights->getUrl_SubInsightsPage( 'users' ),
34
  'ips' => $modInsights->getUrl_SubInsightsPage( 'ips' ),
37
  'show_internal_links' => $con->isPluginAdmin()
38
  ],
39
  'imgs' => [
40
+ 'logo' => empty( $con->labels ) ? $con->getLabels()[ 'url_login2fa_logourl' ] : $con->labels->url_img_pagebanner,
41
  ],
42
  'strings' => [
43
  'security_level' => __( 'Level', 'wp-simple-firewall' ),
162
  ),
163
  'recent_users' => array_map(
164
  function ( $sess ) use ( $modInsights ) {
165
+
166
+ $user = $sess[ 'user_login' ];
167
+ $userHref = Services::WpUsers()->getAdminUrl_ProfileEdit( $sess[ 'user_id' ] );
168
+ if ( $this->isObfuscateData() ) {
169
+ $user = is_email( $user ) ?
170
+ Obfuscate::Email( $user )
171
+ : substr( $user, 0, 1 ).'****'.substr( $user, -1, 1 );
172
+ $userHref = '#';
173
+ }
174
+
175
  return [
176
+ 'user' => $user,
177
+ 'user_href' => $userHref,
 
178
  'ip' => $sess[ 'ip' ],
179
  'ip_href' => $modInsights->getUrl_IpAnalysis( $sess[ 'ip' ] ),
180
  'at' => Services::Request()
191
 
192
  return $vars;
193
  }
194
+
195
+ private function isObfuscateData() :bool {
196
+ return !$this->getCon()->isPluginAdmin();
197
+ }
198
  }
src/lib/src/Modules/Plugin/Debug.php CHANGED
@@ -4,20 +4,35 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots\ShieldNET\BuildData;
 
7
  use FernleafSystems\Wordpress\Plugin\Shield\Tests\RunTests;
 
8
  use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Verify\Email;
9
  use FernleafSystems\Wordpress\Services\Utilities\Net\IpID;
10
 
11
  class Debug extends Modules\Base\Debug {
12
 
13
  public function run() {
14
- $this->testAAAA( 'fwdproxy-odn-017.fbsv.net' );
 
15
  die( 'finish' );
16
  }
17
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  private function testAAAA( string $hostname ) {
19
- $id = ( new IpID('2a03:2880:32ff:11::face:b00c', 'facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)') )->run();
20
- var_dump($id);
21
  // $record = dns_get_record( $hostname, DNS_AAAA );
22
  // var_dump( $record );
23
  }
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots\ShieldNET\BuildData;
7
+ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Afs\Processing\FileScanOptimiser;
8
  use FernleafSystems\Wordpress\Plugin\Shield\Tests\RunTests;
9
+ use FernleafSystems\Wordpress\Services\Utilities\File\Search\SearchFile;
10
  use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Verify\Email;
11
  use FernleafSystems\Wordpress\Services\Utilities\Net\IpID;
12
 
13
  class Debug extends Modules\Base\Debug {
14
 
15
  public function run() {
16
+ // $this->testAAAA( 'fwdproxy-odn-017.fbsv.net' );
17
+ $this->cleanoptimisehashes();
18
  die( 'finish' );
19
  }
20
 
21
+ private function cleanoptimisehashes() {
22
+ ( new FileScanOptimiser() )
23
+ ->setMod( $this->getMod() )
24
+ ->cleanStaleHashesOlderThan( 1654091228 );
25
+ }
26
+
27
+ private function testFileSearch() {
28
+ $searcher = new SearchFile( $this->getCon()->root_file );
29
+ var_dump( $searcher->exists( 'a' ) );
30
+ var_dump( $searcher->multipleFindFirst( [ 'init', 'if' ] ) );
31
+ }
32
+
33
  private function testAAAA( string $hostname ) {
34
+ $id = ( new IpID( '2a03:2880:32ff:11::face:b00c', 'facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)' ) )->run();
35
+ var_dump( $id );
36
  // $record = dns_get_record( $hostname, DNS_AAAA );
37
  // var_dump( $record );
38
  }
src/lib/src/Modules/Plugin/Lib/ImportExport/ImportExportController.php CHANGED
@@ -133,18 +133,18 @@ class ImportExportController extends Shield\Modules\Base\Common\ExecOnceModConsu
133
  * We've been notified that there's an update to pull in from the master site so we set a cron to do this.
134
  */
135
  private function runOptionsUpdateNotified() {
136
- $oCon = $this->getCon();
137
  /** @var Plugin\Options $opts */
138
  $opts = $this->getOptions();
139
 
140
- $sCronHook = $oCon->prefix( 'importexport_updatenotified' );
141
- if ( wp_next_scheduled( $sCronHook ) ) {
142
- wp_clear_scheduled_hook( $sCronHook );
143
  }
144
 
145
- if ( !wp_next_scheduled( $sCronHook ) ) {
146
 
147
- wp_schedule_single_event( Services::Request()->ts() + 12, $sCronHook );
148
 
149
  preg_match( '#.*WordPress/.*\s+(.*)\s?#', Services::Request()->getUserAgent(), $aMatches );
150
  if ( !empty( $aMatches[ 1 ] ) && filter_var( $aMatches[ 1 ], FILTER_VALIDATE_URL ) ) {
@@ -157,7 +157,7 @@ class ImportExportController extends Shield\Modules\Base\Common\ExecOnceModConsu
157
  $url = '';
158
  }
159
 
160
- $this->getCon()->fireEvent(
161
  'import_notify_received',
162
  [ 'audit_params' => [ 'master_site' => $opts->getImportExportMasterImportUrl() ] ]
163
  );
133
  * We've been notified that there's an update to pull in from the master site so we set a cron to do this.
134
  */
135
  private function runOptionsUpdateNotified() {
136
+ $con = $this->getCon();
137
  /** @var Plugin\Options $opts */
138
  $opts = $this->getOptions();
139
 
140
+ $cronHook = $con->prefix( 'importexport_updatenotified' );
141
+ if ( wp_next_scheduled( $cronHook ) ) {
142
+ wp_clear_scheduled_hook( $cronHook );
143
  }
144
 
145
+ if ( !wp_next_scheduled( $cronHook ) ) {
146
 
147
+ wp_schedule_single_event( Services::Request()->ts() + 12, $cronHook );
148
 
149
  preg_match( '#.*WordPress/.*\s+(.*)\s?#', Services::Request()->getUserAgent(), $aMatches );
150
  if ( !empty( $aMatches[ 1 ] ) && filter_var( $aMatches[ 1 ], FILTER_VALIDATE_URL ) ) {
157
  $url = '';
158
  }
159
 
160
+ $con->fireEvent(
161
  'import_notify_received',
162
  [ 'audit_params' => [ 'master_site' => $opts->getImportExportMasterImportUrl() ] ]
163
  );
src/lib/src/Modules/Plugin/ModCon.php CHANGED
@@ -6,6 +6,7 @@ use FernleafSystems\Wordpress\Plugin\Shield;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Controller\Assets\Enqueue;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield;
8
  use FernleafSystems\Wordpress\Services\Services;
 
9
  use FernleafSystems\Wordpress\Services\Utilities\Net\VisitorIpDetection;
10
 
11
  class ModCon extends BaseShield\ModCon {
@@ -100,13 +101,20 @@ class ModCon extends BaseShield\ModCon {
100
  * Forcefully sets preferred Visitor IP source in the Data component for use throughout the plugin
101
  */
102
  private function setVisitorIpSource() {
 
103
  /** @var Options $opts */
104
  $opts = $this->getOptions();
105
  if ( $opts->getIpSource() !== 'AUTO_DETECT_IP' ) {
 
 
 
106
  Services::IP()->setIpDetector(
107
  ( new VisitorIpDetection() )->setPreferredSource( $opts->getIpSource() )
108
  );
109
  }
 
 
 
110
  }
111
 
112
  protected function handleFileDownload( string $downloadID ) {
@@ -164,13 +172,6 @@ class ModCon extends BaseShield\ModCon {
164
  return $can;
165
  }
166
 
167
- /**
168
- * @deprecated 15.0
169
- */
170
- public function getActivePluginFeatures() :array {
171
- return $this->getOptions()->getDef( 'active_plugin_features' );
172
- }
173
-
174
  public function getLinkToTrackingDataDump() :string {
175
  return add_query_arg( [ 'shield_action' => 'dump_tracking_data' ], Services::WpGeneral()->getAdminUrl() );
176
  }
@@ -439,6 +440,12 @@ class ModCon extends BaseShield\ModCon {
439
  'ajax' => [
440
  'render_dashboard_widget' => $this->getAjaxActionData( 'render_dashboard_widget' )
441
  ]
 
 
 
 
 
 
442
  ]
443
  ],
444
  ]
@@ -501,12 +508,4 @@ class ModCon extends BaseShield\ModCon {
501
  protected function getNamespaceBase() :string {
502
  return 'Plugin';
503
  }
504
-
505
- /**
506
- * @deprecated 15.0
507
- */
508
- public function getImportExportWhitelist() :array {
509
- $list = $this->getOptions()->getOpt( 'importexport_whitelist', [] );
510
- return is_array( $list ) ? $list : [];
511
- }
512
  }
6
  use FernleafSystems\Wordpress\Plugin\Shield\Controller\Assets\Enqueue;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield;
8
  use FernleafSystems\Wordpress\Services\Services;
9
+ use FernleafSystems\Wordpress\Services\Utilities\Net\RequestIpDetect;
10
  use FernleafSystems\Wordpress\Services\Utilities\Net\VisitorIpDetection;
11
 
12
  class ModCon extends BaseShield\ModCon {
101
  * Forcefully sets preferred Visitor IP source in the Data component for use throughout the plugin
102
  */
103
  private function setVisitorIpSource() {
104
+ $con = $this->getCon();
105
  /** @var Options $opts */
106
  $opts = $this->getOptions();
107
  if ( $opts->getIpSource() !== 'AUTO_DETECT_IP' ) {
108
+ Services::Request()->setIpDetector(
109
+ ( new RequestIpDetect() )->setPreferredSource( $opts->getIpSource() )
110
+ );
111
  Services::IP()->setIpDetector(
112
  ( new VisitorIpDetection() )->setPreferredSource( $opts->getIpSource() )
113
  );
114
  }
115
+ $con->this_req->ip = Services::Request()->ip();
116
+ $con->this_req->ip_is_public = !empty( $con->this_req->ip )
117
+ && Services::IP()->isValidIp_PublicRemote( $con->this_req->ip );
118
  }
119
 
120
  protected function handleFileDownload( string $downloadID ) {
172
  return $can;
173
  }
174
 
 
 
 
 
 
 
 
175
  public function getLinkToTrackingDataDump() :string {
176
  return add_query_arg( [ 'shield_action' => 'dump_tracking_data' ], Services::WpGeneral()->getAdminUrl() );
177
  }
440
  'ajax' => [
441
  'render_dashboard_widget' => $this->getAjaxActionData( 'render_dashboard_widget' )
442
  ]
443
+ ],
444
+ 'notices' => [
445
+ 'ajax' => [
446
+ 'auto_db_repair' => $this->getAjaxActionData( 'auto_db_repair' ),
447
+ 'delete_forceoff' => $this->getAjaxActionData( 'delete_forceoff' ),
448
+ ]
449
  ]
450
  ],
451
  ]
508
  protected function getNamespaceBase() :string {
509
  return 'Plugin';
510
  }
 
 
 
 
 
 
 
 
511
  }
src/lib/src/Modules/Plugin/Options.php CHANGED
@@ -36,13 +36,6 @@ class Options extends BaseShield\Options {
36
  return !empty( $this->getImportExportMasterImportUrl() );
37
  }
38
 
39
- /**
40
- * @deprecated 15.0
41
- */
42
- public function isIpSourceAutoDetect() :bool {
43
- return $this->getIpSource() == 'AUTO_DETECT_IP';
44
- }
45
-
46
  public function isPluginGloballyDisabled() :bool {
47
  return !$this->isOpt( 'global_enable_plugin_features', 'Y' );
48
  }
36
  return !empty( $this->getImportExportMasterImportUrl() );
37
  }
38
 
 
 
 
 
 
 
 
39
  public function isPluginGloballyDisabled() :bool {
40
  return !$this->isOpt( 'global_enable_plugin_features', 'Y' );
41
  }
src/lib/src/Modules/Plugin/Processor.php CHANGED
@@ -39,13 +39,6 @@ class Processor extends BaseShield\Processor {
39
  } );
40
  }
41
 
42
- /**
43
- * @deprecated 15.0
44
- */
45
- private function printDashboardWidget() {
46
- echo '';
47
- }
48
-
49
  public function runDailyCron() {
50
  $this->getCon()->fireEvent( 'test_cron_run' );
51
  ( new CleanStorage() )
39
  } );
40
  }
41
 
 
 
 
 
 
 
 
42
  public function runDailyCron() {
43
  $this->getCon()->fireEvent( 'test_cron_run' );
44
  ( new CleanStorage() )
src/lib/src/Modules/Plugin/Strings.php CHANGED
@@ -478,7 +478,6 @@ class Strings extends Base\Strings {
478
  __( 'Week', 'wp-simple-firewall' );
479
  __( 'Month', 'wp-simple-firewall' );
480
  __( 'With Shield Bot Protection', 'wp-simple-firewall' );
481
- __( 'Audit Log Only', 'wp-simple-firewall' );
482
  __( 'Increment Offense Counter', 'wp-simple-firewall' );
483
  __( 'Double-Increment Offense Counter', 'wp-simple-firewall' );
484
  __( 'Immediate Block', 'wp-simple-firewall' );
478
  __( 'Week', 'wp-simple-firewall' );
479
  __( 'Month', 'wp-simple-firewall' );
480
  __( 'With Shield Bot Protection', 'wp-simple-firewall' );
 
481
  __( 'Increment Offense Counter', 'wp-simple-firewall' );
482
  __( 'Double-Increment Offense Counter', 'wp-simple-firewall' );
483
  __( 'Immediate Block', 'wp-simple-firewall' );
src/lib/src/Modules/SecurityAdmin/AdminNotices.php CHANGED
@@ -80,20 +80,19 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
80
  }
81
 
82
  protected function isDisplayNeeded( NoticeVO $notice ) :bool {
83
- /** @var Options $oOpts */
84
- $oOpts = $this->getOptions();
85
 
86
- $sCurrentPage = Services::WpPost()->getCurrentPage();
87
 
88
  switch ( $notice->id ) {
89
 
90
  case 'admin-users-restricted':
91
- $needed = in_array( $sCurrentPage, $oOpts->getDef( 'restricted_pages_users' ) );
92
  break;
93
 
94
  case 'certain-options-restricted':
95
- $sCurrentGetPage = Services::Request()->query( 'page' );
96
- $needed = empty( $sCurrentGetPage ) && in_array( $sCurrentPage, $oOpts->getOptionsPagesToRestrict() );
97
  break;
98
 
99
  default:
80
  }
81
 
82
  protected function isDisplayNeeded( NoticeVO $notice ) :bool {
83
+ /** @var Options $opts */
84
+ $opts = $this->getOptions();
85
 
86
+ $current = Services::WpPost()->getCurrentPage();
87
 
88
  switch ( $notice->id ) {
89
 
90
  case 'admin-users-restricted':
91
+ $needed = in_array( $current, $opts->getDef( 'restricted_pages_users' ) );
92
  break;
93
 
94
  case 'certain-options-restricted':
95
+ $needed = empty( Services::Request()->query( 'page' ) ) && in_array( $current, $opts->getOptionsPagesToRestrict() );
 
96
  break;
97
 
98
  default:
src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/Restrictions/BaseCapabilitiesRestrict.php CHANGED
@@ -40,7 +40,8 @@ class BaseCapabilitiesRestrict extends Base {
40
  protected function getRestrictedCapabilities() :array {
41
  /** @var Options $opts */
42
  $opts = $this->getOptions();
43
- return $opts->getSecAdminAreaCaps( static::AREA_SLUG );
 
44
  }
45
 
46
  protected function isCapabilityToBeRestricted( string $cap ) :bool {
40
  protected function getRestrictedCapabilities() :array {
41
  /** @var Options $opts */
42
  $opts = $this->getOptions();
43
+ $caps = $opts->getOpt( 'admin_access_restrict_'.static::AREA_SLUG, [] );
44
+ return is_array( $caps ) ? $caps : [];
45
  }
46
 
47
  protected function isCapabilityToBeRestricted( string $cap ) :bool {
src/lib/src/Modules/SecurityAdmin/Lib/SecurityAdmin/SecurityAdminController.php CHANGED
@@ -17,12 +17,17 @@ class SecurityAdminController extends ExecOnceModConsumer {
17
  }
18
 
19
  protected function run() {
20
-
21
- add_filter( $this->getCon()->prefix( 'is_plugin_admin' ), [ $this, 'adjustUserAdminPermissions' ] );
22
  add_action( 'admin_init', function () {
23
  $this->enqueueJS();
24
  } );
 
 
25
 
 
 
 
 
26
  if ( !$this->getCon()->isPluginAdmin() ) {
27
  foreach ( $this->enumRestrictionZones() as $zone ) {
28
  ( new $zone() )->setMod( $this->getMod() )->execute();
@@ -74,7 +79,7 @@ class SecurityAdminController extends ExecOnceModConsumer {
74
  'req_email_remove' => $mod->getAjaxActionData( 'req_email_remove' ),
75
  ],
76
  'flags' => [
77
- 'restrict_options' => !$isSecAdmin && $opts->getAdminAccessArea_Options(),
78
  'run_checks' => $this->getCon()->getIsPage_PluginAdmin() && $isSecAdmin
79
  && !$this->isCurrentUserRegisteredSecAdmin(),
80
  ],
@@ -158,7 +163,7 @@ class SecurityAdminController extends ExecOnceModConsumer {
158
  $opts = $this->getOptions();
159
  return $mod->renderTemplate( '/components/security_admin/login_box.twig', [
160
  'flags' => [
161
- 'restrict_options' => $opts->getAdminAccessArea_Options()
162
  ],
163
  'strings' => [
164
  'access_message' => __( 'Enter your Security Admin PIN', 'wp-simple-firewall' ),
17
  }
18
 
19
  protected function run() {
20
+ add_filter( $this->getCon()->prefix( 'is_plugin_admin' ), [ $this, 'adjustUserAdminPermissions' ], 0 );
 
21
  add_action( 'admin_init', function () {
22
  $this->enqueueJS();
23
  } );
24
+ add_action( 'init', [ $this, 'setupRestrictions' ] );
25
+ }
26
 
27
+ /**
28
+ * Restrictions should only be applied after INIT
29
+ */
30
+ public function setupRestrictions() {
31
  if ( !$this->getCon()->isPluginAdmin() ) {
32
  foreach ( $this->enumRestrictionZones() as $zone ) {
33
  ( new $zone() )->setMod( $this->getMod() )->execute();
79
  'req_email_remove' => $mod->getAjaxActionData( 'req_email_remove' ),
80
  ],
81
  'flags' => [
82
+ 'restrict_options' => !$isSecAdmin && $opts->isRestrictWpOptions(),
83
  'run_checks' => $this->getCon()->getIsPage_PluginAdmin() && $isSecAdmin
84
  && !$this->isCurrentUserRegisteredSecAdmin(),
85
  ],
163
  $opts = $this->getOptions();
164
  return $mod->renderTemplate( '/components/security_admin/login_box.twig', [
165
  'flags' => [
166
+ 'restrict_options' => $opts->isRestrictWpOptions()
167
  ],
168
  'strings' => [
169
  'access_message' => __( 'Enter your Security Admin PIN', 'wp-simple-firewall' ),
src/lib/src/Modules/SecurityAdmin/Lib/WhiteLabel/BuildOptions.php CHANGED
@@ -5,6 +5,9 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Lib\Whit
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
6
  use FernleafSystems\Wordpress\Services\Services;
7
 
 
 
 
8
  class BuildOptions {
9
 
10
  use ModConsumer;
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
6
  use FernleafSystems\Wordpress\Services\Services;
7
 
8
+ /**
9
+ * @deprecated 15.1
10
+ */
11
  class BuildOptions {
12
 
13
  use ModConsumer;
src/lib/src/Modules/SecurityAdmin/Lib/WhiteLabel/WhitelabelController.php CHANGED
@@ -2,6 +2,7 @@
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Lib\WhiteLabel;
4
 
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Common\ExecOnceModConsumer;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin;
7
  use FernleafSystems\Wordpress\Services\Services;
@@ -22,55 +23,93 @@ class WhitelabelController extends ExecOnceModConsumer {
22
 
23
  protected function run() {
24
  $con = $this->getCon();
25
- add_action( 'init', [ $this, 'onWpInit' ] );
26
  add_filter( $con->prefix( 'is_relabelled' ), '__return_true' );
27
- add_filter( $con->prefix( 'plugin_labels' ), [ $this, 'applyPluginLabels' ] );
28
  add_filter( 'plugin_row_meta', [ $this, 'removePluginMetaLinks' ], 200, 2 );
29
- add_action( 'admin_print_footer_scripts-plugin-editor.php', [ $this, 'hideFromPluginEditor' ] );
30
- }
31
 
32
- public function onWpInit() {
33
  /** @var SecurityAdmin\Options $opts */
34
  $opts = $this->getOptions();
35
- if ( $opts->isOpt( 'wl_hide_updates', 'Y' ) && $this->isNeedToHideUpdates() && !$this->getCon()
36
- ->isPluginAdmin() ) {
37
- $this->hideUpdates();
 
 
 
 
 
 
 
38
  }
39
  }
40
 
41
- /**
42
- * Depending on the page, we hide the update data,
43
- * or we adjust the number of displayed updates counts
44
- */
45
- protected function hideUpdates() {
46
- if ( in_array( Services::WpPost()->getCurrentPage(), [ 'plugins.php', 'update-core.php' ] ) ) {
47
- add_filter( 'site_transient_update_plugins', [ $this, 'hidePluginUpdatesFromUI' ] );
 
48
  }
49
- else {
50
- add_filter( 'wp_get_update_data', [ $this, 'adjustUpdateDataCount' ] );
 
 
 
51
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  }
53
 
54
  /**
55
  * Adjusts the available updates count so as not to include Shield updates if they're hidden
56
- * @param array $aUpdateData
57
  * @return array
58
  */
59
- public function adjustUpdateDataCount( $aUpdateData ) {
60
 
61
  $file = $this->getCon()->base_file;
62
  if ( Services::WpPlugins()->isUpdateAvailable( $file ) ) {
63
- $aUpdateData[ 'counts' ][ 'total' ]--;
64
- $aUpdateData[ 'counts' ][ 'plugins' ]--;
65
  }
66
 
67
- return $aUpdateData;
68
- }
69
-
70
- public function hideFromPluginEditor() {
71
- // TODO
72
  }
73
 
 
 
 
74
  public function applyPluginLabels( array $pluginLabels ) :array {
75
  $labels = ( new BuildOptions() )
76
  ->setMod( $this->getMod() )
@@ -120,9 +159,8 @@ class WhitelabelController extends ExecOnceModConsumer {
120
  public function verifyUrls() {
121
  $DP = Services::Data();
122
  $opts = $this->getOptions();
123
- $optsBuilder = ( new BuildOptions() )->setMod( $this->getMod() );
124
  foreach ( [ 'wl_menuiconurl', 'wl_dashboardlogourl', 'wl_login2fa_logourl' ] as $key ) {
125
- if ( $opts->isOptChanged( $key ) && !$DP->isValidWebUrl( $optsBuilder->buildWlImageUrl( $key ) ) ) {
126
  $opts->resetOptToDefault( $key );
127
  }
128
  }
@@ -152,7 +190,30 @@ class WhitelabelController extends ExecOnceModConsumer {
152
  return $plugins;
153
  }
154
 
155
- private function isNeedToHideUpdates() :bool {
156
- return is_admin() && !Services::WpGeneral()->isCron();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  }
158
  }
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin\Lib\WhiteLabel;
4
 
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Controller\Config\Labels;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Common\ExecOnceModConsumer;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\SecurityAdmin;
8
  use FernleafSystems\Wordpress\Services\Services;
23
 
24
  protected function run() {
25
  $con = $this->getCon();
 
26
  add_filter( $con->prefix( 'is_relabelled' ), '__return_true' );
27
+ add_filter( $con->prefix( 'labels' ), [ $this, 'applyWhiteLabels' ], 200 );
28
  add_filter( 'plugin_row_meta', [ $this, 'removePluginMetaLinks' ], 200, 2 );
 
 
29
 
 
30
  /** @var SecurityAdmin\Options $opts */
31
  $opts = $this->getOptions();
32
+ if ( $opts->isOpt( 'wl_hide_updates', 'Y' ) && is_admin()
33
+ && !Services::WpGeneral()->isCron()
34
+ && !$this->getCon()->isPluginAdmin() ) {
35
+
36
+ if ( in_array( Services::WpPost()->getCurrentPage(), [ 'plugins.php', 'update-core.php' ] ) ) {
37
+ add_filter( 'site_transient_update_plugins', [ $this, 'hidePluginUpdatesFromUI' ] );
38
+ }
39
+ else {
40
+ add_filter( 'wp_get_update_data', [ $this, 'adjustUpdateDataCount' ] );
41
+ }
42
  }
43
  }
44
 
45
+ public function applyWhiteLabels( Labels $labels ) :Labels {
46
+ $opts = $this->getOptions();
47
+
48
+ // these are the old white labelling keys which will be replaced upon final release of white labelling.
49
+ $name = $opts->getOpt( 'wl_pluginnamemain' );
50
+ if ( !empty( $name ) ) {
51
+ $labels->Name = $name;
52
+ $labels->Title = $name;
53
  }
54
+
55
+ $companyName = $opts->getOpt( 'wl_companyname' );
56
+ if ( !empty( $companyName ) ) {
57
+ $labels->Author = $companyName;
58
+ $labels->AuthorName = $companyName;
59
  }
60
+
61
+ $labels->MenuTitle = empty( $opts->getOpt( 'wl_namemenu' ) ) ? $labels->Name : $opts->getOpt( 'wl_namemenu' );
62
+
63
+ if ( !empty( $opts->getOpt( 'wl_description' ) ) ) {
64
+ $labels->Description = $opts->getOpt( 'wl_description' );
65
+ }
66
+
67
+ $homeURL = $opts->getOpt( 'wl_homeurl' );
68
+ if ( !empty( $homeURL ) ) {
69
+ $labels->PluginURI = $homeURL;
70
+ $labels->AuthorURI = $homeURL;
71
+ }
72
+
73
+ $urlIcon = $this->constructImageURL( 'wl_menuiconurl' );
74
+ if ( !empty( $urlIcon ) ) {
75
+ $labels->icon_url_16x16 = $urlIcon;
76
+ $labels->icon_url_32x32 = $urlIcon;
77
+ }
78
+
79
+ $urlDashboardLogo = $this->constructImageURL( 'wl_dashboardlogourl' );
80
+ if ( !empty( $urlDashboardLogo ) ) {
81
+ $labels->icon_url_128x128 = $urlDashboardLogo;
82
+ }
83
+
84
+ $urlPageBanner = $this->constructImageURL( 'wl_login2fa_logourl' );
85
+ if ( !empty( $urlPageBanner ) ) {
86
+ $labels->url_img_pagebanner = $urlPageBanner;
87
+ }
88
+
89
+ $labels->url_secadmin_forgotten_key = $labels->AuthorURI;
90
+
91
+ return $labels;
92
  }
93
 
94
  /**
95
  * Adjusts the available updates count so as not to include Shield updates if they're hidden
96
+ * @param array $updateData
97
  * @return array
98
  */
99
+ public function adjustUpdateDataCount( $updateData ) {
100
 
101
  $file = $this->getCon()->base_file;
102
  if ( Services::WpPlugins()->isUpdateAvailable( $file ) ) {
103
+ $updateData[ 'counts' ][ 'total' ]--;
104
+ $updateData[ 'counts' ][ 'plugins' ]--;
105
  }
106
 
107
+ return $updateData;
 
 
 
 
108
  }
109
 
110
+ /**
111
+ * @deprecated 15.1
112
+ */
113
  public function applyPluginLabels( array $pluginLabels ) :array {
114
  $labels = ( new BuildOptions() )
115
  ->setMod( $this->getMod() )
159
  public function verifyUrls() {
160
  $DP = Services::Data();
161
  $opts = $this->getOptions();
 
162
  foreach ( [ 'wl_menuiconurl', 'wl_dashboardlogourl', 'wl_login2fa_logourl' ] as $key ) {
163
+ if ( $opts->isOptChanged( $key ) && !$DP->isValidWebUrl( $this->constructImageURL( $key ) ) ) {
164
  $opts->resetOptToDefault( $key );
165
  }
166
  }
190
  return $plugins;
191
  }
192
 
193
+ /**
194
+ * We cater for 3 options:
195
+ * Full URL
196
+ * Relative path URL: i.e. starts with /
197
+ * Or Plugin image URL i.e. doesn't start with HTTP or /
198
+ * @param string $key
199
+ * @return string
200
+ */
201
+ private function constructImageURL( string $key ) :string {
202
+ $opts = $this->getOptions();
203
+
204
+ $url = $opts->getOpt( $key );
205
+ if ( empty( $url ) ) {
206
+ $opts->resetOptToDefault( $key );
207
+ $url = $opts->getOpt( $key );
208
+ }
209
+ if ( !empty( $url ) && !Services::Data()->isValidWebUrl( $url ) && strpos( $url, '/' ) !== 0 ) {
210
+ $url = $this->getCon()->urls->forImage( $url );
211
+ if ( empty( $url ) ) {
212
+ $opts->resetOptToDefault( $key );
213
+ $url = $this->getCon()->urls->forImage( $opts->getOpt( $key ) );
214
+ }
215
+ }
216
+
217
+ return $url;
218
  }
219
  }
src/lib/src/Modules/SecurityAdmin/Options.php CHANGED
@@ -12,15 +12,16 @@ class Options extends BaseShield\Options {
12
  }
13
 
14
  /**
15
- * @deprecated 15.0 - see isRestrictWpOptions()
16
  */
17
  public function getAdminAccessArea_Options() :bool {
18
  return $this->isOpt( 'admin_access_restrict_options', 'Y' );
19
  }
20
 
21
  /**
22
- * @since 11.1
23
  * @param string $area one of plugins, themes
 
24
  */
25
  public function getSecAdminAreaCaps( $area = 'plugins' ) :array {
26
  $d = $this->getOpt( 'admin_access_restrict_'.$area, [] );
@@ -32,25 +33,16 @@ class Options extends BaseShield\Options {
32
  return is_array( $options ) ? $options : [];
33
  }
34
 
35
- /**
36
- * TODO: Bug where if $sType is defined, it'll be set to 'wp' anyway
37
- * @param string $type - wp or wpms
38
- * @return array
39
- */
40
- public function getOptionsToRestrict( $type = '' ) {
41
- $type = empty( $type ) ? ( Services::WpGeneral()->isMultisite() ? 'wpms' : 'wp' ) : 'wp';
42
  $options = $this->getRestrictedOptions();
43
- return ( isset( $options[ $type.'_options' ] ) && is_array( $options[ $type.'_options' ] ) ) ? $options[ $type.'_options' ] : [];
44
  }
45
 
46
- /**
47
- * @param string $type - wp or wpms
48
- * @return array
49
- */
50
- public function getOptionsPagesToRestrict( $type = '' ) {
51
- $type = empty( $type ) ? ( Services::WpGeneral()->isMultisite() ? 'wpms' : 'wp' ) : 'wp';
52
- $aOptions = $this->getRestrictedOptions();
53
- return ( isset( $aOptions[ $type.'_pages' ] ) && is_array( $aOptions[ $type.'_pages' ] ) ) ? $aOptions[ $type.'_pages' ] : [];
54
  }
55
 
56
  public function getSecurityAdminUsers() :array {
12
  }
13
 
14
  /**
15
+ * @deprecated 15.1
16
  */
17
  public function getAdminAccessArea_Options() :bool {
18
  return $this->isOpt( 'admin_access_restrict_options', 'Y' );
19
  }
20
 
21
  /**
22
+ * @since 11.1
23
  * @param string $area one of plugins, themes
24
+ * @deprecated 15.1
25
  */
26
  public function getSecAdminAreaCaps( $area = 'plugins' ) :array {
27
  $d = $this->getOpt( 'admin_access_restrict_'.$area, [] );
33
  return is_array( $options ) ? $options : [];
34
  }
35
 
36
+ public function getOptionsToRestrict() :array {
37
+ $type = ( Services::WpGeneral()->isMultisite() ? 'wpms' : 'wp' ).'_options';
 
 
 
 
 
38
  $options = $this->getRestrictedOptions();
39
+ return is_array( $options[ $type ] ?? [] ) ? $options[ $type ] : [];
40
  }
41
 
42
+ public function getOptionsPagesToRestrict() :array {
43
+ $type = ( Services::WpGeneral()->isMultisite() ? 'wpms' : 'wp' ).'_pages';
44
+ $options = $this->getRestrictedOptions();
45
+ return is_array( $options[ $type ] ?? [] ) ? $options[ $type ] : [];
 
 
 
 
46
  }
47
 
48
  public function getSecurityAdminUsers() :array {
src/lib/src/Modules/SecurityAdmin/Processor.php CHANGED
@@ -6,7 +6,7 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield;
6
 
7
  class Processor extends BaseShield\Processor {
8
 
9
- public function onWpInit() {
10
  /** @var ModCon $mod */
11
  $mod = $this->getMod();
12
  $mod->getSecurityAdminController()->execute();
6
 
7
  class Processor extends BaseShield\Processor {
8
 
9
+ protected function run() {
10
  /** @var ModCon $mod */
11
  $mod = $this->getMod();
12
  $mod->getSecurityAdminController()->execute();
src/lib/src/Modules/Sessions/Lib/SessionController.php CHANGED
@@ -18,18 +18,6 @@ class SessionController extends ExecOnceModConsumer {
18
  */
19
  private $currentWP;
20
 
21
- /**
22
- * @var Session\EntryVO
23
- * @deprecated 15.0
24
- */
25
- private $current;
26
-
27
- /**
28
- * @var ?string
29
- * @deprecated 15.0
30
- */
31
- private $sessionID;
32
-
33
  protected function run() {
34
  if ( !Services::WpUsers()->isProfilePage() && !Services::IP()->isLoopback() ) { // only on logout
35
  add_action( 'clear_auth_cookie', function () {
@@ -164,13 +152,6 @@ class SessionController extends ExecOnceModConsumer {
164
  }
165
  }
166
 
167
- /**
168
- * @deprecated 15.0
169
- */
170
- public function hasSession() :bool {
171
- return (bool)$this->getCurrentWP()->valid;
172
- }
173
-
174
  public function terminateCurrentSession() :bool {
175
  $current = $this->getCurrentWP();
176
 
@@ -193,42 +174,7 @@ class SessionController extends ExecOnceModConsumer {
193
  return true;
194
  }
195
 
196
- /**
197
- * @deprecated 15.0
198
- */
199
- public function hasSessionID() :bool {
200
- return !empty( $this->getSessionID() );
201
- }
202
-
203
  public function getSessionID() :string {
204
  return '';
205
  }
206
-
207
- /**
208
- * @param string $sessionID
209
- * @return Session\EntryVO|null
210
- * @deprecated 15.0
211
- */
212
- private function queryGetSession( string $sessionID, $username = '' ) {
213
- /** @var ModCon $mod */
214
- $mod = $this->getMod();
215
- /** @var Session\Select $sel */
216
- $sel = $mod->getDbHandler_Sessions()->getQuerySelector();
217
- return $sel->retrieveUserSession( $sessionID, (string)$username );
218
- }
219
-
220
- /**
221
- * @deprecated 15.0
222
- */
223
- public function createSession( \WP_User $user, string $sessionID = '' ) :bool {
224
- return false;
225
- }
226
-
227
- /**
228
- * @return Session\EntryVO|null
229
- * @deprecated 15.0
230
- */
231
- public function getCurrent() {
232
- return $this->current ?? null;
233
- }
234
  }
18
  */
19
  private $currentWP;
20
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  protected function run() {
22
  if ( !Services::WpUsers()->isProfilePage() && !Services::IP()->isLoopback() ) { // only on logout
23
  add_action( 'clear_auth_cookie', function () {
152
  }
153
  }
154
 
 
 
 
 
 
 
 
155
  public function terminateCurrentSession() :bool {
156
  $current = $this->getCurrentWP();
157
 
174
  return true;
175
  }
176
 
 
 
 
 
 
 
 
177
  public function getSessionID() :string {
178
  return '';
179
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
  }
src/lib/src/Modules/Sessions/ModCon.php CHANGED
@@ -18,11 +18,4 @@ class ModCon extends BaseShield\ModCon {
18
  }
19
  return $this->sessionCon;
20
  }
21
-
22
- /**
23
- * @deprecated 15.0
24
- */
25
- public function getDbHandler_Sessions() :Databases\Session\Handler {
26
- return $this->getDbH( 'sessions' );
27
- }
28
  }
18
  }
19
  return $this->sessionCon;
20
  }
 
 
 
 
 
 
 
21
  }
src/lib/src/Modules/Sessions/Processor.php CHANGED
@@ -8,12 +8,6 @@ use FernleafSystems\Wordpress\Services\Services;
8
 
9
  class Processor extends BaseShield\Processor {
10
 
11
- /**
12
- * @var Session\EntryVO
13
- * @deprecated 15.0
14
- */
15
- private $current;
16
-
17
  protected function run() {
18
  /** @var ModCon $mod */
19
  $mod = $this->getMod();
@@ -21,12 +15,6 @@ class Processor extends BaseShield\Processor {
21
  add_filter( 'login_message', [ $this, 'printLinkToAdmin' ] );
22
  }
23
 
24
- /**
25
- * @deprecated 15.0
26
- */
27
- protected function captureLogin( \WP_User $user ) {
28
- }
29
-
30
  /**
31
  * Only show Go To Admin link for Authors+
32
  * @param string $msg
8
 
9
  class Processor extends BaseShield\Processor {
10
 
 
 
 
 
 
 
11
  protected function run() {
12
  /** @var ModCon $mod */
13
  $mod = $this->getMod();
15
  add_filter( 'login_message', [ $this, 'printLinkToAdmin' ] );
16
  }
17
 
 
 
 
 
 
 
18
  /**
19
  * Only show Go To Admin link for Authors+
20
  * @param string $msg
src/lib/src/Modules/Traffic/Lib/Limit/Limiter.php DELETED
@@ -1,49 +0,0 @@
1
- <?php
2
-
3
- namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Traffic\Lib\Limit;
4
-
5
- use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Common\ExecOnceModConsumer;
6
- use FernleafSystems\Wordpress\Plugin\Shield\Modules\Traffic;
7
- use FernleafSystems\Wordpress\Services\Services;
8
-
9
- /**
10
- * @deprecated 15.0
11
- */
12
- class Limiter extends ExecOnceModConsumer {
13
-
14
- protected function canRun() :bool {
15
- /** @var Traffic\Options $opts */
16
- $opts = $this->getOptions();
17
- return $opts->isTrafficLimitEnabled();
18
- }
19
-
20
- protected function run() {
21
- add_action( 'init', [ $this, 'limit' ] );
22
- }
23
-
24
- public function limit() {
25
- try {
26
- ( new TestIpLimit() )
27
- ->setMod( $this->getMod() )
28
- ->setIP( Services::IP()->getRequestIp() )
29
- ->run();
30
- }
31
- catch ( RateLimitExceededException $rle ) {
32
- /** @var Traffic\Options $opts */
33
- $opts = $this->getOptions();
34
- $this->getCon()->fireEvent(
35
- 'request_limit_exceeded',
36
- [
37
- 'audit_params' => [
38
- 'requests' => $rle->getCount(),
39
- 'count' => $opts->getLimitRequestCount(),
40
- 'span' => $opts->getLimitTimeSpan(),
41
- ]
42
- ]
43
- );
44
- }
45
- catch ( \Exception $e ) {
46
- // error_log( $e->getMessage() );
47
- }
48
- }
49
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/src/Modules/Traffic/ModCon.php CHANGED
@@ -50,9 +50,9 @@ class ModCon extends BaseShield\ModCon {
50
  }
51
 
52
  protected function isReadyToExecute() :bool {
53
- $IP = Services::IP();
54
- return $IP->isValidIp_PublicRange( $IP->getRequestIp() )
55
- && $this->getCon()->getModule_Data()->getDbH_ReqLogs()->isReady()
56
  && parent::isReadyToExecute();
57
  }
58
  }
50
  }
51
 
52
  protected function isReadyToExecute() :bool {
53
+ $con = $this->getCon();
54
+ return $con->this_req->ip_is_public
55
+ && $con->getModule_Data()->getDbH_ReqLogs()->isReady()
56
  && parent::isReadyToExecute();
57
  }
58
  }
src/lib/src/Modules/Traffic/UI.php CHANGED
@@ -34,19 +34,19 @@ class UI extends BaseShield\UI {
34
  }
35
 
36
  public function getSectionWarnings( string $section ) :array {
 
37
  /** @var Options $opts */
38
  $opts = $this->getOptions();
39
 
40
  $warning = [];
41
 
42
- $srvIP = Services::IP();
43
- if ( !$srvIP->isValidIp_PublicRange( $srvIP->getRequestIp() ) ) {
44
  $warning[] = __( 'Traffic Watcher will not run because visitor IP address detection is not correctly configured.', 'wp-simple-firewall' );
45
  }
46
 
47
  switch ( $section ) {
48
  case 'section_traffic_limiter':
49
- if ( $this->getCon()->isPremiumActive() ) {
50
  if ( !$opts->isTrafficLoggerEnabled() ) {
51
  $warning[] = sprintf( __( '%s may only be enabled if the Traffic Logger feature is also turned on.', 'wp-simple-firewall' ), __( 'Traffic Rate Limiter', 'wp-simple-firewall' ) );
52
  }
34
  }
35
 
36
  public function getSectionWarnings( string $section ) :array {
37
+ $con = $this->getCon();
38
  /** @var Options $opts */
39
  $opts = $this->getOptions();
40
 
41
  $warning = [];
42
 
43
+ if ( !$con->this_req->ip_is_public ) {
 
44
  $warning[] = __( 'Traffic Watcher will not run because visitor IP address detection is not correctly configured.', 'wp-simple-firewall' );
45
  }
46
 
47
  switch ( $section ) {
48
  case 'section_traffic_limiter':
49
+ if ( $con->isPremiumActive() ) {
50
  if ( !$opts->isTrafficLoggerEnabled() ) {
51
  $warning[] = sprintf( __( '%s may only be enabled if the Traffic Logger feature is also turned on.', 'wp-simple-firewall' ), __( 'Traffic Rate Limiter', 'wp-simple-firewall' ) );
52
  }
src/lib/src/Modules/UserManagement/Processor.php CHANGED
@@ -192,19 +192,19 @@ class Processor extends BaseShield\Processor {
192
  'subscriber' => 'read',
193
  ];
194
 
195
- $sRoleToCheck = strtolower( apply_filters(
196
  $con->prefix( 'login-notification-email-role' ), 'administrator' ) );
197
- if ( !array_key_exists( $sRoleToCheck, $aUserCapToRolesMap ) ) {
198
- $sRoleToCheck = 'administrator';
199
  }
200
- $sHumanName = ucwords( str_replace( '_', ' ', $sRoleToCheck ) ).'+';
201
 
202
  $isUserSignificantEnough = false;
203
  foreach ( $aUserCapToRolesMap as $sRole => $sCap ) {
204
  if ( isset( $user->allcaps[ $sCap ] ) && $user->allcaps[ $sCap ] ) {
205
  $isUserSignificantEnough = true;
206
  }
207
- if ( $sRoleToCheck == $sRole ) {
208
  break; // we've hit our role limit.
209
  }
210
  }
192
  'subscriber' => 'read',
193
  ];
194
 
195
+ $roleToCheck = strtolower( apply_filters(
196
  $con->prefix( 'login-notification-email-role' ), 'administrator' ) );
197
+ if ( !array_key_exists( $roleToCheck, $aUserCapToRolesMap ) ) {
198
+ $roleToCheck = 'administrator';
199
  }
200
+ $sHumanName = ucwords( str_replace( '_', ' ', $roleToCheck ) ).'+';
201
 
202
  $isUserSignificantEnough = false;
203
  foreach ( $aUserCapToRolesMap as $sRole => $sCap ) {
204
  if ( isset( $user->allcaps[ $sCap ] ) && $user->allcaps[ $sCap ] ) {
205
  $isUserSignificantEnough = true;
206
  }
207
+ if ( $roleToCheck == $sRole ) {
208
  break; // we've hit our role limit.
209
  }
210
  }
src/lib/src/Modules/UserManagement/WpCli/SessionTerminate.php DELETED
@@ -1,73 +0,0 @@
1
- <?php
2
-
3
- namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\UserManagement\WpCli;
4
-
5
- use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\WpCli\BaseWpCliCmd;
6
- use WP_CLI;
7
-
8
- /**
9
- * @deprecated 15.0
10
- */
11
- class SessionTerminate extends BaseWpCliCmd {
12
-
13
- /**
14
- * @throws \Exception
15
- */
16
- protected function addCmds() {
17
- WP_CLI::add_command(
18
- $this->buildCmd( [ 'session', 'terminate' ] ),
19
- [ $this, 'cmdTerminate' ], $this->mergeCommonCmdArgs( [
20
- 'shortdesc' => 'Terminate 1, some, or all user sessions.',
21
- 'synopsis' => [
22
- [
23
- 'type' => 'assoc',
24
- 'name' => 'uid',
25
- 'optional' => true,
26
- 'description' => 'Terminate all sessions for the given user ID.',
27
- ],
28
- [
29
- 'type' => 'assoc',
30
- 'name' => 'username',
31
- 'optional' => true,
32
- 'description' => 'Terminate all sessions for a user with the given username.',
33
- ],
34
- [
35
- 'type' => 'assoc',
36
- 'name' => 'email',
37
- 'optional' => true,
38
- 'description' => 'Terminate all sessions for a user with the given email address.',
39
- ],
40
- [
41
- 'type' => 'flag',
42
- 'name' => 'all',
43
- 'optional' => true,
44
- 'description' => 'Terminate all sessions.',
45
- ],
46
- [
47
- 'type' => 'flag',
48
- 'name' => 'force',
49
- 'optional' => true,
50
- 'description' => 'Bypass confirmation prompt.',
51
- ],
52
- ],
53
- ] ) );
54
- }
55
-
56
- /**
57
- * @param array $null
58
- * @param array $aA
59
- * @throws WP_CLI\ExitException
60
- */
61
- public function cmdTerminate( $null, $aA ) {
62
- }
63
-
64
- /**
65
- * @param \WP_User $oUser
66
- * @throws WP_CLI\ExitException
67
- */
68
- private function runTerminateByUser( $oUser ) {
69
- }
70
-
71
- private function runTerminateAll() {
72
- }
73
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/src/Request/ThisRequest.php CHANGED
@@ -9,6 +9,7 @@ use FernleafSystems\Wordpress\Services\Services;
9
 
10
  /**
11
  * @property string $ip
 
12
  * @property BotSignalRecord $botsignal_record
13
  * @property string $ip_id
14
  * @property bool $is_force_off
@@ -38,7 +39,7 @@ class ThisRequest extends DynPropertiesClass {
38
  switch ( $key ) {
39
 
40
  case 'ip':
41
- if ( empty( $value ) ) {
42
  $value = (string)Services::IP()->getRequestIp();
43
  $this->ip = $value;
44
  }
9
 
10
  /**
11
  * @property string $ip
12
+ * @property bool $ip_is_public
13
  * @property BotSignalRecord $botsignal_record
14
  * @property string $ip_id
15
  * @property bool $is_force_off
39
  switch ( $key ) {
40
 
41
  case 'ip':
42
+ if ( !is_string( $value ) ) {
43
  $value = (string)Services::IP()->getRequestIp();
44
  $this->ip = $value;
45
  }
src/lib/src/Rules/Conditions/IsIpBlocked.php CHANGED
@@ -4,6 +4,7 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Rules\Conditions;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Components\QueryIpBlock;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Rules\Conditions\Traits\RequestIP;
 
7
 
8
  class IsIpBlocked extends Base {
9
 
@@ -18,10 +19,13 @@ class IsIpBlocked extends Base {
18
  protected function execConditionCheck() :bool {
19
  $thisReq = $this->getCon()->this_req;
20
  if ( !isset( $thisReq->is_ip_blocked ) ) {
21
- $thisReq->is_ip_blocked = ( new QueryIpBlock() )
22
- ->setMod( $this->getCon()->getModule_IPs() )
23
- ->setIp( $this->getRequestIP() )
24
- ->run();
 
 
 
25
  }
26
  return $thisReq->is_ip_blocked;
27
  }
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Components\QueryIpBlock;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Rules\Conditions\Traits\RequestIP;
7
+ use FernleafSystems\Wordpress\Services\Services;
8
 
9
  class IsIpBlocked extends Base {
10
 
19
  protected function execConditionCheck() :bool {
20
  $thisReq = $this->getCon()->this_req;
21
  if ( !isset( $thisReq->is_ip_blocked ) ) {
22
+ $srvIP = Services::IP();
23
+ $thisReq->is_ip_blocked =
24
+ !$srvIP->checkIp( $this->getRequestIP(), $srvIP->getServerPublicIPs() )
25
+ && ( new QueryIpBlock() )
26
+ ->setMod( $this->getCon()->getModule_IPs() )
27
+ ->setIp( $this->getRequestIP() )
28
+ ->run();
29
  }
30
  return $thisReq->is_ip_blocked;
31
  }
src/lib/src/Rules/RulesStorageHandler.php CHANGED
@@ -70,18 +70,22 @@ class RulesStorageHandler {
70
  private function loadRawFromFile() :array {
71
  $rules = [];
72
 
73
- $content = Services::WpFs()->getFileContent( $this->getPathToRules() );
74
- if ( !empty( $content ) ) {
75
- $decoded = @json_decode( $content, true );
76
- if ( is_array( $decoded ) ) {
77
- $rules = $decoded;
 
 
 
78
  }
79
  }
 
80
  return $rules;
81
  }
82
 
83
  private function getPathToRules() :string {
84
- return path_join( __DIR__, 'rules.json' );
85
  }
86
 
87
  private function getWpStorageKey() :string {
70
  private function loadRawFromFile() :array {
71
  $rules = [];
72
 
73
+ $FS = Services::WpFs();
74
+ if ( $FS->exists( $this->getPathToRules() ) ) {
75
+ $content = $FS->getFileContent( $this->getPathToRules() );
76
+ if ( !empty( $content ) ) {
77
+ $decoded = @json_decode( $content, true );
78
+ if ( is_array( $decoded ) ) {
79
+ $rules = $decoded;
80
+ }
81
  }
82
  }
83
+
84
  return $rules;
85
  }
86
 
87
  private function getPathToRules() :string {
88
+ return path_join( $this->getRulesCon()->getCon()->cache_dir_handler->build(), 'rules.json' );
89
  }
90
 
91
  private function getWpStorageKey() :string {
src/lib/src/Scans/Afs/BuildScanAction.php CHANGED
@@ -7,7 +7,7 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
7
 
8
  class BuildScanAction extends Base\BuildScanAction {
9
 
10
- protected function buildItems() {
11
  $this->getScanActionVO()->items = ( new BuildScanItems() )
12
  ->setMod( $this->getScanController()->getMod() )
13
  ->setScanActionVO( $this->getScanActionVO() )
@@ -22,4 +22,10 @@ class BuildScanAction extends Base\BuildScanAction {
22
  $action->file_exts = $this->getFileExts();
23
  $action->realtime_scan_last_at = $opts->getLastRealtimeScanAt( true );
24
  }
 
 
 
 
 
 
25
  }
7
 
8
  class BuildScanAction extends Base\BuildScanAction {
9
 
10
+ protected function buildScanItems() {
11
  $this->getScanActionVO()->items = ( new BuildScanItems() )
12
  ->setMod( $this->getScanController()->getMod() )
13
  ->setScanActionVO( $this->getScanActionVO() )
22
  $action->file_exts = $this->getFileExts();
23
  $action->realtime_scan_last_at = $opts->getLastRealtimeScanAt( true );
24
  }
25
+
26
+ protected function getFileExts() :array {
27
+ $scanCon = $this->getScanController();
28
+ $ext = apply_filters( 'shield/scan_ptg_file_exts', $scanCon->getOptions()->getDef( 'file_scan_extensions' ) );
29
+ return is_array( $ext ) ? $ext : $scanCon->getOptions()->getDef( 'file_scan_extensions' );
30
+ }
31
  }
src/lib/src/Scans/Afs/BuildScanItems.php CHANGED
@@ -2,22 +2,31 @@
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Afs;
4
 
5
- use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\BaseBuildFileMap;
 
 
6
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Helpers\StandardDirectoryIterator;
 
7
  use FernleafSystems\Wordpress\Services\Services;
8
 
9
- class BuildScanItems extends BaseBuildFileMap {
10
 
11
- /**
12
- * @return string[]
13
- */
14
- public function build() :array {
15
  $this->preBuild();
16
 
17
- $files = array_unique( array_merge(
18
- $this->buildFilesFromDisk(),
19
- $this->buildFilesFromWpHashes()
20
- ) );
 
 
 
 
 
 
21
  natsort( $files );
22
 
23
  return array_map(
@@ -28,6 +37,25 @@ class BuildScanItems extends BaseBuildFileMap {
28
  );
29
  }
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  private function buildFilesFromWpHashes() :array {
32
  $files = [];
33
 
@@ -36,10 +64,7 @@ class BuildScanItems extends BaseBuildFileMap {
36
  foreach ( array_keys( $coreHashes->getHashes() ) as $fragment ) {
37
  // To reduce noise, we exclude plugins and themes (by default)
38
  if ( strpos( $fragment, 'wp-content/' ) === false ) {
39
- $fullPath = wp_normalize_path( path_join( ABSPATH, $fragment ) );
40
- if ( !$this->isWhitelistedPath( $fullPath ) ) {
41
- $files[] = $fullPath;
42
- }
43
  }
44
  }
45
  }
@@ -56,10 +81,9 @@ class BuildScanItems extends BaseBuildFileMap {
56
  try {
57
  foreach ( StandardDirectoryIterator::create( $scanDir, (int)$depth, $action->file_exts, false ) as $item ) {
58
  /** @var \SplFileInfo $item */
59
- $path = wp_normalize_path( $item->getPathname() );
60
  try {
61
- if ( !$this->isWhitelistedPath( $path ) && !$this->isAutoFilterFile( $item ) ) {
62
- $files[] = $path;
63
  }
64
  }
65
  catch ( \Exception $e ) {
@@ -76,20 +100,32 @@ class BuildScanItems extends BaseBuildFileMap {
76
  return $files;
77
  }
78
 
79
- protected function preBuild() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  /** @var ScanActionVO $action */
81
  $action = $this->getScanActionVO();
82
-
83
- if ( empty( $action->scan_root_dirs ) || !is_array( $action->scan_root_dirs ) ) {
84
- $action->scan_root_dirs = [
85
- ABSPATH => 1,
86
- path_join( ABSPATH, WPINC ) => 0,
87
- path_join( ABSPATH, 'wp-admin' ) => 0,
88
- WP_CONTENT_DIR => 0,
89
- ];
90
- }
91
- if ( !is_array( $action->paths_whitelisted ) ) {
92
- $action->paths_whitelisted = [];
93
  }
 
94
  }
95
  }
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Afs;
4
 
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Options;
6
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
7
+ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Common\ScanActionConsumer;
8
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Helpers\StandardDirectoryIterator;
9
+ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal\ScanActionVO;
10
  use FernleafSystems\Wordpress\Services\Services;
11
 
12
+ class BuildScanItems {
13
 
14
+ use ModConsumer;
15
+ use ScanActionConsumer;
16
+
17
+ public function run() :array {
18
  $this->preBuild();
19
 
20
+ $files = array_filter(
21
+ array_unique( array_merge(
22
+ $this->buildFilesFromDisk(),
23
+ $this->buildFilesFromWpHashes()
24
+ ) ),
25
+ function ( $path ) {
26
+ return !$this->isWhitelistedPath( $path );
27
+ }
28
+ );
29
+
30
  natsort( $files );
31
 
32
  return array_map(
37
  );
38
  }
39
 
40
+ protected function preBuild() {
41
+ /** @var ScanActionVO $action */
42
+ $action = $this->getScanActionVO();
43
+
44
+ if ( empty( $action->scan_root_dirs ) || !is_array( $action->scan_root_dirs ) ) {
45
+ $action->scan_root_dirs = [
46
+ ABSPATH => 1,
47
+ path_join( ABSPATH, WPINC ) => 0,
48
+ path_join( ABSPATH, 'wp-admin' ) => 0,
49
+ WP_CONTENT_DIR => 0,
50
+ ];
51
+ }
52
+ if ( !is_array( $action->paths_whitelisted ) ) {
53
+ /** @var Options $opts */
54
+ $opts = $this->getMod()->getOptions();
55
+ $action->paths_whitelisted = $opts->getWhitelistedPathsAsRegex();
56
+ }
57
+ }
58
+
59
  private function buildFilesFromWpHashes() :array {
60
  $files = [];
61
 
64
  foreach ( array_keys( $coreHashes->getHashes() ) as $fragment ) {
65
  // To reduce noise, we exclude plugins and themes (by default)
66
  if ( strpos( $fragment, 'wp-content/' ) === false ) {
67
+ $files[] = wp_normalize_path( path_join( ABSPATH, $fragment ) );
 
 
 
68
  }
69
  }
70
  }
81
  try {
82
  foreach ( StandardDirectoryIterator::create( $scanDir, (int)$depth, $action->file_exts, false ) as $item ) {
83
  /** @var \SplFileInfo $item */
 
84
  try {
85
+ if ( !$this->isAutoFilterFile( $item ) ) {
86
+ $files[] = wp_normalize_path( $item->getPathname() );
87
  }
88
  }
89
  catch ( \Exception $e ) {
100
  return $files;
101
  }
102
 
103
+ private function isAutoFilterFile( \SplFileInfo $file ) :bool {
104
+ /** @var Options $opts */
105
+ $opts = $this->getOptions();
106
+ /**
107
+ * Remove anything in wp-content as this is only relevant for Plugins/Themes/Malware
108
+ * and this is PRO-only anyway.
109
+ */
110
+ return (
111
+ !$this->getCon()->isPremiumActive()
112
+ && strpos( wp_normalize_path( $file->getPathname() ), '/wp-content/' ) !== false
113
+ )
114
+ ||
115
+ ( $opts->isAutoFilterResults() && $file->getSize() === 0 );
116
+ }
117
+
118
+ private function isWhitelistedPath( string $path ) :bool {
119
+ $whitelisted = false;
120
+
121
  /** @var ScanActionVO $action */
122
  $action = $this->getScanActionVO();
123
+ foreach ( $action->paths_whitelisted as $wlPathRegEx ) {
124
+ if ( preg_match( $wlPathRegEx, $path ) ) {
125
+ $whitelisted = true;
126
+ break;
127
+ }
 
 
 
 
 
 
128
  }
129
+ return $whitelisted;
130
  }
131
  }
src/lib/src/Scans/Afs/Processing/FileScanOptimiser.php ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Afs\Processing;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules;
6
+ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Afs\ScanActionVO;
7
+ use FernleafSystems\Wordpress\Services\Services;
8
+ use FernleafSystems\Wordpress\Services\Utilities\File\Search\SearchFile;
9
+ use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Malware;
10
+
11
+ class FileScanOptimiser {
12
+
13
+ use Modules\ModConsumer;
14
+
15
+ public function addFilesFromAction( ScanActionVO $action ) {
16
+ if ( is_array( $action->results ) && is_array( $action->items ) ) {
17
+ $results = array_map(
18
+ function ( $result ) {
19
+ return $result[ 'path_full' ];
20
+ },
21
+ $action->results
22
+ );
23
+ $items = array_map(
24
+ function ( $item ) {
25
+ return base64_decode( $item );
26
+ },
27
+ $action->items
28
+ );
29
+
30
+ $filesToAdd = array_diff( $items, $results );
31
+ if ( !empty( $filesToAdd ) ) {
32
+ $this->addFiles( $filesToAdd );
33
+ }
34
+ }
35
+ }
36
+
37
+ public function filterFilesFromAction( ScanActionVO $action ) {
38
+ if ( is_array( $action->items ) ) {
39
+ $items = array_map(
40
+ function ( $item ) {
41
+ return base64_decode( $item );
42
+ },
43
+ $action->items
44
+ );
45
+
46
+ $action->items = array_map(
47
+ function ( $item ) {
48
+ return base64_encode( $item );
49
+ },
50
+ array_diff( $items, $this->findHashedFiles( $items ) )
51
+ );
52
+ }
53
+ }
54
+
55
+ public function findHashedFiles( array $files ) :array {
56
+ $FS = Services::WpFs();
57
+
58
+ $filesFound = [];
59
+
60
+ $pathToHashes = $this->pathToHashes();
61
+ if ( $FS->exists( $pathToHashes ) && $FS->getFileSize( $pathToHashes ) > 0 ) {
62
+
63
+ $filesThatExist = array_filter(
64
+ $files,
65
+ function ( $file ) {
66
+ return Services::WpFs()->exists( $file );
67
+ }
68
+ );
69
+
70
+ $filesAndTheirHashes = [];
71
+ foreach ( $filesThatExist as $file ) {
72
+ $filesAndTheirHashes[ $file ] = hash_file( 'md5', $file );
73
+ }
74
+
75
+ try {
76
+ $searcher = new SearchFile( $pathToHashes );
77
+ $filesFound = array_keys( array_intersect(
78
+ $filesAndTheirHashes,
79
+ array_keys( array_filter( $searcher->multipleExists( array_values( $filesAndTheirHashes ) ) ) )
80
+ ) );
81
+ }
82
+ catch ( \Exception $e ) {
83
+ }
84
+ }
85
+
86
+ return $filesFound;
87
+ }
88
+
89
+ public function cleanStaleHashesOlderThan( int $ts ) {
90
+ $FS = Services::WpFs();
91
+ $pathToHashes = $this->pathToHashes();
92
+ $pathToHashesTmp = $this->pathToHashes().'.tmp';
93
+
94
+ if ( $FS->exists( $pathToHashes ) ) {
95
+
96
+ $source = fopen( $pathToHashes, 'r' );
97
+ $target = fopen( $pathToHashesTmp, 'w' );
98
+
99
+ if ( !is_resource( $source ) && is_resource( $target ) ) {
100
+ fclose( $target );
101
+ $FS->deleteFile( $pathToHashes );
102
+ $FS->deleteFile( $pathToHashesTmp );
103
+ }
104
+ elseif ( !is_resource( $target ) && is_resource( $source ) ) {
105
+ fclose( $source );
106
+ $FS->deleteFile( $pathToHashes );
107
+ }
108
+ else {
109
+ while ( !feof( $source ) ) {
110
+ $line = fgets( $source );
111
+ if ( is_string( $line ) ) {
112
+ $colonAt = strpos( $line, ':' );
113
+ if ( $colonAt !== false ) {
114
+ if ( substr( $line, 0, $colonAt ) > $ts ) {
115
+ fputs( $target, $line );
116
+ }
117
+ }
118
+ }
119
+ }
120
+ if ( is_resource( $source ) ) {
121
+ fclose( $source );
122
+ }
123
+ if ( is_resource( $target ) ) {
124
+ fclose( $target );
125
+ }
126
+
127
+ $FS->move( $pathToHashesTmp, $pathToHashes );
128
+ }
129
+ }
130
+ }
131
+
132
+ public function addFiles( array $files ) {
133
+ $FS = Services::WpFs();
134
+ if ( $this->getCon()->cache_dir_handler->dirExists() ) {
135
+ $pathToHashes = $this->pathToHashes();
136
+ if ( !$FS->exists( $pathToHashes ) ) {
137
+ $FS->touch( $pathToHashes );
138
+ }
139
+ if ( $FS->exists( $pathToHashes ) ) {
140
+ $fileHashes = array_unique( array_filter( array_map(
141
+ function ( $file ) {
142
+ return hash_file( 'md5', $file );
143
+ },
144
+ array_filter(
145
+ $files,
146
+ function ( $file ) {
147
+ return Services::WpFs()->exists( $file );
148
+ }
149
+ )
150
+ ) ) );
151
+
152
+ try {
153
+ $searcher = new SearchFile( $pathToHashes );
154
+ $allNotFoundHashes = array_diff(
155
+ $fileHashes,
156
+ array_keys( array_filter( $searcher->multipleExists( $fileHashes ) ) )
157
+ );
158
+ file_put_contents(
159
+ $pathToHashes,
160
+ sprintf( '%s:%s', Services::Request()->ts(), implode( ',', $allNotFoundHashes )."\n" ),
161
+ FILE_APPEND
162
+ );
163
+ }
164
+ catch ( \Exception $e ) {
165
+ }
166
+ }
167
+ }
168
+ }
169
+
170
+ public function pathToHashes() :string {
171
+ return path_join( $this->getCon()->cache_dir_handler->build(), 'file_scan_hashes.txt' );
172
+ }
173
+ }
src/lib/src/Scans/Afs/Scan.php CHANGED
@@ -5,7 +5,7 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Afs;
5
  use FernleafSystems\Wordpress\Plugin\Shield;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
7
 
8
- class Scan extends Shield\Scans\Base\Files\BaseFileMapScan {
9
 
10
  /**
11
  * @throws \Exception
@@ -19,6 +19,12 @@ class Scan extends Shield\Scans\Base\Files\BaseFileMapScan {
19
  /** @var ScanActionVO $action */
20
  $action = $this->getScanActionVO();
21
 
 
 
 
 
 
 
22
  $action->confidence_threshold = $opts->getMalConfidenceBoundary();
23
 
24
  $patterns = ( new Utilities\Patterns() )
@@ -30,11 +36,37 @@ class Scan extends Shield\Scans\Base\Files\BaseFileMapScan {
30
  }
31
 
32
  /**
33
- * @return ScanFromFileMap
34
  */
35
- protected function getScanFromFileMap() {
36
- return ( new ScanFromFileMap() )
37
- ->setMod( $this->getMod() )
38
- ->setScanActionVO( $this->getScanActionVO() );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  }
40
  }
5
  use FernleafSystems\Wordpress\Plugin\Shield;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
7
 
8
+ class Scan extends Shield\Scans\Base\BaseScan {
9
 
10
  /**
11
  * @throws \Exception
19
  /** @var ScanActionVO $action */
20
  $action = $this->getScanActionVO();
21
 
22
+ if ( $opts->isOpt( 'optimise_scan_speed', 'Y' ) ) {
23
+ ( new Processing\FileScanOptimiser() )
24
+ ->setMod( $this->getMod() )
25
+ ->filterFilesFromAction( $action );
26
+ }
27
+
28
  $action->confidence_threshold = $opts->getMalConfidenceBoundary();
29
 
30
  $patterns = ( new Utilities\Patterns() )
36
  }
37
 
38
  /**
39
+ * @return $this
40
  */
41
+ protected function scanSlice() {
42
+ $action = $this->getScanActionVO();
43
+
44
+ $action->results = array_map(
45
+ function ( $item ) {
46
+ return $item->getRawData();
47
+ },
48
+ // run the scan and get results:
49
+ ( new ScanFromFileMap() )
50
+ ->setMod( $this->getMod() )
51
+ ->setScanController( $this->getScanController() )
52
+ ->setScanActionVO( $action )
53
+ ->run()
54
+ ->getAllItems()
55
+ );
56
+
57
+ return $this;
58
+ }
59
+
60
+ protected function postScan() {
61
+ /** @var HackGuard\Options $opts */
62
+ $opts = $this->getOptions();
63
+
64
+ if ( $opts->isOpt( 'optimise_scan_speed', 'Y' ) ) {
65
+ /** @var ScanActionVO $action */
66
+ $action = $this->getScanActionVO();
67
+ ( new Processing\FileScanOptimiser() )
68
+ ->setMod( $this->getMod() )
69
+ ->addFilesFromAction( $action );
70
+ }
71
  }
72
  }
src/lib/src/Scans/Afs/ScanActionVO.php CHANGED
@@ -16,6 +16,5 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\BaseScanActionVO;
16
  */
17
  class ScanActionVO extends BaseScanActionVO {
18
 
19
- const QUEUE_GROUP_SIZE_LIMIT = 25;
20
  const DEFAULT_SLEEP_SECONDS = 0.1;
21
  }
16
  */
17
  class ScanActionVO extends BaseScanActionVO {
18
 
 
19
  const DEFAULT_SLEEP_SECONDS = 0.1;
20
  }
src/lib/src/Scans/Afs/ScanFromFileMap.php CHANGED
@@ -2,14 +2,59 @@
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Afs;
4
 
5
- use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\Files\BaseScanFromFileMap;
 
 
 
 
 
6
 
7
- class ScanFromFileMap extends BaseScanFromFileMap {
8
 
9
- /**
10
- * @return FileScanner
11
- */
12
- protected function getFileScanner() {
13
- return new FileScanner();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  }
15
  }
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Afs;
4
 
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Options;
6
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Controller\ScanControllerConsumer;
7
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
8
+ use FernleafSystems\Wordpress\Plugin\Shield\Scans;
9
+ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Common\ScanActionConsumer;
10
+ use FernleafSystems\Wordpress\Services\Utilities\Code\AssessPhpFile;
11
 
12
+ class ScanFromFileMap {
13
 
14
+ use ScanControllerConsumer;
15
+ use ModConsumer;
16
+ use ScanActionConsumer;
17
+
18
+ public function run() :ResultsSet {
19
+ /** @var Options $opts */
20
+ $opts = $this->getOptions();
21
+
22
+ $action = $this->getScanActionVO();
23
+ $results = $this->getScanController()->getNewResultsSet();
24
+
25
+ $isAutoFilter = $opts->isAutoFilterResults();
26
+
27
+ if ( is_array( $action->items ) ) {
28
+ foreach ( $action->items as $fullPath ) {
29
+
30
+ // We can exclude files that are empty of relevant code
31
+ if ( !$isAutoFilter || !$this->isEmptyOfCode( $fullPath ) ) {
32
+
33
+ $item = ( new FileScanner() )
34
+ ->setScanController( $this->getScanController() )
35
+ ->setMod( $this->getMod() )
36
+ ->setScanActionVO( $action )
37
+ ->scan( $fullPath );
38
+ if ( !empty( $item ) ) {
39
+ $results->addItem( $item );
40
+ }
41
+ }
42
+ }
43
+ }
44
+
45
+ return $results;
46
+ }
47
+
48
+ protected function isEmptyOfCode( string $path ) :bool {
49
+ try {
50
+ if ( strpos( $path, wp_normalize_path( ABSPATH ) ) === false ) {
51
+ $path = path_join( ABSPATH, $path );
52
+ }
53
+ $isEmpty = ( new AssessPhpFile() )->isEmptyOfCode( $path );
54
+ }
55
+ catch ( \Exception $e ) {
56
+ $isEmpty = false;
57
+ }
58
+ return $isEmpty;
59
  }
60
  }
src/lib/src/Scans/Apc/BuildScanAction.php CHANGED
@@ -1,20 +1,19 @@
1
- <?php
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Apc;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
 
6
 
7
  class BuildScanAction extends Base\BuildScanAction {
8
 
9
- protected function buildItems() {
10
- $this->getScanActionVO()->items = ( new BuildScanItems() )
11
- ->setMod( $this->getScanController()->getMod() )
12
- ->run();
13
  }
14
 
15
  protected function setCustomFields() {
16
- /** @var ScanActionVO $oAction */
17
- $oAction = $this->getScanActionVO();
18
- $oAction->abandoned_limit = YEAR_IN_SECONDS*2;
19
  }
20
  }
1
+ <?php declare( strict_types=1 );
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Apc;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
6
+ use FernleafSystems\Wordpress\Services\Services;
7
 
8
  class BuildScanAction extends Base\BuildScanAction {
9
 
10
+ protected function buildScanItems() {
11
+ $this->getScanActionVO()->items = Services::WpPlugins()->getInstalledPluginFiles();
 
 
12
  }
13
 
14
  protected function setCustomFields() {
15
+ /** @var ScanActionVO $action */
16
+ $action = $this->getScanActionVO();
17
+ $action->abandoned_limit = YEAR_IN_SECONDS*2;
18
  }
19
  }
src/lib/src/Scans/Apc/ScanActionVO.php CHANGED
@@ -9,5 +9,4 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\BaseScanActionVO;
9
  */
10
  class ScanActionVO extends BaseScanActionVO {
11
 
12
- const QUEUE_GROUP_SIZE_LIMIT = 3;
13
  }
9
  */
10
  class ScanActionVO extends BaseScanActionVO {
11
 
 
12
  }
src/lib/src/Scans/Base/BaseScanActionVO.php CHANGED
@@ -17,7 +17,6 @@ abstract class BaseScanActionVO {
17
 
18
  use DynProperties;
19
 
20
- const QUEUE_GROUP_SIZE_LIMIT = 1;
21
  const DEFAULT_SLEEP_SECONDS = 0;
22
 
23
  public function getScanNamespace() :string {
17
 
18
  use DynProperties;
19
 
 
20
  const DEFAULT_SLEEP_SECONDS = 0;
21
 
22
  public function getScanNamespace() :string {
src/lib/src/Scans/Base/BuildScanAction.php CHANGED
@@ -19,7 +19,6 @@ abstract class BuildScanAction {
19
  $scanCon = $this->getScanController();
20
  $this->setScanActionVO( $scanCon->getScanActionVO() );
21
 
22
- $this->setWhitelists();
23
  $this->setCustomFields();
24
  $this->buildScanItems();
25
  $this->setStandardFields();
@@ -27,20 +26,7 @@ abstract class BuildScanAction {
27
  return $this;
28
  }
29
 
30
- /**
31
- * @throws \Exception
32
- */
33
- protected function buildScanItems() {
34
- $this->buildItems();
35
- }
36
-
37
- abstract protected function buildItems();
38
-
39
- protected function getFileExts() :array {
40
- $scanCon = $this->getScanController();
41
- $ext = apply_filters( 'shield/scan_ptg_file_exts', $scanCon->getOptions()->getDef( 'file_scan_extensions' ) );
42
- return is_array( $ext ) ? $ext : $scanCon->getOptions()->getDef( 'file_scan_extensions' );
43
- }
44
 
45
  protected function setStandardFields() {
46
  $action = $this->getScanActionVO();
@@ -57,11 +43,4 @@ abstract class BuildScanAction {
57
 
58
  protected function setCustomFields() {
59
  }
60
-
61
- protected function setWhitelists() {
62
- /** @var Shield\Modules\HackGuard\Options $opts */
63
- $opts = $this->getScanController()->getOptions();
64
- $action = $this->getScanActionVO();
65
- $action->paths_whitelisted = $opts->getWhitelistedPathsAsRegex();
66
- }
67
  }
19
  $scanCon = $this->getScanController();
20
  $this->setScanActionVO( $scanCon->getScanActionVO() );
21
 
 
22
  $this->setCustomFields();
23
  $this->buildScanItems();
24
  $this->setStandardFields();
26
  return $this;
27
  }
28
 
29
+ abstract protected function buildScanItems();
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
  protected function setStandardFields() {
32
  $action = $this->getScanActionVO();
43
 
44
  protected function setCustomFields() {
45
  }
 
 
 
 
 
 
 
46
  }
src/lib/src/Scans/Mal/ScanActionVO.php CHANGED
@@ -15,6 +15,5 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\BaseScanActionVO;
15
  */
16
  class ScanActionVO extends BaseScanActionVO {
17
 
18
- const QUEUE_GROUP_SIZE_LIMIT = 50;
19
  const DEFAULT_SLEEP_SECONDS = 0.1;
20
  }
15
  */
16
  class ScanActionVO extends BaseScanActionVO {
17
 
 
18
  const DEFAULT_SLEEP_SECONDS = 0.1;
19
  }
src/lib/src/Scans/Ptg/ScanActionVO.php CHANGED
@@ -11,5 +11,4 @@ class ScanActionVO extends BaseScanActionVO {
11
 
12
  const CONTEXT_PLUGINS = 'plugins';
13
  const CONTEXT_THEMES = 'themes';
14
- const QUEUE_GROUP_SIZE_LIMIT = 50;
15
  }
11
 
12
  const CONTEXT_PLUGINS = 'plugins';
13
  const CONTEXT_THEMES = 'themes';
 
14
  }
src/lib/src/Scans/Ufc/ScanActionVO.php CHANGED
@@ -9,5 +9,4 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\BaseScanActionVO;
9
  */
10
  class ScanActionVO extends BaseScanActionVO {
11
 
12
- const QUEUE_GROUP_SIZE_LIMIT = 100;
13
  }
9
  */
10
  class ScanActionVO extends BaseScanActionVO {
11
 
 
12
  }
src/lib/src/Scans/Wcf/ScanActionVO.php CHANGED
@@ -10,5 +10,4 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\BaseScanActionVO;
10
  */
11
  class ScanActionVO extends BaseScanActionVO {
12
 
13
- const QUEUE_GROUP_SIZE_LIMIT = 100;
14
  }
10
  */
11
  class ScanActionVO extends BaseScanActionVO {
12
 
 
13
  }
src/lib/src/Scans/Wpv/BuildScanAction.php CHANGED
@@ -3,12 +3,15 @@
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
 
6
 
7
  class BuildScanAction extends Base\BuildScanAction {
8
 
9
- protected function buildItems() {
10
- $this->getScanActionVO()->items = ( new BuildScanItems() )
11
- ->setMod( $this->getScanController()->getMod() )
12
- ->run();
 
 
13
  }
14
  }
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
6
+ use FernleafSystems\Wordpress\Services\Services;
7
 
8
  class BuildScanAction extends Base\BuildScanAction {
9
 
10
+ protected function buildScanItems() {
11
+ $items = Services::WpPlugins()->getInstalledPluginFiles();
12
+ $WPT = Services::WpThemes();
13
+ $items[] = ( $WPT->isActiveThemeAChild() ? $WPT->getCurrentParent() : $WPT->getCurrent() )->get_stylesheet();
14
+
15
+ $this->getScanActionVO()->items = $items;
16
  }
17
  }
src/lib/src/Tables/Build/Sessions.php CHANGED
@@ -169,15 +169,6 @@ class Sessions extends BaseBuild {
169
  return new Tables\Render\WpListTable\Sessions();
170
  }
171
 
172
- /**
173
- * @param Session\EntryVO $oEntry
174
- * @return bool
175
- */
176
- private function isSecAdminSession( $oEntry ) {
177
- return ( $oEntry->getSecAdminAt() > 0 ) ||
178
- ( is_array( $this->aSecAdminUsers ) && in_array( $oEntry->wp_username, $this->aSecAdminUsers ) );
179
- }
180
-
181
  /**
182
  * @param array $aSecAdminUsernames
183
  * @return $this
169
  return new Tables\Render\WpListTable\Sessions();
170
  }
171
 
 
 
 
 
 
 
 
 
 
172
  /**
173
  * @param array $aSecAdminUsernames
174
  * @return $this
src/lib/src/Utilities/MU/MUHandler.php CHANGED
@@ -98,8 +98,8 @@ class MUHandler {
98
  $replacements = [
99
  'SHIELD_ROOT_FILE' => $con->getRootFile(),
100
  'SHIELD_PLUGIN_NAME' => $con->getHumanName(),
101
- 'SHIELD_PLUGIN_URL' => $con->getLabels()[ 'PluginURI' ],
102
- 'SHIELD_PLUGIN_AUTHOR' => $con->getLabels()[ 'Author' ],
103
  ];
104
  return str_replace( array_keys( $replacements ), array_values( $replacements ), $template );
105
  }
98
  $replacements = [
99
  'SHIELD_ROOT_FILE' => $con->getRootFile(),
100
  'SHIELD_PLUGIN_NAME' => $con->getHumanName(),
101
+ 'SHIELD_PLUGIN_URL' => $con->labels->PluginURI,
102
+ 'SHIELD_PLUGIN_AUTHOR' => $con->labels->Author,
103
  ];
104
  return str_replace( array_keys( $replacements ), array_values( $replacements ), $template );
105
  }
src/lib/src/Utilities/Render/BasePageDisplay.php CHANGED
@@ -5,6 +5,7 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Utilities\Render;
5
  use FernleafSystems\Wordpress\Services\Services;
6
 
7
  abstract class BasePageDisplay extends BaseTemplateRenderer {
 
8
  public function display() {
9
  $this->issueHeaders();
10
  echo $this->render();
@@ -26,8 +27,14 @@ abstract class BasePageDisplay extends BaseTemplateRenderer {
26
  protected function getRenderData() :array {
27
  $con = $this->getCon();
28
  $WP = Services::WpGeneral();
29
- $labels = $con->getLabels();
30
- $bannerURL = empty( $labels[ 'url_login2fa_logourl' ] ) ? $con->urls->forImage( 'shield/banner-2FA.png' ) : $labels[ 'url_login2fa_logourl' ];
 
 
 
 
 
 
31
 
32
  return [
33
  'flags' => [
5
  use FernleafSystems\Wordpress\Services\Services;
6
 
7
  abstract class BasePageDisplay extends BaseTemplateRenderer {
8
+
9
  public function display() {
10
  $this->issueHeaders();
11
  echo $this->render();
27
  protected function getRenderData() :array {
28
  $con = $this->getCon();
29
  $WP = Services::WpGeneral();
30
+
31
+ if ( empty( $con->labels ) ) {
32
+ $labels = $con->getLabels();
33
+ $bannerURL = empty( $labels[ 'url_login2fa_logourl' ] ) ? $con->urls->forImage( 'shield/banner-2FA.png' ) : $labels[ 'url_login2fa_logourl' ];
34
+ }
35
+ else {
36
+ $bannerURL = $con->labels->url_img_pagebanner;
37
+ }
38
 
39
  return [
40
  'flags' => [
src/lib/vendor/composer/autoload_classmap.php CHANGED
@@ -102,10 +102,11 @@ return array(
102
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Assets\\Paths' => $baseDir . '/src/Controller/Assets/Paths.php',
103
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Assets\\Svgs' => $baseDir . '/src/Controller/Assets/Svgs.php',
104
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Assets\\Urls' => $baseDir . '/src/Controller/Assets/Urls.php',
 
105
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Config\\ConfigVO' => $baseDir . '/src/Controller/Config/ConfigVO.php',
 
106
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Config\\Ops\\LoadConfig' => $baseDir . '/src/Controller/Config/Ops/LoadConfig.php',
107
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Config\\Ops\\Read' => $baseDir . '/src/Controller/Config/Ops/Read.php',
108
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Config\\Ops\\Save' => $baseDir . '/src/Controller/Config/Ops/Save.php',
109
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Controller' => $baseDir . '/src/Controller/Controller.php',
110
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Exceptions\\PluginConfigInvalidException' => $baseDir . '/src/Controller/Exceptions/PluginConfigInvalidException.php',
111
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Exceptions\\VersionMismatchException' => $baseDir . '/src/Controller/Exceptions/VersionMismatchException.php',
@@ -178,12 +179,6 @@ return array(
178
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Reports\\Select' => $baseDir . '/src/Databases/Reports/Select.php',
179
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Reports\\Update' => $baseDir . '/src/Databases/Reports/Update.php',
180
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\ReqLogs\\QueueReqDbRecordMigrator' => $baseDir . '/src/Databases/ReqLogs/QueueReqDbRecordMigrator.php',
181
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Session\\Delete' => $baseDir . '/src/Databases/Session/Delete.php',
182
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Session\\EntryVO' => $baseDir . '/src/Databases/Session/EntryVO.php',
183
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Session\\Handler' => $baseDir . '/src/Databases/Session/Handler.php',
184
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Session\\Insert' => $baseDir . '/src/Databases/Session/Insert.php',
185
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Session\\Select' => $baseDir . '/src/Databases/Session/Select.php',
186
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Session\\Update' => $baseDir . '/src/Databases/Session/Update.php',
187
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Utility\\QueueDbRecordsMigrator' => $baseDir . '/src/Databases/Utility/QueueDbRecordsMigrator.php',
188
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Helpers\\QuickAccess' => $baseDir . '/src/Helpers/QuickAccess.php',
189
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\License\\EddLicenseVO' => $baseDir . '/src/License/EddLicenseVO.php',
@@ -252,6 +247,7 @@ return array(
252
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Config\\ModConfigVO' => $baseDir . '/src/Modules/Base/Config/ModConfigVO.php',
253
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Databases' => $baseDir . '/src/Modules/Base/Databases.php',
254
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Debug' => $baseDir . '/src/Modules/Base/Debug.php',
 
255
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Lib\\Components\\UiTrack' => $baseDir . '/src/Modules/Base/Lib/Components/UiTrack.php',
256
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Lib\\Request\\FormParams' => $baseDir . '/src/Modules/Base/Lib/Request/FormParams.php',
257
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\ModCon' => $baseDir . '/src/Modules/Base/ModCon.php',
@@ -342,7 +338,6 @@ return array(
342
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Checks\\Base' => $baseDir . '/src/Modules/Firewall/Lib/Scan/Checks/Base.php',
343
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Checks\\ExeFiles' => $baseDir . '/src/Modules/Firewall/Lib/Scan/Checks/ExeFiles.php',
344
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Checks\\Standard' => $baseDir . '/src/Modules/Firewall/Lib/Scan/Checks/Standard.php',
345
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\FirewallHandler' => $baseDir . '/src/Modules/Firewall/Lib/Scan/FirewallHandler.php',
346
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Handlers\\Aggressive' => $baseDir . '/src/Modules/Firewall/Lib/Scan/Handlers/Aggressive.php',
347
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Handlers\\Base' => $baseDir . '/src/Modules/Firewall/Lib/Scan/Handlers/Base.php',
348
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Handlers\\BaseRequestParams' => $baseDir . '/src/Modules/Firewall/Lib/Scan/Handlers/BaseRequestParams.php',
@@ -631,6 +626,7 @@ return array(
631
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\Forminator' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/Forminator.php',
632
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\GravityForms' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/GravityForms.php',
633
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\Groundhogg' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/Groundhogg.php',
 
634
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\Helpers\\NinjaForms_ShieldSpamAction' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/Helpers/NinjaForms_ShieldSpamAction.php',
635
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\KaliForms' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/KaliForms.php',
636
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\NinjaForms' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/NinjaForms.php',
@@ -894,7 +890,6 @@ return array(
894
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Strings' => $baseDir . '/src/Modules/Sessions/Strings.php',
895
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Upgrade' => $baseDir . '/src/Modules/Sessions/Upgrade.php',
896
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\AjaxHandler' => $baseDir . '/src/Modules/Traffic/AjaxHandler.php',
897
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\Lib\\Limit\\Limiter' => $baseDir . '/src/Modules/Traffic/Lib/Limit/Limiter.php',
898
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\Lib\\Limit\\RateLimitExceededException' => $baseDir . '/src/Modules/Traffic/Lib/Limit/RateLimitExceededException.php',
899
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\Lib\\Limit\\TestIpLimit' => $baseDir . '/src/Modules/Traffic/Lib/Limit/TestIpLimit.php',
900
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\Lib\\LogHandlers\\LocalDbWriter' => $baseDir . '/src/Modules/Traffic/Lib/LogHandlers/LocalDbWriter.php',
@@ -924,7 +919,6 @@ return array(
924
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Strings' => $baseDir . '/src/Modules/UserManagement/Strings.php',
925
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\UI' => $baseDir . '/src/Modules/UserManagement/UI.php',
926
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\WpCli' => $baseDir . '/src/Modules/UserManagement/WpCli.php',
927
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\WpCli\\SessionTerminate' => $baseDir . '/src/Modules/UserManagement/WpCli/SessionTerminate.php',
928
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Render\\LocateTemplateDirs' => $baseDir . '/src/Render/LocateTemplateDirs.php',
929
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Request\\ThisRequest' => $baseDir . '/src/Request/ThisRequest.php',
930
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Rules\\Build\\BuildRuleBase' => $baseDir . '/src/Rules/Build/BuildRuleBase.php',
@@ -1027,6 +1021,7 @@ return array(
1027
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Exceptions\\WpCoreFileMissingException' => $baseDir . '/src/Scans/Afs/Exceptions/WpCoreFileMissingException.php',
1028
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Exceptions\\WpCoreFileUnrecognisedException' => $baseDir . '/src/Scans/Afs/Exceptions/WpCoreFileUnrecognisedException.php',
1029
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\FileScanner' => $baseDir . '/src/Scans/Afs/FileScanner.php',
 
1030
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Processing\\MalFalsePositiveQuery' => $baseDir . '/src/Scans/Afs/Processing/MalFalsePositiveQuery.php',
1031
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Processing\\MalFalsePositiveReporter' => $baseDir . '/src/Scans/Afs/Processing/MalFalsePositiveReporter.php',
1032
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Processing\\MalReportCache' => $baseDir . '/src/Scans/Afs/Processing/MalReportCache.php',
@@ -1048,27 +1043,19 @@ return array(
1048
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Utilities\\Patterns' => $baseDir . '/src/Scans/Afs/Utilities/Patterns.php',
1049
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Utilities\\RepairItem' => $baseDir . '/src/Scans/Afs/Utilities/RepairItem.php',
1050
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\BuildScanAction' => $baseDir . '/src/Scans/Apc/BuildScanAction.php',
1051
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\BuildScanItems' => $baseDir . '/src/Scans/Apc/BuildScanItems.php',
1052
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\PluginScanner' => $baseDir . '/src/Scans/Apc/PluginScanner.php',
1053
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ResultItem' => $baseDir . '/src/Scans/Apc/ResultItem.php',
1054
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ResultsSet' => $baseDir . '/src/Scans/Apc/ResultsSet.php',
1055
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\Scan' => $baseDir . '/src/Scans/Apc/Scan.php',
1056
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ScanActionVO' => $baseDir . '/src/Scans/Apc/ScanActionVO.php',
1057
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\Utilities\\ItemActionHandler' => $baseDir . '/src/Scans/Apc/Utilities/ItemActionHandler.php',
1058
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseBuildFileMap' => $baseDir . '/src/Scans/Base/BaseBuildFileMap.php',
1059
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseFileScanActionVO' => $baseDir . '/src/Scans/Base/BaseFileScanActionVO.php',
1060
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseMergeItems' => $baseDir . '/src/Scans/Base/BaseMergeItems.php',
1061
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseScan' => $baseDir . '/src/Scans/Base/BaseScan.php',
1062
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseScanActionVO' => $baseDir . '/src/Scans/Base/BaseScanActionVO.php',
1063
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BuildScanAction' => $baseDir . '/src/Scans/Base/BuildScanAction.php',
1064
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\FileResultItem' => $baseDir . '/src/Scans/Base/FileResultItem.php',
1065
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Files\\BaseFileMapScan' => $baseDir . '/src/Scans/Base/Files/BaseFileMapScan.php',
1066
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Files\\BaseFileScanner' => $baseDir . '/src/Scans/Base/Files/BaseFileScanner.php',
1067
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Files\\BaseScanFromFileMap' => $baseDir . '/src/Scans/Base/Files/BaseScanFromFileMap.php',
1068
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\ResultItem' => $baseDir . '/src/Scans/Base/ResultItem.php',
1069
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\ResultsSet' => $baseDir . '/src/Scans/Base/ResultsSet.php',
1070
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\BaseRepair' => $baseDir . '/src/Scans/Base/Utilities/BaseRepair.php',
1071
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\BuildScanItems' => $baseDir . '/src/Scans/Base/Utilities/BuildScanItems.php',
1072
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\ItemActionHandler' => $baseDir . '/src/Scans/Base/Utilities/ItemActionHandler.php',
1073
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\ItemActionHandlerAssets' => $baseDir . '/src/Scans/Base/Utilities/ItemActionHandlerAssets.php',
1074
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\ItemDeleteHandler' => $baseDir . '/src/Scans/Base/Utilities/ItemDeleteHandler.php',
@@ -1089,7 +1076,6 @@ return array(
1089
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ScanActionVO' => $baseDir . '/src/Scans/Ufc/ScanActionVO.php',
1090
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\ScanActionVO' => $baseDir . '/src/Scans/Wcf/ScanActionVO.php',
1091
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\BuildScanAction' => $baseDir . '/src/Scans/Wpv/BuildScanAction.php',
1092
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\BuildScanItems' => $baseDir . '/src/Scans/Wpv/BuildScanItems.php',
1093
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ResultItem' => $baseDir . '/src/Scans/Wpv/ResultItem.php',
1094
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ResultsSet' => $baseDir . '/src/Scans/Wpv/ResultsSet.php',
1095
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\Scan' => $baseDir . '/src/Scans/Wpv/Scan.php',
@@ -1199,6 +1185,7 @@ return array(
1199
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
1200
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpThemeVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpThemeVo.php',
1201
  'FernleafSystems\\Wordpress\\Services\\Services' => $vendorDir . '/fernleafsystems/wordpress-services/src/Services.php',
 
1202
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Assets\\DetectInstallationDate' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Assets/DetectInstallationDate.php',
1203
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Autoloading\\FindClassFromNamespaceRoots' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Autoloading/FindClassFromNamespaceRoots.php',
1204
  'FernleafSystems\\Wordpress\\Services\\Utilities\\BackgroundProcessing\\BackgroundProcess' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/BackgroundProcessing/BackgroundProcess.php',
@@ -1227,6 +1214,7 @@ return array(
1227
  'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\Paths' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/File/Paths.php',
1228
  'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\ReadDataFromFileEncrypted' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/File/ReadDataFromFileEncrypted.php',
1229
  'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\RemoveLineFromFile' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/File/RemoveLineFromFile.php',
 
1230
  'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\TestFileWritable' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/File/TestFileWritable.php',
1231
  'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\WriteDataToFileEncrypted' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/File/WriteDataToFileEncrypted.php',
1232
  'FernleafSystems\\Wordpress\\Services\\Utilities\\GeoIp' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/GeoIp.php',
@@ -1295,6 +1283,7 @@ return array(
1295
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\BaseIP' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Net/BaseIP.php',
1296
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\FindSourceFromIp' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Net/FindSourceFromIp.php',
1297
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\IpID' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Net/IpID.php',
 
1298
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\VerifyHostToIP' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Net/VerifyHostToIP.php',
1299
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\VisitorIpDetection' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Net/VisitorIpDetection.php',
1300
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Obfuscate' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Obfuscate.php',
102
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Assets\\Paths' => $baseDir . '/src/Controller/Assets/Paths.php',
103
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Assets\\Svgs' => $baseDir . '/src/Controller/Assets/Svgs.php',
104
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Assets\\Urls' => $baseDir . '/src/Controller/Assets/Urls.php',
105
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Checks\\PreModulesBootCheck' => $baseDir . '/src/Controller/Checks/PreModulesBootCheck.php',
106
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Config\\ConfigVO' => $baseDir . '/src/Controller/Config/ConfigVO.php',
107
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Config\\Labels' => $baseDir . '/src/Controller/Config/Labels.php',
108
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Config\\Ops\\LoadConfig' => $baseDir . '/src/Controller/Config/Ops/LoadConfig.php',
109
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Config\\Ops\\Read' => $baseDir . '/src/Controller/Config/Ops/Read.php',
 
110
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Controller' => $baseDir . '/src/Controller/Controller.php',
111
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Exceptions\\PluginConfigInvalidException' => $baseDir . '/src/Controller/Exceptions/PluginConfigInvalidException.php',
112
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Exceptions\\VersionMismatchException' => $baseDir . '/src/Controller/Exceptions/VersionMismatchException.php',
179
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Reports\\Select' => $baseDir . '/src/Databases/Reports/Select.php',
180
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Reports\\Update' => $baseDir . '/src/Databases/Reports/Update.php',
181
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\ReqLogs\\QueueReqDbRecordMigrator' => $baseDir . '/src/Databases/ReqLogs/QueueReqDbRecordMigrator.php',
 
 
 
 
 
 
182
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Utility\\QueueDbRecordsMigrator' => $baseDir . '/src/Databases/Utility/QueueDbRecordsMigrator.php',
183
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Helpers\\QuickAccess' => $baseDir . '/src/Helpers/QuickAccess.php',
184
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\License\\EddLicenseVO' => $baseDir . '/src/License/EddLicenseVO.php',
247
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Config\\ModConfigVO' => $baseDir . '/src/Modules/Base/Config/ModConfigVO.php',
248
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Databases' => $baseDir . '/src/Modules/Base/Databases.php',
249
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Debug' => $baseDir . '/src/Modules/Base/Debug.php',
250
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Lib\\CheckModuleRequirements' => $baseDir . '/src/Modules/Base/Lib/CheckModuleRequirements.php',
251
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Lib\\Components\\UiTrack' => $baseDir . '/src/Modules/Base/Lib/Components/UiTrack.php',
252
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Lib\\Request\\FormParams' => $baseDir . '/src/Modules/Base/Lib/Request/FormParams.php',
253
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\ModCon' => $baseDir . '/src/Modules/Base/ModCon.php',
338
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Checks\\Base' => $baseDir . '/src/Modules/Firewall/Lib/Scan/Checks/Base.php',
339
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Checks\\ExeFiles' => $baseDir . '/src/Modules/Firewall/Lib/Scan/Checks/ExeFiles.php',
340
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Checks\\Standard' => $baseDir . '/src/Modules/Firewall/Lib/Scan/Checks/Standard.php',
 
341
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Handlers\\Aggressive' => $baseDir . '/src/Modules/Firewall/Lib/Scan/Handlers/Aggressive.php',
342
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Handlers\\Base' => $baseDir . '/src/Modules/Firewall/Lib/Scan/Handlers/Base.php',
343
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Handlers\\BaseRequestParams' => $baseDir . '/src/Modules/Firewall/Lib/Scan/Handlers/BaseRequestParams.php',
626
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\Forminator' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/Forminator.php',
627
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\GravityForms' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/GravityForms.php',
628
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\Groundhogg' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/Groundhogg.php',
629
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\HappyForms' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/HappyForms.php',
630
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\Helpers\\NinjaForms_ShieldSpamAction' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/Helpers/NinjaForms_ShieldSpamAction.php',
631
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\KaliForms' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/KaliForms.php',
632
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\NinjaForms' => $baseDir . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/NinjaForms.php',
890
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Strings' => $baseDir . '/src/Modules/Sessions/Strings.php',
891
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Upgrade' => $baseDir . '/src/Modules/Sessions/Upgrade.php',
892
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\AjaxHandler' => $baseDir . '/src/Modules/Traffic/AjaxHandler.php',
 
893
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\Lib\\Limit\\RateLimitExceededException' => $baseDir . '/src/Modules/Traffic/Lib/Limit/RateLimitExceededException.php',
894
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\Lib\\Limit\\TestIpLimit' => $baseDir . '/src/Modules/Traffic/Lib/Limit/TestIpLimit.php',
895
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\Lib\\LogHandlers\\LocalDbWriter' => $baseDir . '/src/Modules/Traffic/Lib/LogHandlers/LocalDbWriter.php',
919
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Strings' => $baseDir . '/src/Modules/UserManagement/Strings.php',
920
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\UI' => $baseDir . '/src/Modules/UserManagement/UI.php',
921
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\WpCli' => $baseDir . '/src/Modules/UserManagement/WpCli.php',
 
922
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Render\\LocateTemplateDirs' => $baseDir . '/src/Render/LocateTemplateDirs.php',
923
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Request\\ThisRequest' => $baseDir . '/src/Request/ThisRequest.php',
924
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Rules\\Build\\BuildRuleBase' => $baseDir . '/src/Rules/Build/BuildRuleBase.php',
1021
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Exceptions\\WpCoreFileMissingException' => $baseDir . '/src/Scans/Afs/Exceptions/WpCoreFileMissingException.php',
1022
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Exceptions\\WpCoreFileUnrecognisedException' => $baseDir . '/src/Scans/Afs/Exceptions/WpCoreFileUnrecognisedException.php',
1023
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\FileScanner' => $baseDir . '/src/Scans/Afs/FileScanner.php',
1024
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Processing\\FileScanOptimiser' => $baseDir . '/src/Scans/Afs/Processing/FileScanOptimiser.php',
1025
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Processing\\MalFalsePositiveQuery' => $baseDir . '/src/Scans/Afs/Processing/MalFalsePositiveQuery.php',
1026
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Processing\\MalFalsePositiveReporter' => $baseDir . '/src/Scans/Afs/Processing/MalFalsePositiveReporter.php',
1027
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Processing\\MalReportCache' => $baseDir . '/src/Scans/Afs/Processing/MalReportCache.php',
1043
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Utilities\\Patterns' => $baseDir . '/src/Scans/Afs/Utilities/Patterns.php',
1044
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Utilities\\RepairItem' => $baseDir . '/src/Scans/Afs/Utilities/RepairItem.php',
1045
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\BuildScanAction' => $baseDir . '/src/Scans/Apc/BuildScanAction.php',
 
1046
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\PluginScanner' => $baseDir . '/src/Scans/Apc/PluginScanner.php',
1047
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ResultItem' => $baseDir . '/src/Scans/Apc/ResultItem.php',
1048
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ResultsSet' => $baseDir . '/src/Scans/Apc/ResultsSet.php',
1049
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\Scan' => $baseDir . '/src/Scans/Apc/Scan.php',
1050
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ScanActionVO' => $baseDir . '/src/Scans/Apc/ScanActionVO.php',
1051
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\Utilities\\ItemActionHandler' => $baseDir . '/src/Scans/Apc/Utilities/ItemActionHandler.php',
 
 
1052
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseMergeItems' => $baseDir . '/src/Scans/Base/BaseMergeItems.php',
1053
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseScan' => $baseDir . '/src/Scans/Base/BaseScan.php',
1054
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseScanActionVO' => $baseDir . '/src/Scans/Base/BaseScanActionVO.php',
1055
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BuildScanAction' => $baseDir . '/src/Scans/Base/BuildScanAction.php',
1056
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\FileResultItem' => $baseDir . '/src/Scans/Base/FileResultItem.php',
 
 
 
1057
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\ResultItem' => $baseDir . '/src/Scans/Base/ResultItem.php',
1058
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\ResultsSet' => $baseDir . '/src/Scans/Base/ResultsSet.php',
 
 
1059
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\ItemActionHandler' => $baseDir . '/src/Scans/Base/Utilities/ItemActionHandler.php',
1060
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\ItemActionHandlerAssets' => $baseDir . '/src/Scans/Base/Utilities/ItemActionHandlerAssets.php',
1061
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\ItemDeleteHandler' => $baseDir . '/src/Scans/Base/Utilities/ItemDeleteHandler.php',
1076
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ScanActionVO' => $baseDir . '/src/Scans/Ufc/ScanActionVO.php',
1077
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\ScanActionVO' => $baseDir . '/src/Scans/Wcf/ScanActionVO.php',
1078
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\BuildScanAction' => $baseDir . '/src/Scans/Wpv/BuildScanAction.php',
 
1079
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ResultItem' => $baseDir . '/src/Scans/Wpv/ResultItem.php',
1080
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ResultsSet' => $baseDir . '/src/Scans/Wpv/ResultsSet.php',
1081
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\Scan' => $baseDir . '/src/Scans/Wpv/Scan.php',
1185
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
1186
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpThemeVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpThemeVo.php',
1187
  'FernleafSystems\\Wordpress\\Services\\Services' => $vendorDir . '/fernleafsystems/wordpress-services/src/Services.php',
1188
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Arrays' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Arrays.php',
1189
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Assets\\DetectInstallationDate' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Assets/DetectInstallationDate.php',
1190
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Autoloading\\FindClassFromNamespaceRoots' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Autoloading/FindClassFromNamespaceRoots.php',
1191
  'FernleafSystems\\Wordpress\\Services\\Utilities\\BackgroundProcessing\\BackgroundProcess' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/BackgroundProcessing/BackgroundProcess.php',
1214
  'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\Paths' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/File/Paths.php',
1215
  'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\ReadDataFromFileEncrypted' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/File/ReadDataFromFileEncrypted.php',
1216
  'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\RemoveLineFromFile' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/File/RemoveLineFromFile.php',
1217
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\Search\\SearchFile' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/File/Search/SearchFile.php',
1218
  'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\TestFileWritable' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/File/TestFileWritable.php',
1219
  'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\WriteDataToFileEncrypted' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/File/WriteDataToFileEncrypted.php',
1220
  'FernleafSystems\\Wordpress\\Services\\Utilities\\GeoIp' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/GeoIp.php',
1283
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\BaseIP' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Net/BaseIP.php',
1284
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\FindSourceFromIp' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Net/FindSourceFromIp.php',
1285
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\IpID' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Net/IpID.php',
1286
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\RequestIpDetect' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Net/RequestIpDetect.php',
1287
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\VerifyHostToIP' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Net/VerifyHostToIP.php',
1288
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\VisitorIpDetection' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Net/VisitorIpDetection.php',
1289
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Obfuscate' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Obfuscate.php',
src/lib/vendor/composer/autoload_static.php CHANGED
@@ -289,10 +289,11 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
289
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Assets\\Paths' => __DIR__ . '/../..' . '/src/Controller/Assets/Paths.php',
290
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Assets\\Svgs' => __DIR__ . '/../..' . '/src/Controller/Assets/Svgs.php',
291
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Assets\\Urls' => __DIR__ . '/../..' . '/src/Controller/Assets/Urls.php',
 
292
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Config\\ConfigVO' => __DIR__ . '/../..' . '/src/Controller/Config/ConfigVO.php',
 
293
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Config\\Ops\\LoadConfig' => __DIR__ . '/../..' . '/src/Controller/Config/Ops/LoadConfig.php',
294
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Config\\Ops\\Read' => __DIR__ . '/../..' . '/src/Controller/Config/Ops/Read.php',
295
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Config\\Ops\\Save' => __DIR__ . '/../..' . '/src/Controller/Config/Ops/Save.php',
296
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Controller' => __DIR__ . '/../..' . '/src/Controller/Controller.php',
297
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Exceptions\\PluginConfigInvalidException' => __DIR__ . '/../..' . '/src/Controller/Exceptions/PluginConfigInvalidException.php',
298
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Exceptions\\VersionMismatchException' => __DIR__ . '/../..' . '/src/Controller/Exceptions/VersionMismatchException.php',
@@ -365,12 +366,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
365
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Reports\\Select' => __DIR__ . '/../..' . '/src/Databases/Reports/Select.php',
366
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Reports\\Update' => __DIR__ . '/../..' . '/src/Databases/Reports/Update.php',
367
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\ReqLogs\\QueueReqDbRecordMigrator' => __DIR__ . '/../..' . '/src/Databases/ReqLogs/QueueReqDbRecordMigrator.php',
368
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Session\\Delete' => __DIR__ . '/../..' . '/src/Databases/Session/Delete.php',
369
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Session\\EntryVO' => __DIR__ . '/../..' . '/src/Databases/Session/EntryVO.php',
370
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Session\\Handler' => __DIR__ . '/../..' . '/src/Databases/Session/Handler.php',
371
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Session\\Insert' => __DIR__ . '/../..' . '/src/Databases/Session/Insert.php',
372
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Session\\Select' => __DIR__ . '/../..' . '/src/Databases/Session/Select.php',
373
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Session\\Update' => __DIR__ . '/../..' . '/src/Databases/Session/Update.php',
374
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Utility\\QueueDbRecordsMigrator' => __DIR__ . '/../..' . '/src/Databases/Utility/QueueDbRecordsMigrator.php',
375
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Helpers\\QuickAccess' => __DIR__ . '/../..' . '/src/Helpers/QuickAccess.php',
376
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\License\\EddLicenseVO' => __DIR__ . '/../..' . '/src/License/EddLicenseVO.php',
@@ -439,6 +434,7 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
439
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Config\\ModConfigVO' => __DIR__ . '/../..' . '/src/Modules/Base/Config/ModConfigVO.php',
440
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Databases' => __DIR__ . '/../..' . '/src/Modules/Base/Databases.php',
441
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Debug' => __DIR__ . '/../..' . '/src/Modules/Base/Debug.php',
 
442
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Lib\\Components\\UiTrack' => __DIR__ . '/../..' . '/src/Modules/Base/Lib/Components/UiTrack.php',
443
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Lib\\Request\\FormParams' => __DIR__ . '/../..' . '/src/Modules/Base/Lib/Request/FormParams.php',
444
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\ModCon' => __DIR__ . '/../..' . '/src/Modules/Base/ModCon.php',
@@ -529,7 +525,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
529
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Checks\\Base' => __DIR__ . '/../..' . '/src/Modules/Firewall/Lib/Scan/Checks/Base.php',
530
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Checks\\ExeFiles' => __DIR__ . '/../..' . '/src/Modules/Firewall/Lib/Scan/Checks/ExeFiles.php',
531
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Checks\\Standard' => __DIR__ . '/../..' . '/src/Modules/Firewall/Lib/Scan/Checks/Standard.php',
532
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\FirewallHandler' => __DIR__ . '/../..' . '/src/Modules/Firewall/Lib/Scan/FirewallHandler.php',
533
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Handlers\\Aggressive' => __DIR__ . '/../..' . '/src/Modules/Firewall/Lib/Scan/Handlers/Aggressive.php',
534
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Handlers\\Base' => __DIR__ . '/../..' . '/src/Modules/Firewall/Lib/Scan/Handlers/Base.php',
535
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Handlers\\BaseRequestParams' => __DIR__ . '/../..' . '/src/Modules/Firewall/Lib/Scan/Handlers/BaseRequestParams.php',
@@ -818,6 +813,7 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
818
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\Forminator' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/Forminator.php',
819
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\GravityForms' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/GravityForms.php',
820
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\Groundhogg' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/Groundhogg.php',
 
821
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\Helpers\\NinjaForms_ShieldSpamAction' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/Helpers/NinjaForms_ShieldSpamAction.php',
822
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\KaliForms' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/KaliForms.php',
823
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\NinjaForms' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/NinjaForms.php',
@@ -1081,7 +1077,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
1081
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Strings' => __DIR__ . '/../..' . '/src/Modules/Sessions/Strings.php',
1082
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Upgrade' => __DIR__ . '/../..' . '/src/Modules/Sessions/Upgrade.php',
1083
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\AjaxHandler' => __DIR__ . '/../..' . '/src/Modules/Traffic/AjaxHandler.php',
1084
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\Lib\\Limit\\Limiter' => __DIR__ . '/../..' . '/src/Modules/Traffic/Lib/Limit/Limiter.php',
1085
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\Lib\\Limit\\RateLimitExceededException' => __DIR__ . '/../..' . '/src/Modules/Traffic/Lib/Limit/RateLimitExceededException.php',
1086
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\Lib\\Limit\\TestIpLimit' => __DIR__ . '/../..' . '/src/Modules/Traffic/Lib/Limit/TestIpLimit.php',
1087
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\Lib\\LogHandlers\\LocalDbWriter' => __DIR__ . '/../..' . '/src/Modules/Traffic/Lib/LogHandlers/LocalDbWriter.php',
@@ -1111,7 +1106,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
1111
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Strings' => __DIR__ . '/../..' . '/src/Modules/UserManagement/Strings.php',
1112
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\UI' => __DIR__ . '/../..' . '/src/Modules/UserManagement/UI.php',
1113
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\WpCli' => __DIR__ . '/../..' . '/src/Modules/UserManagement/WpCli.php',
1114
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\WpCli\\SessionTerminate' => __DIR__ . '/../..' . '/src/Modules/UserManagement/WpCli/SessionTerminate.php',
1115
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Render\\LocateTemplateDirs' => __DIR__ . '/../..' . '/src/Render/LocateTemplateDirs.php',
1116
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Request\\ThisRequest' => __DIR__ . '/../..' . '/src/Request/ThisRequest.php',
1117
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Rules\\Build\\BuildRuleBase' => __DIR__ . '/../..' . '/src/Rules/Build/BuildRuleBase.php',
@@ -1214,6 +1208,7 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
1214
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Exceptions\\WpCoreFileMissingException' => __DIR__ . '/../..' . '/src/Scans/Afs/Exceptions/WpCoreFileMissingException.php',
1215
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Exceptions\\WpCoreFileUnrecognisedException' => __DIR__ . '/../..' . '/src/Scans/Afs/Exceptions/WpCoreFileUnrecognisedException.php',
1216
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\FileScanner' => __DIR__ . '/../..' . '/src/Scans/Afs/FileScanner.php',
 
1217
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Processing\\MalFalsePositiveQuery' => __DIR__ . '/../..' . '/src/Scans/Afs/Processing/MalFalsePositiveQuery.php',
1218
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Processing\\MalFalsePositiveReporter' => __DIR__ . '/../..' . '/src/Scans/Afs/Processing/MalFalsePositiveReporter.php',
1219
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Processing\\MalReportCache' => __DIR__ . '/../..' . '/src/Scans/Afs/Processing/MalReportCache.php',
@@ -1235,27 +1230,19 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
1235
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Utilities\\Patterns' => __DIR__ . '/../..' . '/src/Scans/Afs/Utilities/Patterns.php',
1236
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Utilities\\RepairItem' => __DIR__ . '/../..' . '/src/Scans/Afs/Utilities/RepairItem.php',
1237
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\BuildScanAction' => __DIR__ . '/../..' . '/src/Scans/Apc/BuildScanAction.php',
1238
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\BuildScanItems' => __DIR__ . '/../..' . '/src/Scans/Apc/BuildScanItems.php',
1239
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\PluginScanner' => __DIR__ . '/../..' . '/src/Scans/Apc/PluginScanner.php',
1240
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ResultItem' => __DIR__ . '/../..' . '/src/Scans/Apc/ResultItem.php',
1241
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ResultsSet' => __DIR__ . '/../..' . '/src/Scans/Apc/ResultsSet.php',
1242
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\Scan' => __DIR__ . '/../..' . '/src/Scans/Apc/Scan.php',
1243
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ScanActionVO' => __DIR__ . '/../..' . '/src/Scans/Apc/ScanActionVO.php',
1244
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\Utilities\\ItemActionHandler' => __DIR__ . '/../..' . '/src/Scans/Apc/Utilities/ItemActionHandler.php',
1245
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseBuildFileMap' => __DIR__ . '/../..' . '/src/Scans/Base/BaseBuildFileMap.php',
1246
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseFileScanActionVO' => __DIR__ . '/../..' . '/src/Scans/Base/BaseFileScanActionVO.php',
1247
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseMergeItems' => __DIR__ . '/../..' . '/src/Scans/Base/BaseMergeItems.php',
1248
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseScan' => __DIR__ . '/../..' . '/src/Scans/Base/BaseScan.php',
1249
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseScanActionVO' => __DIR__ . '/../..' . '/src/Scans/Base/BaseScanActionVO.php',
1250
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BuildScanAction' => __DIR__ . '/../..' . '/src/Scans/Base/BuildScanAction.php',
1251
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\FileResultItem' => __DIR__ . '/../..' . '/src/Scans/Base/FileResultItem.php',
1252
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Files\\BaseFileMapScan' => __DIR__ . '/../..' . '/src/Scans/Base/Files/BaseFileMapScan.php',
1253
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Files\\BaseFileScanner' => __DIR__ . '/../..' . '/src/Scans/Base/Files/BaseFileScanner.php',
1254
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Files\\BaseScanFromFileMap' => __DIR__ . '/../..' . '/src/Scans/Base/Files/BaseScanFromFileMap.php',
1255
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\ResultItem' => __DIR__ . '/../..' . '/src/Scans/Base/ResultItem.php',
1256
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\ResultsSet' => __DIR__ . '/../..' . '/src/Scans/Base/ResultsSet.php',
1257
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\BaseRepair' => __DIR__ . '/../..' . '/src/Scans/Base/Utilities/BaseRepair.php',
1258
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\BuildScanItems' => __DIR__ . '/../..' . '/src/Scans/Base/Utilities/BuildScanItems.php',
1259
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\ItemActionHandler' => __DIR__ . '/../..' . '/src/Scans/Base/Utilities/ItemActionHandler.php',
1260
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\ItemActionHandlerAssets' => __DIR__ . '/../..' . '/src/Scans/Base/Utilities/ItemActionHandlerAssets.php',
1261
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\ItemDeleteHandler' => __DIR__ . '/../..' . '/src/Scans/Base/Utilities/ItemDeleteHandler.php',
@@ -1276,7 +1263,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
1276
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ScanActionVO' => __DIR__ . '/../..' . '/src/Scans/Ufc/ScanActionVO.php',
1277
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\ScanActionVO' => __DIR__ . '/../..' . '/src/Scans/Wcf/ScanActionVO.php',
1278
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\BuildScanAction' => __DIR__ . '/../..' . '/src/Scans/Wpv/BuildScanAction.php',
1279
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\BuildScanItems' => __DIR__ . '/../..' . '/src/Scans/Wpv/BuildScanItems.php',
1280
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ResultItem' => __DIR__ . '/../..' . '/src/Scans/Wpv/ResultItem.php',
1281
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ResultsSet' => __DIR__ . '/../..' . '/src/Scans/Wpv/ResultsSet.php',
1282
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\Scan' => __DIR__ . '/../..' . '/src/Scans/Wpv/Scan.php',
@@ -1386,6 +1372,7 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
1386
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
1387
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpThemeVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpThemeVo.php',
1388
  'FernleafSystems\\Wordpress\\Services\\Services' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Services.php',
 
1389
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Assets\\DetectInstallationDate' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Assets/DetectInstallationDate.php',
1390
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Autoloading\\FindClassFromNamespaceRoots' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Autoloading/FindClassFromNamespaceRoots.php',
1391
  'FernleafSystems\\Wordpress\\Services\\Utilities\\BackgroundProcessing\\BackgroundProcess' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/BackgroundProcessing/BackgroundProcess.php',
@@ -1414,6 +1401,7 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
1414
  'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\Paths' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/File/Paths.php',
1415
  'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\ReadDataFromFileEncrypted' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/File/ReadDataFromFileEncrypted.php',
1416
  'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\RemoveLineFromFile' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/File/RemoveLineFromFile.php',
 
1417
  'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\TestFileWritable' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/File/TestFileWritable.php',
1418
  'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\WriteDataToFileEncrypted' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/File/WriteDataToFileEncrypted.php',
1419
  'FernleafSystems\\Wordpress\\Services\\Utilities\\GeoIp' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/GeoIp.php',
@@ -1482,6 +1470,7 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
1482
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\BaseIP' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Net/BaseIP.php',
1483
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\FindSourceFromIp' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Net/FindSourceFromIp.php',
1484
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\IpID' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Net/IpID.php',
 
1485
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\VerifyHostToIP' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Net/VerifyHostToIP.php',
1486
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\VisitorIpDetection' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Net/VisitorIpDetection.php',
1487
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Obfuscate' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Obfuscate.php',
289
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Assets\\Paths' => __DIR__ . '/../..' . '/src/Controller/Assets/Paths.php',
290
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Assets\\Svgs' => __DIR__ . '/../..' . '/src/Controller/Assets/Svgs.php',
291
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Assets\\Urls' => __DIR__ . '/../..' . '/src/Controller/Assets/Urls.php',
292
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Checks\\PreModulesBootCheck' => __DIR__ . '/../..' . '/src/Controller/Checks/PreModulesBootCheck.php',
293
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Config\\ConfigVO' => __DIR__ . '/../..' . '/src/Controller/Config/ConfigVO.php',
294
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Config\\Labels' => __DIR__ . '/../..' . '/src/Controller/Config/Labels.php',
295
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Config\\Ops\\LoadConfig' => __DIR__ . '/../..' . '/src/Controller/Config/Ops/LoadConfig.php',
296
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Config\\Ops\\Read' => __DIR__ . '/../..' . '/src/Controller/Config/Ops/Read.php',
 
297
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Controller' => __DIR__ . '/../..' . '/src/Controller/Controller.php',
298
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Exceptions\\PluginConfigInvalidException' => __DIR__ . '/../..' . '/src/Controller/Exceptions/PluginConfigInvalidException.php',
299
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Controller\\Exceptions\\VersionMismatchException' => __DIR__ . '/../..' . '/src/Controller/Exceptions/VersionMismatchException.php',
366
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Reports\\Select' => __DIR__ . '/../..' . '/src/Databases/Reports/Select.php',
367
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Reports\\Update' => __DIR__ . '/../..' . '/src/Databases/Reports/Update.php',
368
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\ReqLogs\\QueueReqDbRecordMigrator' => __DIR__ . '/../..' . '/src/Databases/ReqLogs/QueueReqDbRecordMigrator.php',
 
 
 
 
 
 
369
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Utility\\QueueDbRecordsMigrator' => __DIR__ . '/../..' . '/src/Databases/Utility/QueueDbRecordsMigrator.php',
370
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Helpers\\QuickAccess' => __DIR__ . '/../..' . '/src/Helpers/QuickAccess.php',
371
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\License\\EddLicenseVO' => __DIR__ . '/../..' . '/src/License/EddLicenseVO.php',
434
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Config\\ModConfigVO' => __DIR__ . '/../..' . '/src/Modules/Base/Config/ModConfigVO.php',
435
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Databases' => __DIR__ . '/../..' . '/src/Modules/Base/Databases.php',
436
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Debug' => __DIR__ . '/../..' . '/src/Modules/Base/Debug.php',
437
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Lib\\CheckModuleRequirements' => __DIR__ . '/../..' . '/src/Modules/Base/Lib/CheckModuleRequirements.php',
438
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Lib\\Components\\UiTrack' => __DIR__ . '/../..' . '/src/Modules/Base/Lib/Components/UiTrack.php',
439
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Lib\\Request\\FormParams' => __DIR__ . '/../..' . '/src/Modules/Base/Lib/Request/FormParams.php',
440
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\ModCon' => __DIR__ . '/../..' . '/src/Modules/Base/ModCon.php',
525
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Checks\\Base' => __DIR__ . '/../..' . '/src/Modules/Firewall/Lib/Scan/Checks/Base.php',
526
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Checks\\ExeFiles' => __DIR__ . '/../..' . '/src/Modules/Firewall/Lib/Scan/Checks/ExeFiles.php',
527
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Checks\\Standard' => __DIR__ . '/../..' . '/src/Modules/Firewall/Lib/Scan/Checks/Standard.php',
 
528
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Handlers\\Aggressive' => __DIR__ . '/../..' . '/src/Modules/Firewall/Lib/Scan/Handlers/Aggressive.php',
529
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Handlers\\Base' => __DIR__ . '/../..' . '/src/Modules/Firewall/Lib/Scan/Handlers/Base.php',
530
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Lib\\Scan\\Handlers\\BaseRequestParams' => __DIR__ . '/../..' . '/src/Modules/Firewall/Lib/Scan/Handlers/BaseRequestParams.php',
813
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\Forminator' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/Forminator.php',
814
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\GravityForms' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/GravityForms.php',
815
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\Groundhogg' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/Groundhogg.php',
816
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\HappyForms' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/HappyForms.php',
817
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\Helpers\\NinjaForms_ShieldSpamAction' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/Helpers/NinjaForms_ShieldSpamAction.php',
818
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\KaliForms' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/KaliForms.php',
819
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Bots\\Spam\\Handlers\\NinjaForms' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Bots/Spam/Handlers/NinjaForms.php',
1077
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Strings' => __DIR__ . '/../..' . '/src/Modules/Sessions/Strings.php',
1078
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Upgrade' => __DIR__ . '/../..' . '/src/Modules/Sessions/Upgrade.php',
1079
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\AjaxHandler' => __DIR__ . '/../..' . '/src/Modules/Traffic/AjaxHandler.php',
 
1080
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\Lib\\Limit\\RateLimitExceededException' => __DIR__ . '/../..' . '/src/Modules/Traffic/Lib/Limit/RateLimitExceededException.php',
1081
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\Lib\\Limit\\TestIpLimit' => __DIR__ . '/../..' . '/src/Modules/Traffic/Lib/Limit/TestIpLimit.php',
1082
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Traffic\\Lib\\LogHandlers\\LocalDbWriter' => __DIR__ . '/../..' . '/src/Modules/Traffic/Lib/LogHandlers/LocalDbWriter.php',
1106
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Strings' => __DIR__ . '/../..' . '/src/Modules/UserManagement/Strings.php',
1107
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\UI' => __DIR__ . '/../..' . '/src/Modules/UserManagement/UI.php',
1108
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\WpCli' => __DIR__ . '/../..' . '/src/Modules/UserManagement/WpCli.php',
 
1109
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Render\\LocateTemplateDirs' => __DIR__ . '/../..' . '/src/Render/LocateTemplateDirs.php',
1110
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Request\\ThisRequest' => __DIR__ . '/../..' . '/src/Request/ThisRequest.php',
1111
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Rules\\Build\\BuildRuleBase' => __DIR__ . '/../..' . '/src/Rules/Build/BuildRuleBase.php',
1208
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Exceptions\\WpCoreFileMissingException' => __DIR__ . '/../..' . '/src/Scans/Afs/Exceptions/WpCoreFileMissingException.php',
1209
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Exceptions\\WpCoreFileUnrecognisedException' => __DIR__ . '/../..' . '/src/Scans/Afs/Exceptions/WpCoreFileUnrecognisedException.php',
1210
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\FileScanner' => __DIR__ . '/../..' . '/src/Scans/Afs/FileScanner.php',
1211
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Processing\\FileScanOptimiser' => __DIR__ . '/../..' . '/src/Scans/Afs/Processing/FileScanOptimiser.php',
1212
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Processing\\MalFalsePositiveQuery' => __DIR__ . '/../..' . '/src/Scans/Afs/Processing/MalFalsePositiveQuery.php',
1213
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Processing\\MalFalsePositiveReporter' => __DIR__ . '/../..' . '/src/Scans/Afs/Processing/MalFalsePositiveReporter.php',
1214
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Processing\\MalReportCache' => __DIR__ . '/../..' . '/src/Scans/Afs/Processing/MalReportCache.php',
1230
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Utilities\\Patterns' => __DIR__ . '/../..' . '/src/Scans/Afs/Utilities/Patterns.php',
1231
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Afs\\Utilities\\RepairItem' => __DIR__ . '/../..' . '/src/Scans/Afs/Utilities/RepairItem.php',
1232
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\BuildScanAction' => __DIR__ . '/../..' . '/src/Scans/Apc/BuildScanAction.php',
 
1233
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\PluginScanner' => __DIR__ . '/../..' . '/src/Scans/Apc/PluginScanner.php',
1234
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ResultItem' => __DIR__ . '/../..' . '/src/Scans/Apc/ResultItem.php',
1235
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ResultsSet' => __DIR__ . '/../..' . '/src/Scans/Apc/ResultsSet.php',
1236
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\Scan' => __DIR__ . '/../..' . '/src/Scans/Apc/Scan.php',
1237
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\ScanActionVO' => __DIR__ . '/../..' . '/src/Scans/Apc/ScanActionVO.php',
1238
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Apc\\Utilities\\ItemActionHandler' => __DIR__ . '/../..' . '/src/Scans/Apc/Utilities/ItemActionHandler.php',
 
 
1239
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseMergeItems' => __DIR__ . '/../..' . '/src/Scans/Base/BaseMergeItems.php',
1240
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseScan' => __DIR__ . '/../..' . '/src/Scans/Base/BaseScan.php',
1241
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BaseScanActionVO' => __DIR__ . '/../..' . '/src/Scans/Base/BaseScanActionVO.php',
1242
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\BuildScanAction' => __DIR__ . '/../..' . '/src/Scans/Base/BuildScanAction.php',
1243
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\FileResultItem' => __DIR__ . '/../..' . '/src/Scans/Base/FileResultItem.php',
 
 
 
1244
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\ResultItem' => __DIR__ . '/../..' . '/src/Scans/Base/ResultItem.php',
1245
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\ResultsSet' => __DIR__ . '/../..' . '/src/Scans/Base/ResultsSet.php',
 
 
1246
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\ItemActionHandler' => __DIR__ . '/../..' . '/src/Scans/Base/Utilities/ItemActionHandler.php',
1247
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\ItemActionHandlerAssets' => __DIR__ . '/../..' . '/src/Scans/Base/Utilities/ItemActionHandlerAssets.php',
1248
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\ItemDeleteHandler' => __DIR__ . '/../..' . '/src/Scans/Base/Utilities/ItemDeleteHandler.php',
1263
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ScanActionVO' => __DIR__ . '/../..' . '/src/Scans/Ufc/ScanActionVO.php',
1264
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wcf\\ScanActionVO' => __DIR__ . '/../..' . '/src/Scans/Wcf/ScanActionVO.php',
1265
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\BuildScanAction' => __DIR__ . '/../..' . '/src/Scans/Wpv/BuildScanAction.php',
 
1266
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ResultItem' => __DIR__ . '/../..' . '/src/Scans/Wpv/ResultItem.php',
1267
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ResultsSet' => __DIR__ . '/../..' . '/src/Scans/Wpv/ResultsSet.php',
1268
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\Scan' => __DIR__ . '/../..' . '/src/Scans/Wpv/Scan.php',
1372
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
1373
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpThemeVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpThemeVo.php',
1374
  'FernleafSystems\\Wordpress\\Services\\Services' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Services.php',
1375
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Arrays' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Arrays.php',
1376
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Assets\\DetectInstallationDate' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Assets/DetectInstallationDate.php',
1377
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Autoloading\\FindClassFromNamespaceRoots' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Autoloading/FindClassFromNamespaceRoots.php',
1378
  'FernleafSystems\\Wordpress\\Services\\Utilities\\BackgroundProcessing\\BackgroundProcess' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/BackgroundProcessing/BackgroundProcess.php',
1401
  'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\Paths' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/File/Paths.php',
1402
  'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\ReadDataFromFileEncrypted' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/File/ReadDataFromFileEncrypted.php',
1403
  'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\RemoveLineFromFile' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/File/RemoveLineFromFile.php',
1404
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\Search\\SearchFile' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/File/Search/SearchFile.php',
1405
  'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\TestFileWritable' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/File/TestFileWritable.php',
1406
  'FernleafSystems\\Wordpress\\Services\\Utilities\\File\\WriteDataToFileEncrypted' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/File/WriteDataToFileEncrypted.php',
1407
  'FernleafSystems\\Wordpress\\Services\\Utilities\\GeoIp' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/GeoIp.php',
1470
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\BaseIP' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Net/BaseIP.php',
1471
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\FindSourceFromIp' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Net/FindSourceFromIp.php',
1472
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\IpID' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Net/IpID.php',
1473
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\RequestIpDetect' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Net/RequestIpDetect.php',
1474
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\VerifyHostToIP' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Net/VerifyHostToIP.php',
1475
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\VisitorIpDetection' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Net/VisitorIpDetection.php',
1476
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Obfuscate' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Obfuscate.php',
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Handler.php CHANGED
@@ -27,17 +27,15 @@ abstract class Handler {
27
  */
28
  private $isReady;
29
 
30
- /**
31
- * @var array
32
- */
33
- protected $tableDefinition;
34
-
35
  /**
36
  * @var TableSchema
37
  */
38
  protected $schema;
39
 
40
- private $allowAutoDelete = false;
 
 
 
41
 
42
  public function __construct( array $tableDefinition ) {
43
  if ( empty( $tableDefinition[ 'slug' ] ) ) {
@@ -50,51 +48,58 @@ abstract class Handler {
50
  * @throws \Exception
51
  */
52
  protected function run() {
53
- $this->tableInit();
54
  }
55
 
56
  /**
57
- * @return $this
58
  * @throws \Exception
59
  */
60
- public function tableInit() {
61
 
62
- $this->setupTableSchema();
63
 
64
- if ( !$this->isReady() ) {
65
 
66
- $this->tableCreate();
 
 
 
 
 
 
67
 
68
- if ( !$this->isReady( true ) && $this->allowAutoDelete ) {
69
  $this->tableDelete();
70
- $this->tableCreate();
71
  }
72
  }
73
 
74
- return $this;
75
  }
76
 
77
  private function setupTableSchema() :TableSchema {
78
- $this->schema = new TableSchema();
79
-
80
- $this->schema->applyFromArray( array_merge(
81
- [
82
- 'slug' => '',
83
- 'table_prefix' => '',
84
- 'primary_key' => 'id',
85
- 'cols_custom' => [],
86
- 'cols_timestamps' => [],
87
- 'has_updated_at' => true,
88
- 'has_created_at' => true,
89
- 'has_deleted_at' => true,
90
- 'col_older_than' => 'created_at',
91
- 'autoexpire' => 0,
92
- 'has_ip_col' => false,
93
- ],
94
- $this->tableDefinition
95
- ) );
96
-
97
- $this->schema->table = $this->getTable();
 
 
98
 
99
  return $this->schema;
100
  }
@@ -177,26 +182,8 @@ abstract class Handler {
177
  ->record();
178
  }
179
 
180
- /**
181
- * @return Record|mixed
182
- * @deprecated
183
- */
184
- public function getVo() {
185
- return $this->getRecord();
186
- }
187
-
188
- /**
189
- * @return $this
190
- * @throws \Exception
191
- */
192
- protected function tableCreate() {
193
- $DB = Services::WpDb();
194
- $sch = $this->getTableSchema();
195
- if ( !$DB->getIfTableExists( $sch->table ) ) {
196
- $DB->doSql( $sch->buildCreate() );
197
- $DB->clearResultShowTables();
198
- }
199
- return $this;
200
  }
201
 
202
  public function tableDelete( bool $truncate = false ) :bool {
@@ -204,86 +191,106 @@ abstract class Handler {
204
  $DB = Services::WpDb();
205
  $mResult = !$this->tableExists() ||
206
  ( $truncate ? $DB->doTruncateTable( $table ) : $DB->doDropTable( $table ) );
 
207
  $this->reset();
208
- return $mResult !== false;
209
  }
210
 
211
  public function tableExists() :bool {
212
- return Services::WpDb()->getIfTableExists( $this->getTable() );
213
  }
214
 
215
- public function tableTrimExcess( int $rowsLimit ) {
216
- try {
217
- $this->getQueryDeleter()->deleteExcess( $rowsLimit );
218
- }
219
- catch ( \Exception $e ) {
220
  }
221
- return $this;
222
  }
223
 
224
- public function isReady( bool $reTest = false ) :bool {
225
- if ( $reTest ) {
226
- $this->reset();
 
 
 
227
  }
 
 
228
 
229
- if ( !isset( $this->isReady ) ) {
230
- $schema = $this->getTableSchema();
231
- try {
232
- if ( $this->getReadyCache()->isReady( $schema ) ) {
233
- $this->isReady = true;
234
- }
235
- else {
236
- $align = new AlignTableWithSchema( $schema );
237
- $align->align();
238
- $this->isReady = $this->tableExists() && $align->isAligned();
239
- if ( $this->isReady ) {
240
- $this->getReadyCache()->setReady( $schema );
241
- }
242
- }
243
- }
244
- catch ( \Exception $e ) {
245
- $this->isReady = false;
246
- }
247
  }
 
 
248
 
249
- return $this->isReady;
 
 
 
 
 
250
  }
251
 
252
- protected function getReadyCache() :TableReadyCache {
253
- if ( !isset( self::$ReadyCache ) ) {
254
- self::$ReadyCache = new TableReadyCache();
255
- }
256
- return self::$ReadyCache;
257
  }
258
 
259
  /**
260
- * @deprecated
261
  */
262
  protected function getTransientReadyKey() :string {
263
  return 'apto-db-ready-'.substr( md5( serialize( $this->getTableSchema() ) ), 0, 10 );
264
  }
265
 
266
- public function getTableSchema() :TableSchema {
267
- return $this->schema;
 
 
 
 
 
 
 
 
 
 
 
 
268
  }
269
 
270
  /**
271
  * @return $this
 
272
  */
273
- public function setAllowAutoDelete( bool $allowAutoDelete ) {
274
- $this->allowAutoDelete = true;
275
  return $this;
276
  }
277
 
278
  /**
279
  * @return $this
 
 
280
  */
281
- private function reset() {
282
- unset( $this->isReady );
 
 
 
 
 
283
  return $this;
284
  }
285
 
286
- public function getBaseNamespaces() :array {
287
- return [ __NAMESPACE__ ];
 
 
 
 
 
 
 
 
288
  }
289
  }
27
  */
28
  private $isReady;
29
 
 
 
 
 
 
30
  /**
31
  * @var TableSchema
32
  */
33
  protected $schema;
34
 
35
+ /**
36
+ * @var array
37
+ */
38
+ protected $tableDefinition;
39
 
40
  public function __construct( array $tableDefinition ) {
41
  if ( empty( $tableDefinition[ 'slug' ] ) ) {
48
  * @throws \Exception
49
  */
50
  protected function run() {
51
+ $this->tableInit( true );
52
  }
53
 
54
  /**
 
55
  * @throws \Exception
56
  */
57
+ public function tableInit( bool $mayDeleteIfNotReady = false, bool $useReadyCheckCache = true ) {
58
 
59
+ $schema = $this->getTableSchema();
60
 
61
+ $ready = $useReadyCheckCache && static::GetTableReadyCache()->isReady( $schema );
62
 
63
+ if ( !$ready ) {
64
+ $aligner = new AlignTableWithSchema( $schema );
65
+ $aligner->align();
66
+ if ( $this->tableExists() && $aligner->isAligned() ) {
67
+ $ready = true;
68
+ static::GetTableReadyCache()->setReady( $schema );
69
+ }
70
 
71
+ if ( !$ready && $mayDeleteIfNotReady ) {
72
  $this->tableDelete();
73
+ $this->tableInit();
74
  }
75
  }
76
 
77
+ $this->isReady = $ready;
78
  }
79
 
80
  private function setupTableSchema() :TableSchema {
81
+ if ( !$this->schema instanceof TableSchema ) {
82
+
83
+ $this->schema = ( new TableSchema() )->applyFromArray( array_merge(
84
+ [
85
+ 'slug' => '',
86
+ 'table_prefix' => '',
87
+ 'primary_key' => 'id',
88
+ 'cols_custom' => [],
89
+ 'cols_timestamps' => [],
90
+ 'has_updated_at' => true,
91
+ 'has_created_at' => true,
92
+ 'has_deleted_at' => true,
93
+ 'col_older_than' => 'created_at',
94
+ 'autoexpire' => 0,
95
+ 'has_ip_col' => false,
96
+ ],
97
+ $this->tableDefinition
98
+ ) );
99
+
100
+ // why this??
101
+ $this->schema->table = $this->getTable();
102
+ }
103
 
104
  return $this->schema;
105
  }
182
  ->record();
183
  }
184
 
185
+ public function isReady() :bool {
186
+ return (bool)$this->isReady;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  }
188
 
189
  public function tableDelete( bool $truncate = false ) :bool {
191
  $DB = Services::WpDb();
192
  $mResult = !$this->tableExists() ||
193
  ( $truncate ? $DB->doTruncateTable( $table ) : $DB->doDropTable( $table ) );
194
+ $DB->clearResultShowTables();
195
  $this->reset();
196
+ return $mResult;
197
  }
198
 
199
  public function tableExists() :bool {
200
+ return Services::WpDb()->tableExists( $this->getTable() );
201
  }
202
 
203
+ public static function GetTableReadyCache() :TableReadyCache {
204
+ if ( !isset( self::$ReadyCache ) ) {
205
+ self::$ReadyCache = new TableReadyCache();
 
 
206
  }
207
+ return self::$ReadyCache;
208
  }
209
 
210
+ /**
211
+ * @deprecated 1.1
212
+ */
213
+ protected function getReadyCache() :TableReadyCache {
214
+ if ( !isset( self::$ReadyCache ) ) {
215
+ self::$ReadyCache = new TableReadyCache();
216
  }
217
+ return self::$ReadyCache;
218
+ }
219
 
220
+ public function getTableSchema() :TableSchema {
221
+ if ( !isset( $this->schema ) ) {
222
+ $this->setupTableSchema();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  }
224
+ return $this->schema;
225
+ }
226
 
227
+ /**
228
+ * @return $this
229
+ */
230
+ private function reset() {
231
+ unset( $this->isReady );
232
+ return $this;
233
  }
234
 
235
+ public function getBaseNamespaces() :array {
236
+ return [ __NAMESPACE__ ];
 
 
 
237
  }
238
 
239
  /**
240
+ * @deprecated 1.1
241
  */
242
  protected function getTransientReadyKey() :string {
243
  return 'apto-db-ready-'.substr( md5( serialize( $this->getTableSchema() ) ), 0, 10 );
244
  }
245
 
246
+ /**
247
+ * @return $this
248
+ * @deprecated 1.1
249
+ */
250
+ public function bypassReadyCheckCache() {
251
+ return $this;
252
+ }
253
+
254
+ /**
255
+ * @return Record|mixed
256
+ * @deprecated 1.1
257
+ */
258
+ public function getVo() {
259
+ return $this->getRecord();
260
  }
261
 
262
  /**
263
  * @return $this
264
+ * @deprecated 1.1
265
  */
266
+ public function setAllowAutoDelete() {
 
267
  return $this;
268
  }
269
 
270
  /**
271
  * @return $this
272
+ * @throws \Exception
273
+ * @deprecated 1.1
274
  */
275
+ protected function tableCreate() {
276
+ $DB = Services::WpDb();
277
+ $sch = $this->getTableSchema();
278
+ if ( !$DB->tableExists( $sch->table ) ) {
279
+ $DB->doSql( $sch->buildCreate() );
280
+ $DB->clearResultShowTables();
281
+ }
282
  return $this;
283
  }
284
 
285
+ /**
286
+ * @deprecated 1.1
287
+ */
288
+ public function tableTrimExcess( int $rowsLimit ) {
289
+ try {
290
+ $this->getQueryDeleter()->deleteExcess( $rowsLimit );
291
+ }
292
+ catch ( \Exception $e ) {
293
+ }
294
+ return $this;
295
  }
296
  }
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/AlignTableWithSchema.php CHANGED
@@ -23,14 +23,14 @@ class AlignTableWithSchema {
23
  public function isAligned() :bool {
24
  $colsActual = $this->getColumnsActual();
25
  $colsSchema = $this->schema->getColumnNames();
26
- asort( $colsActual );
27
- asort( $colsSchema );
28
- return array_values( $colsActual ) === array_values( $colsSchema );
29
  }
30
 
31
  public function align() {
32
  $DB = Services::WpDb();
33
- if ( !$DB->getIfTableExists( $this->schema->table ) ) {
34
  $DB->doSql( $this->schema->buildCreate() );
35
  $DB->clearResultShowTables();
36
  }
23
  public function isAligned() :bool {
24
  $colsActual = $this->getColumnsActual();
25
  $colsSchema = $this->schema->getColumnNames();
26
+ ksort( $colsActual );
27
+ ksort( $colsSchema );
28
+ return serialize( $colsActual ) === serialize( $colsSchema );
29
  }
30
 
31
  public function align() {
32
  $DB = Services::WpDb();
33
+ if ( !$DB->tableExists( $this->schema->table ) ) {
34
  $DB->doSql( $this->schema->buildCreate() );
35
  $DB->clearResultShowTables();
36
  }
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/TableReadyCache.php CHANGED
@@ -18,13 +18,18 @@ class TableReadyCache {
18
  }
19
 
20
  public function save() {
21
- $status = $this->getStatus();
22
- if ( $this->save && !empty( $status ) ) {
23
  ksort( $status );
24
  Services::WpGeneral()->updateOption( self::DB_STATUS_KEY, $status );
25
  }
26
  }
27
 
 
 
 
 
 
28
  public function isReady( TableSchema $schema ) :bool {
29
  $lifetime = (int)max( 1,
30
  apply_filters( 'apto/db/table_ready_cache_lifetime', self::READY_LIFETIME, $schema )
@@ -33,9 +38,14 @@ class TableReadyCache {
33
  < ( $this->getStatus()[ $this->uniqTableID( $schema ) ] ?? 0 );
34
  }
35
 
36
- public function setReady( TableSchema $schema ) {
37
  $status = $this->getStatus();
38
- $status[ $this->uniqTableID( $schema ) ] = time();
 
 
 
 
 
39
  $this->status = $status;
40
  $this->save = true;
41
  }
18
  }
19
 
20
  public function save() {
21
+ if ( $this->save ) {
22
+ $status = $this->getStatus();
23
  ksort( $status );
24
  Services::WpGeneral()->updateOption( self::DB_STATUS_KEY, $status );
25
  }
26
  }
27
 
28
+ public function reset() {
29
+ unset( $this->status );
30
+ $this->save = true;
31
+ }
32
+
33
  public function isReady( TableSchema $schema ) :bool {
34
  $lifetime = (int)max( 1,
35
  apply_filters( 'apto/db/table_ready_cache_lifetime', self::READY_LIFETIME, $schema )
38
  < ( $this->getStatus()[ $this->uniqTableID( $schema ) ] ?? 0 );
39
  }
40
 
41
+ public function setReady( TableSchema $schema, bool $isReady = true ) {
42
  $status = $this->getStatus();
43
+ if ( $isReady ) {
44
+ $status[ $this->uniqTableID( $schema ) ] = time();
45
+ }
46
+ else {
47
+ unset( $status[ $this->uniqTableID( $schema ) ] );
48
+ }
49
  $this->status = $status;
50
  $this->save = true;
51
  }
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Request.php CHANGED
@@ -5,6 +5,7 @@ namespace FernleafSystems\Wordpress\Services\Core;
5
  use Carbon\Carbon;
6
  use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
7
  use FernleafSystems\Wordpress\Services\Services;
 
8
 
9
  /**
10
  * @property array $post
@@ -21,6 +22,16 @@ class Request extends DynPropertiesClass {
21
  */
22
  private $id;
23
 
 
 
 
 
 
 
 
 
 
 
24
  /**
25
  * @var int
26
  */
@@ -36,6 +47,11 @@ class Request extends DynPropertiesClass {
36
  */
37
  private $content;
38
 
 
 
 
 
 
39
  /**
40
  * Request constructor.
41
  */
@@ -62,7 +78,7 @@ class Request extends DynPropertiesClass {
62
 
63
  public function getID( bool $sub = false, int $length = 10 ) :string {
64
  if ( empty( $this->id ) ) {
65
- $str = Services::IP()->getRequestIp().Services::Request()->ts().wp_rand();
66
  $this->id = (string)hash( 'sha256', $str );
67
  if ( empty( $this->id ) ) {
68
  $this->id = (string)hash( 'md5', $str );
@@ -71,6 +87,17 @@ class Request extends DynPropertiesClass {
71
  return ( $sub && $length > 0 && $length < strlen( $this->id ) ) ? substr( $this->id, 0, $length ) : $this->id;
72
  }
73
 
 
 
 
 
 
 
 
 
 
 
 
74
  public function getContent() :string {
75
  if ( !isset( $this->content ) ) {
76
  $this->content = file_get_contents( 'php://input' );
@@ -84,38 +111,40 @@ class Request extends DynPropertiesClass {
84
  }
85
 
86
  /**
87
- * @param bool $bMsOnly
88
  * @return int
89
  */
90
- public function mts( $bMsOnly = false ) {
91
  $now = $this->ts();
92
  if ( empty( $this->nMts ) ) {
93
- $now = $bMsOnly ? 0 : $now;
94
  }
95
  else {
96
- $now = $bMsOnly ? preg_replace( '#^[0-9]+\.#', '', $this->nMts ) : $this->nMts;
97
  }
98
  return $now;
99
  }
100
 
101
- public function ts() :int {
102
- if ( empty( $this->nTs ) ) {
103
- $this->nTs = time();
104
- $this->nMts = function_exists( 'microtime' ) ? @microtime( true ) : false;
 
 
105
  }
 
106
  return $this->nTs;
107
  }
108
 
109
  /**
110
- * @param bool $bSetTimezone - useful only when you're reporting times or displaying
111
  * @return Carbon
112
  */
113
- public function carbon( $bSetTimezone = false ) {
114
  $WP = Services::WpGeneral();
115
  $carbon = new Carbon();
116
  $carbon->setTimestamp( $this->ts() );
117
  $carbon->setLocale( $WP->getLocaleCountry() );
118
- if ( $bSetTimezone ) {
119
  $TZ = $WP->getOption( 'timezone_string' );
120
  if ( !empty( $TZ ) ) {
121
  $carbon->setTimezone( $TZ );
@@ -267,20 +296,9 @@ class Request extends DynPropertiesClass {
267
  return is_null( $value ) ? $default : $value;
268
  }
269
 
270
- /**
271
- * @param string $sContainer
272
- * @param string $sKey
273
- * @param mixed $mDefault
274
- * @return mixed|null
275
- * @deprecated
276
- */
277
- private function arrayFetch( $sContainer, $sKey, $mDefault = null ) {
278
- $sArray = 'a'.ucfirst( $sContainer );
279
- $aArray = $this->{$sArray};
280
- if ( is_null( $sKey ) || !isset( $aArray[ $sKey ] ) || !is_array( $aArray ) ) {
281
- return $mDefault;
282
- }
283
- return $aArray[ $sKey ];
284
  }
285
 
286
  /**
@@ -292,12 +310,12 @@ class Request extends DynPropertiesClass {
292
  }
293
 
294
  /**
295
- * @param bool $bMicro
296
  * @return int
297
  * @deprecated
298
  */
299
- public function getRequestTime( $bMicro = false ) {
300
- return $this->mts( $bMicro );
301
  }
302
 
303
  /**
5
  use Carbon\Carbon;
6
  use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
7
  use FernleafSystems\Wordpress\Services\Services;
8
+ use FernleafSystems\Wordpress\Services\Utilities\Net\RequestIpDetect;
9
 
10
  /**
11
  * @property array $post
22
  */
23
  private $id;
24
 
25
+ /**
26
+ * @var int
27
+ */
28
+ private $ts;
29
+
30
+ /**
31
+ * @var float
32
+ */
33
+ private $ms;
34
+
35
  /**
36
  * @var int
37
  */
47
  */
48
  private $content;
49
 
50
+ /**
51
+ * @var RequestIpDetect
52
+ */
53
+ private $requestIpDetector;
54
+
55
  /**
56
  * Request constructor.
57
  */
78
 
79
  public function getID( bool $sub = false, int $length = 10 ) :string {
80
  if ( empty( $this->id ) ) {
81
+ $str = $this->ip().$this->ts().wp_rand();
82
  $this->id = (string)hash( 'sha256', $str );
83
  if ( empty( $this->id ) ) {
84
  $this->id = (string)hash( 'md5', $str );
87
  return ( $sub && $length > 0 && $length < strlen( $this->id ) ) ? substr( $this->id, 0, $length ) : $this->id;
88
  }
89
 
90
+ public function getIpDetector() :RequestIpDetect {
91
+ if ( !isset( $this->requestIpDetector ) ) {
92
+ $this->requestIpDetector = new RequestIpDetect();
93
+ }
94
+ return $this->requestIpDetector;
95
+ }
96
+
97
+ public function ip() :string {
98
+ return $this->getIpDetector()->getPublicRequestIP();
99
+ }
100
+
101
  public function getContent() :string {
102
  if ( !isset( $this->content ) ) {
103
  $this->content = file_get_contents( 'php://input' );
111
  }
112
 
113
  /**
 
114
  * @return int
115
  */
116
+ public function mts( bool $msOnly = false ) {
117
  $now = $this->ts();
118
  if ( empty( $this->nMts ) ) {
119
+ $now = $msOnly ? 0 : $now;
120
  }
121
  else {
122
+ $now = $msOnly ? preg_replace( '#^\d+\.#', '', $this->nMts ) : $this->nMts;
123
  }
124
  return $now;
125
  }
126
 
127
+ public function ts( bool $update = false ) :int {
128
+ if ( $update || ( empty( $this->nTs ) && empty( $this->ts ) ) ) {
129
+ $this->ts = time();
130
+ $this->ms = function_exists( 'microtime' ) ? @microtime( true ) : false;
131
+ $this->nTs = $this->ts;
132
+ $this->nMts = $this->ms;
133
  }
134
+ /** @deprecated 2.27 */
135
  return $this->nTs;
136
  }
137
 
138
  /**
139
+ * @param bool $setTimezone - useful only when you're reporting times or displaying
140
  * @return Carbon
141
  */
142
+ public function carbon( $setTimezone = false ) {
143
  $WP = Services::WpGeneral();
144
  $carbon = new Carbon();
145
  $carbon->setTimestamp( $this->ts() );
146
  $carbon->setLocale( $WP->getLocaleCountry() );
147
+ if ( $setTimezone ) {
148
  $TZ = $WP->getOption( 'timezone_string' );
149
  if ( !empty( $TZ ) ) {
150
  $carbon->setTimezone( $TZ );
296
  return is_null( $value ) ? $default : $value;
297
  }
298
 
299
+ public function setIpDetector( RequestIpDetect $detector ) :self {
300
+ $this->requestIpDetector = $detector;
301
+ return $this;
 
 
 
 
 
 
 
 
 
 
 
302
  }
303
 
304
  /**
310
  }
311
 
312
  /**
313
+ * @param bool $micro
314
  * @return int
315
  * @deprecated
316
  */
317
+ public function getRequestTime( $micro = false ) {
318
+ return $this->mts( (bool)$micro );
319
  }
320
 
321
  /**
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Arrays.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities;
4
+
5
+ class Arrays {
6
+
7
+ public static function SetAllValuesTo( array $arrayToSet, $value ) :array {
8
+ return array_fill_keys( array_keys( $arrayToSet ), $value );
9
+ }
10
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Data.php CHANGED
@@ -249,13 +249,13 @@ class Data {
249
  }
250
 
251
  /**
252
- * @param array $aArray
253
- * @param string $sKey The array key to fetch
254
  * @param mixed $mDefault
255
  * @return mixed|null
256
  */
257
- public static function ArrayFetch( $aArray, $sKey, $mDefault = null ) {
258
- return isset( $aArray[ $sKey ] ) ? $aArray[ $sKey ] : $mDefault;
259
  }
260
 
261
  /**
249
  }
250
 
251
  /**
252
+ * @param array $theArray
253
+ * @param string $key The array key to fetch
254
  * @param mixed $mDefault
255
  * @return mixed|null
256
  */
257
+ public static function ArrayFetch( $theArray, $key, $mDefault = null ) {
258
+ return $theArray[ $key ] ?? $mDefault;
259
  }
260
 
261
  /**
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/File/Search/SearchFile.php ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\File\Search;
4
+
5
+ use FernleafSystems\Wordpress\Services\Utilities\Arrays;
6
+
7
+ class SearchFile {
8
+
9
+ /**
10
+ * @var string
11
+ */
12
+ private $file;
13
+
14
+ /**
15
+ * @var bool
16
+ */
17
+ public $caseSensitive = true;
18
+
19
+ /**
20
+ * @throws \Exception
21
+ */
22
+ public function __construct( string $file, bool $caseSensitive = true ) {
23
+ if ( !file_exists( $file ) ) {
24
+ throw new \Exception( "File doesn't exist." );
25
+ }
26
+ if ( !is_readable( $file ) ) {
27
+ throw new \Exception( "File not readable." );
28
+ }
29
+ $openedFile = fopen( $file, 'r' );
30
+ if ( !is_resource( $openedFile ) ) {
31
+ throw new \Exception( "File can't be opened for reading." );
32
+ }
33
+ fclose( $openedFile );
34
+
35
+ $this->file = $file;
36
+ $this->caseSensitive = $caseSensitive;
37
+ }
38
+
39
+ public function exists( string $needle ) :bool {
40
+ return $this->findFirst( $needle ) >= 0;
41
+ }
42
+
43
+ public function findFirst( string $needle ) :int {
44
+ $finds = $this->findAll( $needle, 1 );
45
+ return empty( $finds ) ? -1 : array_pop( $finds );
46
+ }
47
+
48
+ public function findAll( string $needle, int $limit = 0 ) :array {
49
+ return $this->multipleFindAll( [ $needle ], $limit )[ $needle ];
50
+ }
51
+
52
+ public function multipleExists( array $needles ) :array {
53
+ return array_map(
54
+ function ( array $finds ) {
55
+ return count( $finds ) > 0;
56
+ },
57
+ $this->multipleFindFirst( $needles )
58
+ );
59
+ }
60
+
61
+ public function multipleFindFirst( array $needles ) :array {
62
+ return $this->multipleFindAll( $needles, 1 );
63
+ }
64
+
65
+ public function multipleFindAll( array $needles, int $limit = 0 ) :array {
66
+ $openedFile = fopen( $this->file, 'r' );
67
+
68
+ $needles = array_map( 'strval', $needles );
69
+
70
+ $theLines = Arrays::SetAllValuesTo( array_flip( $needles ), [] );
71
+ $num = -1;
72
+ while ( !feof( $openedFile ) ) {
73
+ $num++;
74
+
75
+ $line = fgets( $openedFile );
76
+ if ( is_string( $line ) ) {
77
+
78
+ foreach ( $needles as $needleKey => $needle ) {
79
+
80
+ if ( $this->caseSensitive ? ( strpos( $line, $needle ) !== false ) : ( stripos( $line, $needle ) !== false ) ) {
81
+ $theLines[ $needle ][] = $num;
82
+ if ( !empty( $limit ) && count( $theLines[ $needle ] ) === $limit ) {
83
+ unset( $needles[ $needleKey ] );
84
+ }
85
+ }
86
+ }
87
+
88
+ if ( empty( $needles ) ) {
89
+ break;
90
+ }
91
+ }
92
+ }
93
+ fclose( $openedFile );
94
+
95
+ return $theLines;
96
+ }
97
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/IpUtils.php CHANGED
@@ -204,18 +204,26 @@ class IpUtils {
204
  }
205
 
206
  /**
 
207
  * @param bool $asHuman
208
  * @return int|string|bool - visitor IP Address as IP2Long
 
209
  */
210
  public function getRequestIp( $asHuman = true ) {
211
- $sIP = empty( $this->sIp ) ? $this->getIpDetector()->getIP() : $this->sIp;
 
 
 
 
 
 
212
 
213
  // If it's IPv6 we never return as long (we can't!)
214
- if ( !empty( $sIP ) || $asHuman || $this->getIpVersion( $sIP ) == 6 ) {
215
- return $sIP;
216
  }
217
 
218
- return ip2long( $sIP );
219
  }
220
 
221
  /**
@@ -369,14 +377,4 @@ class IpUtils {
369
  $this->oIpDetector = $detector;
370
  return $this;
371
  }
372
-
373
- /**
374
- * Override the Detector with this IP.
375
- * @param string $ip
376
- * @return $this
377
- */
378
- public function setRequestIpAddress( $ip ) {
379
- $this->sIp = $ip;
380
- return $this;
381
- }
382
  }
204
  }
205
 
206
  /**
207
+ * TODO: Switch this to use the Request::ip()
208
  * @param bool $asHuman
209
  * @return int|string|bool - visitor IP Address as IP2Long
210
+ * @deprecated 2.27
211
  */
212
  public function getRequestIp( $asHuman = true ) {
213
+ $req = Services::Request();
214
+ if ( method_exists( $req, 'ip' ) ) {
215
+ $ip = $req->ip();
216
+ }
217
+ else {
218
+ $ip = empty( $this->sIp ) ? $this->getIpDetector()->getIP() : $this->sIp;
219
+ }
220
 
221
  // If it's IPv6 we never return as long (we can't!)
222
+ if ( !empty( $ip ) || $asHuman || $this->getIpVersion( $ip ) == 6 ) {
223
+ return $ip;
224
  }
225
 
226
+ return ip2long( $ip );
227
  }
228
 
229
  /**
377
  $this->oIpDetector = $detector;
378
  return $this;
379
  }
 
 
 
 
 
 
 
 
 
 
380
  }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Net/BaseIP.php CHANGED
@@ -24,6 +24,25 @@ class BaseIP {
24
  /**
25
  * @return string[]
26
  */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  public function getIpSourceOptions() :array {
28
  return [
29
  'REMOTE_ADDR',
24
  /**
25
  * @return string[]
26
  */
27
+ public function getSources() :array {
28
+ return [
29
+ 'REMOTE_ADDR',
30
+ 'HTTP_CF_CONNECTING_IP',
31
+ 'HTTP_X_FORWARDED_FOR',
32
+ 'HTTP_X_FORWARDED',
33
+ 'HTTP_X_REAL_IP',
34
+ 'HTTP_X_SUCURI_CLIENTIP',
35
+ 'HTTP_INCAP_CLIENT_IP',
36
+ 'HTTP_X_SP_FORWARDED_IP',
37
+ 'HTTP_FORWARDED',
38
+ 'HTTP_CLIENT_IP'
39
+ ];
40
+ }
41
+
42
+ /**
43
+ * @return string[]
44
+ * @deprecated
45
+ */
46
  public function getIpSourceOptions() :array {
47
  return [
48
  'REMOTE_ADDR',
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Net/FindSourceFromIp.php CHANGED
@@ -12,7 +12,7 @@ class FindSourceFromIp extends BaseIP {
12
  */
13
  public function run( string $ip ) {
14
  $theSource = null;
15
- foreach ( $this->getIpSourceOptions() as $source ) {
16
  try {
17
  if ( Services::IP()->checkIp( $ip, $this->getIpsFromSource( $source ) ) ) {
18
  $theSource = $source;
12
  */
13
  public function run( string $ip ) {
14
  $theSource = null;
15
+ foreach ( $this->getSources() as $source ) {
16
  try {
17
  if ( Services::IP()->checkIp( $ip, $this->getIpsFromSource( $source ) ) ) {
18
  $theSource = $source;
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Net/IpID.php CHANGED
@@ -8,6 +8,7 @@ use FernleafSystems\Wordpress\Services\Utilities\Options\Transient;
8
  class IpID {
9
 
10
  const UNKNOWN = 'unknown';
 
11
  const VISITOR = 'visitor';
12
  const THIS_SERVER = 'server';
13
 
@@ -46,42 +47,48 @@ class IpID {
46
  $theSlug = null;
47
  $theName = null;
48
 
49
- $bots = Services::ServiceProviders()->getProviders();
50
- if ( empty( $bots[ 'services' ] ) || empty( $bots[ 'crawlers' ] ) ) {
51
- throw new \Exception( 'Could not request Provider IPs' );
52
  }
53
-
54
- foreach ( $bots[ 'services' ] as $slug => $service ) {
55
- // For "services" we don't need to verify the agent as the IPs are fixed.
56
- if ( self::IsIpInServiceCollection( $this->ip, $slug ) ) {
57
- $theSlug = $slug;
58
- $theName = $service[ 'name' ];
59
- break;
60
  }
61
- }
62
 
63
- if ( empty( $theSlug ) ) {
64
- foreach ( $bots[ 'crawlers' ] as $slug => $crawler ) {
65
- if ( $this->checkCrawler( $slug, $crawler ) ) {
66
  $theSlug = $slug;
67
- $theName = $crawler[ 'name' ];
68
  break;
69
  }
70
  }
71
- }
72
 
73
- if ( empty( $theSlug ) ) {
74
- if ( $srvIP->checkIp( $this->ip, $srvIP->getServerPublicIPs() ) ) {
75
- $theSlug = self::THIS_SERVER;
76
- $theName = 'This Server';
77
- }
78
- elseif ( $srvIP->checkIp( $this->ip, $srvIP->getRequestIp() ) ) {
79
- $theSlug = self::VISITOR;
80
- $theName = 'You';
81
  }
82
- else {
83
- $theSlug = self::UNKNOWN;
84
- $theName = 'Unknown';
 
 
 
 
 
 
 
 
 
 
 
85
  }
86
  }
87
 
8
  class IpID {
9
 
10
  const UNKNOWN = 'unknown';
11
+ const LOOPBACK = 'loopback';
12
  const VISITOR = 'visitor';
13
  const THIS_SERVER = 'server';
14
 
47
  $theSlug = null;
48
  $theName = null;
49
 
50
+ if ( $srvIP->isTrueLoopback($this->ip) ) {
51
+ $theSlug = self::LOOPBACK;
52
+ $theName = 'Loopback';
53
  }
54
+ else {
55
+ $bots = Services::ServiceProviders()->getProviders();
56
+ if ( empty( $bots[ 'services' ] ) || empty( $bots[ 'crawlers' ] ) ) {
57
+ throw new \Exception( 'Could not request Provider IPs' );
 
 
 
58
  }
 
59
 
60
+ foreach ( $bots[ 'services' ] as $slug => $service ) {
61
+ // For "services" we don't need to verify the agent as the IPs are fixed.
62
+ if ( self::IsIpInServiceCollection( $this->ip, $slug ) ) {
63
  $theSlug = $slug;
64
+ $theName = $service[ 'name' ];
65
  break;
66
  }
67
  }
 
68
 
69
+ if ( empty( $theSlug ) ) {
70
+ foreach ( $bots[ 'crawlers' ] as $slug => $crawler ) {
71
+ if ( $this->checkCrawler( $slug, $crawler ) ) {
72
+ $theSlug = $slug;
73
+ $theName = $crawler[ 'name' ];
74
+ break;
75
+ }
76
+ }
77
  }
78
+
79
+ if ( empty( $theSlug ) ) {
80
+ if ( $srvIP->checkIp( $this->ip, $srvIP->getServerPublicIPs() ) ) {
81
+ $theSlug = self::THIS_SERVER;
82
+ $theName = 'This Server';
83
+ }
84
+ elseif ( $srvIP->checkIp( $this->ip, $srvIP->getRequestIp() ) ) {
85
+ $theSlug = self::VISITOR;
86
+ $theName = 'You';
87
+ }
88
+ else {
89
+ $theSlug = self::UNKNOWN;
90
+ $theName = 'Unknown';
91
+ }
92
  }
93
  }
94
 
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Net/RequestIpDetect.php ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\Net;
4
+
5
+ use FernleafSystems\Wordpress\Services\Services;
6
+ use FernleafSystems\Wordpress\Services\Utilities\ServiceProviders;
7
+
8
+ class RequestIpDetect extends BaseIP {
9
+
10
+ const DEFAULT_SOURCE = 'REMOTE_ADDR';
11
+
12
+ /**
13
+ * @var string
14
+ */
15
+ private $preferredSource = '';
16
+
17
+ /**
18
+ * @var array
19
+ */
20
+ private $visitorIP;
21
+
22
+ public function getPublicRequestIP() :string {
23
+ return $this->getPublicRequestIPData()[ 'ip' ];
24
+ }
25
+
26
+ public function getPublicRequestID() :string {
27
+ return $this->getPublicRequestIPData()[ 'ip_id' ];
28
+ }
29
+
30
+ public function getPublicRequestSource() :string {
31
+ return $this->getPublicRequestIPData()[ 'source' ];
32
+ }
33
+
34
+ public function getPublicRequestIPData() :array {
35
+ if ( !isset( $this->visitorIP ) ) {
36
+
37
+ $this->visitorIP = [
38
+ 'source' => '',
39
+ 'ip' => '',
40
+ 'ip_id' => IpID::UNKNOWN,
41
+ 'all_ips' => [],
42
+ ];
43
+
44
+ // Find on the preferred source:
45
+ $result = $this->runDetection( true );
46
+ if ( empty( $result ) ) {
47
+ // Find on the preferred source but allow the host IP:
48
+ $result = $this->runDetection( true, false );
49
+ }
50
+ if ( empty( $result ) ) {
51
+ // Find on any source but don't allow the host IP:
52
+ $result = $this->runDetection( false, true );
53
+ }
54
+ if ( empty( $result ) ) {
55
+ // Find on any source but allow the host IP:
56
+ $result = $this->runDetection( false, false );
57
+ }
58
+ if ( empty( $result ) ) {
59
+ // Find any IP whatsoever on the preferred:
60
+ $result = $this->runDetection( true, true, false );
61
+ }
62
+ if ( empty( $result ) ) {
63
+ // Find any IP whatsoever:
64
+ $result = $this->runDetection( false, true, false );
65
+ }
66
+
67
+ if ( !empty( $result ) ) {
68
+ // Take the first result (ideally the preferred source)
69
+ $this->visitorIP[ 'source' ] = key( $result );
70
+ $this->visitorIP[ 'ip' ] = current( current( $result ) );
71
+ $this->visitorIP[ 'all_ips' ] = $result;
72
+
73
+ try {
74
+ $ipIDer = new IpID( $this->visitorIP[ 'ip' ], Services::Request()->getUserAgent() );
75
+ $identity = $ipIDer->run()[ 0 ];
76
+ }
77
+ catch ( \Exception $e ) {
78
+ $identity = IpID::UNKNOWN;
79
+ }
80
+ $this->visitorIP[ 'ip_id' ] = $identity === IpID::VISITOR ? IpID::UNKNOWN : $identity;
81
+ }
82
+ }
83
+ return $this->visitorIP;
84
+ }
85
+
86
+ public function runDetection( bool $usePreferred = true, bool $excludeHost = true, bool $publicOnly = true, bool $excludeCloudflare = true ) :array {
87
+ $srvIP = Services::IP();
88
+
89
+ $potentialIPs = [];
90
+
91
+ $preferred = $this->getPreferredSource();
92
+
93
+ foreach ( $this->buildIPSources() as $source => $IPs ) {
94
+
95
+ if ( $usePreferred && !empty( $preferred ) && $source !== $preferred ) {
96
+ continue;
97
+ }
98
+
99
+ if ( !empty( $IPs ) ) {
100
+ $thisSource = [];
101
+ foreach ( $IPs as $IP ) {
102
+
103
+ if ( $publicOnly && !$srvIP->isValidIp_PublicRemote( $IP ) ) {
104
+ continue;
105
+ }
106
+ if ( $excludeHost && $srvIP->checkIp( $IP, $srvIP->getServerPublicIPs() ) ) {
107
+ continue;
108
+ }
109
+ if ( $excludeCloudflare && IpID::IsIpInServiceCollection( $IP, ServiceProviders::PROVIDER_CLOUDFLARE ) ) {
110
+ continue;
111
+ }
112
+
113
+ $thisSource[] = $IP;
114
+ }
115
+
116
+ if ( !empty( $thisSource ) ) {
117
+ $potentialIPs[ $source ] = $thisSource;
118
+ }
119
+ }
120
+ }
121
+
122
+ return $potentialIPs;
123
+ }
124
+
125
+ /**
126
+ * Get all the IPs for each available source.
127
+ * @return array[]
128
+ */
129
+ public function buildIPSources() :array {
130
+ $ipSources = [];
131
+ foreach ( $this->getSources() as $source ) {
132
+ $ipSources[ $source ] = $this->getIpsFromSource( $source );
133
+ }
134
+ return $ipSources;
135
+ }
136
+
137
+ public function getPreferredSource() :string {
138
+ return (string)$this->preferredSource;
139
+ }
140
+
141
+ public function setPreferredSource( string $preferredSource ) :self {
142
+ $this->preferredSource = $preferredSource;
143
+ return $this;
144
+ }
145
+ }
src/wizards/plugin.php CHANGED
@@ -771,32 +771,8 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
771
  ->setMessageText( $msg );
772
  }
773
 
774
- /**
775
- * @return array
776
- */
777
- private function getGdprSearchItems() {
778
- $aItems = Services::WpGeneral()->getTransient( $this->getCon()->prefix( 'gdpr-items' ) );
779
- if ( !is_array( $aItems ) ) {
780
- $aItems = [];
781
- }
782
- return $aItems;
783
- }
784
-
785
- /**
786
- * @param array $aItems
787
- * @return array
788
- */
789
- private function setGdprSearchItems( $aItems ) {
790
- if ( !is_array( $aItems ) ) {
791
- $aItems = [];
792
- }
793
- $aItems = array_filter( array_unique( $aItems ) );
794
- Services::WpGeneral()
795
- ->setTransient(
796
- $this->getCon()->prefix( 'gdpr-items' ),
797
- $aItems,
798
- MINUTE_IN_SECONDS*10
799
- );
800
- return $aItems;
801
  }
802
  }
771
  ->setMessageText( $msg );
772
  }
773
 
774
+ private function getGdprSearchItems() :array {
775
+ $items = Services::WpGeneral()->getTransient( $this->getCon()->prefix( 'gdpr-items' ) );
776
+ return is_array( $items ) ? $items : [];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
777
  }
778
  }
templates/twig/notices/base.twig CHANGED
@@ -24,8 +24,8 @@
24
  {% endfor %}
25
  {% endif %}
26
  {% if strings.read_more|default('') is not empty %}
27
- <p><a href="{{ hrefs.read_more }}" target="_blank">{{ strings.read_more }}</a></p>
28
- {% endif %}
29
  {% endblock %}
30
  </div>
31
  </div>
24
  {% endfor %}
25
  {% endif %}
26
  {% if strings.read_more|default('') is not empty %}
27
+ <p><a href="{{ hrefs.read_more }}" target="_blank">{{ strings.read_more }}</a></p>
28
+ {% endif %}
29
  {% endblock %}
30
  </div>
31
  </div>
templates/twig/notices/databases-not-ready.twig ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {% extends "/notices/base-error.twig" %}
2
+
3
+ {% block notice_body %}
4
+ {% for line in strings.lines %}
5
+ <p>{{ line }}</p>
6
+ {% endfor %}
7
+ <p>
8
+ <a href="#" class="shield_admin_notice_action" data-notice_action="auto_db_repair">
9
+ {{ strings.click_repair }}</a>
10
+ </p>
11
+ {% endblock %}
templates/twig/notices/override-forceoff.twig CHANGED
@@ -2,23 +2,7 @@
2
 
3
  {% block notice_body %}
4
  <p>{{ strings.message }}</p>
5
- <p><a href="#" id="ForceOffDelete">{{ strings.delete }}</a></p>
6
-
7
- <script type="text/javascript">
8
- jQuery( document ).on(
9
- 'click',
10
- 'a#ForceOffDelete',
11
- delete_force_off
12
- );
13
-
14
- function delete_force_off() {
15
- iCWP_WPSF_BodyOverlay.show();
16
- jQuery.get( ajaxurl, {{ ajax.delete_forceoff|raw }} )
17
- .always(
18
- function () {
19
- location.reload();
20
- }
21
- );
22
- }
23
- </script>
24
  {% endblock %}
2
 
3
  {% block notice_body %}
4
  <p>{{ strings.message }}</p>
5
+ <p>
6
+ <a href="#" class="shield_admin_notice_action" data-notice_action="delete_forceoff">{{ strings.delete }}</a>
7
+ </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  {% endblock %}
templates/twig/pages/block/block_page_ip.twig CHANGED
@@ -25,12 +25,14 @@
25
  </div>
26
  </div>
27
 
28
- <div class="col-md-3 mb-3">
29
- <div class="alert alert-secondary">
30
- If you're the website administrator,
31
- <a href="{{ hrefs.how_to_unblock }}" target="_blank">please review this guide</a>.
32
- </div>
33
- </div>
 
 
34
  </div>
35
 
36
  {% endblock %}
25
  </div>
26
  </div>
27
 
28
+ {% if not flags.is_whitelabelled %}
29
+ <div class="col-md-3 mb-3">
30
+ <div class="alert alert-secondary">
31
+ If you're the website administrator,
32
+ <a href="{{ hrefs.how_to_unblock }}" target="_blank">please review this guide</a>.
33
+ </div>
34
+ </div>
35
+ {% endif %}
36
  </div>
37
 
38
  {% endblock %}
templates/twig/pages/block/block_page_standard.twig CHANGED
@@ -7,8 +7,7 @@
7
  {% block body_header %}
8
  <div class="overflow-hidden" style="max-height: 30vh;">
9
  <div class="container px-5">
10
- <img src="{{ imgs.banner }}" class="img-fluid rounded-3 mb-4"
11
- alt="Example image" width="400" loading="lazy">
12
  </div>
13
  </div>
14
 
7
  {% block body_header %}
8
  <div class="overflow-hidden" style="max-height: 30vh;">
9
  <div class="container px-5">
10
+ <img src="{{ imgs.banner }}" class="img-fluid rounded-3 mb-4" alt="Logo" width="400" loading="lazy">
 
11
  </div>
12
  </div>
13