Version Description
Download this release
Release Info
Developer | paultgoodchild |
Plugin | Shield Security for WordPress |
Version | 13.0.6 |
Comparing to | |
See all releases |
Code changes from version 13.0.5 to 13.0.6
- cl.json +27 -0
- config/lockdown.json +5 -9
- icwp-wpsf.php +1 -1
- plugin-spec.php +3 -3
- plugin.json +3 -3
- readme.txt +1 -1
- src/lib/src/Databases/IPs/Handler.php +4 -0
- src/lib/src/Databases/IPs/Insert.php +4 -0
- src/lib/src/Databases/IPs/Update.php +13 -0
- src/lib/src/Modules/Base/ModCon.php +18 -17
- src/lib/src/Modules/Base/Options.php +33 -78
- src/lib/src/Modules/Base/Options/BuildForDisplay.php +256 -0
- src/lib/src/Modules/Base/UI.php +8 -144
- src/lib/src/Modules/BaseShield/ModCon.php +7 -15
- src/lib/src/Modules/BaseShield/UI.php +2 -1
- src/lib/src/Modules/HackGuard/Render/ScanResults/SectionThemes.php +28 -0
- src/lib/src/Modules/HackGuard/UI.php +1 -13
- src/lib/src/Modules/IPs/AjaxHandler.php +3 -3
- src/lib/src/Modules/IPs/Lib/Ops/AddIp.php +6 -14
- src/lib/src/Modules/IPs/UI.php +1 -1
- src/lib/src/Modules/IPs/WpCli/Add.php +2 -4
- src/lib/src/Modules/Integrations/UI.php +2 -2
- src/lib/src/Modules/Lockdown/ModCon.php +3 -0
- src/lib/src/Modules/Lockdown/Options.php +7 -16
- src/lib/src/Modules/Lockdown/Strings.php +33 -11
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/MfaProfilesController.php +1 -0
- src/lib/src/Modules/LoginGuard/UI.php +2 -2
- src/lib/src/Modules/Plugin/Lib/Debug/Collate.php +16 -12
- src/lib/src/Modules/Plugin/UI.php +1 -15
- src/lib/src/Modules/SecurityAdmin/UI.php +1 -1
- src/lib/src/Modules/Traffic/UI.php +1 -1
- src/lib/src/Tables/Render/WpListTable/AdminNotes.php +2 -6
- src/lib/src/Tables/Render/WpListTable/IpBase.php +5 -1
- src/lib/src/Tables/Render/WpListTable/IpBlack.php +8 -8
- src/lib/vendor/fernleafsystems/wordpress-services/src/Core/General.php +13 -1
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/ClassicPress.php +0 -4
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Cp/Download.php +2 -3
- templates/twig/components/options_form/option.twig +12 -17
cl.json
CHANGED
@@ -165,6 +165,33 @@
|
|
165 |
"title": "Prevent some fatal errors when integrating with 3rd parties and their data isn't as expected.",
|
166 |
"description": [],
|
167 |
"patch": "13.0.5"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
}
|
169 |
]
|
170 |
},
|
165 |
"title": "Prevent some fatal errors when integrating with 3rd parties and their data isn't as expected.",
|
166 |
"description": [],
|
167 |
"patch": "13.0.5"
|
168 |
+
},
|
169 |
+
{
|
170 |
+
"type": "improved",
|
171 |
+
"title": "Improved handling of ClassicPress versions and file scanning for migrated WP sites.",
|
172 |
+
"description": [],
|
173 |
+
"patch": "13.0.6"
|
174 |
+
},
|
175 |
+
{
|
176 |
+
"type": "changed",
|
177 |
+
"title": "Official WP.org themes that are inactive no longer display a warning in results tables.",
|
178 |
+
"description": [],
|
179 |
+
"patch": "13.0.6"
|
180 |
+
},
|
181 |
+
{
|
182 |
+
"type": "fixed",
|
183 |
+
"title": "[Minor Security Vulnerability] An authenticated (administrator+) Persistent XSS.",
|
184 |
+
"description": [
|
185 |
+
"Privately disclosed to us by Yoru Oni - thank you."
|
186 |
+
],
|
187 |
+
"href": "https://shsec.io/kh",
|
188 |
+
"patch": "13.0.6"
|
189 |
+
},
|
190 |
+
{
|
191 |
+
"type": "changed",
|
192 |
+
"title": "It's now possible to add custom exclusions to the anonymous REST API block.",
|
193 |
+
"description": [],
|
194 |
+
"patch": "13.0.6"
|
195 |
}
|
196 |
]
|
197 |
},
|
config/lockdown.json
CHANGED
@@ -103,11 +103,14 @@
|
|
103 |
},
|
104 |
{
|
105 |
"key": "api_namespace_exclusions",
|
106 |
-
"section": "
|
107 |
"default": [
|
108 |
"contact-form-7",
|
109 |
"jetpack",
|
110 |
-
"
|
|
|
|
|
|
|
111 |
],
|
112 |
"type": "array",
|
113 |
"link_info": "",
|
@@ -175,13 +178,6 @@
|
|
175 |
}
|
176 |
],
|
177 |
"definitions": {
|
178 |
-
"default_restapi_exclusions": [
|
179 |
-
"contact-form-7",
|
180 |
-
"jetpack",
|
181 |
-
"tho",
|
182 |
-
"wpstatistics",
|
183 |
-
"woocommerce"
|
184 |
-
],
|
185 |
"events": {
|
186 |
"block_anonymous_restapi": {
|
187 |
"audit_params": [
|
103 |
},
|
104 |
{
|
105 |
"key": "api_namespace_exclusions",
|
106 |
+
"section": "section_apixml",
|
107 |
"default": [
|
108 |
"contact-form-7",
|
109 |
"jetpack",
|
110 |
+
"tho",
|
111 |
+
"woocommerce",
|
112 |
+
"tribe",
|
113 |
+
"wpstatistics"
|
114 |
],
|
115 |
"type": "array",
|
116 |
"link_info": "",
|
178 |
}
|
179 |
],
|
180 |
"definitions": {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
181 |
"events": {
|
182 |
"block_anonymous_restapi": {
|
183 |
"audit_params": [
|
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: 13.0.
|
7 |
* Text Domain: wp-simple-firewall
|
8 |
* Domain Path: /languages
|
9 |
* Author: Shield Security
|
3 |
* Plugin Name: Shield Security
|
4 |
* Plugin URI: https://shsec.io/2f
|
5 |
* Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
|
6 |
+
* Version: 13.0.6
|
7 |
* Text Domain: wp-simple-firewall
|
8 |
* Domain Path: /languages
|
9 |
* Author: Shield Security
|
plugin-spec.php
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
{
|
2 |
"properties": {
|
3 |
-
"version": "13.0.
|
4 |
-
"release_timestamp":
|
5 |
-
"build": "202201.
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield Security",
|
1 |
{
|
2 |
"properties": {
|
3 |
+
"version": "13.0.6",
|
4 |
+
"release_timestamp": 1642088418,
|
5 |
+
"build": "202201.1301",
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield Security",
|
plugin.json
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
{
|
2 |
"properties": {
|
3 |
-
"version": "13.0.
|
4 |
-
"release_timestamp":
|
5 |
-
"build": "202201.
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield Security",
|
1 |
{
|
2 |
"properties": {
|
3 |
+
"version": "13.0.6",
|
4 |
+
"release_timestamp": 1642088418,
|
5 |
+
"build": "202201.1301",
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield Security",
|
readme.txt
CHANGED
@@ -8,7 +8,7 @@ Requires at least: 3.7
|
|
8 |
Requires PHP: 7.0
|
9 |
Recommended PHP: 7.4
|
10 |
Tested up to: 5.9
|
11 |
-
Stable tag: 13.0.
|
12 |
|
13 |
No-Nonsense Security Hardening that protects WordPress against hackers, malicious bots, and spammers (no captchas!). Now with exclusive ShieldNET Technology.
|
14 |
|
8 |
Requires PHP: 7.0
|
9 |
Recommended PHP: 7.4
|
10 |
Tested up to: 5.9
|
11 |
+
Stable tag: 13.0.6
|
12 |
|
13 |
No-Nonsense Security Hardening that protects WordPress against hackers, malicious bots, and spammers (no captchas!). Now with exclusive ShieldNET Technology.
|
14 |
|
src/lib/src/Databases/IPs/Handler.php
CHANGED
@@ -19,6 +19,10 @@ class Handler extends Base\Handler {
|
|
19 |
->query();
|
20 |
}
|
21 |
|
|
|
|
|
|
|
|
|
22 |
/**
|
23 |
* @param int $timestamp
|
24 |
* @return bool
|
19 |
->query();
|
20 |
}
|
21 |
|
22 |
+
public function cleanLabel( string $label ) :string {
|
23 |
+
return trim( empty( $label ) ? '' : preg_replace( '#[^\sa-z0-9_-]#i', '', $label ) );
|
24 |
+
}
|
25 |
+
|
26 |
/**
|
27 |
* @param int $timestamp
|
28 |
* @return bool
|
src/lib/src/Databases/IPs/Insert.php
CHANGED
@@ -26,6 +26,10 @@ class Insert extends Base\Insert {
|
|
26 |
$data[ 'is_range' ] = true;
|
27 |
}
|
28 |
|
|
|
|
|
|
|
|
|
29 |
return $this->setInsertData( $data );
|
30 |
}
|
31 |
}
|
26 |
$data[ 'is_range' ] = true;
|
27 |
}
|
28 |
|
29 |
+
/** @var Handler $dbh */
|
30 |
+
$dbh = $this->getDbH();
|
31 |
+
$data[ 'label' ] = $dbh->cleanLabel( $data[ 'label' ] ?? '' );
|
32 |
+
|
33 |
return $this->setInsertData( $data );
|
34 |
}
|
35 |
}
|
src/lib/src/Databases/IPs/Update.php
CHANGED
@@ -7,6 +7,19 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
7 |
|
8 |
class Update extends Base\Update {
|
9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
/**
|
11 |
* Also updates last access at
|
12 |
* @param int $nIncrement
|
7 |
|
8 |
class Update extends Base\Update {
|
9 |
|
10 |
+
/**
|
11 |
+
* @return array
|
12 |
+
*/
|
13 |
+
public function getUpdateData() {
|
14 |
+
$data = parent::getUpdateData();
|
15 |
+
if ( !empty( $data[ 'label' ] ) ) {
|
16 |
+
/** @var Handler $dbh */
|
17 |
+
$dbh = $this->getDbH();
|
18 |
+
$data[ 'label' ] = $dbh->cleanLabel( $data[ 'label' ] );
|
19 |
+
}
|
20 |
+
return $data;
|
21 |
+
}
|
22 |
+
|
23 |
/**
|
24 |
* Also updates last access at
|
25 |
* @param int $nIncrement
|
src/lib/src/Modules/Base/ModCon.php
CHANGED
@@ -809,20 +809,15 @@ abstract class ModCon {
|
|
809 |
}
|
810 |
|
811 |
/**
|
812 |
-
* @
|
813 |
*/
|
814 |
-
protected function getAllFormOptionsAndTypes() {
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
}
|
822 |
-
}
|
823 |
-
}
|
824 |
-
|
825 |
-
return $opts;
|
826 |
}
|
827 |
|
828 |
protected function handleModAction( string $action ) {
|
@@ -898,9 +893,15 @@ abstract class ModCon {
|
|
898 |
// standard options use b64 and fail-over to lz-string
|
899 |
$form = FormParams::Retrieve( FormParams::ENC_BASE64 );
|
900 |
|
901 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
902 |
|
903 |
-
$optValue = $form[ $
|
904 |
if ( is_null( $optValue ) ) {
|
905 |
|
906 |
if ( in_array( $optType, [ 'text', 'email' ] ) ) { //text box, and it's null, don't update
|
@@ -930,7 +931,7 @@ abstract class ModCon {
|
|
930 |
continue;
|
931 |
}
|
932 |
|
933 |
-
$confirm = $form[ $
|
934 |
if ( $sTempValue !== $confirm ) {
|
935 |
throw new \Exception( __( 'Password values do not match.', 'wp-simple-firewall' ) );
|
936 |
}
|
@@ -948,7 +949,7 @@ abstract class ModCon {
|
|
948 |
|
949 |
// Prevent overwriting of non-editable fields
|
950 |
if ( !in_array( $optType, [ 'noneditable_text' ] ) ) {
|
951 |
-
$this->getOptions()->setOpt( $
|
952 |
}
|
953 |
}
|
954 |
|
809 |
}
|
810 |
|
811 |
/**
|
812 |
+
* @deprecated 13.0.6
|
813 |
*/
|
814 |
+
protected function getAllFormOptionsAndTypes() :array {
|
815 |
+
return array_map(
|
816 |
+
function ( $optDef ) {
|
817 |
+
return $optDef[ 'type' ];
|
818 |
+
},
|
819 |
+
$this->getOptions()->getVisibleOptions()
|
820 |
+
);
|
|
|
|
|
|
|
|
|
|
|
821 |
}
|
822 |
|
823 |
protected function handleModAction( string $action ) {
|
893 |
// standard options use b64 and fail-over to lz-string
|
894 |
$form = FormParams::Retrieve( FormParams::ENC_BASE64 );
|
895 |
|
896 |
+
$optsAndTypes = array_map(
|
897 |
+
function ( $optDef ) {
|
898 |
+
return $optDef[ 'type' ];
|
899 |
+
},
|
900 |
+
$this->getOptions()->getVisibleOptions()
|
901 |
+
);
|
902 |
+
foreach ( $optsAndTypes as $optKey => $optType ) {
|
903 |
|
904 |
+
$optValue = $form[ $optKey ] ?? null;
|
905 |
if ( is_null( $optValue ) ) {
|
906 |
|
907 |
if ( in_array( $optType, [ 'text', 'email' ] ) ) { //text box, and it's null, don't update
|
931 |
continue;
|
932 |
}
|
933 |
|
934 |
+
$confirm = $form[ $optKey.'_confirm' ] ?? null;
|
935 |
if ( $sTempValue !== $confirm ) {
|
936 |
throw new \Exception( __( 'Password values do not match.', 'wp-simple-firewall' ) );
|
937 |
}
|
949 |
|
950 |
// Prevent overwriting of non-editable fields
|
951 |
if ( !in_array( $optType, [ 'noneditable_text' ] ) ) {
|
952 |
+
$this->getOptions()->setOpt( $optKey, $optValue );
|
953 |
}
|
954 |
}
|
955 |
|
src/lib/src/Modules/Base/Options.php
CHANGED
@@ -296,90 +296,45 @@ class Options {
|
|
296 |
}
|
297 |
|
298 |
/**
|
299 |
-
* @return
|
300 |
*/
|
301 |
-
public function
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
|
|
|
|
311 |
}
|
|
|
|
|
312 |
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
|
|
|
|
|
|
317 |
}
|
318 |
|
|
|
|
|
|
|
319 |
public function getOptionsForPluginUse() :array {
|
320 |
-
|
321 |
-
$optionsData = [];
|
322 |
-
|
323 |
-
foreach ( $this->getRawData_OptionsSections() as $section ) {
|
324 |
-
|
325 |
-
if ( isset( $section[ 'hidden' ] ) && $section[ 'hidden' ] ) {
|
326 |
-
continue;
|
327 |
-
}
|
328 |
-
|
329 |
-
$section = array_merge(
|
330 |
-
[
|
331 |
-
'primary' => false,
|
332 |
-
'options' => $this->getOptionsForSection( $section[ 'slug' ] ),
|
333 |
-
'help_video_id' => ''
|
334 |
-
],
|
335 |
-
$section
|
336 |
-
);
|
337 |
-
|
338 |
-
if ( !empty( $section[ 'options' ] ) ) {
|
339 |
-
$optionsData[] = $section;
|
340 |
-
}
|
341 |
-
}
|
342 |
-
|
343 |
-
return $optionsData;
|
344 |
}
|
345 |
|
|
|
|
|
|
|
346 |
protected function getOptionsForSection( string $slug ) :array {
|
347 |
-
|
348 |
-
$allOptions = [];
|
349 |
-
foreach ( $this->getRawData_AllOptions() as $optDef ) {
|
350 |
-
|
351 |
-
if ( ( $optDef[ 'section' ] != $slug ) || ( isset( $optDef[ 'hidden' ] ) && $optDef[ 'hidden' ] ) ) {
|
352 |
-
continue;
|
353 |
-
}
|
354 |
-
|
355 |
-
if ( isset( $optDef[ 'hidden' ] ) && $optDef[ 'hidden' ] ) {
|
356 |
-
continue;
|
357 |
-
}
|
358 |
-
|
359 |
-
$optDef = array_merge(
|
360 |
-
[
|
361 |
-
'link_info' => '',
|
362 |
-
'link_blog' => '',
|
363 |
-
'help_video_id' => '',
|
364 |
-
'value_options' => [],
|
365 |
-
'premium' => false,
|
366 |
-
'advanced' => false
|
367 |
-
],
|
368 |
-
$optDef
|
369 |
-
);
|
370 |
-
$optDef[ 'value' ] = $this->getOpt( $optDef[ 'key' ] );
|
371 |
-
|
372 |
-
if ( in_array( $optDef[ 'type' ], [ 'select', 'multiple_select' ] ) ) {
|
373 |
-
$convertedOptions = [];
|
374 |
-
foreach ( $optDef[ 'value_options' ] as $selectValues ) {
|
375 |
-
$convertedOptions[ $selectValues[ 'value_key' ] ] = __( $selectValues[ 'text' ], 'wp-simple-firewall' );
|
376 |
-
}
|
377 |
-
$optDef[ 'value_options' ] = $convertedOptions;
|
378 |
-
}
|
379 |
-
|
380 |
-
$allOptions[] = $optDef;
|
381 |
-
}
|
382 |
-
return $allOptions;
|
383 |
}
|
384 |
|
385 |
public function getAdditionalMenuItems() :array {
|
@@ -413,7 +368,7 @@ class Options {
|
|
413 |
}
|
414 |
|
415 |
/**
|
416 |
-
* @param mixed
|
417 |
* @return mixed|null
|
418 |
*/
|
419 |
public function getOptDefault( string $key, $mDefault = null ) {
|
@@ -426,8 +381,8 @@ class Options {
|
|
426 |
}
|
427 |
|
428 |
/**
|
429 |
-
* @param mixed
|
430 |
-
* @param bool
|
431 |
*/
|
432 |
public function isOpt( string $key, $mValueToTest, $strict = false ) :bool {
|
433 |
return $strict ? $this->getOpt( $key ) === $mValueToTest : $this->getOpt( $key ) == $mValueToTest;
|
296 |
}
|
297 |
|
298 |
/**
|
299 |
+
* @return array[]
|
300 |
*/
|
301 |
+
public function getVisibleOptions() :array {
|
302 |
+
return array_filter(
|
303 |
+
$this->getRawData_AllOptions(),
|
304 |
+
function ( $optDef ) {
|
305 |
+
if ( $optDef[ 'hidden' ] ?? false ) {
|
306 |
+
return null;
|
307 |
+
}
|
308 |
+
$section = $this->getSection( $optDef[ 'section' ] );
|
309 |
+
if ( empty( $section ) || ( $section[ 'hidden' ] ?? false ) ) {
|
310 |
+
return null;
|
311 |
+
}
|
312 |
+
return $optDef;
|
313 |
}
|
314 |
+
);
|
315 |
+
}
|
316 |
|
317 |
+
/**
|
318 |
+
* @return string[]
|
319 |
+
*/
|
320 |
+
public function getVisibleOptionsKeys() :array {
|
321 |
+
return array_map( function ( $optDef ) {
|
322 |
+
return $optDef[ 'key' ];
|
323 |
+
}, $this->getVisibleOptions() );
|
324 |
}
|
325 |
|
326 |
+
/**
|
327 |
+
* @deprecated 13.0.6
|
328 |
+
*/
|
329 |
public function getOptionsForPluginUse() :array {
|
330 |
+
return [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
331 |
}
|
332 |
|
333 |
+
/**
|
334 |
+
* @deprecated 13.0.6
|
335 |
+
*/
|
336 |
protected function getOptionsForSection( string $slug ) :array {
|
337 |
+
return [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
338 |
}
|
339 |
|
340 |
public function getAdditionalMenuItems() :array {
|
368 |
}
|
369 |
|
370 |
/**
|
371 |
+
* @param mixed $mDefault
|
372 |
* @return mixed|null
|
373 |
*/
|
374 |
public function getOptDefault( string $key, $mDefault = null ) {
|
381 |
}
|
382 |
|
383 |
/**
|
384 |
+
* @param mixed $mValueToTest
|
385 |
+
* @param bool $strict
|
386 |
*/
|
387 |
public function isOpt( string $key, $mValueToTest, $strict = false ) :bool {
|
388 |
return $strict ? $this->getOpt( $key ) === $mValueToTest : $this->getOpt( $key ) == $mValueToTest;
|
src/lib/src/Modules/Base/Options/BuildForDisplay.php
ADDED
@@ -0,0 +1,256 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Options;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
class BuildForDisplay {
|
9 |
+
|
10 |
+
use ModConsumer;
|
11 |
+
|
12 |
+
private $isWhitelabelled = false;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Will initiate the plugin options structure for use by the UI builder.
|
16 |
+
* It doesn't set any values, just populates the array created in buildOptions()
|
17 |
+
* with values stored.
|
18 |
+
* It has to handle the conversion of stored values to data to be displayed to the user.
|
19 |
+
*/
|
20 |
+
public function standard() :array {
|
21 |
+
$con = $this->getCon();
|
22 |
+
$mod = $this->getMod();
|
23 |
+
$UI = $mod->getUIHandler();
|
24 |
+
|
25 |
+
$isPremium = $con->isPremiumExtensionsEnabled();
|
26 |
+
$showAdvanced = $con->getModule_Plugin()->isShowAdvanced();
|
27 |
+
|
28 |
+
$opts = $this->getOptions();
|
29 |
+
$sections = $this->buildAvailableSections();
|
30 |
+
|
31 |
+
foreach ( $sections as $sectionKey => $sect ) {
|
32 |
+
|
33 |
+
if ( !empty( $sect[ 'options' ] ) ) {
|
34 |
+
|
35 |
+
foreach ( $sect[ 'options' ] as $optKey => $option ) {
|
36 |
+
$option[ 'is_value_default' ] = ( $option[ 'value' ] === $option[ 'default' ] );
|
37 |
+
$isOptPremium = $option[ 'premium' ] ?? false;
|
38 |
+
$bIsAdv = $option[ 'advanced' ] ?? false;
|
39 |
+
if ( ( !$isOptPremium || $isPremium ) && ( !$bIsAdv || $showAdvanced ) ) {
|
40 |
+
$sect[ 'options' ][ $optKey ] = $this->buildOptionForUi( $option );
|
41 |
+
}
|
42 |
+
else {
|
43 |
+
unset( $sect[ 'options' ][ $optKey ] );
|
44 |
+
}
|
45 |
+
}
|
46 |
+
|
47 |
+
if ( empty( $sect[ 'options' ] ) ) {
|
48 |
+
unset( $sections[ $sectionKey ] );
|
49 |
+
}
|
50 |
+
else {
|
51 |
+
try {
|
52 |
+
$sect = array_merge(
|
53 |
+
$sect,
|
54 |
+
$this->getMod()
|
55 |
+
->getStrings()
|
56 |
+
->getSectionStrings( $sect[ 'slug' ] )
|
57 |
+
);
|
58 |
+
}
|
59 |
+
catch ( \Exception $e ) {
|
60 |
+
}
|
61 |
+
$sections[ $sectionKey ] = $sect;
|
62 |
+
}
|
63 |
+
|
64 |
+
if ( isset( $sections[ $sectionKey ] ) ) {
|
65 |
+
$warning = [];
|
66 |
+
if ( !$opts->isSectionReqsMet( $sect[ 'slug' ] ) ) {
|
67 |
+
$warning[] = __( 'Unfortunately your WordPress and/or PHP versions are too old to support this feature.', 'wp-simple-firewall' );
|
68 |
+
}
|
69 |
+
$sections[ $sectionKey ][ 'warnings' ] = array_merge(
|
70 |
+
$warning,
|
71 |
+
$UI->getSectionWarnings( $sect[ 'slug' ] )
|
72 |
+
);
|
73 |
+
$sections[ $sectionKey ][ 'notices' ] = $UI->getSectionNotices( $sect[ 'slug' ] );
|
74 |
+
}
|
75 |
+
}
|
76 |
+
}
|
77 |
+
|
78 |
+
return $sections;
|
79 |
+
}
|
80 |
+
|
81 |
+
protected function buildAvailableSections() :array {
|
82 |
+
$opts = $this->getOptions();
|
83 |
+
|
84 |
+
$optionsData = [];
|
85 |
+
|
86 |
+
foreach ( $opts->getSections() as $section ) {
|
87 |
+
|
88 |
+
$section = array_merge(
|
89 |
+
[
|
90 |
+
'primary' => false,
|
91 |
+
'options' => $this->buildOptionsForSection( $section[ 'slug' ] ),
|
92 |
+
'beacon_id' => false,
|
93 |
+
],
|
94 |
+
$section
|
95 |
+
);
|
96 |
+
|
97 |
+
if ( !empty( $section[ 'options' ] ) ) {
|
98 |
+
|
99 |
+
if ( $this->isWhitelabelled ) {
|
100 |
+
$section[ 'beacon_id' ] = false;
|
101 |
+
}
|
102 |
+
|
103 |
+
$optionsData[] = $section;
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
return $optionsData;
|
108 |
+
}
|
109 |
+
|
110 |
+
protected function buildOptionsForSection( string $section ) :array {
|
111 |
+
$opts = $this->getOptions();
|
112 |
+
|
113 |
+
$allOptions = [];
|
114 |
+
foreach ( $opts->getVisibleOptions() as $optDef ) {
|
115 |
+
|
116 |
+
if ( $optDef[ 'section' ] !== $section ) {
|
117 |
+
continue;
|
118 |
+
}
|
119 |
+
|
120 |
+
$optDef = array_merge(
|
121 |
+
[
|
122 |
+
'link_info' => '',
|
123 |
+
'link_blog' => '',
|
124 |
+
'value_options' => [],
|
125 |
+
'premium' => false,
|
126 |
+
'advanced' => false,
|
127 |
+
'beacon_id' => false
|
128 |
+
],
|
129 |
+
$optDef
|
130 |
+
);
|
131 |
+
$optDef[ 'value' ] = $opts->getOpt( $optDef[ 'key' ] );
|
132 |
+
|
133 |
+
if ( in_array( $optDef[ 'type' ], [ 'select', 'multiple_select' ] ) ) {
|
134 |
+
$convertedOptions = [];
|
135 |
+
foreach ( $optDef[ 'value_options' ] as $selectValues ) {
|
136 |
+
$convertedOptions[ $selectValues[ 'value_key' ] ] = __( $selectValues[ 'text' ], 'wp-simple-firewall' );
|
137 |
+
}
|
138 |
+
$optDef[ 'value_options' ] = $convertedOptions;
|
139 |
+
}
|
140 |
+
|
141 |
+
if ( $this->isWhitelabelled ) {
|
142 |
+
$optDef[ 'beacon_id' ] = false;
|
143 |
+
}
|
144 |
+
|
145 |
+
$allOptions[] = $optDef;
|
146 |
+
}
|
147 |
+
return $allOptions;
|
148 |
+
}
|
149 |
+
|
150 |
+
protected function buildOptionForUi( array $option ) :array {
|
151 |
+
|
152 |
+
$value = $option[ 'value' ];
|
153 |
+
|
154 |
+
switch ( $option[ 'type' ] ) {
|
155 |
+
|
156 |
+
case 'password':
|
157 |
+
if ( !empty( $value ) ) {
|
158 |
+
$value = '';
|
159 |
+
}
|
160 |
+
break;
|
161 |
+
|
162 |
+
case 'array':
|
163 |
+
if ( empty( $value ) || !is_array( $value ) ) {
|
164 |
+
$value = [];
|
165 |
+
}
|
166 |
+
|
167 |
+
$option[ 'rows' ] = count( $value ) + 2;
|
168 |
+
$value = stripslashes( implode( "\n", $value ) );
|
169 |
+
|
170 |
+
break;
|
171 |
+
|
172 |
+
case 'comma_separated_lists':
|
173 |
+
|
174 |
+
$converted = [];
|
175 |
+
if ( !empty( $value ) && is_array( $value ) ) {
|
176 |
+
foreach ( $value as $page => $params ) {
|
177 |
+
$converted[] = $page.', '.implode( ", ", $params );
|
178 |
+
}
|
179 |
+
}
|
180 |
+
$option[ 'rows' ] = count( $converted ) + 1;
|
181 |
+
$value = implode( "\n", $converted );
|
182 |
+
|
183 |
+
break;
|
184 |
+
|
185 |
+
case 'multiple_select':
|
186 |
+
if ( !is_array( $value ) ) {
|
187 |
+
$value = [];
|
188 |
+
}
|
189 |
+
break;
|
190 |
+
|
191 |
+
case 'text':
|
192 |
+
$value = stripslashes( $this->getMod()->getTextOpt( $option[ 'key' ] ) );
|
193 |
+
break;
|
194 |
+
}
|
195 |
+
|
196 |
+
$params = [
|
197 |
+
'value' => is_scalar( $value ) ? esc_attr( $value ) : $value,
|
198 |
+
'disabled' => !$this->getCon()
|
199 |
+
->isPremiumActive() && ( isset( $option[ 'premium' ] ) && $option[ 'premium' ] ),
|
200 |
+
];
|
201 |
+
$params[ 'enabled' ] = !$params[ 'disabled' ];
|
202 |
+
$option = array_merge( [ 'rows' => '2' ], $option, $params );
|
203 |
+
|
204 |
+
// add strings
|
205 |
+
try {
|
206 |
+
$optStrings = $this->getMod()->getStrings()->getOptionStrings( $option[ 'key' ] );
|
207 |
+
if ( !is_array( $optStrings[ 'description' ] ) ) {
|
208 |
+
$optStrings[ 'description' ] = [ $optStrings[ 'description' ] ];
|
209 |
+
}
|
210 |
+
$option = Services::DataManipulation()->mergeArraysRecursive( $option, $optStrings );
|
211 |
+
}
|
212 |
+
catch ( \Exception $e ) {
|
213 |
+
}
|
214 |
+
|
215 |
+
return $this->addPerOptionCustomisation( $option );
|
216 |
+
}
|
217 |
+
|
218 |
+
private function addPerOptionCustomisation( array $option ) :array {
|
219 |
+
switch ( $option[ 'key' ] ) {
|
220 |
+
|
221 |
+
case 'file_locker':
|
222 |
+
if ( !Services::Data()->isWindows() ) {
|
223 |
+
error_log( var_export( $option[ 'value_options' ][ 'root_webconfig' ], true ) );
|
224 |
+
$option[ 'value_options' ][ 'root_webconfig' ] .= sprintf( ' (%s)', __( 'unavailable', 'wp-simple-firewall' ) );
|
225 |
+
error_log( var_export( $option, true ) );
|
226 |
+
}
|
227 |
+
break;
|
228 |
+
|
229 |
+
case 'visitor_address_source':
|
230 |
+
$newOptions = [];
|
231 |
+
$ipDetector = Services::IP()->getIpDetector();
|
232 |
+
foreach ( $option[ 'value_options' ] as $valKey => $source ) {
|
233 |
+
if ( $valKey == 'AUTO_DETECT_IP' ) {
|
234 |
+
$newOptions[ $valKey ] = $source;
|
235 |
+
}
|
236 |
+
else {
|
237 |
+
$IPs = implode( ', ', $ipDetector->getIpsFromSource( $source ) );
|
238 |
+
if ( !empty( $IPs ) ) {
|
239 |
+
$newOptions[ $valKey ] = sprintf( '%s (%s)', $source, $IPs );
|
240 |
+
}
|
241 |
+
}
|
242 |
+
}
|
243 |
+
$option[ 'value_options' ] = $newOptions;
|
244 |
+
break;
|
245 |
+
|
246 |
+
default:
|
247 |
+
break;
|
248 |
+
}
|
249 |
+
return $option;
|
250 |
+
}
|
251 |
+
|
252 |
+
public function setIsWhitelabelled( bool $isOrNot ) :self {
|
253 |
+
$this->isWhitelabelled = $isOrNot;
|
254 |
+
return $this;
|
255 |
+
}
|
256 |
+
}
|
src/lib/src/Modules/Base/UI.php
CHANGED
@@ -10,140 +10,11 @@ class UI {
|
|
10 |
|
11 |
use ModConsumer;
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
*/
|
19 |
-
public function buildOptions() {
|
20 |
-
$con = $this->getCon();
|
21 |
-
|
22 |
-
$bPremiumEnabled = $con->isPremiumExtensionsEnabled();
|
23 |
-
$bShowAdvanced = $con->getModule_Plugin()->isShowAdvanced();
|
24 |
-
|
25 |
-
$opts = $this->getOptions();
|
26 |
-
$options = $opts->getOptionsForPluginUse();
|
27 |
-
|
28 |
-
foreach ( $options as $sectionKey => $sect ) {
|
29 |
-
|
30 |
-
if ( !empty( $sect[ 'options' ] ) ) {
|
31 |
-
|
32 |
-
foreach ( $sect[ 'options' ] as $optKey => $option ) {
|
33 |
-
$option[ 'is_value_default' ] = ( $option[ 'value' ] === $option[ 'default' ] );
|
34 |
-
$bIsPrem = $option[ 'premium' ] ?? false;
|
35 |
-
$bIsAdv = $option[ 'advanced' ] ?? false;
|
36 |
-
if ( ( !$bIsPrem || $bPremiumEnabled ) && ( !$bIsAdv || $bShowAdvanced ) ) {
|
37 |
-
$sect[ 'options' ][ $optKey ] = $this->buildOptionForUi( $option );
|
38 |
-
}
|
39 |
-
else {
|
40 |
-
unset( $sect[ 'options' ][ $optKey ] );
|
41 |
-
}
|
42 |
-
}
|
43 |
-
|
44 |
-
if ( empty( $sect[ 'options' ] ) ) {
|
45 |
-
unset( $options[ $sectionKey ] );
|
46 |
-
}
|
47 |
-
else {
|
48 |
-
try {
|
49 |
-
$sect = array_merge(
|
50 |
-
$sect,
|
51 |
-
$this->getMod()
|
52 |
-
->getStrings()
|
53 |
-
->getSectionStrings( $sect[ 'slug' ] )
|
54 |
-
);
|
55 |
-
}
|
56 |
-
catch ( \Exception $e ) {
|
57 |
-
}
|
58 |
-
$options[ $sectionKey ] = $sect;
|
59 |
-
}
|
60 |
-
|
61 |
-
if ( isset( $options[ $sectionKey ] ) ) {
|
62 |
-
$warning = [];
|
63 |
-
if ( !$opts->isSectionReqsMet( $sect[ 'slug' ] ) ) {
|
64 |
-
$warning[] = __( 'Unfortunately your WordPress and/or PHP versions are too old to support this feature.', 'wp-simple-firewall' );
|
65 |
-
}
|
66 |
-
$options[ $sectionKey ][ 'warnings' ] = array_merge(
|
67 |
-
$warning,
|
68 |
-
$this->getSectionWarnings( $sect[ 'slug' ] )
|
69 |
-
);
|
70 |
-
$options[ $sectionKey ][ 'notices' ] = $this->getSectionNotices( $sect[ 'slug' ] );
|
71 |
-
}
|
72 |
-
}
|
73 |
-
}
|
74 |
-
|
75 |
-
return $options;
|
76 |
-
}
|
77 |
-
|
78 |
-
/**
|
79 |
-
* @param array $option
|
80 |
-
* @return array
|
81 |
-
*/
|
82 |
-
protected function buildOptionForUi( $option ) {
|
83 |
-
|
84 |
-
$value = $option[ 'value' ];
|
85 |
-
|
86 |
-
switch ( $option[ 'type' ] ) {
|
87 |
-
|
88 |
-
case 'password':
|
89 |
-
if ( !empty( $value ) ) {
|
90 |
-
$value = '';
|
91 |
-
}
|
92 |
-
break;
|
93 |
-
|
94 |
-
case 'array':
|
95 |
-
if ( empty( $value ) || !is_array( $value ) ) {
|
96 |
-
$value = [];
|
97 |
-
}
|
98 |
-
|
99 |
-
$option[ 'rows' ] = count( $value ) + 2;
|
100 |
-
$value = stripslashes( implode( "\n", $value ) );
|
101 |
-
|
102 |
-
break;
|
103 |
-
|
104 |
-
case 'comma_separated_lists':
|
105 |
-
|
106 |
-
$converted = [];
|
107 |
-
if ( !empty( $value ) && is_array( $value ) ) {
|
108 |
-
foreach ( $value as $page => $params ) {
|
109 |
-
$converted[] = $page.', '.implode( ", ", $params );
|
110 |
-
}
|
111 |
-
}
|
112 |
-
$option[ 'rows' ] = count( $converted ) + 1;
|
113 |
-
$value = implode( "\n", $converted );
|
114 |
-
|
115 |
-
break;
|
116 |
-
|
117 |
-
case 'multiple_select':
|
118 |
-
if ( !is_array( $value ) ) {
|
119 |
-
$value = [];
|
120 |
-
}
|
121 |
-
break;
|
122 |
-
|
123 |
-
case 'text':
|
124 |
-
$value = stripslashes( $this->getMod()->getTextOpt( $option[ 'key' ] ) );
|
125 |
-
break;
|
126 |
-
}
|
127 |
-
|
128 |
-
$params = [
|
129 |
-
'value' => is_scalar( $value ) ? esc_attr( $value ) : $value,
|
130 |
-
'disabled' => !$this->getCon()
|
131 |
-
->isPremiumActive() && ( isset( $option[ 'premium' ] ) && $option[ 'premium' ] ),
|
132 |
-
];
|
133 |
-
$params[ 'enabled' ] = !$params[ 'disabled' ];
|
134 |
-
$option = array_merge( [ 'rows' => 2 ], $option, $params );
|
135 |
-
|
136 |
-
// add strings
|
137 |
-
try {
|
138 |
-
$aOptStrings = $this->getMod()->getStrings()->getOptionStrings( $option[ 'key' ] );
|
139 |
-
if ( !is_array( $aOptStrings[ 'description' ] ) ) {
|
140 |
-
$aOptStrings[ 'description' ] = [ $aOptStrings[ 'description' ] ];
|
141 |
-
}
|
142 |
-
$option = Services::DataManipulation()->mergeArraysRecursive( $option, $aOptStrings );
|
143 |
-
}
|
144 |
-
catch ( \Exception $e ) {
|
145 |
-
}
|
146 |
-
return $option;
|
147 |
}
|
148 |
|
149 |
public function buildSelectData_ModuleSettings() :array {
|
@@ -199,7 +70,7 @@ class UI {
|
|
199 |
'data' => [
|
200 |
'mod_slug' => $mod->getModSlug( true ),
|
201 |
'mod_slug_short' => $mod->getModSlug( false ),
|
202 |
-
'all_options' => $this->
|
203 |
'xferable_opts' => ( new Shield\Modules\Plugin\Lib\ImportExport\Options\BuildTransferableOptions() )
|
204 |
->setMod( $mod )
|
205 |
->build(),
|
@@ -342,18 +213,11 @@ class UI {
|
|
342 |
return false;
|
343 |
}
|
344 |
|
345 |
-
|
346 |
-
* @return string
|
347 |
-
*/
|
348 |
-
protected function getHelpVideoId() {
|
349 |
-
return $this->getOptions()->getDef( 'help_video_id' );
|
350 |
-
}
|
351 |
-
|
352 |
-
protected function getSectionNotices( string $section ) :array {
|
353 |
return [];
|
354 |
}
|
355 |
|
356 |
-
|
357 |
return [];
|
358 |
}
|
359 |
|
10 |
|
11 |
use ModConsumer;
|
12 |
|
13 |
+
public function buildOptionsForStandardUI() :array {
|
14 |
+
return ( new Options\BuildForDisplay() )
|
15 |
+
->setMod( $this->getMod() )
|
16 |
+
->setIsWhitelabelled( $this->getCon()->getModule_SecAdmin()->getWhiteLabelController()->isEnabled() )
|
17 |
+
->standard();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
}
|
19 |
|
20 |
public function buildSelectData_ModuleSettings() :array {
|
70 |
'data' => [
|
71 |
'mod_slug' => $mod->getModSlug( true ),
|
72 |
'mod_slug_short' => $mod->getModSlug( false ),
|
73 |
+
'all_options' => $this->buildOptionsForStandardUI(),
|
74 |
'xferable_opts' => ( new Shield\Modules\Plugin\Lib\ImportExport\Options\BuildTransferableOptions() )
|
75 |
->setMod( $mod )
|
76 |
->build(),
|
213 |
return false;
|
214 |
}
|
215 |
|
216 |
+
public function getSectionNotices( string $section ) :array {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
217 |
return [];
|
218 |
}
|
219 |
|
220 |
+
public function getSectionWarnings( string $section ) :array {
|
221 |
return [];
|
222 |
}
|
223 |
|
src/lib/src/Modules/BaseShield/ModCon.php
CHANGED
@@ -192,24 +192,16 @@ class ModCon extends Base\ModCon {
|
|
192 |
->isXmlrpcBypass();
|
193 |
}
|
194 |
|
195 |
-
|
196 |
-
|
197 |
-
* @param string $sPregReplacePattern
|
198 |
-
* @return string[]
|
199 |
-
*/
|
200 |
-
protected function cleanStringArray( $aArray, $sPregReplacePattern ) {
|
201 |
-
$aCleaned = [];
|
202 |
-
if ( !is_array( $aArray ) ) {
|
203 |
-
return $aCleaned;
|
204 |
-
}
|
205 |
|
206 |
-
foreach ( $
|
207 |
-
$
|
208 |
-
if (
|
209 |
-
$
|
210 |
}
|
211 |
}
|
212 |
-
return
|
213 |
}
|
214 |
|
215 |
protected function getNamespaceRoots() :array {
|
192 |
->isXmlrpcBypass();
|
193 |
}
|
194 |
|
195 |
+
public function cleanStringArray( array $arr, string $pregReplacePattern ) :array {
|
196 |
+
$cleaned = [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
197 |
|
198 |
+
foreach ( $arr as $val ) {
|
199 |
+
$val = preg_replace( $pregReplacePattern, '', $val );
|
200 |
+
if ( strlen( $val ) > 0 ) {
|
201 |
+
$cleaned[] = $val;
|
202 |
}
|
203 |
}
|
204 |
+
return $cleaned;
|
205 |
}
|
206 |
|
207 |
protected function getNamespaceRoots() :array {
|
src/lib/src/Modules/BaseShield/UI.php
CHANGED
@@ -45,7 +45,8 @@ class UI extends Base\UI {
|
|
45 |
'has_session' => $con->getModule_Sessions()
|
46 |
->getSessionCon()
|
47 |
->hasSession(),
|
48 |
-
'display_helpdesk_widget' => !$isWhitelabelled
|
|
|
49 |
],
|
50 |
'hrefs' => [
|
51 |
'aar_forget_key' => $isWhitelabelled ?
|
45 |
'has_session' => $con->getModule_Sessions()
|
46 |
->getSessionCon()
|
47 |
->hasSession(),
|
48 |
+
'display_helpdesk_widget' => !$isWhitelabelled,
|
49 |
+
'is_whitelabelled' => $isWhitelabelled
|
50 |
],
|
51 |
'hrefs' => [
|
52 |
'aar_forget_key' => $isWhitelabelled ?
|
src/lib/src/Modules/HackGuard/Render/ScanResults/SectionThemes.php
CHANGED
@@ -126,6 +126,7 @@ class SectionThemes extends SectionPluginThemesBase {
|
|
126 |
'is_abandoned' => !empty( $abandoned ),
|
127 |
'has_guard_files' => !empty( $guardFilesData ),
|
128 |
'is_active' => $theme->active || $theme->is_parent,
|
|
|
129 |
'is_vulnerable' => !empty( $vulnerabilities ),
|
130 |
'is_wporg' => $theme->isWpOrg(),
|
131 |
'is_child' => $theme->is_child,
|
@@ -144,6 +145,33 @@ class SectionThemes extends SectionPluginThemesBase {
|
|
144 |
!$data[ 'flags' ][ 'is_active' ]
|
145 |
|| $data[ 'flags' ][ 'has_update' ]
|
146 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
return $data;
|
148 |
}
|
149 |
}
|
126 |
'is_abandoned' => !empty( $abandoned ),
|
127 |
'has_guard_files' => !empty( $guardFilesData ),
|
128 |
'is_active' => $theme->active || $theme->is_parent,
|
129 |
+
'is_ignored' => $theme->active || $theme->is_parent,
|
130 |
'is_vulnerable' => !empty( $vulnerabilities ),
|
131 |
'is_wporg' => $theme->isWpOrg(),
|
132 |
'is_child' => $theme->is_child,
|
145 |
!$data[ 'flags' ][ 'is_active' ]
|
146 |
|| $data[ 'flags' ][ 'has_update' ]
|
147 |
);
|
148 |
+
if ( $theme->isWpOrg() && $data[ 'flags' ][ 'has_warning' ] && !$data[ 'flags' ][ 'has_update' ] ) {
|
149 |
+
$wpOrgThemes = implode( '|', array_map( function ( $ver ) {
|
150 |
+
return 'twenty'.$ver;
|
151 |
+
}, [
|
152 |
+
'twentyseven',
|
153 |
+
'twentysix',
|
154 |
+
'twentyfive',
|
155 |
+
'twentyfour',
|
156 |
+
'twentythree',
|
157 |
+
'twentytwo',
|
158 |
+
'twentyone',
|
159 |
+
'twenty',
|
160 |
+
'nineteen',
|
161 |
+
'seventeen',
|
162 |
+
'sixteen',
|
163 |
+
'fifteen',
|
164 |
+
'fourteen',
|
165 |
+
'thirteen',
|
166 |
+
'twelve',
|
167 |
+
'eleven',
|
168 |
+
'ten',
|
169 |
+
] ) );
|
170 |
+
if ( preg_match( sprintf( '#^%s$#', $wpOrgThemes ), strtolower( (string)$theme->slug ) ) ) {
|
171 |
+
$data[ 'flags' ][ 'has_warning' ] = false;
|
172 |
+
}
|
173 |
+
}
|
174 |
+
|
175 |
return $data;
|
176 |
}
|
177 |
}
|
src/lib/src/Modules/HackGuard/UI.php
CHANGED
@@ -189,18 +189,6 @@ class UI extends BaseShield\UI {
|
|
189 |
return $scans;
|
190 |
}
|
191 |
|
192 |
-
/**
|
193 |
-
* @param array $option
|
194 |
-
* @return array
|
195 |
-
*/
|
196 |
-
protected function buildOptionForUi( $option ) {
|
197 |
-
$option = parent::buildOptionForUi( $option );
|
198 |
-
if ( $option[ 'key' ] === 'file_locker' && !Services::Data()->isWindows() ) {
|
199 |
-
$option[ 'value_options' ][ 'root_webconfig' ] .= sprintf( ' (%s)', __( 'unavailable', 'wp-simple-firewall' ) );
|
200 |
-
}
|
201 |
-
return $option;
|
202 |
-
}
|
203 |
-
|
204 |
protected function getFileLockerVars() :array {
|
205 |
/** @var ModCon $mod */
|
206 |
$mod = $this->getMod();
|
@@ -239,7 +227,7 @@ class UI extends BaseShield\UI {
|
|
239 |
];
|
240 |
}
|
241 |
|
242 |
-
|
243 |
$warnings = [];
|
244 |
|
245 |
switch ( $section ) {
|
189 |
return $scans;
|
190 |
}
|
191 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
192 |
protected function getFileLockerVars() :array {
|
193 |
/** @var ModCon $mod */
|
194 |
$mod = $this->getMod();
|
227 |
];
|
228 |
}
|
229 |
|
230 |
+
public function getSectionWarnings( string $section ) :array {
|
231 |
$warnings = [];
|
232 |
|
233 |
switch ( $section ) {
|
src/lib/src/Modules/IPs/AjaxHandler.php
CHANGED
@@ -111,7 +111,7 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
111 |
$msg = __( "This IP is reserved and can't be blacklisted.", 'wp-simple-firewall' );
|
112 |
}
|
113 |
else {
|
114 |
-
$label = $formParams[ 'label' ] ?? '';
|
115 |
$IP = null;
|
116 |
switch ( $list ) {
|
117 |
case $mod::LIST_MANUAL_WHITE:
|
@@ -119,7 +119,7 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
119 |
$IP = ( new Shield\Modules\IPs\Lib\Ops\AddIp() )
|
120 |
->setMod( $mod )
|
121 |
->setIP( $ip )
|
122 |
-
->toManualWhitelist(
|
123 |
}
|
124 |
catch ( \Exception $e ) {
|
125 |
}
|
@@ -130,7 +130,7 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
130 |
$IP = ( new Shield\Modules\IPs\Lib\Ops\AddIp() )
|
131 |
->setMod( $mod )
|
132 |
->setIP( $ip )
|
133 |
-
->toManualBlacklist(
|
134 |
}
|
135 |
catch ( \Exception $e ) {
|
136 |
}
|
111 |
$msg = __( "This IP is reserved and can't be blacklisted.", 'wp-simple-firewall' );
|
112 |
}
|
113 |
else {
|
114 |
+
$label = (string)$formParams[ 'label' ] ?? '';
|
115 |
$IP = null;
|
116 |
switch ( $list ) {
|
117 |
case $mod::LIST_MANUAL_WHITE:
|
119 |
$IP = ( new Shield\Modules\IPs\Lib\Ops\AddIp() )
|
120 |
->setMod( $mod )
|
121 |
->setIP( $ip )
|
122 |
+
->toManualWhitelist( $label );
|
123 |
}
|
124 |
catch ( \Exception $e ) {
|
125 |
}
|
130 |
$IP = ( new Shield\Modules\IPs\Lib\Ops\AddIp() )
|
131 |
->setMod( $mod )
|
132 |
->setIP( $ip )
|
133 |
+
->toManualBlacklist( $label );
|
134 |
}
|
135 |
catch ( \Exception $e ) {
|
136 |
}
|
src/lib/src/Modules/IPs/Lib/Ops/AddIp.php
CHANGED
@@ -62,11 +62,10 @@ class AddIp {
|
|
62 |
}
|
63 |
|
64 |
/**
|
65 |
-
* @param string $label
|
66 |
* @return Databases\IPs\EntryVO|null
|
67 |
* @throws \Exception
|
68 |
*/
|
69 |
-
public function toManualBlacklist( $label = '' ) {
|
70 |
/** @var ModCon $mod */
|
71 |
$mod = $this->getMod();
|
72 |
$srvIP = Services::IP();
|
@@ -126,11 +125,10 @@ class AddIp {
|
|
126 |
}
|
127 |
|
128 |
/**
|
129 |
-
* @param string $label
|
130 |
* @return Databases\IPs\EntryVO|null
|
131 |
* @throws \Exception
|
132 |
*/
|
133 |
-
public function toManualWhitelist( $label = '' ) {
|
134 |
/** @var ModCon $mod */
|
135 |
$mod = $this->getMod();
|
136 |
$srvIP = Services::IP();
|
@@ -182,13 +180,10 @@ class AddIp {
|
|
182 |
}
|
183 |
|
184 |
/**
|
185 |
-
* @param string $list
|
186 |
-
* @param string $label
|
187 |
-
* @param int|null $lastAccess
|
188 |
* @return Databases\IPs\EntryVO|null
|
189 |
* @throws \Exception
|
190 |
*/
|
191 |
-
private function add( string $list, $label = '', $
|
192 |
$IP = null;
|
193 |
|
194 |
/** @var ModCon $mod */
|
@@ -201,16 +196,13 @@ class AddIp {
|
|
201 |
$tmp = $dbh->getVo();
|
202 |
$tmp->ip = $this->getIP();
|
203 |
$tmp->list = $list;
|
204 |
-
$tmp->label =
|
205 |
-
|
206 |
-
$tmp->last_access_at = $lastAccess;
|
207 |
-
}
|
208 |
|
209 |
if ( $dbh->getQueryInserter()->insert( $tmp ) ) {
|
210 |
/** @var Databases\IPs\EntryVO $IP */
|
211 |
$IP = $dbh->getQuerySelector()
|
212 |
-
->
|
213 |
-
->first();
|
214 |
}
|
215 |
|
216 |
if ( !$IP instanceof Databases\IPs\EntryVO ) {
|
62 |
}
|
63 |
|
64 |
/**
|
|
|
65 |
* @return Databases\IPs\EntryVO|null
|
66 |
* @throws \Exception
|
67 |
*/
|
68 |
+
public function toManualBlacklist( string $label = '' ) {
|
69 |
/** @var ModCon $mod */
|
70 |
$mod = $this->getMod();
|
71 |
$srvIP = Services::IP();
|
125 |
}
|
126 |
|
127 |
/**
|
|
|
128 |
* @return Databases\IPs\EntryVO|null
|
129 |
* @throws \Exception
|
130 |
*/
|
131 |
+
public function toManualWhitelist( string $label = '' ) {
|
132 |
/** @var ModCon $mod */
|
133 |
$mod = $this->getMod();
|
134 |
$srvIP = Services::IP();
|
180 |
}
|
181 |
|
182 |
/**
|
|
|
|
|
|
|
183 |
* @return Databases\IPs\EntryVO|null
|
184 |
* @throws \Exception
|
185 |
*/
|
186 |
+
private function add( string $list, string $label = '', int $accessAt = 0 ) {
|
187 |
$IP = null;
|
188 |
|
189 |
/** @var ModCon $mod */
|
196 |
$tmp = $dbh->getVo();
|
197 |
$tmp->ip = $this->getIP();
|
198 |
$tmp->list = $list;
|
199 |
+
$tmp->label = (string)$label;
|
200 |
+
$tmp->last_access_at = $accessAt;
|
|
|
|
|
201 |
|
202 |
if ( $dbh->getQueryInserter()->insert( $tmp ) ) {
|
203 |
/** @var Databases\IPs\EntryVO $IP */
|
204 |
$IP = $dbh->getQuerySelector()
|
205 |
+
->byId( Services::WpDb()->getVar( 'SELECT LAST_INSERT_ID()' ) );
|
|
|
206 |
}
|
207 |
|
208 |
if ( !$IP instanceof Databases\IPs\EntryVO ) {
|
src/lib/src/Modules/IPs/UI.php
CHANGED
@@ -71,7 +71,7 @@ class UI extends BaseShield\UI {
|
|
71 |
];
|
72 |
}
|
73 |
|
74 |
-
|
75 |
$warnings = [];
|
76 |
|
77 |
/** @var Options $opts */
|
71 |
];
|
72 |
}
|
73 |
|
74 |
+
public function getSectionWarnings( string $section ) :array {
|
75 |
$warnings = [];
|
76 |
|
77 |
/** @var Options $opts */
|
src/lib/src/Modules/IPs/WpCli/Add.php
CHANGED
@@ -34,17 +34,15 @@ class Add extends BaseAddRemove {
|
|
34 |
*/
|
35 |
public function cmdIpAdd( array $null, array $args ) {
|
36 |
|
37 |
-
$label = $args[ 'label' ] ?? 'none';
|
38 |
-
|
39 |
$adder = ( new Ops\AddIp() )
|
40 |
->setMod( $this->getMod() )
|
41 |
->setIP( $args[ 'ip' ] );
|
42 |
try {
|
43 |
if ( $args[ 'list' ] === 'white' ) {
|
44 |
-
$adder->toManualWhitelist( $label );
|
45 |
}
|
46 |
else {
|
47 |
-
$adder->toManualBlacklist( $label );
|
48 |
}
|
49 |
}
|
50 |
catch ( \Exception $e ) {
|
34 |
*/
|
35 |
public function cmdIpAdd( array $null, array $args ) {
|
36 |
|
|
|
|
|
37 |
$adder = ( new Ops\AddIp() )
|
38 |
->setMod( $this->getMod() )
|
39 |
->setIP( $args[ 'ip' ] );
|
40 |
try {
|
41 |
if ( $args[ 'list' ] === 'white' ) {
|
42 |
+
$adder->toManualWhitelist( $args[ 'label' ] ?? '' );
|
43 |
}
|
44 |
else {
|
45 |
+
$adder->toManualBlacklist( $args[ 'label' ] ?? '' );
|
46 |
}
|
47 |
}
|
48 |
catch ( \Exception $e ) {
|
src/lib/src/Modules/Integrations/UI.php
CHANGED
@@ -7,7 +7,7 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\Bots\Common
|
|
7 |
|
8 |
class UI extends Modules\BaseShield\UI {
|
9 |
|
10 |
-
|
11 |
$notices = [];
|
12 |
|
13 |
/** @var Modules\LoginGuard\Options $loginGuardOpts */
|
@@ -47,7 +47,7 @@ class UI extends Modules\BaseShield\UI {
|
|
47 |
return $notices;
|
48 |
}
|
49 |
|
50 |
-
|
51 |
$warnings = [];
|
52 |
$con = $this->getCon();
|
53 |
|
7 |
|
8 |
class UI extends Modules\BaseShield\UI {
|
9 |
|
10 |
+
public function getSectionNotices( string $section ) :array {
|
11 |
$notices = [];
|
12 |
|
13 |
/** @var Modules\LoginGuard\Options $loginGuardOpts */
|
47 |
return $notices;
|
48 |
}
|
49 |
|
50 |
+
public function getSectionWarnings( string $section ) :array {
|
51 |
$warnings = [];
|
52 |
$con = $this->getCon();
|
53 |
|
src/lib/src/Modules/Lockdown/ModCon.php
CHANGED
@@ -20,6 +20,9 @@ class ModCon extends BaseShield\ModCon {
|
|
20 |
$this->cleanApiExclusions();
|
21 |
}
|
22 |
|
|
|
|
|
|
|
23 |
private function cleanApiExclusions() {
|
24 |
/** @var Options $opts */
|
25 |
$opts = $this->getOptions();
|
20 |
$this->cleanApiExclusions();
|
21 |
}
|
22 |
|
23 |
+
/**
|
24 |
+
* @deprecated 13.0.6
|
25 |
+
*/
|
26 |
private function cleanApiExclusions() {
|
27 |
/** @var Options $opts */
|
28 |
$opts = $this->getOptions();
|
src/lib/src/Modules/Lockdown/Options.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<?php
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Lockdown;
|
4 |
|
@@ -9,29 +9,20 @@ class Options extends BaseShield\Options {
|
|
9 |
/**
|
10 |
* @return string[]
|
11 |
*/
|
12 |
-
public function getRestApiAnonymousExclusions() {
|
13 |
-
$
|
14 |
-
return
|
15 |
}
|
16 |
|
17 |
-
|
18 |
-
* @return bool
|
19 |
-
*/
|
20 |
-
public function isOptFileEditingDisabled() {
|
21 |
return $this->isOpt( 'disable_file_editing', 'Y' );
|
22 |
}
|
23 |
|
24 |
-
|
25 |
-
* @return bool
|
26 |
-
*/
|
27 |
-
public function isRestApiAnonymousAccessDisabled() {
|
28 |
return $this->isOpt( 'disable_anonymous_restapi', 'Y' );
|
29 |
}
|
30 |
|
31 |
-
|
32 |
-
* @return bool
|
33 |
-
*/
|
34 |
-
public function isXmlrpcDisabled() {
|
35 |
return $this->isOpt( 'disable_xmlrpc', 'Y' );
|
36 |
}
|
37 |
}
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Lockdown;
|
4 |
|
9 |
/**
|
10 |
* @return string[]
|
11 |
*/
|
12 |
+
public function getRestApiAnonymousExclusions() :array {
|
13 |
+
$exc = apply_filters( 'shield/anonymous_rest_api_exclusions', $this->getOpt( 'api_namespace_exclusions' ) );
|
14 |
+
return $this->getMod()->cleanStringArray( $exc, '#[^a-z0-9_-]#i' );
|
15 |
}
|
16 |
|
17 |
+
public function isOptFileEditingDisabled() :bool {
|
|
|
|
|
|
|
18 |
return $this->isOpt( 'disable_file_editing', 'Y' );
|
19 |
}
|
20 |
|
21 |
+
public function isRestApiAnonymousAccessDisabled() :bool {
|
|
|
|
|
|
|
22 |
return $this->isOpt( 'disable_anonymous_restapi', 'Y' );
|
23 |
}
|
24 |
|
25 |
+
public function isXmlrpcDisabled() :bool {
|
|
|
|
|
|
|
26 |
return $this->isOpt( 'disable_xmlrpc', 'Y' );
|
27 |
}
|
28 |
}
|
src/lib/src/Modules/Lockdown/Strings.php
CHANGED
@@ -84,8 +84,6 @@ class Strings extends Base\Strings {
|
|
84 |
}
|
85 |
|
86 |
/**
|
87 |
-
* @param string $key
|
88 |
-
* @return array
|
89 |
* @throws \Exception
|
90 |
*/
|
91 |
public function getOptionStrings( string $key ) :array {
|
@@ -110,29 +108,51 @@ class Strings extends Base\Strings {
|
|
110 |
$name = __( 'Anonymous Rest API', 'wp-simple-firewall' );
|
111 |
$summary = sprintf( __( 'Disable The %s System', 'wp-simple-firewall' ), __( 'Anonymous Rest API', 'wp-simple-firewall' ) );
|
112 |
$description = [
|
113 |
-
__( 'You can
|
114 |
-
sprintf( '%s: %s', __( 'Important', 'wp-simple-firewall' ), __( 'Enabling this option may break plugins that use the REST API for your site visitors.', 'wp-simple-firewall' ) )
|
|
|
115 |
];
|
116 |
break;
|
117 |
|
118 |
case 'api_namespace_exclusions' :
|
119 |
$name = __( 'Rest API Exclusions', 'wp-simple-firewall' );
|
120 |
$summary = __( 'Anonymous REST API Exclusions', 'wp-simple-firewall' );
|
121 |
-
$description =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
122 |
break;
|
123 |
|
124 |
case 'disable_file_editing' :
|
125 |
$name = __( 'Disable File Editing', 'wp-simple-firewall' );
|
126 |
$summary = __( 'Disable Ability To Edit Files From Within WordPress', 'wp-simple-firewall' );
|
127 |
-
$description =
|
128 |
-
|
|
|
|
|
129 |
break;
|
130 |
|
131 |
case 'force_ssl_admin' :
|
132 |
$name = __( 'Force SSL Admin', 'wp-simple-firewall' );
|
133 |
$summary = __( 'Forces WordPress Admin Dashboard To Be Delivered Over SSL', 'wp-simple-firewall' );
|
134 |
-
$description =
|
135 |
-
|
|
|
|
|
136 |
break;
|
137 |
|
138 |
case 'hide_wordpress_generator_tag' :
|
@@ -155,8 +175,10 @@ class Strings extends Base\Strings {
|
|
155 |
case 'block_author_discovery' :
|
156 |
$name = __( 'Block Username Fishing', 'wp-simple-firewall' );
|
157 |
$summary = __( 'Block the ability to discover WordPress usernames based on author IDs', 'wp-simple-firewall' );
|
158 |
-
$description =
|
159 |
-
|
|
|
|
|
160 |
break;
|
161 |
|
162 |
default:
|
84 |
}
|
85 |
|
86 |
/**
|
|
|
|
|
87 |
* @throws \Exception
|
88 |
*/
|
89 |
public function getOptionStrings( string $key ) :array {
|
108 |
$name = __( 'Anonymous Rest API', 'wp-simple-firewall' );
|
109 |
$summary = sprintf( __( 'Disable The %s System', 'wp-simple-firewall' ), __( 'Anonymous Rest API', 'wp-simple-firewall' ) );
|
110 |
$description = [
|
111 |
+
__( 'You can completely disable anonymous access to the REST API.', 'wp-simple-firewall' ),
|
112 |
+
sprintf( '%s: %s', __( 'Important', 'wp-simple-firewall' ), __( 'Enabling this option may break plugins that use the REST API for your site visitors.', 'wp-simple-firewall' ) ),
|
113 |
+
__( 'Use the exclusions option to allow anonymous access to specific API endpoints.', 'wp-simple-firewall' ),
|
114 |
];
|
115 |
break;
|
116 |
|
117 |
case 'api_namespace_exclusions' :
|
118 |
$name = __( 'Rest API Exclusions', 'wp-simple-firewall' );
|
119 |
$summary = __( 'Anonymous REST API Exclusions', 'wp-simple-firewall' );
|
120 |
+
$description = [
|
121 |
+
__( 'These REST API namespaces will be excluded from the Anonymous API restriction.', 'wp-simple-firewall' ),
|
122 |
+
sprintf( __( 'Some plugins (e.g. %s) use the REST API anonymously so you need to provide exclusions for them to work correctly.', 'wp-simple-firewall' ),
|
123 |
+
'Contact Form 7' ),
|
124 |
+
__( "Please contact the developer of a plugin to ask them for their REST API namespace if you need it." ),
|
125 |
+
__( 'Some common namespaces' ).':',
|
126 |
+
];
|
127 |
+
|
128 |
+
$defaultEx = [
|
129 |
+
'contact-form-7' => 'Contact Form 7',
|
130 |
+
'tribe' => 'The Events Calendar',
|
131 |
+
'jetpack' => 'JetPack',
|
132 |
+
'woocommerce' => 'WooCommerce',
|
133 |
+
'wpstatistics' => 'WP Statistics',
|
134 |
+
];
|
135 |
+
foreach ( $defaultEx as $defNamespace => $defName ) {
|
136 |
+
$description[] = sprintf( '<code>%s</code> - %s', $defNamespace, $defName );
|
137 |
+
}
|
138 |
break;
|
139 |
|
140 |
case 'disable_file_editing' :
|
141 |
$name = __( 'Disable File Editing', 'wp-simple-firewall' );
|
142 |
$summary = __( 'Disable Ability To Edit Files From Within WordPress', 'wp-simple-firewall' );
|
143 |
+
$description = [
|
144 |
+
__( 'Removes the option to directly edit any files from within the WordPress admin area.', 'wp-simple-firewall' ),
|
145 |
+
__( 'Equivalent to setting "DISALLOW_FILE_EDIT" to TRUE.', 'wp-simple-firewall' )
|
146 |
+
];
|
147 |
break;
|
148 |
|
149 |
case 'force_ssl_admin' :
|
150 |
$name = __( 'Force SSL Admin', 'wp-simple-firewall' );
|
151 |
$summary = __( 'Forces WordPress Admin Dashboard To Be Delivered Over SSL', 'wp-simple-firewall' );
|
152 |
+
$description = [
|
153 |
+
__( 'Please only enable this option if you have a valid SSL certificate installed.', 'wp-simple-firewall' ),
|
154 |
+
__( 'Equivalent to setting "FORCE_SSL_ADMIN" to TRUE.', 'wp-simple-firewall' )
|
155 |
+
];
|
156 |
break;
|
157 |
|
158 |
case 'hide_wordpress_generator_tag' :
|
175 |
case 'block_author_discovery' :
|
176 |
$name = __( 'Block Username Fishing', 'wp-simple-firewall' );
|
177 |
$summary = __( 'Block the ability to discover WordPress usernames based on author IDs', 'wp-simple-firewall' );
|
178 |
+
$description = [
|
179 |
+
sprintf( __( 'When enabled, any URL requests containing "%s" will be killed.', 'wp-simple-firewall' ), 'author=' ),
|
180 |
+
sprintf( '%s - %s', __( 'Warning', 'wp-simple-firewall' ), __( 'Enabling this option may interfere with expected operations of your site.', 'wp-simple-firewall' ) )
|
181 |
+
];
|
182 |
break;
|
183 |
|
184 |
default:
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/MfaProfilesController.php
CHANGED
@@ -130,6 +130,7 @@ class MfaProfilesController {
|
|
130 |
},
|
131 |
$mfaCon->getProvidersForUser( $user, true )
|
132 |
);
|
|
|
133 |
|
134 |
echo $mfaCon->getMod()->renderTemplate( '/admin/user/profile/mfa/remove_for_other_user.twig', [
|
135 |
'flags' => [
|
130 |
},
|
131 |
$mfaCon->getProvidersForUser( $user, true )
|
132 |
);
|
133 |
+
$this->rendered = true;
|
134 |
|
135 |
echo $mfaCon->getMod()->renderTemplate( '/admin/user/profile/mfa/remove_for_other_user.twig', [
|
136 |
'flags' => [
|
src/lib/src/Modules/LoginGuard/UI.php
CHANGED
@@ -9,7 +9,7 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
9 |
|
10 |
class UI extends BaseShield\UI {
|
11 |
|
12 |
-
|
13 |
/** @var Options $opts */
|
14 |
$opts = $this->getOptions();
|
15 |
|
@@ -31,7 +31,7 @@ class UI extends BaseShield\UI {
|
|
31 |
return $notices;
|
32 |
}
|
33 |
|
34 |
-
|
35 |
$con = $this->getCon();
|
36 |
/** @var Options $opts */
|
37 |
$opts = $this->getOptions();
|
9 |
|
10 |
class UI extends BaseShield\UI {
|
11 |
|
12 |
+
public function getSectionNotices( string $section ) :array {
|
13 |
/** @var Options $opts */
|
14 |
$opts = $this->getOptions();
|
15 |
|
31 |
return $notices;
|
32 |
}
|
33 |
|
34 |
+
public function getSectionWarnings( string $section ) :array {
|
35 |
$con = $this->getCon();
|
36 |
/** @var Options $opts */
|
37 |
$opts = $this->getOptions();
|
src/lib/src/Modules/Plugin/Lib/Debug/Collate.php
CHANGED
@@ -117,11 +117,11 @@ class Collate {
|
|
117 |
|
118 |
$data = [];
|
119 |
|
120 |
-
foreach ( $oWpPlugins->getPluginsAsVo() as $
|
121 |
-
if ( $filterByActive === $
|
122 |
-
$data[ $
|
123 |
-
$
|
124 |
-
$
|
125 |
);
|
126 |
}
|
127 |
}
|
@@ -268,7 +268,7 @@ class Collate {
|
|
268 |
|
269 |
private function getServiceIPs() :array {
|
270 |
return [
|
271 |
-
'ips'=>var_export(Services::ServiceProviders()::GetProviderIPs(),true),
|
272 |
|
273 |
];
|
274 |
}
|
@@ -276,6 +276,15 @@ class Collate {
|
|
276 |
private function getWordPressSummary() :array {
|
277 |
$WP = Services::WpGeneral();
|
278 |
$data = [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
279 |
'URL - Home' => $WP->getHomeUrl(),
|
280 |
'URL - Site' => $WP->getWpUrl(),
|
281 |
'WP' => $WP->getVersion( true ),
|
@@ -289,11 +298,6 @@ class Collate {
|
|
289 |
sprintf( 'User: <code>%s</code>', DB_USER ),
|
290 |
sprintf( 'Prefix: <code>%s</code>', Services::WpDb()->getPrefix() ),
|
291 |
],
|
292 |
-
];
|
293 |
-
if ( $WP->isClassicPress() ) {
|
294 |
-
$data[ 'ClassicPress' ] = $WP->getVersion();
|
295 |
-
}
|
296 |
-
|
297 |
-
return $data;
|
298 |
}
|
299 |
}
|
117 |
|
118 |
$data = [];
|
119 |
|
120 |
+
foreach ( $oWpPlugins->getPluginsAsVo() as $VO ) {
|
121 |
+
if ( $filterByActive === $VO->active ) {
|
122 |
+
$data[ $VO->Name ] = sprintf( '%s / %s / %s',
|
123 |
+
$VO->Version, $VO->active ? 'Active' : 'Deactivated',
|
124 |
+
$VO->hasUpdate() ? 'Update Available' : 'No Update'
|
125 |
);
|
126 |
}
|
127 |
}
|
268 |
|
269 |
private function getServiceIPs() :array {
|
270 |
return [
|
271 |
+
'ips' => var_export( Services::ServiceProviders()::GetProviderIPs(), true ),
|
272 |
|
273 |
];
|
274 |
}
|
276 |
private function getWordPressSummary() :array {
|
277 |
$WP = Services::WpGeneral();
|
278 |
$data = [
|
279 |
+
'URL - Home' => $WP->getHomeUrl(),
|
280 |
+
'URL - Site' => $WP->getWpUrl(),
|
281 |
+
'WP' => $WP->getVersion( true ),
|
282 |
+
];
|
283 |
+
if ( $WP->isClassicPress() ) {
|
284 |
+
$data[ 'ClassicPress' ] = $WP->getVersion();
|
285 |
+
}
|
286 |
+
|
287 |
+
return array_merge( $data, [
|
288 |
'URL - Home' => $WP->getHomeUrl(),
|
289 |
'URL - Site' => $WP->getWpUrl(),
|
290 |
'WP' => $WP->getVersion( true ),
|
298 |
sprintf( 'User: <code>%s</code>', DB_USER ),
|
299 |
sprintf( 'Prefix: <code>%s</code>', Services::WpDb()->getPrefix() ),
|
300 |
],
|
301 |
+
] );
|
|
|
|
|
|
|
|
|
|
|
302 |
}
|
303 |
}
|
src/lib/src/Modules/Plugin/UI.php
CHANGED
@@ -72,25 +72,11 @@ class UI extends BaseShield\UI {
|
|
72 |
protected function buildOptionForUi( $option ) {
|
73 |
$option = parent::buildOptionForUi( $option );
|
74 |
if ( $option[ 'key' ] === 'visitor_address_source' ) {
|
75 |
-
$newOptions = [];
|
76 |
-
$ipDetector = Services::IP()->getIpDetector();
|
77 |
-
foreach ( $option[ 'value_options' ] as $valKey => $source ) {
|
78 |
-
if ( $valKey == 'AUTO_DETECT_IP' ) {
|
79 |
-
$newOptions[ $valKey ] = $source;
|
80 |
-
}
|
81 |
-
else {
|
82 |
-
$IPs = implode( ', ', $ipDetector->getIpsFromSource( $source ) );
|
83 |
-
if ( !empty( $IPs ) ) {
|
84 |
-
$newOptions[ $valKey ] = sprintf( '%s (%s)', $source, $IPs );
|
85 |
-
}
|
86 |
-
}
|
87 |
-
}
|
88 |
-
$option[ 'value_options' ] = $newOptions;
|
89 |
}
|
90 |
return $option;
|
91 |
}
|
92 |
|
93 |
-
|
94 |
/** @var ModCon $mod */
|
95 |
$mod = $this->getMod();
|
96 |
$opts = $this->getOptions();
|
72 |
protected function buildOptionForUi( $option ) {
|
73 |
$option = parent::buildOptionForUi( $option );
|
74 |
if ( $option[ 'key' ] === 'visitor_address_source' ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
}
|
76 |
return $option;
|
77 |
}
|
78 |
|
79 |
+
public function getSectionWarnings( string $section ) :array {
|
80 |
/** @var ModCon $mod */
|
81 |
$mod = $this->getMod();
|
82 |
$opts = $this->getOptions();
|
src/lib/src/Modules/SecurityAdmin/UI.php
CHANGED
@@ -6,7 +6,7 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield;
|
|
6 |
|
7 |
class UI extends BaseShield\UI {
|
8 |
|
9 |
-
|
10 |
/** @var ModCon $mod */
|
11 |
$mod = $this->getMod();
|
12 |
|
6 |
|
7 |
class UI extends BaseShield\UI {
|
8 |
|
9 |
+
public function getSectionWarnings( string $section ) :array {
|
10 |
/** @var ModCon $mod */
|
11 |
$mod = $this->getMod();
|
12 |
|
src/lib/src/Modules/Traffic/UI.php
CHANGED
@@ -38,7 +38,7 @@ class UI extends BaseShield\UI {
|
|
38 |
);
|
39 |
}
|
40 |
|
41 |
-
|
42 |
/** @var Options $opts */
|
43 |
$opts = $this->getOptions();
|
44 |
|
38 |
);
|
39 |
}
|
40 |
|
41 |
+
public function getSectionWarnings( string $section ) :array {
|
42 |
/** @var Options $opts */
|
43 |
$opts = $this->getOptions();
|
44 |
|
src/lib/src/Tables/Render/WpListTable/AdminNotes.php
CHANGED
@@ -4,12 +4,8 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Tables\Render\WpListTable;
|
|
4 |
|
5 |
class AdminNotes extends Base {
|
6 |
|
7 |
-
|
8 |
-
|
9 |
-
* @return string
|
10 |
-
*/
|
11 |
-
public function column_note( $aItem ) {
|
12 |
-
return $aItem[ 'note' ].$this->buildActions( [ $this->getActionButton_Delete( $aItem[ 'id' ] ) ] );
|
13 |
}
|
14 |
|
15 |
/**
|
4 |
|
5 |
class AdminNotes extends Base {
|
6 |
|
7 |
+
public function column_note( array $item ) :string {
|
8 |
+
return esc_html( $item[ 'note' ] ).$this->buildActions( [ $this->getActionButton_Delete( $item[ 'id' ] ) ] );
|
|
|
|
|
|
|
|
|
9 |
}
|
10 |
|
11 |
/**
|
src/lib/src/Tables/Render/WpListTable/IpBase.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<?php
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Tables\Render\WpListTable;
|
4 |
|
@@ -8,6 +8,10 @@ class IpBase extends Base {
|
|
8 |
return $item[ 'ip' ].$this->buildActions( [ $this->getActionButton_Delete( $item[ 'id' ] ) ] );
|
9 |
}
|
10 |
|
|
|
|
|
|
|
|
|
11 |
public function get_columns() {
|
12 |
return [
|
13 |
'ip' => __( 'IP Address' ),
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Tables\Render\WpListTable;
|
4 |
|
8 |
return $item[ 'ip' ].$this->buildActions( [ $this->getActionButton_Delete( $item[ 'id' ] ) ] );
|
9 |
}
|
10 |
|
11 |
+
public function column_label( array $item ) :string {
|
12 |
+
return esc_html( empty( $item[ 'label' ] ) ? __( 'No Label', 'wp-simple-firewall' ) : $item[ 'label' ] );
|
13 |
+
}
|
14 |
+
|
15 |
public function get_columns() {
|
16 |
return [
|
17 |
'ip' => __( 'IP Address' ),
|
src/lib/src/Tables/Render/WpListTable/IpBlack.php
CHANGED
@@ -7,20 +7,20 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\ModCon;
|
|
7 |
class IpBlack extends IpBase {
|
8 |
|
9 |
/**
|
10 |
-
* @param array $
|
11 |
* @return string
|
12 |
*/
|
13 |
-
public function column_details( $
|
14 |
-
$
|
15 |
return implode( '<br/>', [
|
16 |
-
sprintf( '%s: %s', __( 'Blocked', 'wp-simple-firewall' ), $
|
17 |
sprintf( '%s / %s',
|
18 |
-
$
|
19 |
-
$
|
20 |
),
|
21 |
sprintf( '%s - %s',
|
22 |
-
sprintf( _n( '%s Offense', '%s Offenses', $
|
23 |
-
sprintf( '%s: %s', __( 'Last Access', 'wp-simple-firewall' ), $
|
24 |
),
|
25 |
] );
|
26 |
}
|
7 |
class IpBlack extends IpBase {
|
8 |
|
9 |
/**
|
10 |
+
* @param array $item
|
11 |
* @return string
|
12 |
*/
|
13 |
+
public function column_details( $item ) {
|
14 |
+
$autoBlock = $item[ 'list' ] === ModCon::LIST_AUTO_BLACK;
|
15 |
return implode( '<br/>', [
|
16 |
+
sprintf( '%s: %s', __( 'Blocked', 'wp-simple-firewall' ), $item[ 'blocked' ] ),
|
17 |
sprintf( '%s / %s',
|
18 |
+
$item[ 'is_range' ] ? __( 'IP Range', 'wp-simple-firewall' ) : __( 'Single IP', 'wp-simple-firewall' ),
|
19 |
+
$autoBlock ? __( 'Automatic', 'wp-simple-firewall' ) : __( 'Manual', 'wp-simple-firewall' )
|
20 |
),
|
21 |
sprintf( '%s - %s',
|
22 |
+
sprintf( _n( '%s Offense', '%s Offenses', $item[ 'transgressions' ], 'wp-simple-firewall' ), $item[ 'transgressions' ] ),
|
23 |
+
sprintf( '%s: %s', __( 'Last Access', 'wp-simple-firewall' ), $item[ 'last_trans_at' ] )
|
24 |
),
|
25 |
] );
|
26 |
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/General.php
CHANGED
@@ -332,7 +332,19 @@ class General {
|
|
332 |
$this->sWpVersion = $wp_version;
|
333 |
}
|
334 |
}
|
335 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
336 |
}
|
337 |
|
338 |
public function getWordpressIsAtLeastVersion( string $version, bool $ignoreCP = true ) :bool {
|
332 |
$this->sWpVersion = $wp_version;
|
333 |
}
|
334 |
}
|
335 |
+
|
336 |
+
if ( $bIgnoreClassicpress || !$this->isClassicPress() ) {
|
337 |
+
$version = $this->sWpVersion;
|
338 |
+
}
|
339 |
+
else {
|
340 |
+
$version = \classicpress_version();
|
341 |
+
preg_match( '#^(\d+(?:\.\d)+)(.*)$#', $version, $matches );
|
342 |
+
if ( !empty( $matches[ 2 ] ) ) {
|
343 |
+
$version = $matches[ 1 ];
|
344 |
+
}
|
345 |
+
}
|
346 |
+
|
347 |
+
return $version;
|
348 |
}
|
349 |
|
350 |
public function getWordpressIsAtLeastVersion( string $version, bool $ignoreCP = true ) :bool {
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/ClassicPress.php
CHANGED
@@ -4,10 +4,6 @@ namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Has
|
|
4 |
|
5 |
use FernleafSystems\Wordpress\Services;
|
6 |
|
7 |
-
/**
|
8 |
-
* Class ClassicPress
|
9 |
-
* @package FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Hashes
|
10 |
-
*/
|
11 |
class ClassicPress extends AssetHashesBase {
|
12 |
|
13 |
const TYPE = 'classicpress';
|
4 |
|
5 |
use FernleafSystems\Wordpress\Services;
|
6 |
|
|
|
|
|
|
|
|
|
7 |
class ClassicPress extends AssetHashesBase {
|
8 |
|
9 |
const TYPE = 'classicpress';
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Cp/Download.php
CHANGED
@@ -28,16 +28,15 @@ class Download {
|
|
28 |
}
|
29 |
|
30 |
/**
|
31 |
-
* @param $version
|
32 |
* @return string|null
|
33 |
*/
|
34 |
-
private function getZipDownloadUrl( $
|
35 |
$url = null;
|
36 |
$versions = @json_decode( Services::HttpRequest()->getContent( Repo::GetUrlForVersions() ), true );
|
37 |
|
38 |
if ( is_array( $versions ) ) {
|
39 |
foreach ( $versions as $version ) {
|
40 |
-
if ( $version[ 'tag_name' ] == $
|
41 |
$url = $version[ 'zipball_url' ];
|
42 |
break;
|
43 |
}
|
28 |
}
|
29 |
|
30 |
/**
|
|
|
31 |
* @return string|null
|
32 |
*/
|
33 |
+
private function getZipDownloadUrl( string $versionToFind ) {
|
34 |
$url = null;
|
35 |
$versions = @json_decode( Services::HttpRequest()->getContent( Repo::GetUrlForVersions() ), true );
|
36 |
|
37 |
if ( is_array( $versions ) ) {
|
38 |
foreach ( $versions as $version ) {
|
39 |
+
if ( $version[ 'tag_name' ] == $versionToFind ) {
|
40 |
$url = $version[ 'zipball_url' ];
|
41 |
break;
|
42 |
}
|
templates/twig/components/options_form/option.twig
CHANGED
@@ -14,11 +14,9 @@
|
|
14 |
title="{{ strings.opt_info_helpdesk }}">
|
15 |
<span class="dashicons dashicons-editor-help"></span>
|
16 |
</a>
|
17 |
-
{%
|
18 |
-
{% if aOption.link_info %}
|
19 |
<a href="{{ aOption.link_info }}" class="option_link_info d-inline-block" target="_blank"
|
20 |
title="{{ strings.opt_info_helpdesk }}"></a>
|
21 |
-
{% endif %}
|
22 |
{% endif %}
|
23 |
</span>
|
24 |
|
@@ -183,22 +181,19 @@
|
|
183 |
</div>
|
184 |
|
185 |
<div class="mt-3 text-left text-nowrap">
|
186 |
-
{% if aOption.
|
187 |
-
|
188 |
-
|
189 |
-
<a href="javascript:{}" data-beacon-article-sidebar="{{ aOption.beacon_id }}"
|
190 |
-
title="{{ strings.opt_info_helpdesk }}">{{ strings.more_info }}</a>
|
191 |
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
{% endif %}
|
202 |
{% endif %}
|
203 |
|
204 |
{% if flags.is_wpcli %}
|
14 |
title="{{ strings.opt_info_helpdesk }}">
|
15 |
<span class="dashicons dashicons-editor-help"></span>
|
16 |
</a>
|
17 |
+
{% elseif aOption.link_info %}
|
|
|
18 |
<a href="{{ aOption.link_info }}" class="option_link_info d-inline-block" target="_blank"
|
19 |
title="{{ strings.opt_info_helpdesk }}"></a>
|
|
|
20 |
{% endif %}
|
21 |
</span>
|
22 |
|
181 |
</div>
|
182 |
|
183 |
<div class="mt-3 text-left text-nowrap">
|
184 |
+
{% if aOption.beacon_id|default(false) %}
|
185 |
+
<a href="javascript:{}" data-beacon-article-sidebar="{{ aOption.beacon_id }}"
|
186 |
+
title="{{ strings.opt_info_helpdesk }}">{{ strings.more_info }}</a>
|
|
|
|
|
187 |
|
188 |
+
{% elseif aOption.link_info %}
|
189 |
+
<a href="{{ aOption.link_info }}" target="_blank"
|
190 |
+
title="{{ strings.opt_info_helpdesk }}">{{ strings.more_info }}</a>
|
191 |
+
{% endif %}
|
192 |
|
193 |
+
{% if aOption.link_blog %}
|
194 |
+
<span class="m-1">|</span>
|
195 |
+
<a href="{{ aOption.link_blog }}" target="_blank"
|
196 |
+
title="{{ strings.opt_info_blog }}">{{ strings.blog }}</a>
|
|
|
197 |
{% endif %}
|
198 |
|
199 |
{% if flags.is_wpcli %}
|