Shield Security for WordPress - Version 15.1.2

Version Description

Download this release

Release Info

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

Code changes from version 15.1.0 to 15.1.2

cl.json CHANGED
@@ -1,7 +1,7 @@
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"
@@ -31,11 +31,27 @@
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": [
1
  {
2
  "15.1": {
3
  "version": "15.1",
4
+ "released_at": 1654522432,
5
  "hrefs": {
6
  "release": "https://shsec.io/shieldrelease151",
7
  "upgrade": "https://shsec.io/shieldupgradeguide151"
31
  {
32
  "type": "improved",
33
  "pro_only": true,
34
+ "title": "Whitelabelling",
35
+ "description": [
36
+ "We've refactored our white labelling feature to ensure your custom brand displays more consistently throughout the plugin."
37
+ ]
38
+ },
39
+ {
40
+ "type": "improved",
41
+ "pro_only": false,
42
  "title": "Automatic Visitor IP Detection",
43
  "description": [
44
  "The 100% fully automatic detection of visitor IP addresses is a lofty goal and with each release we get a bit closer.",
45
  "You can always help Shield by manually setting your Visitor IP source option: Shield > Config > General IP Source."
46
  ]
47
+ },
48
+ {
49
+ "type": "improved",
50
+ "pro_only": false,
51
+ "title": "Plugin Loading",
52
+ "description": [
53
+ "Shield is a large and complex plugin so we've done a lot of work to help ensure it's more reliable when loading."
54
+ ]
55
  }
56
  ],
57
  "patches": [
config/deprecated/hack_protect.php CHANGED
@@ -244,6 +244,18 @@
244
  "summary": "Apply Updates Automatically To Vulnerable Plugins",
245
  "description": "When an update becomes available, automatically apply updates to items with known vulnerabilities."
246
  },
 
 
 
 
 
 
 
 
 
 
 
 
247
  {
248
  "key": "scan_frequency",
249
  "section": "section_scan_options",
@@ -316,18 +328,6 @@
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",
244
  "summary": "Apply Updates Automatically To Vulnerable Plugins",
245
  "description": "When an update becomes available, automatically apply updates to items with known vulnerabilities."
246
  },
247
+ {
248
+ "key": "optimise_scan_speed",
249
+ "section": "section_scan_options",
250
+ "premium": false,
251
+ "type": "checkbox",
252
+ "default": "Y",
253
+ "link_info": "",
254
+ "link_blog": "",
255
+ "name": "Optimise File Scans",
256
+ "summary": "Optimise File Scans",
257
+ "description": "Optimise file scans wherever possible."
258
+ },
259
  {
260
  "key": "scan_frequency",
261
  "section": "section_scan_options",
328
  "summary": "Show Re-Install Links For Plugins",
329
  "description": "Show links to re-install plugins and offer re-install when activating plugins."
330
  },
 
 
 
 
 
 
 
 
 
 
 
 
331
  {
332
  "key": "scans_to_build",
333
  "section": "section_non_ui",
config/hack_protect.json CHANGED
@@ -244,6 +244,18 @@
244
  "summary": "Apply Updates Automatically To Vulnerable Plugins",
245
  "description": "When an update becomes available, automatically apply updates to items with known vulnerabilities."
246
  },
 
 
 
 
 
 
 
 
 
 
 
 
247
  {
248
  "key": "scan_frequency",
249
  "section": "section_scan_options",
@@ -316,18 +328,6 @@
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",
244
  "summary": "Apply Updates Automatically To Vulnerable Plugins",
245
  "description": "When an update becomes available, automatically apply updates to items with known vulnerabilities."
246
  },
247
+ {
248
+ "key": "optimise_scan_speed",
249
+ "section": "section_scan_options",
250
+ "premium": false,
251
+ "type": "checkbox",
252
+ "default": "Y",
253
+ "link_info": "",
254
+ "link_blog": "",
255
+ "name": "Optimise File Scans",
256
+ "summary": "Optimise File Scans",
257
+ "description": "Optimise file scans wherever possible."
258
+ },
259
  {
260
  "key": "scan_frequency",
261
  "section": "section_scan_options",
328
  "summary": "Show Re-Install Links For Plugins",
329
  "description": "Show links to re-install plugins and offer re-install when activating plugins."
330
  },
 
 
 
 
 
 
 
 
 
 
 
 
331
  {
332
  "key": "scans_to_build",
333
  "section": "section_non_ui",
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.1.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: 15.1.2
7
  * Text Domain: wp-simple-firewall
8
  * Domain Path: /languages
9
  * Author: Shield Security
init.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
 
3
  use FernleafSystems\Wordpress\Plugin\Shield;
 
4
 
5
  /** @var string $rootFile */
6
  global $oICWP_Wpsf;
@@ -57,6 +58,8 @@ class ICWP_WPSF_Shield_Security {
57
  }
58
  }
59
 
 
 
60
  try {
61
  $oICWP_Wpsf_Controller = Shield\Controller\Controller::GetInstance( $rootFile );
62
  $oICWP_Wpsf = ICWP_WPSF_Shield_Security::GetInstance( $oICWP_Wpsf_Controller );
1
  <?php
2
 
3
  use FernleafSystems\Wordpress\Plugin\Shield;
4
+ use FernleafSystems\Wordpress\Services\Services;
5
 
6
  /** @var string $rootFile */
7
  global $oICWP_Wpsf;
58
  }
59
  }
60
 
61
+ Services::GetInstance();
62
+
63
  try {
64
  $oICWP_Wpsf_Controller = Shield\Controller\Controller::GetInstance( $rootFile );
65
  $oICWP_Wpsf = ICWP_WPSF_Shield_Security::GetInstance( $oICWP_Wpsf_Controller );
plugin-spec.php CHANGED
@@ -1,8 +1,8 @@
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",
@@ -72,11 +72,12 @@
72
  "plugin",
73
  "jquery/featherlight",
74
  "jquery/fileDownload",
75
- "shield/tours",
76
- "shield/datatables",
77
- "shield/traffic",
78
  "shield/audit_trail",
 
 
79
  "shield/scanners",
 
 
80
  "tp/circular-progress"
81
  ]
82
  },
@@ -257,6 +258,8 @@
257
  "datatables-bootstrap",
258
  "global-plugin",
259
  "shield/navigation",
 
 
260
  "base64.min",
261
  "lz-string.min"
262
  ]
@@ -308,7 +311,7 @@
308
  },
309
  "shield/tables": {
310
  "deps": [
311
- "plugin"
312
  ]
313
  },
314
  "shield/audit_trail": {
@@ -370,7 +373,7 @@
370
  },
371
  "shield/ipanalyse": {
372
  "deps": [
373
- "plugin"
374
  ]
375
  },
376
  "shield/mainwp-extension": {
1
  {
2
  "properties": {
3
+ "version": "15.1.2",
4
+ "release_timestamp": 1654596067,
5
+ "build": "202206.0701",
6
  "slug_parent": "icwp",
7
  "slug_plugin": "wpsf",
8
  "text_domain": "wp-simple-firewall",
72
  "plugin",
73
  "jquery/featherlight",
74
  "jquery/fileDownload",
 
 
 
75
  "shield/audit_trail",
76
+ "shield/datatables",
77
+ "shield/ipanalyse",
78
  "shield/scanners",
79
+ "shield/tours",
80
+ "shield/traffic",
81
  "tp/circular-progress"
82
  ]
83
  },
258
  "datatables-bootstrap",
259
  "global-plugin",
260
  "shield/navigation",
261
+ "shield/ipanalyse",
262
+ "shield/tables",
263
  "base64.min",
264
  "lz-string.min"
265
  ]
311
  },
312
  "shield/tables": {
313
  "deps": [
314
+ "wp-jquery"
315
  ]
316
  },
317
  "shield/audit_trail": {
373
  },
374
  "shield/ipanalyse": {
375
  "deps": [
376
+ "wp-jquery"
377
  ]
378
  },
379
  "shield/mainwp-extension": {
plugin.json CHANGED
@@ -1,8 +1,8 @@
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",
@@ -72,11 +72,12 @@
72
  "plugin",
73
  "jquery/featherlight",
74
  "jquery/fileDownload",
75
- "shield/tours",
76
- "shield/datatables",
77
- "shield/traffic",
78
  "shield/audit_trail",
 
 
79
  "shield/scanners",
 
 
80
  "tp/circular-progress"
81
  ]
82
  },
@@ -257,6 +258,8 @@
257
  "datatables-bootstrap",
258
  "global-plugin",
259
  "shield/navigation",
 
 
260
  "base64.min",
261
  "lz-string.min"
262
  ]
@@ -308,7 +311,7 @@
308
  },
309
  "shield/tables": {
310
  "deps": [
311
- "plugin"
312
  ]
313
  },
314
  "shield/audit_trail": {
@@ -370,7 +373,7 @@
370
  },
371
  "shield/ipanalyse": {
372
  "deps": [
373
- "plugin"
374
  ]
375
  },
376
  "shield/mainwp-extension": {
1
  {
2
  "properties": {
3
+ "version": "15.1.2",
4
+ "release_timestamp": 1654596067,
5
+ "build": "202206.0701",
6
  "slug_parent": "icwp",
7
  "slug_plugin": "wpsf",
8
  "text_domain": "wp-simple-firewall",
72
  "plugin",
73
  "jquery/featherlight",
74
  "jquery/fileDownload",
 
 
 
75
  "shield/audit_trail",
76
+ "shield/datatables",
77
+ "shield/ipanalyse",
78
  "shield/scanners",
79
+ "shield/tours",
80
+ "shield/traffic",
81
  "tp/circular-progress"
82
  ]
83
  },
258
  "datatables-bootstrap",
259
  "global-plugin",
260
  "shield/navigation",
261
+ "shield/ipanalyse",
262
+ "shield/tables",
263
  "base64.min",
264
  "lz-string.min"
265
  ]
311
  },
312
  "shield/tables": {
313
  "deps": [
314
+ "wp-jquery"
315
  ]
316
  },
317
  "shield/audit_trail": {
373
  },
374
  "shield/ipanalyse": {
375
  "deps": [
376
+ "wp-jquery"
377
  ]
378
  },
379
  "shield/mainwp-extension": {
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: 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
 
8
  Requires PHP: 7.0
9
  Recommended PHP: 7.4
10
  Tested up to: 6.0
11
+ Stable tag: 15.1.2
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
 
resources/js/plugin.js CHANGED
@@ -418,7 +418,9 @@ let iCWP_WPSF_Helpscout = new function () {
418
  };
419
  }();
420
 
421
- jQuery( document ).ready( function () {
 
 
422
 
423
  if ( typeof icwp_wpsf_vars_insights.vars.meters !== 'undefined' ) {
424
  iCWP_WPSF_ProgressMeters.initialise( icwp_wpsf_vars_insights.vars.meters );
@@ -435,6 +437,10 @@ jQuery( document ).ready( function () {
435
  iCWP_WPSF_Modals.initialise();
436
  if ( typeof icwp_wpsf_vars_ips.components.modal_ip_analysis !== 'undefined' ) {
437
  iCWP_WPSF_Modals.setData( 'modal_ip_analysis', icwp_wpsf_vars_ips.components.modal_ip_analysis );
 
 
 
 
438
  }
439
 
440
  jQuery( document ).ajaxComplete( function () {
418
  };
419
  }();
420
 
421
+ let jQueryDoc = jQuery( 'document' );
422
+
423
+ jQueryDoc.ready( function () {
424
 
425
  if ( typeof icwp_wpsf_vars_insights.vars.meters !== 'undefined' ) {
426
  iCWP_WPSF_ProgressMeters.initialise( icwp_wpsf_vars_insights.vars.meters );
437
  iCWP_WPSF_Modals.initialise();
438
  if ( typeof icwp_wpsf_vars_ips.components.modal_ip_analysis !== 'undefined' ) {
439
  iCWP_WPSF_Modals.setData( 'modal_ip_analysis', icwp_wpsf_vars_ips.components.modal_ip_analysis );
440
+
441
+ if ( typeof jQueryDoc.icwpWpsfIpAnalyse !== 'undefined' ) {
442
+ jQueryDoc.icwpWpsfIpAnalyse( icwp_wpsf_vars_ips.components.ip_analysis.ajax );
443
+ }
444
  }
445
 
446
  jQuery( document ).ajaxComplete( function () {
resources/js/shield/ipanalyse.js CHANGED
@@ -1,6 +1,7 @@
1
  jQuery.fn.icwpWpsfIpAnalyse = function ( options ) {
2
 
3
- var runAnalysis = function () {
 
4
  let newUrl = window.location.href.replace( /&analyse_ip=.+/i, "" );
5
  if ( $ipSelect.val() && $ipSelect.val().length > 0 ) {
6
  newUrl += "&analyse_ip=" + $ipSelect.val();
@@ -27,7 +28,7 @@ jQuery.fn.icwpWpsfIpAnalyse = function ( options ) {
27
 
28
  jQuery( '#IpReviewContent' ).html( 'loading IP info ...' );
29
 
30
- let reqData = aOpts[ 'ajax_ip_analyse_build' ];
31
  jQuery.post( ajaxurl, jQuery.extend( reqData, params ),
32
  function ( response ) {
33
 
@@ -56,54 +57,50 @@ jQuery.fn.icwpWpsfIpAnalyse = function ( options ) {
56
  );
57
  };
58
 
59
- var initialise = function () {
60
 
61
  jQuery( '#TabsIps a[data-toggle="tab"]' ).on( 'show.bs.tab', function ( e ) {
62
  clearAnalyseIpParam();
63
  localStorage.setItem( 'ipsActiveTab', jQuery( e.target ).attr( 'href' ) );
64
  } );
65
 
66
- jQuery( document ).ready( function () {
67
-
68
- let $ipActions = jQuery( document ).on( 'click', 'a.ip_analyse_action', function ( evt ) {
69
- evt.preventDefault();
70
- if ( confirm( 'Are you sure?' ) ) {
71
- let $oThis = jQuery( this );
72
- let params = aOpts[ 'ajax_ip_analyse_action' ];
73
- params.ip = $oThis.data( 'ip' );
74
- params.ip_action = $oThis.data( 'ip_action' );
75
- iCWP_WPSF_StandardAjax.send_ajax_req( params );
76
- }
77
- return false;
78
- } );
79
-
80
- $ipSelect.on( 'change', runAnalysis );
81
-
82
- let urlParams = new URLSearchParams( window.location.search );
83
- let theIP = urlParams.get( 'analyse_ip' );
84
- if ( theIP ) {
85
 
86
- /**
87
- * Since using dynamic AJAX requests to filter IP list,
88
- * we must manually create an option and select it
89
- */
90
- if ( $ipSelect.find( "option[value='" + theIP + "']" ).length === 0 ) {
91
- $ipSelect.append( new Option( theIP, theIP, true, true ) ).trigger( 'change' );
92
- }
93
- $ipSelect.val( theIP );
 
 
 
 
94
  }
95
- else {
96
- let activeTab = localStorage.getItem( 'ipsActiveTab' );
97
- if ( activeTab ) {
98
- jQuery( 'a[href="' + activeTab + '"]' ).tab( 'show' );
99
- }
 
100
  }
101
-
102
- } );
103
  };
104
 
105
- var $ipSelect = jQuery( '#IpReviewSelect' );
106
- var aOpts = jQuery.extend( {}, options );
107
  initialise();
108
 
109
  return this;
1
  jQuery.fn.icwpWpsfIpAnalyse = function ( options ) {
2
 
3
+ let runAnalysis = function () {
4
+ let $ipSelect = jQuery( ipReviewSelector );
5
  let newUrl = window.location.href.replace( /&analyse_ip=.+/i, "" );
6
  if ( $ipSelect.val() && $ipSelect.val().length > 0 ) {
7
  newUrl += "&analyse_ip=" + $ipSelect.val();
28
 
29
  jQuery( '#IpReviewContent' ).html( 'loading IP info ...' );
30
 
31
+ let reqData = opts[ 'ip_analyse_build' ];
32
  jQuery.post( ajaxurl, jQuery.extend( reqData, params ),
33
  function ( response ) {
34
 
57
  );
58
  };
59
 
60
+ let initialise = function () {
61
 
62
  jQuery( '#TabsIps a[data-toggle="tab"]' ).on( 'show.bs.tab', function ( e ) {
63
  clearAnalyseIpParam();
64
  localStorage.setItem( 'ipsActiveTab', jQuery( e.target ).attr( 'href' ) );
65
  } );
66
 
67
+ jQuery( document ).on( 'click', 'a.ip_analyse_action', function ( evt ) {
68
+ evt.preventDefault();
69
+ if ( confirm( 'Are you sure?' ) ) {
70
+ let $this = jQuery( this );
71
+ let params = opts[ 'ip_analyse_action' ];
72
+ params.ip = $this.data( 'ip' );
73
+ params.ip_action = $this.data( 'ip_action' );
74
+ iCWP_WPSF_StandardAjax.send_ajax_req( params );
75
+ }
76
+ return false;
77
+ } );
 
 
 
 
 
 
 
 
78
 
79
+ jQuery( document ).on( 'change', ipReviewSelector, runAnalysis );
80
+
81
+ let urlParams = new URLSearchParams( window.location.search );
82
+ let theIP = urlParams.get( 'analyse_ip' );
83
+ if ( theIP ) {
84
+ let $ipSelect = jQuery( ipReviewSelector );
85
+ /**
86
+ * Since using dynamic AJAX requests to filter IP list,
87
+ * we must manually create an option and select it
88
+ */
89
+ if ( $ipSelect.find( "option[value='" + theIP + "']" ).length === 0 ) {
90
+ $ipSelect.append( new Option( theIP, theIP, true, true ) ).trigger( 'change' );
91
  }
92
+ $ipSelect.val( theIP );
93
+ }
94
+ else {
95
+ let activeTab = localStorage.getItem( 'ipsActiveTab' );
96
+ if ( activeTab ) {
97
+ jQuery( 'a[href="' + activeTab + '"]' ).tab( 'show' );
98
  }
99
+ }
 
100
  };
101
 
102
+ let opts = jQuery.extend( {}, options );
103
+ let ipReviewSelector = '#IpReviewSelect';
104
  initialise();
105
 
106
  return this;
resources/js/shield/tables.js CHANGED
@@ -10,26 +10,25 @@ jQuery.fn.icwpWpsfTableWithFilter = function ( aOptions ) {
10
  jQuery( 'input[type=checkbox]', $oForm ).each( function () {
11
  jQuery( this ).prop( 'checked', false );
12
  } );
13
- aOpts[ 'table' ].renderTableFromForm( $oForm );
14
  };
15
 
16
  var submitFilters = function ( evt ) {
17
  evt.preventDefault();
18
- aOpts[ 'table' ].renderTableFromForm( $oForm );
19
  return false;
20
  };
21
 
22
  var initialise = function () {
23
  jQuery( document ).ready( function () {
24
- $oForm = jQuery( aOpts[ 'selector_filter_form' ] );
25
  $oForm.on( 'submit', submitFilters );
26
  $oForm.on( 'click', 'a#ClearForm', resetFilters );
27
  } );
28
  };
29
 
30
- var $oThis = this;
31
- var aOpts = jQuery.extend( {}, aOptions );
32
- var $oForm;
33
  initialise();
34
 
35
  return this;
10
  jQuery( 'input[type=checkbox]', $oForm ).each( function () {
11
  jQuery( this ).prop( 'checked', false );
12
  } );
13
+ opts[ 'table' ].renderTableFromForm( $oForm );
14
  };
15
 
16
  var submitFilters = function ( evt ) {
17
  evt.preventDefault();
18
+ opts[ 'table' ].renderTableFromForm( $oForm );
19
  return false;
20
  };
21
 
22
  var initialise = function () {
23
  jQuery( document ).ready( function () {
24
+ $oForm = jQuery( opts[ 'selector_filter_form' ] );
25
  $oForm.on( 'submit', submitFilters );
26
  $oForm.on( 'click', 'a#ClearForm', resetFilters );
27
  } );
28
  };
29
 
30
+ let opts = jQuery.extend( {}, aOptions );
31
+ let $oForm;
 
32
  initialise();
33
 
34
  return this;
src/lib/src/Controller/Controller.php CHANGED
@@ -12,22 +12,22 @@ 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
@@ -122,6 +122,8 @@ class Controller extends DynPropertiesClass {
122
  public function __get( string $key ) {
123
  $val = parent::__get( $key );
124
 
 
 
125
  switch ( $key ) {
126
 
127
  case 'flags':
@@ -150,11 +152,17 @@ class Controller extends DynPropertiesClass {
150
  case 'modules_loaded':
151
  case 'plugin_deactivating':
152
  case 'plugin_deleting':
153
- case 'plugin_reset':
154
  case 'user_can_base_permissions':
155
  $val = (bool)$val;
156
  break;
157
 
 
 
 
 
 
 
 
158
  case 'is_rest_enabled':
159
  if ( is_null( $val ) ) {
160
  $restReqs = $this->cfg->reqs_rest;
@@ -898,11 +906,10 @@ class Controller extends DynPropertiesClass {
898
 
899
  protected function deleteFlags() {
900
  $FS = Services::WpFs();
901
- if ( $FS->exists( $this->paths->forFlag( 'rebuild' ) ) ) {
902
- $FS->deleteFile( $this->paths->forFlag( 'rebuild' ) );
903
- }
904
- if ( $this->getIsResetPlugin() ) {
905
- $FS->deleteFile( $this->paths->forFlag( 'reset' ) );
906
  }
907
  }
908
 
@@ -1066,6 +1073,9 @@ class Controller extends DynPropertiesClass {
1066
  return strpos( Services::WpGeneral()->getCurrentWpAdminPage(), $this->getPluginPrefix() ) === 0;
1067
  }
1068
 
 
 
 
1069
  public function getIsResetPlugin() :bool {
1070
  if ( !isset( $this->plugin_reset ) ) {
1071
  $this->plugin_reset = Services::WpFs()->isFile( $this->paths->forFlag( 'reset' ) );
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
122
  public function __get( string $key ) {
123
  $val = parent::__get( $key );
124
 
125
+ $FS = Services::WpFs();
126
+
127
  switch ( $key ) {
128
 
129
  case 'flags':
152
  case 'modules_loaded':
153
  case 'plugin_deactivating':
154
  case 'plugin_deleting':
 
155
  case 'user_can_base_permissions':
156
  $val = (bool)$val;
157
  break;
158
 
159
+ case 'plugin_reset':
160
+ if ( is_null( $val ) ) {
161
+ $val = $FS->isFile( $this->paths->forFlag( 'reset' ) );
162
+ $this->plugin_reset = $val;
163
+ }
164
+ break;
165
+
166
  case 'is_rest_enabled':
167
  if ( is_null( $val ) ) {
168
  $restReqs = $this->cfg->reqs_rest;
906
 
907
  protected function deleteFlags() {
908
  $FS = Services::WpFs();
909
+ foreach ( [ 'rebuild', 'reset' ] as $flag ) {
910
+ if ( $FS->exists( $this->paths->forFlag( $flag ) ) ) {
911
+ $FS->deleteFile( $this->paths->forFlag( $flag ) );
912
+ }
 
913
  }
914
  }
915
 
1073
  return strpos( Services::WpGeneral()->getCurrentWpAdminPage(), $this->getPluginPrefix() ) === 0;
1074
  }
1075
 
1076
+ /**
1077
+ * @deprecated 15.1
1078
+ */
1079
  public function getIsResetPlugin() :bool {
1080
  if ( !isset( $this->plugin_reset ) ) {
1081
  $this->plugin_reset = Services::WpFs()->isFile( $this->paths->forFlag( 'reset' ) );
src/lib/src/Modules/Base/ModCon.php CHANGED
@@ -719,7 +719,7 @@ abstract class ModCon extends DynPropertiesClass {
719
  $con = $this->getCon();
720
  add_filter( $con->prefix( 'bypass_is_plugin_admin' ), '__return_true', 1000 );
721
  $this->getOptions()
722
- ->doOptionsSave( $con->getIsResetPlugin(), $this->isPremium() );
723
  remove_filter( $con->prefix( 'bypass_is_plugin_admin' ), '__return_true', 1000 );
724
  }
725
 
719
  $con = $this->getCon();
720
  add_filter( $con->prefix( 'bypass_is_plugin_admin' ), '__return_true', 1000 );
721
  $this->getOptions()
722
+ ->doOptionsSave( $con->plugin_reset, $this->isPremium() );
723
  remove_filter( $con->prefix( 'bypass_is_plugin_admin' ), '__return_true', 1000 );
724
  }
725
 
src/lib/src/Modules/Base/Options/Storage.php CHANGED
@@ -24,7 +24,7 @@ class Storage {
24
  * @throws \Exception
25
  */
26
  public function loadOptions() :array {
27
- if ( $this->getCon()->getIsResetPlugin() ) {
28
  throw new \Exception( 'Resetting plugin - not loading stored options' );
29
  }
30
  return $this->loadFromWP();
24
  * @throws \Exception
25
  */
26
  public function loadOptions() :array {
27
+ if ( $this->getCon()->plugin_reset ) {
28
  throw new \Exception( 'Resetting plugin - not loading stored options' );
29
  }
30
  return $this->loadFromWP();
src/lib/src/Modules/HackGuard/Scan/Queue/CleanQueue.php CHANGED
@@ -15,6 +15,7 @@ class CleanQueue extends ExecOnceModConsumer {
15
  protected function run() {
16
  $this->resetStaleScanItems();
17
  $this->deleteStaleScans();
 
18
  }
19
 
20
  private function resetStaleScanItems() {
@@ -36,6 +37,24 @@ class CleanQueue extends ExecOnceModConsumer {
36
  $this->deleteScansWithNoScanItems();
37
  }
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  /**
40
  * Stale: Scan has been ready for 20 minutes
41
  */
15
  protected function run() {
16
  $this->resetStaleScanItems();
17
  $this->deleteStaleScans();
18
+ $this->deleteStaleResultItems();
19
  }
20
 
21
  private function resetStaleScanItems() {
37
  $this->deleteScansWithNoScanItems();
38
  }
39
 
40
+ private function deleteStaleResultItems() {
41
+ /** @var ModCon $mod */
42
+ $mod = $this->getMod();
43
+ $resultItemIds = $mod->getDbH_ScanResults()
44
+ ->getQuerySelector()
45
+ ->getDistinctForColumn( 'resultitem_ref' );
46
+ if ( !empty( $resultItemIds ) ) {
47
+ $dbhResultsItems = $mod->getDbH_ResultItems();
48
+ // 1. Get IDs for all scan items
49
+ Services::WpDb()->doSql(
50
+ sprintf( "DELETE FROM `%s` WHERE `id` NOT IN (%s)",
51
+ $dbhResultsItems->getTableSchema()->table,
52
+ implode( ',', $resultItemIds )
53
+ )
54
+ );
55
+ }
56
+ }
57
+
58
  /**
59
  * Stale: Scan has been ready for 20 minutes
60
  */
src/lib/src/Modules/IPs/AjaxHandler.php CHANGED
@@ -227,14 +227,14 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
227
  if ( !$validIP ) {
228
  $msg = __( "IP provided was invalid.", 'wp-simple-firewall' );
229
  }
230
- elseif ( !in_array( $ipKey, [ IpID::UNKNOWN, IpID::VISITOR ] ) ) {
231
- $msg = sprintf( __( "IP can't be processed from this page as it's a known service IP: %s" ), $ipName );
232
- }
233
  else {
234
  switch ( $req->post( 'ip_action' ) ) {
235
 
236
  case 'block':
237
  try {
 
 
 
238
  $success = ( new Ops\AddIp() )
239
  ->setMod( $this->getMod() )
240
  ->setIP( $ip )
227
  if ( !$validIP ) {
228
  $msg = __( "IP provided was invalid.", 'wp-simple-firewall' );
229
  }
 
 
 
230
  else {
231
  switch ( $req->post( 'ip_action' ) ) {
232
 
233
  case 'block':
234
  try {
235
+ if ( !in_array( $ipKey, [ IpID::UNKNOWN, IpID::VISITOR ] ) ) {
236
+ throw new \Exception( sprintf( __( "IP can't be blocked from this page as it's a known service IP: %s" ), $ipName ) );
237
+ }
238
  $success = ( new Ops\AddIp() )
239
  ->setMod( $this->getMod() )
240
  ->setIP( $ip )
src/lib/src/Modules/IPs/ModCon.php CHANGED
@@ -142,9 +142,16 @@ class ModCon extends BaseShield\ModCon {
142
  'icwp_wpsf_vars_ips',
143
  [
144
  'components' => [
145
- 'modal_ip_analysis' => [
146
  'ajax' => [
147
- 'render_ip_analysis' => $this->getAjaxActionData( 'render_ip_analysis' )
 
 
 
 
 
 
 
148
  ]
149
  ],
150
  ],
142
  'icwp_wpsf_vars_ips',
143
  [
144
  'components' => [
145
+ 'modal_ip_analysis' => [
146
  'ajax' => [
147
+ 'render_ip_analysis' => $this->getAjaxActionData( 'render_ip_analysis' ),
148
+ ]
149
+ ],
150
+ 'ip_analysis' => [
151
+ 'ajax' => [
152
+ 'ip_analyse_build' => $this->getAjaxActionData( 'ip_analyse_build' ),
153
+ 'ip_analyse_action' => $this->getAjaxActionData( 'ip_analyse_action' ),
154
+ 'ip_review_select' => $this->getAjaxActionData( 'ip_review_select' ),
155
  ]
156
  ],
157
  ],
src/lib/src/Modules/Insights/ModCon.php CHANGED
@@ -161,9 +161,6 @@ class ModCon extends BaseShield\ModCon {
161
  if ( in_array( $inav, [ 'scans_results', 'scans_run' ] ) ) {
162
  $enq[ Enqueue::JS ][] = 'shield/scans';
163
  }
164
- elseif ( $inav == 'ips' ) {
165
- $enq[ Enqueue::JS ][] = 'shield/ipanalyse';
166
- }
167
  break;
168
  }
169
  }
161
  if ( in_array( $inav, [ 'scans_results', 'scans_run' ] ) ) {
162
  $enq[ Enqueue::JS ][] = 'shield/scans';
163
  }
 
 
 
164
  break;
165
  }
166
  }
src/lib/src/Modules/License/Lib/LicenseHandler.php CHANGED
@@ -131,14 +131,12 @@ class LicenseHandler extends Modules\Base\Common\ExecOnceModConsumer {
131
  public function getRegistrationExpiresAt() :int {
132
  /** @var ModCon $mod */
133
  $mod = $this->getMod();
134
- $opts = $this->getOptions();
135
 
136
- $verifiedExpiredDays = rand( 9, 14 ) /* $this->getLicVerifyExpireDays() */
137
- + $opts->getDef( 'lic_verify_expire_grace_days' );
138
 
139
  $lic = $mod->getLicenseHandler()->getLicense();
140
  return (int)min(
141
- $lic->getExpiresAt() + $opts->getDef( 'lic_verify_expire_grace_days' )*DAY_IN_SECONDS,
142
  $lic->last_verified_at + $verifiedExpiredDays*DAY_IN_SECONDS
143
  );
144
  }
@@ -163,14 +161,12 @@ class LicenseHandler extends Modules\Base\Common\ExecOnceModConsumer {
163
 
164
  public function isLastVerifiedExpired() :bool {
165
  return ( Services::Request()->ts() - $this->getLicense()->last_verified_at )
166
- > rand( 9, 14 )*DAY_IN_SECONDS; /* $this->getLicVerifyExpireDays() */
167
  }
168
 
169
  public function isLastVerifiedGraceExpired() :bool {
170
- $opts = $this->getOptions();
171
- $grace = ( rand( 9, 14 ) /* $this->getLicVerifyExpireDays() */
172
- + $opts->getDef( 'lic_verify_expire_grace_days' ) )*DAY_IN_SECONDS;
173
- return ( Services::Request()->ts() - $this->getLicense()->last_verified_at ) > $grace;
174
  }
175
 
176
  private function isMaybeExpiring() :bool {
@@ -218,14 +214,14 @@ class LicenseHandler extends Modules\Base\Common\ExecOnceModConsumer {
218
  }
219
 
220
  private function canLicenseCheck_FileFlag() :bool {
221
- $mtime = Services::WpFs()->getModifiedTime(
222
- $this->getCon()->paths->forFlag( 'license_check' )
223
- );
224
  return ( Services::Request()->ts() - $mtime ) > MINUTE_IN_SECONDS;
225
  }
226
 
227
  private function getLicVerifyExpireDays() :int {
228
- return (int)rand( 9, 14 );
229
  }
230
 
231
  private function getLicExpireGraceDays() :int {
131
  public function getRegistrationExpiresAt() :int {
132
  /** @var ModCon $mod */
133
  $mod = $this->getMod();
 
134
 
135
+ $verifiedExpiredDays = $this->getLicVerifyExpireDays() + $this->getLicExpireGraceDays();
 
136
 
137
  $lic = $mod->getLicenseHandler()->getLicense();
138
  return (int)min(
139
+ $lic->getExpiresAt() + $this->getLicExpireGraceDays()*DAY_IN_SECONDS,
140
  $lic->last_verified_at + $verifiedExpiredDays*DAY_IN_SECONDS
141
  );
142
  }
161
 
162
  public function isLastVerifiedExpired() :bool {
163
  return ( Services::Request()->ts() - $this->getLicense()->last_verified_at )
164
+ > $this->getLicVerifyExpireDays()*DAY_IN_SECONDS;
165
  }
166
 
167
  public function isLastVerifiedGraceExpired() :bool {
168
+ return ( Services::Request()->ts() - $this->getLicense()->last_verified_at )
169
+ > ( DAY_IN_SECONDS*( $this->getLicVerifyExpireDays() + $this->getLicExpireGraceDays() ) );
 
 
170
  }
171
 
172
  private function isMaybeExpiring() :bool {
214
  }
215
 
216
  private function canLicenseCheck_FileFlag() :bool {
217
+ $FS = Services::WpFs();
218
+ $path = $this->getCon()->paths->forFlag( 'license_check' );
219
+ $mtime = $FS->exists( $path ) ? $FS->getModifiedTime( $path ) : 0;
220
  return ( Services::Request()->ts() - $mtime ) > MINUTE_IN_SECONDS;
221
  }
222
 
223
  private function getLicVerifyExpireDays() :int {
224
+ return (int)wp_rand( 9, 14 );
225
  }
226
 
227
  private function getLicExpireGraceDays() :int {
src/lib/src/Scans/Afs/FileScanner.php CHANGED
@@ -135,6 +135,13 @@ class FileScanner {
135
  }
136
  }
137
 
 
 
 
 
 
 
 
138
  return $item;
139
  }
140
 
135
  }
136
  }
137
 
138
+ // If there's no result item, and the file is marked as 'valid', we mark it for optimisation in future scans.
139
+ if ( empty( $item ) && $validFile ) {
140
+ $validFiles = is_array( $action->valid_files ) ? $action->valid_files : [];
141
+ $validFiles[] = $fullPath;
142
+ $action->valid_files = $validFiles;
143
+ }
144
+
145
  return $item;
146
  }
147
 
src/lib/src/Scans/Afs/Processing/FileScanOptimiser.php CHANGED
@@ -12,24 +12,40 @@ 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
  }
@@ -129,44 +145,6 @@ class FileScanOptimiser {
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
  }
12
 
13
  use Modules\ModConsumer;
14
 
15
+ public function addFiles( array $files ) {
16
+ $FS = Services::WpFs();
17
+ if ( $this->getCon()->cache_dir_handler->dirExists() && !empty( $files ) ) {
18
+ $pathToHashes = $this->pathToHashes();
19
+ if ( !$FS->exists( $pathToHashes ) ) {
20
+ $FS->touch( $pathToHashes );
21
+ }
22
+ if ( $FS->exists( $pathToHashes ) ) {
23
+ $fileHashes = array_unique( array_filter( array_map(
24
+ function ( $file ) {
25
+ return hash_file( 'md5', $file );
26
+ },
27
+ array_filter(
28
+ $files,
29
+ function ( $file ) {
30
+ return Services::WpFs()->exists( $file );
31
+ }
32
+ )
33
+ ) ) );
34
 
35
+ try {
36
+ $searcher = new SearchFile( $pathToHashes );
37
+ $allNotFoundHashes = array_diff(
38
+ $fileHashes,
39
+ array_keys( array_filter( $searcher->multipleExists( $fileHashes ) ) )
40
+ );
41
+ file_put_contents(
42
+ $pathToHashes,
43
+ sprintf( '%s:%s', Services::Request()->ts(), implode( ',', $allNotFoundHashes )."\n" ),
44
+ FILE_APPEND
45
+ );
46
+ }
47
+ catch ( \Exception $e ) {
48
+ }
49
  }
50
  }
51
  }
145
  }
146
  }
147
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  public function pathToHashes() :string {
149
  return path_join( $this->getCon()->cache_dir_handler->build(), 'file_scan_hashes.txt' );
150
  }
src/lib/src/Scans/Afs/Scan.php CHANGED
@@ -60,13 +60,13 @@ class Scan extends Shield\Scans\Base\BaseScan {
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
  }
60
  protected function postScan() {
61
  /** @var HackGuard\Options $opts */
62
  $opts = $this->getOptions();
63
+ /** @var ScanActionVO $action */
64
+ $action = $this->getScanActionVO();
65
 
66
+ if ( $opts->isOpt( 'optimise_scan_speed', 'Y' ) && is_array( $action->valid_files ) ) {
 
 
67
  ( new Processing\FileScanOptimiser() )
68
  ->setMod( $this->getMod() )
69
+ ->addFiles( $action->valid_files );
70
  }
71
  }
72
  }
src/lib/src/Scans/Afs/ScanActionVO.php CHANGED
@@ -13,6 +13,7 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\BaseScanActionVO;
13
  * @property string[] $patterns_regex
14
  * @property string[] $patterns_simple
15
  * @property int $confidence_threshold
 
16
  */
17
  class ScanActionVO extends BaseScanActionVO {
18
 
13
  * @property string[] $patterns_regex
14
  * @property string[] $patterns_simple
15
  * @property int $confidence_threshold
16
+ * @property string[] $valid_files
17
  */
18
  class ScanActionVO extends BaseScanActionVO {
19
 
templates/twig/wpadmin_pages/insights/ips/ip_analyse/index.twig CHANGED
@@ -26,17 +26,4 @@
26
  <div class="alert alert-info mb-0">{{ strings.please_select }}</div>
27
  </div>
28
  </div>
29
- </div>
30
-
31
- {% block section_table_js %}
32
- <script type="text/javascript">
33
- jQuery( document ).ready( function () {
34
- jQuery( 'document' ).icwpWpsfIpAnalyse(
35
- {
36
- 'ajax_ip_analyse_build':{{ ajax.ip_analyse_build|raw }},
37
- 'ajax_ip_analyse_action':{{ ajax.ip_analyse_action|raw }}
38
- }
39
- );
40
- } );
41
- </script>
42
- {% endblock %}
26
  <div class="alert alert-info mb-0">{{ strings.please_select }}</div>
27
  </div>
28
  </div>
29
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
templates/twig/wpadmin_pages/insights/ips/ips_base.twig CHANGED
@@ -1,4 +1,3 @@
1
-
2
  {% block section_pre_table %}
3
  {% endblock %}
4
 
 
1
  {% block section_pre_table %}
2
  {% endblock %}
3
 
templates/twig/wpadmin_pages/insights/ips/ips_black.twig CHANGED
@@ -91,7 +91,7 @@
91
 
92
  {% block section_table_js %}
93
  <script>
94
- var $oTableIpsBlack = jQuery( '#TableIpsBlack' ).icwpWpsfAjaxTable(
95
  {
96
  'ajax_render':{{ ajax.render_table_ip|raw }},
97
  'req_params': {
91
 
92
  {% block section_table_js %}
93
  <script>
94
+ let $oTableIpsBlack = jQuery( '#TableIpsBlack' ).icwpWpsfAjaxTable(
95
  {
96
  'ajax_render':{{ ajax.render_table_ip|raw }},
97
  'req_params': {
templates/twig/wpadmin_pages/insights/ips/ips_white.twig CHANGED
@@ -82,7 +82,7 @@
82
 
83
  {% block section_table_js %}
84
  <script>
85
- var $oTableIpsWhite = jQuery( '#TableIpsWhite' ).icwpWpsfAjaxTable(
86
  {
87
  'ajax_render':{{ ajax.render_table_ip|raw }},
88
  'req_params': {
82
 
83
  {% block section_table_js %}
84
  <script>
85
+ let $oTableIpsWhite = jQuery( '#TableIpsWhite' ).icwpWpsfAjaxTable(
86
  {
87
  'ajax_render':{{ ajax.render_table_ip|raw }},
88
  'req_params': {