Shield Security for WordPress - Version 16.1.5

Version Description

Download this release

Release Info

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

Code changes from version 16.1.4 to 16.1.5

Files changed (49) hide show
  1. cl.json +37 -0
  2. config/deprecated/firewall.php +2 -1
  3. config/firewall.json +2 -1
  4. icwp-wpsf.php +1 -1
  5. plugin-spec.php +6 -3
  6. plugin.json +6 -3
  7. readme.txt +1 -1
  8. resources/js/shield/integrations/mainwp-server.js +21 -15
  9. resources/js/tp/qrcode.min.js +2 -0
  10. src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/BuildEncryptedFilePayload.php +1 -1
  11. src/lib/src/Modules/HackGuard/Lib/Reports/Query/ScanCounts.php +3 -0
  12. src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/Base.php +39 -1
  13. src/lib/src/Modules/HackGuard/ModCon.php +1 -1
  14. src/lib/src/Modules/HackGuard/Scan/Results/Counts.php +14 -0
  15. src/lib/src/Modules/IPs/Lib/CrowdSec/Signals/EventsToSignals.php +14 -5
  16. src/lib/src/Modules/Insights/ModCon.php +11 -0
  17. src/lib/src/Modules/Integrations/Lib/MainWP/Client/Actions/Init.php +1 -1
  18. src/lib/src/Modules/Integrations/Lib/MainWP/Common/MWPExtensionVO.php +0 -31
  19. src/lib/src/Modules/Integrations/Lib/MainWP/Common/MWPSiteVO.php +0 -2
  20. src/lib/src/Modules/Integrations/Lib/MainWP/Controller.php +7 -3
  21. src/lib/src/Modules/Integrations/Lib/MainWP/Server/Actions/Action.php +0 -3
  22. src/lib/src/Modules/Integrations/Lib/MainWP/Server/Ajax/AjaxHandlerMainwp.php +2 -2
  23. src/lib/src/Modules/Integrations/Lib/MainWP/Server/Data/SyncHandler.php +0 -1
  24. src/lib/src/Modules/Integrations/Lib/MainWP/Server/Init.php +29 -12
  25. src/lib/src/Modules/Integrations/Lib/MainWP/Server/MwpExtensionLoader.php +19 -0
  26. src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/BaseRender.php +11 -1
  27. src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/ExtensionSettingsPage.php +22 -22
  28. src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/ManageSites/SitesListTableHandler.php +14 -13
  29. src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/BaseTab.php +70 -0
  30. src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/MwpOutOfDate.php +29 -0
  31. src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/NotShieldPro.php +22 -0
  32. src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/PluginOutOfDate.php +24 -0
  33. src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/SiteManageFrame.php +146 -0
  34. src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/SitesList.php +157 -0
  35. src/lib/src/Modules/License/AdminNotices.php +1 -1
  36. src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/GoogleAuth.php +10 -11
  37. src/lib/src/Modules/Plugin/Debug.php +1 -1
  38. src/lib/src/Modules/Traffic/Rules/Build/IsRateLimitExceeded.php +4 -0
  39. src/lib/src/Scans/Afs/Processing/MalFalsePositiveReporter.php +1 -0
  40. src/lib/vendor/composer/autoload_classmap.php +7 -4
  41. src/lib/vendor/composer/autoload_static.php +7 -4
  42. src/lib/vendor/composer/installed.json +6 -6
  43. src/lib/vendor/composer/installed.php +5 -5
  44. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Encrypt/OpenSslEncrypt.php +7 -4
  45. templates/twig/admin/user/profile/mfa/mfa_ga.twig +7 -5
  46. templates/twig/integration/mainwp/page_extension.twig +0 -12
  47. templates/twig/integration/mainwp/pages/page_base.twig +38 -0
  48. templates/twig/integration/mainwp/pages/site.twig +8 -0
  49. templates/twig/integration/mainwp/pages/sites.twig +174 -140
cl.json CHANGED
@@ -127,6 +127,43 @@
127
  }
128
  ],
129
  "patches": [
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  {
131
  "version": "4",
132
  "released_at": 1663064000,
127
  }
128
  ],
129
  "patches": [
130
+ {
131
+ "version": "5",
132
+ "released_at": 1663236000,
133
+ "items": [
134
+ {
135
+ "title": "Improvements to MainWP Extension",
136
+ "type": "improved",
137
+ "description": [
138
+ "As part of our plans to enhance our MainWP extension we've made a number of fixes and tweaks."
139
+ ]
140
+ },
141
+ {
142
+ "title": "Obscure Access To Local Plugin/Theme Hashes",
143
+ "type": "security",
144
+ "description": [
145
+ "It was pointed out that the storage of plugin/theme hashes locally were accessible on nginx servers.",
146
+ "It made info publicly available about which plugins/themes were installed, for some sites. Not a security problem in itself, but not ideal either."
147
+ ]
148
+ },
149
+ {
150
+ "title": "QR Code Rendered Locally.",
151
+ "type": "security",
152
+ "description": [
153
+ "It was pointed out that there are other means of generating QR codes that are preferrable to sending data to Google's API.",
154
+ "QR Code images are now rendered locally on the browser using Javascript."
155
+ ]
156
+ },
157
+ {
158
+ "title": "Logged-In User Won't Be Rated Limited.",
159
+ "type": "change",
160
+ "description": [
161
+ "If you're logged-into a site, and you trigger the rate limiter, you won't be limited.",
162
+ "You may still trigger the rate limiter if you issue non-authenticated requests, such a REST API requests."
163
+ ]
164
+ }
165
+ ]
166
+ },
167
  {
168
  "version": "4",
169
  "released_at": 1663064000,
config/deprecated/firewall.php CHANGED
@@ -320,7 +320,8 @@
320
  "spd-custhash",
321
  "joe-custinfo",
322
  "_wpcf7cf_hidden_group_fields",
323
- "wl_homeurl"
 
324
  ]
325
  }
326
  },
320
  "spd-custhash",
321
  "joe-custinfo",
322
  "_wpcf7cf_hidden_group_fields",
323
+ "wl_homeurl",
324
+ "where"
325
  ]
326
  }
327
  },
config/firewall.json CHANGED
@@ -320,7 +320,8 @@
320
  "spd-custhash",
321
  "joe-custinfo",
322
  "_wpcf7cf_hidden_group_fields",
323
- "wl_homeurl"
 
324
  ]
325
  }
326
  },
320
  "spd-custhash",
321
  "joe-custinfo",
322
  "_wpcf7cf_hidden_group_fields",
323
+ "wl_homeurl",
324
+ "where"
325
  ]
326
  }
327
  },
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: 16.1.4
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: 16.1.5
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": "16.1.4",
4
- "release_timestamp": 1663064000,
5
- "build": "202209.1302",
6
  "slug_parent": "icwp",
7
  "slug_plugin": "wpsf",
8
  "text_domain": "wp-simple-firewall",
@@ -196,6 +196,8 @@
196
  "wp-jquery"
197
  ]
198
  },
 
 
199
  "plugin": {
200
  "deps": [
201
  "bootstrap",
@@ -329,6 +331,7 @@
329
  "shield/userprofile": {
330
  "deps": [
331
  "u2f-bundle",
 
332
  "shield/dialog"
333
  ],
334
  "footer": true
1
  {
2
  "properties": {
3
+ "version": "16.1.5",
4
+ "release_timestamp": 1663236000,
5
+ "build": "202209.1501",
6
  "slug_parent": "icwp",
7
  "slug_plugin": "wpsf",
8
  "text_domain": "wp-simple-firewall",
196
  "wp-jquery"
197
  ]
198
  },
199
+ "tp/qrcode.min": {
200
+ },
201
  "plugin": {
202
  "deps": [
203
  "bootstrap",
331
  "shield/userprofile": {
332
  "deps": [
333
  "u2f-bundle",
334
+ "tp/qrcode.min",
335
  "shield/dialog"
336
  ],
337
  "footer": true
plugin.json CHANGED
@@ -1,8 +1,8 @@
1
  {
2
  "properties": {
3
- "version": "16.1.4",
4
- "release_timestamp": 1663064000,
5
- "build": "202209.1302",
6
  "slug_parent": "icwp",
7
  "slug_plugin": "wpsf",
8
  "text_domain": "wp-simple-firewall",
@@ -196,6 +196,8 @@
196
  "wp-jquery"
197
  ]
198
  },
 
 
199
  "plugin": {
200
  "deps": [
201
  "bootstrap",
@@ -329,6 +331,7 @@
329
  "shield/userprofile": {
330
  "deps": [
331
  "u2f-bundle",
 
332
  "shield/dialog"
333
  ],
334
  "footer": true
1
  {
2
  "properties": {
3
+ "version": "16.1.5",
4
+ "release_timestamp": 1663236000,
5
+ "build": "202209.1501",
6
  "slug_parent": "icwp",
7
  "slug_plugin": "wpsf",
8
  "text_domain": "wp-simple-firewall",
196
  "wp-jquery"
197
  ]
198
  },
199
+ "tp/qrcode.min": {
200
+ },
201
  "plugin": {
202
  "deps": [
203
  "bootstrap",
331
  "shield/userprofile": {
332
  "deps": [
333
  "u2f-bundle",
334
+ "tp/qrcode.min",
335
  "shield/dialog"
336
  ],
337
  "footer": true
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: 16.1.4
12
 
13
  Bad Bots Are Your #1 Security Risk. Stop playing whack-a-mole with malware and vulnerabilities. Discover the advantage of putting real security before marketing.
14
 
8
  Requires PHP: 7.0
9
  Recommended PHP: 7.4
10
  Tested up to: 6.0
11
+ Stable tag: 16.1.5
12
 
13
  Bad Bots Are Your #1 Security Risk. Stop playing whack-a-mole with malware and vulnerabilities. Discover the advantage of putting real security before marketing.
14
 
resources/js/shield/integrations/mainwp-server.js CHANGED
@@ -1,6 +1,7 @@
1
  (function ( $, window, document, undefined ) {
2
 
3
- var pluginName = 'icwpWpsfMainwpExtension';
 
4
 
5
  function Ob_TableActions( element, options ) {
6
  this.element = element;
@@ -43,7 +44,7 @@
43
  evt.preventDefault();
44
 
45
  plugin.options[ 'req_params' ] = $.extend(
46
- plugin.options[ 'ajax_sh_site_action' ],
47
  {
48
  'sid': $( this ).parent().data( 'sid' ),
49
  'saction': $( this ).data( 'saction' )
@@ -69,23 +70,23 @@
69
  '.tablenav.top input[type=submit].button.action',
70
  function ( evt ) {
71
  evt.preventDefault();
72
- var sAction = $( '#bulk-action-selector-top', plugin.$element ).find( ":selected" ).val();
73
 
74
- if ( sAction === "-1" ) {
75
  alert( icwp_wpsf_vars_insights.strings.select_action );
76
  }
77
  else {
78
- var aCheckedIds = $( "input:checkbox[name=ids]:checked", plugin.$element ).map(
79
  function () {
80
  return $( this ).val()
81
  } ).get();
82
 
83
- if ( aCheckedIds.length < 1 ) {
84
  alert( 'No rows currently selected' );
85
  }
86
  else {
87
- plugin.options[ 'req_params' ][ 'bulk_action' ] = sAction;
88
- plugin.options[ 'req_params' ][ 'ids' ] = aCheckedIds;
89
  plugin.bulkAction.call( plugin );
90
  }
91
  }
@@ -98,16 +99,16 @@
98
  'button.action.custom-action',
99
  function ( evt ) {
100
  evt.preventDefault();
101
- var $oButt = $( this );
102
- var sCustomAction = $oButt.data( 'custom-action' );
103
- if ( sCustomAction in plugin.options[ 'custom_actions_ajax' ] ) {
104
- plugin.options[ 'working_custom_action' ] = plugin.options[ 'custom_actions_ajax' ][ sCustomAction ];
105
- plugin.options[ 'working_custom_action' ][ 'rid' ] = $oButt.data( 'rid' );
106
  plugin.customAction.call( plugin );
107
  }
108
  else {
109
  /** This should never be reached live: **/
110
- alert( 'custom action not supported: ' + sCustomAction );
111
  }
112
  }
113
  );
@@ -184,7 +185,7 @@
184
  "url": ajaxurl,
185
  "type": "POST",
186
  "data": function ( d ) {
187
- return $.extend( {}, d, this.options[ 'ajax_sh_site_action' ] );
188
  },
189
  "dataSrc": function ( json ) {
190
  for ( var i = 0, ien = json.data.length; i < ien; i++ ) {
@@ -198,6 +199,11 @@
198
  },
199
  } );
200
  */
 
 
 
 
 
201
  return this.each(
202
  function () {
203
  if ( !$.data( this, "plugin_" + pluginName ) ) {
1
  (function ( $, window, document, undefined ) {
2
 
3
+ let pluginName = 'icwpWpsfMainwpExtension';
4
+ let siteFrame;
5
 
6
  function Ob_TableActions( element, options ) {
7
  this.element = element;
44
  evt.preventDefault();
45
 
46
  plugin.options[ 'req_params' ] = $.extend(
47
+ plugin.options.ajax_actions[ 'site_action' ],
48
  {
49
  'sid': $( this ).parent().data( 'sid' ),
50
  'saction': $( this ).data( 'saction' )
70
  '.tablenav.top input[type=submit].button.action',
71
  function ( evt ) {
72
  evt.preventDefault();
73
+ let action = $( '#bulk-action-selector-top', plugin.$element ).find( ":selected" ).val();
74
 
75
+ if ( action === "-1" ) {
76
  alert( icwp_wpsf_vars_insights.strings.select_action );
77
  }
78
  else {
79
+ let checkedIds = $( "input:checkbox[name=ids]:checked", plugin.$element ).map(
80
  function () {
81
  return $( this ).val()
82
  } ).get();
83
 
84
+ if ( checkedIds.length < 1 ) {
85
  alert( 'No rows currently selected' );
86
  }
87
  else {
88
+ plugin.options[ 'req_params' ][ 'bulk_action' ] = action;
89
+ plugin.options[ 'req_params' ][ 'ids' ] = checkedIds;
90
  plugin.bulkAction.call( plugin );
91
  }
92
  }
99
  'button.action.custom-action',
100
  function ( evt ) {
101
  evt.preventDefault();
102
+ let $button = $( this );
103
+ let customAction = $button.data( 'custom-action' );
104
+ if ( customAction in plugin.options[ 'custom_actions_ajax' ] ) {
105
+ plugin.options[ 'working_custom_action' ] = plugin.options[ 'custom_actions_ajax' ][ customAction ];
106
+ plugin.options[ 'working_custom_action' ][ 'rid' ] = $button.data( 'rid' );
107
  plugin.customAction.call( plugin );
108
  }
109
  else {
110
  /** This should never be reached live: **/
111
+ alert( 'custom action not supported: ' + customAction );
112
  }
113
  }
114
  );
185
  "url": ajaxurl,
186
  "type": "POST",
187
  "data": function ( d ) {
188
+ return $.extend( {}, d, this.options.ajax_actions[ 'site_action' ] );
189
  },
190
  "dataSrc": function ( json ) {
191
  for ( var i = 0, ien = json.data.length; i < ien; i++ ) {
199
  },
200
  } );
201
  */
202
+ siteFrame = $( "iframe#SiteContent" );
203
+ if ( siteFrame.length === 1 ) {
204
+ siteFrame.attr( "srcdoc", "<p>This content was updated dynamically!</p>" );
205
+ }
206
+
207
  return this.each(
208
  function () {
209
  if ( !$.data( this, "plugin_" + pluginName ) ) {
resources/js/tp/qrcode.min.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ /** https://github.com/datalog/qrcode-svg under MIT license */
2
+ 'use strict';function QRCode(r){var n,t,o,e,a=[],f=[],i=Math.max,u=Math.min,h=Math.abs,v=Math.ceil,c=/^[0-9]*$/,s=/^[A-Z0-9 $%*+.\/:-]*$/,l="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:",g=[[-1,7,10,15,20,26,18,20,24,30,18,20,24,26,30,22,24,28,30,28,28,28,28,30,30,26,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30],[-1,10,16,26,18,24,16,18,22,22,26,30,22,22,24,24,28,28,26,26,26,26,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28],[-1,13,22,18,26,18,24,18,22,20,24,28,26,24,20,30,24,28,28,26,30,28,30,30,30,30,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30],[-1,17,28,22,16,22,28,26,26,24,28,24,28,22,24,24,30,28,28,26,28,30,24,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30]],d=[[-1,1,1,1,1,1,2,2,2,2,4,4,4,4,4,6,6,6,6,7,8,8,9,9,10,12,12,12,13,14,15,16,17,18,19,19,20,21,22,24,25],[-1,1,1,1,2,2,4,4,4,5,5,5,8,9,9,10,10,11,13,14,16,17,17,18,20,21,23,25,26,28,29,31,33,35,37,38,40,43,45,47,49],[-1,1,1,2,2,4,4,6,6,8,8,8,10,12,16,12,17,16,18,21,20,23,23,25,27,29,34,34,35,38,40,43,45,48,51,53,56,59,62,65,68],[-1,1,1,2,4,4,4,5,6,8,8,11,11,16,16,18,16,19,21,25,25,25,34,30,32,35,37,40,42,45,48,51,54,57,60,63,66,70,74,77,81]],m={L:[0,1],M:[1,0],Q:[2,3],H:[3,2]},p=function(r,n){for(var t=0,o=8;o--;)t=t<<1^285*(t>>>7)^(n>>>o&1)*r;return t},C=function(r,n){for(var t=[],o=r.length,e=o;e;)for(var a=r[o-e--]^t.shift(),f=n.length;f--;)t[f]^=p(n[f],a);return t},w=function(r){for(var n=[function(){return 0==(t+o)%2},function(){return 0==t%2},function(){return 0==o%3},function(){return 0==(t+o)%3},function(){return 0==((t/2|0)+(o/3|0))%2},function(){return 0==t*o%2+t*o%3},function(){return 0==(t*o%2+t*o%3)%2},function(){return 0==((t+o)%2+t*o%3)%2}][r],t=e;t--;)for(var o=e;o--;)f[t][o]||(a[t][o]^=n())},b=function(){for(var r=function(r,n){n[6]||(r+=e),n.shift(),n.push(r)},n=function(n,o,a){return n&&(r(o,a),o=0),r(o+=e,a),t(a)},t=function(r){var n=r[5],t=n>0&&r[4]==n&&r[3]==3*n&&r[2]==n&&r[1]==n;return(t&&r[6]>=4*n&&r[0]>=n?1:0)+(t&&r[0]>=4*n&&r[6]>=n?1:0)},o=0,f=e*e,i=0,u=e;u--;){for(var c=[0,0,0,0,0,0,0],s=[0,0,0,0,0,0,0],l=!1,g=!1,d=0,m=0,p=e;p--;){a[u][p]==l?5==++d?o+=3:d>5&&o++:(r(d,c),o+=40*t(c),d=1,l=a[u][p]),a[p][u]==g?5==++m?o+=3:m>5&&o++:(r(m,s),o+=40*t(s),m=1,g=a[p][u]);var C=a[u][p];C&&i++,p&&u&&C==a[u][p-1]&&C==a[u-1][p]&&C==a[u-1][p-1]&&(o+=3)}o+=40*n(l,d,c)+40*n(g,m,s)}return o+=10*(v(h(20*i-10*f)/f)-1)},A=function(r,n,t){for(;n--;)t.push(r>>>n&1)},M=function(r,n){return r.numBitsCharCount[(n+7)/17|0]},B=function(r,n){return 0!=(r>>>n&1)},x=function(r,n){for(var t=0,o=r.length;o--;){var e=r[o],a=M(e,n);if(1<<a<=e.numChars)return 1/0;t+=4+a+e.bitData.length}return t},D=function(r){if(r<1||r>40)throw"Version number out of range";var n=(16*r+128)*r+64;if(r>=2){var t=r/7|2;n-=(25*t-10)*t-55,r>=7&&(n-=36)}return n},I=function(r,n){for(var t=2;-2<=t;t--)for(var o=2;-2<=o;o--)E(r+o,n+t,1!=i(h(o),h(t)))},H=function(r,n){for(var t=4;-4<=t;t--)for(var o=4;-4<=o;o--){var a=i(h(o),h(t)),f=r+o,u=n+t;0<=f&&f<e&&0<=u&&u<e&&E(f,u,2!=a&&4!=a)}},$=function(r){for(var n=t[1]<<3|r,o=n,a=10;a--;)o=o<<1^1335*(o>>>9);var f=21522^(n<<10|o);if(f>>>15!=0)throw"Assertion error";for(a=0;a<=5;a++)E(8,a,B(f,a));E(8,7,B(f,6)),E(8,8,B(f,7)),E(7,8,B(f,8));for(a=9;a<15;a++)E(14-a,8,B(f,a));for(a=0;a<8;a++)E(e-1-a,8,B(f,a));for(a=8;a<15;a++)E(8,e-15+a,B(f,a));E(8,e-8,1)},O=function(){for(var r=e;r--;)E(6,r,0==r%2),E(r,6,0==r%2);for(var t=function(){var r=[];if(n>1)for(var t=2+(n/7|0),o=32==n?26:2*v((e-13)/(2*t-2));t--;)r[t]=t*o+6;return r}(),o=r=t.length;o--;)for(var a=r;a--;)0==a&&0==o||0==a&&o==r-1||a==r-1&&0==o||I(t[a],t[o]);H(3,3),H(e-4,3),H(3,e-4),$(0),function(){if(!(7>n)){for(var r=n,t=12;t--;)r=r<<1^7973*(r>>>11);var o=n<<12|r;if(t=18,o>>>18!=0)throw"Assertion error";for(;t--;){var a=e-11+t%3,f=t/3|0,i=B(o,t);E(a,f,i),E(f,a,i)}}}()},Q=function(r){if(r.length!=V(n,t))throw"Invalid argument";for(var o=d[t[0]][n],e=g[t[0]][n],a=D(n)/8|0,f=o-a%o,i=a/o|0,u=[],h=function(r){var n=1,t=[];t[r-1]=1;for(var o=0;o<r;o++){for(var e=0;e<r;e++)t[e]=p(t[e],n)^t[e+1];n=p(n,2)}return t}(e),v=0,c=0;v<o;v++){var s=r.slice(c,c+i-e+(v<f?0:1));c+=s.length;var l=C(s,h);v<f&&s.push(0),u.push(s.concat(l))}var m=[];for(v=0;v<u[0].length;v++)for(var w=0;w<u.length;w++)(v!=i-e||w>=f)&&m.push(u[w][v]);return m},S=function(r){for(var n=[],t=(r=encodeURI(r),0);t<r.length;t++)"%"!=r.charAt(t)?n.push(r.charCodeAt(t)):(n.push(parseInt(r.substr(t+1,2),16)),t+=2);return n},V=function(r,n){return(D(r)/8|0)-g[n[0]][r]*d[n[0]][r]},E=function(r,n,t){a[n][r]=t?1:0,f[n][r]=1},R=function(r){for(var n=[],t=0,o=r;t<o.length;t++){var e=o[t];A(e,8,n)}return{modeBits:4,numBitsCharCount:[8,16,16],numChars:r.length,bitData:n}},Z=function(r){if(!c.test(r))throw"String contains non-numeric characters";for(var n=[],t=0;t<r.length;){var o=u(r.length-t,3);A(parseInt(r.substr(t,o),10),3*o+1,n),t+=o}return{modeBits:1,numBitsCharCount:[10,12,14],numChars:r.length,bitData:n}},z=function(r){if(!s.test(r))throw"String contains unencodable characters in alphanumeric mode";var n,t=[];for(n=0;n+2<=r.length;n+=2){var o=45*l.indexOf(r.charAt(n));o+=l.indexOf(r.charAt(n+1)),A(o,11,t)}return n<r.length&&A(l.indexOf(r.charAt(n)),6,t),{modeBits:2,numBitsCharCount:[9,11,13],numChars:r.length,bitData:t}},L=function(r,n,t,o){var e=function(r){return""==r?[]:c.test(r)?[Z(r)]:s.test(r)?[z(r)]:[R(S(r))]}(r);return U(e,n,t,o)},N=function(r,i,u,h){t=i,o=h;for(var v=e=4*(n=r)+17;v--;)a[v]=[],f[v]=[];if(O(),function(r){for(var n=0,t=1,o=e-1,i=o;i>0;i-=2){6==i&&--i;for(var u=0>(t=-t)?o:0,h=0;h<e;++h){for(var v=i;v>i-2;--v)f[u][v]||(a[u][v]=B(r[n>>>3],7-(7&n)),++n);u+=t}}}(Q(u)),0>o){var c=1e9;for(v=8;v--;){w(v),$(v);var s=b();c>s&&(c=s,o=v),w(v)}}w(o),$(o),f=[]},U=function(r,n,t,o,e,a){if(void 0===e&&(e=1),void 0===a&&(a=40),void 0===o&&(o=-1),void 0===t&&(t=!0),!(1<=e&&e<=a&&a<=40)||o<-1||o>7)throw"Invalid value";for(var f=[],i=236,h=[],v=e;;){var c=x(r,v);if(c<=8*V(v,n))break;if(v>=a)throw"Data too long";v++}if(t)for(var s=(l=[m.H,m.Q,m.M]).length;s--;)c<=8*V(v,l[s])&&(n=l[s]);for(var l=0;l<r.length;l++){var g=r[l];A(g.modeBits,4,f),A(g.numChars,M(g,v),f);for(var d=0,p=g.bitData;d<p.length;d++)f.push(p[d])}if(f.length!=c)throw"Assertion error";var C=8*V(v,n);if(f.length>C)throw"Assertion error";if(A(0,u(4,C-f.length),f),A(0,(8-f.length%8)%8,f),f.length%8!=0)throw"Assertion error";for(;f.length<C;)A(i,8,f),i^=253;for(s=f.length;s--;)h[s>>>3]|=f[s]<<7-(7&s);return N(v,n,h,o)};return function(){function n(r){return/^#[0-9a-f]{3}(?:[0-9a-f]{3})?$/i.test(r)}function t(r,n){for(var t in r=document.createElementNS(s,r),n||{})r.setAttribute(t,n[t]);return r}var o,f,i,u,v,c,s="http://www.w3.org/2000/svg",l="",g="string"==typeof r?{msg:r}:r||{},d=g.pal||["#000"],p=h(g.dim)||256,C=[1,0,0,1,c=(c=h(g.pad))>-1?c:4,c],w=n(w=d[0])?w:"#000",b=n(b=d[1])?b:0,A=g.vrb?0:1;for(L(g.msg||"",m[g.ecl]||m.M,0==g.ecb?0:1,g.mtx),v=e+2*c,i=e;i--;)for(u=0,f=e;f--;)a[i][f]&&(A?(u++,a[i][f-1]||(l+="M"+f+","+i+"h"+u+"v1h-"+u+"v-1z",u=0)):l+="M"+f+","+i+"h1v1h-1v-1z");return o=t("svg",{viewBox:[0,0,v,v].join(" "),width:p,height:p,fill:w,"shape-rendering":"crispEdges",xmlns:s,version:"1.1"}),b&&o.appendChild(t("path",{fill:b,d:"M0,0V"+v+"H"+v+"V0H0Z"})),o.appendChild(t("path",{transform:"matrix("+C+")",d:l})),o}()}
src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/BuildEncryptedFilePayload.php CHANGED
@@ -15,7 +15,7 @@ class BuildEncryptedFilePayload extends BaseOps {
15
  $srvEnc = Services::Encrypt();
16
  $payload = $srvEnc->sealData( Services::WpFs()->getFileContent( $path ), $publicKey );
17
  if ( !$payload->success ) {
18
- throw new \Exception( 'File contents could not be encrypted' );
19
  }
20
  $encoded = wp_json_encode( $payload->getRawData() );
21
  if ( empty( $encoded ) || !is_string( $encoded ) ) {
15
  $srvEnc = Services::Encrypt();
16
  $payload = $srvEnc->sealData( Services::WpFs()->getFileContent( $path ), $publicKey );
17
  if ( !$payload->success ) {
18
+ throw new \Exception( 'File contents could not be encrypted with message: '.$payload->message );
19
  }
20
  $encoded = wp_json_encode( $payload->getRawData() );
21
  if ( empty( $encoded ) || !is_string( $encoded ) ) {
src/lib/src/Modules/HackGuard/Lib/Reports/Query/ScanCounts.php CHANGED
@@ -9,6 +9,9 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\DB\{
9
  };
10
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
11
 
 
 
 
12
  class ScanCounts {
13
 
14
  use ModConsumer;
9
  };
10
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
11
 
12
+ /**
13
+ * TODO: FIX!
14
+ */
15
  class ScanCounts {
16
 
17
  use ModConsumer;
src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/Base.php CHANGED
@@ -3,6 +3,7 @@
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\StoreAction;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
 
6
 
7
  class Base {
8
 
@@ -13,6 +14,43 @@ class Base {
13
  }
14
 
15
  protected function getTempDir() :string {
16
- return $this->getCon()->cache_dir_handler->buildSubDir( 'ptguard' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  }
18
  }
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\StoreAction;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
6
+ use FernleafSystems\Wordpress\Services\Services;
7
 
8
  class Base {
9
 
14
  }
15
 
16
  protected function getTempDir() :string {
17
+ $FS = Services::WpFs();
18
+ try {
19
+ $dir = $this->findTempDir();
20
+ if ( basename( $dir ) === 'ptguard' ) {
21
+ $oldDir = $dir;
22
+ $dir = $this->generateNewDirName();
23
+ foreach ( [ 'plugins', 'themes' ] as $type ) {
24
+ $FS->moveDirContents( path_join( $oldDir, $type ), path_join( $dir, $type ) );
25
+ }
26
+ $FS->deleteDir( $oldDir );
27
+ }
28
+ }
29
+ catch ( \Exception $e ) {
30
+ $dir = $this->generateNewDirName();
31
+ }
32
+ return $dir;
33
+ }
34
+
35
+ private function generateNewDirName() :string {
36
+ return $this->getCon()->cache_dir_handler->buildSubDir( 'ptguard-'.wp_generate_password( 16, false ) );
37
+ }
38
+
39
+ /**
40
+ * @throws \Exception
41
+ */
42
+ private function findTempDir() :string {
43
+ $FS = Services::WpFs();
44
+ $dir = null;
45
+ foreach ( $FS->getAllFilesInDir( $this->getCon()->cache_dir_handler->dir() ) as $fileItem ) {
46
+ if ( strpos( basename( $fileItem ), 'ptguard' ) === 0 && $FS->isDir( $fileItem ) ) {
47
+ $dir = $fileItem;
48
+ break;
49
+ }
50
+ }
51
+ if ( empty( $dir ) ) {
52
+ throw new \Exception( "Dir doesn't exist" );
53
+ }
54
+ return $dir;
55
  }
56
  }
src/lib/src/Modules/HackGuard/ModCon.php CHANGED
@@ -87,7 +87,7 @@ class ModCon extends BaseShield\ModCon {
87
 
88
  public function getMainWpData() :array {
89
  return array_merge( parent::getMainWpData(), [
90
- 'scan_issues' => array_filter( ( new Lib\Reports\Query\ScanCounts() )->setMod( $this )->all() )
91
  ] );
92
  }
93
 
87
 
88
  public function getMainWpData() :array {
89
  return array_merge( parent::getMainWpData(), [
90
+ 'scan_issues' => array_filter( ( new Shield\Modules\HackGuard\Scan\Results\Counts() )->setMod( $this )->all() )
91
  ] );
92
  }
93
 
src/lib/src/Modules/HackGuard/Scan/Results/Counts.php CHANGED
@@ -17,6 +17,20 @@ class Counts {
17
 
18
  private $counts;
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  public function countMalware() :int {
21
  return $this->getCount( 'malware_files' );
22
  }
17
 
18
  private $counts;
19
 
20
+ public function all() :array {
21
+ array_map( function ( string $type ) {
22
+ $this->getCount( $type );
23
+ }, [
24
+ 'malware_files',
25
+ 'abandoned',
26
+ 'plugin_files',
27
+ 'theme_files',
28
+ 'assets_vulnerable',
29
+ 'wp_files',
30
+ ] );
31
+ return $this->getCounts();
32
+ }
33
+
34
  public function countMalware() :int {
35
  return $this->getCount( 'malware_files' );
36
  }
src/lib/src/Modules/IPs/Lib/CrowdSec/Signals/EventsToSignals.php CHANGED
@@ -82,22 +82,31 @@ class EventsToSignals extends EventsListener {
82
  );
83
  }
84
 
85
- // and finally, trigger a send to Crowdsec
86
  $this->triggerSignalsCron();
87
  }
88
  }
89
 
90
  private function getMilliseconds() :string {
91
- return substr(
92
- function_exists( 'microtime' ) ? explode( '.', (string)@microtime( true ) )[ 1 ] : '0', 0, 6
93
- );
 
 
 
 
 
 
 
 
94
  }
95
 
96
  private function triggerSignalsCron() {
97
  $con = $this->getCon();
98
  if ( !wp_next_scheduled( $con->prefix( 'adhoc_cron_crowdsec_signals' ) ) ) {
99
  wp_schedule_single_event(
100
- Services::Request()->ts() + apply_filters( 'shield/crowdsec/signals_cron_interval', MINUTE_IN_SECONDS*5 ),
 
101
  $con->prefix( 'adhoc_cron_crowdsec_signals' )
102
  );
103
  }
82
  );
83
  }
84
 
85
+ // and finally, trigger send to Crowdsec
86
  $this->triggerSignalsCron();
87
  }
88
  }
89
 
90
  private function getMilliseconds() :string {
91
+ $milli = '0';
92
+ if ( function_exists( 'microtime' ) ) {
93
+ $ts = microtime();
94
+ if ( !empty( $ts ) && strpos( $ts, ' ' ) ) {
95
+ $ts = explode( ' ', $ts )[ 0 ];
96
+ if ( strpos( $ts, '.' ) ) {
97
+ $milli = rtrim( substr( explode( '.', $ts )[ 1 ] ?? '', 0, 6 ), '0' );
98
+ }
99
+ }
100
+ }
101
+ return strlen( $milli ) > 0 ? $milli : '0';
102
  }
103
 
104
  private function triggerSignalsCron() {
105
  $con = $this->getCon();
106
  if ( !wp_next_scheduled( $con->prefix( 'adhoc_cron_crowdsec_signals' ) ) ) {
107
  wp_schedule_single_event(
108
+ Services::Request()
109
+ ->ts() + apply_filters( 'shield/crowdsec/signals_cron_interval', MINUTE_IN_SECONDS*5 ),
110
  $con->prefix( 'adhoc_cron_crowdsec_signals' )
111
  );
112
  }
src/lib/src/Modules/Insights/ModCon.php CHANGED
@@ -4,6 +4,7 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Insights;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Controller\Assets\Enqueue;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield;
 
7
  use FernleafSystems\Wordpress\Services\Services;
8
 
9
  class ModCon extends BaseShield\ModCon {
@@ -32,6 +33,16 @@ class ModCon extends BaseShield\ModCon {
32
  }
33
  }
34
 
 
 
 
 
 
 
 
 
 
 
35
  public function getUrl_IpAnalysis( string $ip ) :string {
36
  return add_query_arg( [ 'analyse_ip' => $ip ], $this->getUrl_IPs() );
37
  }
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Controller\Assets\Enqueue;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield;
7
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Insights\Lib\MeterAnalysis\Components;
8
  use FernleafSystems\Wordpress\Services\Services;
9
 
10
  class ModCon extends BaseShield\ModCon {
33
  }
34
  }
35
 
36
+ public function getMainWpData() :array {
37
+ return array_merge( parent::getMainWpData(), [
38
+ 'grades' => [
39
+ 'integrity' => ( new Components() )
40
+ ->setCon( $this->getCon() )
41
+ ->getComponent( 'all' )
42
+ ]
43
+ ] );
44
+ }
45
+
46
  public function getUrl_IpAnalysis( string $ip ) :string {
47
  return add_query_arg( [ 'analyse_ip' => $ip ], $this->getUrl_IPs() );
48
  }
src/lib/src/Modules/Integrations/Lib/MainWP/Client/Actions/Init.php CHANGED
@@ -19,7 +19,7 @@ class Init {
19
  // Skip 2FA login if we can verify MainWP Authentication
20
  add_filter( 'icwp_shield_2fa_skip', function ( $canSkip ) {
21
  return $canSkip || ReproduceClientAuthByKey::Auth();
22
- }, 20, 1 );
23
 
24
  // Whitelist the MainWP Server IP
25
  add_action( 'mainwp_child_site_stats', function () {
19
  // Skip 2FA login if we can verify MainWP Authentication
20
  add_filter( 'icwp_shield_2fa_skip', function ( $canSkip ) {
21
  return $canSkip || ReproduceClientAuthByKey::Auth();
22
+ }, 20 );
23
 
24
  // Whitelist the MainWP Server IP
25
  add_action( 'mainwp_child_site_stats', function () {
src/lib/src/Modules/Integrations/Lib/MainWP/Common/MWPExtensionVO.php CHANGED
@@ -3,40 +3,9 @@
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Common;
4
 
5
  use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
6
- use MainWP\Dashboard\MainWP_Extensions_Handler;
7
 
8
  /**
9
  * @property string $page - e.g. Extensions-Wp-Simple-Firewall
10
  */
11
  class MWPExtensionVO extends DynPropertiesClass {
12
-
13
- /**
14
- * @param string $key
15
- * @return mixed
16
- */
17
- public function __get( string $key ) {
18
-
19
- $value = parent::__get( $key );
20
-
21
- switch ( $key ) {
22
- case 'official_extension_data':
23
- $value = $this->findOfficialExtensionData();
24
- break;
25
- default:
26
- break;
27
- }
28
-
29
- return $value;
30
- }
31
-
32
- private function findOfficialExtensionData() :array {
33
- $data = [];
34
- foreach ( MainWP_Extensions_Handler::get_extensions() as $ext ) {
35
- if ( $ext[ 'plugin' ] === $this->child_file ) {
36
- $data = $ext;
37
- break;
38
- }
39
- }
40
- return $data;
41
- }
42
  }
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Common;
4
 
5
  use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
 
6
 
7
  /**
8
  * @property string $page - e.g. Extensions-Wp-Simple-Firewall
9
  */
10
  class MWPExtensionVO extends DynPropertiesClass {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  }
src/lib/src/Modules/Integrations/Lib/MainWP/Common/MWPSiteVO.php CHANGED
@@ -14,8 +14,6 @@ use MainWP\Dashboard\MainWP_DB;
14
  class MWPSiteVO extends DynPropertiesClass {
15
 
16
  /**
17
- * @param int $siteID
18
- * @return MWPSiteVO
19
  * @throws \Exception
20
  */
21
  public static function LoadByID( int $siteID ) :MWPSiteVO {
14
  class MWPSiteVO extends DynPropertiesClass {
15
 
16
  /**
 
 
17
  * @throws \Exception
18
  */
19
  public static function LoadByID( int $siteID ) :MWPSiteVO {
src/lib/src/Modules/Integrations/Lib/MainWP/Controller.php CHANGED
@@ -6,7 +6,6 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Common\ExecOnceModConsu
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Client;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Common\MainWPVO;
8
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server;
9
- use FernleafSystems\Wordpress\Services\Services;
10
 
11
  class Controller extends ExecOnceModConsumer {
12
 
@@ -27,6 +26,11 @@ class Controller extends ExecOnceModConsumer {
27
  }
28
  }
29
 
 
 
 
 
 
30
  /**
31
  * @throws \Exception
32
  */
@@ -52,6 +56,8 @@ class Controller extends ExecOnceModConsumer {
52
  private function runServerSide() {
53
  $con = $this->getCon();
54
  $mwpVO = $con->mwpVO ?? new MainWPVO();
 
 
55
  $mwpVO->is_server = false;
56
 
57
  if ( !$this->isMainWPServerActive() ) {
@@ -64,8 +70,6 @@ class Controller extends ExecOnceModConsumer {
64
  $mwpVO->child_file = $con->getRootFile();
65
 
66
  $mwpVO->is_server = true;
67
-
68
- $con->mwpVO = $mwpVO;
69
  }
70
 
71
  private function isMainWPChildActive() :bool {
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Client;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Common\MainWPVO;
8
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server;
 
9
 
10
  class Controller extends ExecOnceModConsumer {
11
 
26
  }
27
  }
28
 
29
+ public function isServerExtensionLoaded() :bool {
30
+ $extData = $this->getCon()->mwpVO->official_extension_data;
31
+ return !empty( $extData );
32
+ }
33
+
34
  /**
35
  * @throws \Exception
36
  */
56
  private function runServerSide() {
57
  $con = $this->getCon();
58
  $mwpVO = $con->mwpVO ?? new MainWPVO();
59
+ $con->mwpVO = $mwpVO;
60
+
61
  $mwpVO->is_server = false;
62
 
63
  if ( !$this->isMainWPServerActive() ) {
70
  $mwpVO->child_file = $con->getRootFile();
71
 
72
  $mwpVO->is_server = true;
 
 
73
  }
74
 
75
  private function isMainWPChildActive() :bool {
src/lib/src/Modules/Integrations/Lib/MainWP/Server/Actions/Action.php CHANGED
@@ -12,9 +12,6 @@ class Action {
12
  use MainWP\Common\Consumers\MWPSiteConsumer;
13
 
14
  /**
15
- * @param string $actionToExecute
16
- * @param array $params
17
- * @return array
18
  * @throws \Exception
19
  */
20
  public function run( string $actionToExecute, array $params = [] ) :array {
12
  use MainWP\Common\Consumers\MWPSiteConsumer;
13
 
14
  /**
 
 
 
15
  * @throws \Exception
16
  */
17
  public function run( string $actionToExecute, array $params = [] ) :array {
src/lib/src/Modules/Integrations/Lib/MainWP/Server/Ajax/AjaxHandlerMainwp.php CHANGED
@@ -12,8 +12,8 @@ class AjaxHandlerMainwp extends Shield\Modules\BaseShield\AjaxHandler {
12
  $map = parent::getAjaxActionCallbackMap( $isAuth );
13
  if ( $isAuth ) {
14
  $map = array_merge( $map, [
15
- 'mwp_sh_ext_table' => [ $this, 'ajaxExec_ExtensionTableSites' ],
16
- 'mwp_sh_site_action' => [ $this, 'ajaxExec_SiteAction' ],
17
  ] );
18
  }
19
  return $map;
12
  $map = parent::getAjaxActionCallbackMap( $isAuth );
13
  if ( $isAuth ) {
14
  $map = array_merge( $map, [
15
+ 'ext_table' => [ $this, 'ajaxExec_ExtensionTableSites' ],
16
+ 'site_action' => [ $this, 'ajaxExec_SiteAction' ],
17
  ] );
18
  }
19
  return $map;
src/lib/src/Modules/Integrations/Lib/MainWP/Server/Data/SyncHandler.php CHANGED
@@ -19,7 +19,6 @@ class SyncHandler extends ExecOnceModConsumer {
19
 
20
  /**
21
  * @param object $website
22
- * @param array $info
23
  */
24
  private function syncSite( $website, array $info ) {
25
  $con = $this->getCon();
19
 
20
  /**
21
  * @param object $website
 
22
  */
23
  private function syncSite( $website, array $info ) {
24
  $con = $this->getCon();
src/lib/src/Modules/Integrations/Lib/MainWP/Server/Init.php CHANGED
@@ -54,20 +54,37 @@ class Init {
54
  }
55
 
56
  private function addOurExtension() :ExtensionSettingsPage {
57
- $con = $this->getCon();
58
 
59
- $extensionsPage = new ExtensionSettingsPage();
60
- $extensionParams = [
61
- 'plugin' => $con->getRootFile(),
62
- // while this is a "callback" field, a Closure isn't supported as it's serialized for DB storage. Sigh.
63
- 'callback' => [ $extensionsPage, 'render' ],
64
- 'icon' => $con->urls->forImage( 'pluginlogo_col_32x32.png' ),
65
- ];
66
- add_filter( 'mainwp_getextensions', function ( $exts ) use ( $extensionParams ) {
67
- return array_merge( $exts, [ $extensionParams ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  } );
69
 
70
- // We add Mod afterwards. It wasn't correctly saving for some reason while with it in the callback.
71
- return $extensionsPage->setMod( $this->getMod() );
72
  }
73
  }
54
  }
55
 
56
  private function addOurExtension() :ExtensionSettingsPage {
 
57
 
58
+ // We must create a simple class (MwpExtensionLoader) without any ModConsumer so that it can be reliably stored
59
+ // in the MainWP extensions option. Previously the saving wasn't working and the extension wouldn't appear.
60
+ add_filter( 'mainwp_getextensions', function ( $extensions ) {
61
+ $con = $this->getCon();
62
+ $extensions[] = [
63
+ 'plugin' => $con->getRootFile(),
64
+ // while this is a "callback" field, a Closure isn't supported as it's serialized for DB storage. Sigh.
65
+ 'callback' => [ new MwpExtensionLoader(), 'run' ],
66
+ 'icon' => $con->urls->forImage( 'pluginlogo_col_32x32.png' ),
67
+ ];
68
+ return $extensions;
69
+ } );
70
+
71
+ // Here we add extra data to our extension that can't be added through the normal channel due to the way they've coded it.
72
+ add_filter( "pre_update_option_mainwp_extensions", function ( $value ) {
73
+ if ( is_array( $value ) ) {
74
+ $con = $this->getCon();
75
+ foreach ( $value as $key => $ext ) {
76
+ if ( ( $ext[ 'plugin' ] ?? '' ) === $con->getRootFile() ) {
77
+ $value[ $key ][ 'description' ] = implode( ' ', [
78
+ 'Shield Security for MainWP builds upon the already powerful security platform,',
79
+ 'helping you extend security management across your entire portfolio with ease.'
80
+ ] );
81
+ $value[ $key ][ 'DocumentationURI' ] = $con->labels->url_helpdesk;
82
+ }
83
+ }
84
+ }
85
+ return $value;
86
  } );
87
 
88
+ return ( new ExtensionSettingsPage() )->setMod( $this->getMod() );
 
89
  }
90
  }
src/lib/src/Modules/Integrations/Lib/MainWP/Server/MwpExtensionLoader.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\UI\ExtensionSettingsPage;
6
+
7
+ use function FernleafSystems\Wordpress\Plugin\Shield\Functions\get_plugin;
8
+
9
+ class MwpExtensionLoader {
10
+
11
+ /**
12
+ * @throws \Exception
13
+ */
14
+ public function run() {
15
+ ( new ExtensionSettingsPage() )
16
+ ->setMod( get_plugin()->getController()->getModule_Integrations() )
17
+ ->render();
18
+ }
19
+ }
src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/BaseRender.php CHANGED
@@ -3,6 +3,8 @@
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\UI;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
 
 
6
 
7
  abstract class BaseRender {
8
 
@@ -14,7 +16,7 @@ abstract class BaseRender {
14
  try {
15
  $output = $con->getRenderer()
16
  ->setTemplateEngineTwig()
17
- ->setTemplate( sprintf( '/integration/mainwp/%s.twig', $this->getTemplateSlug() ) )
18
  ->setRenderVars( $this->getData() )
19
  ->render();
20
  }
@@ -25,6 +27,10 @@ abstract class BaseRender {
25
  }
26
 
27
  protected function getData() :array {
 
 
 
 
28
  return [
29
  'content' => [
30
  ],
@@ -33,5 +39,9 @@ abstract class BaseRender {
33
  ];
34
  }
35
 
 
 
 
 
36
  abstract protected function getTemplateSlug() :string;
37
  }
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\UI;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
6
+ use FernleafSystems\Wordpress\Services\Services;
7
+ use FernleafSystems\Wordpress\Services\Utilities\File\Paths;
8
 
9
  abstract class BaseRender {
10
 
16
  try {
17
  $output = $con->getRenderer()
18
  ->setTemplateEngineTwig()
19
+ ->setTemplate( Paths::AddExt( sprintf( '/integration/mainwp/%s', $this->getTemplateSlug() ), 'twig' ) )
20
  ->setRenderVars( $this->getData() )
21
  ->render();
22
  }
27
  }
28
 
29
  protected function getData() :array {
30
+ return Services::DataManipulation()->mergeArraysRecursive( $this->getBaseData(), $this->getPageSpecificData() );
31
+ }
32
+
33
+ protected function getBaseData() :array {
34
  return [
35
  'content' => [
36
  ],
39
  ];
40
  }
41
 
42
+ protected function getPageSpecificData() :array {
43
+ return [];
44
+ }
45
+
46
  abstract protected function getTemplateSlug() :string;
47
  }
src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/ExtensionSettingsPage.php CHANGED
@@ -5,7 +5,7 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainW
5
  use FernleafSystems\Wordpress\Plugin\Shield\Controller\Assets\Enqueue;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Common\ExecOnceModConsumer;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Controller;
8
- use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\UI\PageRender;
9
  use FernleafSystems\Wordpress\Services\Services;
10
 
11
  class ExtensionSettingsPage extends ExecOnceModConsumer {
@@ -13,8 +13,9 @@ class ExtensionSettingsPage extends ExecOnceModConsumer {
13
  protected function run() {
14
 
15
  add_filter( 'shield/custom_enqueues', function ( array $enqueues, $hook ) {
16
-
17
- if ( 'mainwp_page_'.$this->getCon()->mwpVO->extension->page === $hook ) {
 
18
 
19
  $enqueues[ Enqueue::JS ][] = 'shield/integrations/mainwp-server';
20
  $enqueues[ Enqueue::CSS ][] = 'shield/integrations/mainwp-server';
@@ -59,23 +60,32 @@ class ExtensionSettingsPage extends ExecOnceModConsumer {
59
  do_action( 'mainwp_pagefooter_extensions', $this->getCon()->getRootFile() );
60
  $mainwpFooter = ob_get_clean();
61
 
62
- $currentTab = empty( $req->query( 'tab' ) ) ? 'sites' : $req->query( 'tab' );
63
  if ( !$con->isPremiumActive() ) {
64
- $pageRenderer = new PageRender\NotShieldPro();
65
  }
66
  elseif ( $this->serverPluginNeedsUpdate() ) {
67
- $pageRenderer = new PageRender\PluginOutOfDate();
68
  }
69
  elseif ( !Controller::isMainWPServerVersionSupported() ) {
70
- $pageRenderer = new PageRender\MwpOutOfDate();
71
  }
72
  else {
73
- switch ( $currentTab ) {
74
- case 'sites':
75
- $pageRenderer = new PageRender\SitesList();
 
 
 
 
 
 
76
  break;
77
- default:
78
- throw new \Exception( 'Not a supported tab' );
 
 
 
79
  }
80
  }
81
 
@@ -86,16 +96,6 @@ class ExtensionSettingsPage extends ExecOnceModConsumer {
86
  'mainwp_footer' => $mainwpFooter,
87
  'page_inner' => $pageRenderer->setMod( $this->getMod() )->render(),
88
  ],
89
- 'vars' => [
90
- 'submenu' => [
91
- [
92
- 'title' => 'Sites Dashboard',
93
- 'href' => add_query_arg( [ 'tab' => 'sites' ], $req->getUri() ),
94
- 'icon' => 'globe',
95
- 'active' => $currentTab === 'sites',
96
- ]
97
- ],
98
- ]
99
  ] );
100
  }
101
  catch ( \Exception $e ) {
5
  use FernleafSystems\Wordpress\Plugin\Shield\Controller\Assets\Enqueue;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Common\ExecOnceModConsumer;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Controller;
8
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\UI\TabRender;
9
  use FernleafSystems\Wordpress\Services\Services;
10
 
11
  class ExtensionSettingsPage extends ExecOnceModConsumer {
13
  protected function run() {
14
 
15
  add_filter( 'shield/custom_enqueues', function ( array $enqueues, $hook ) {
16
+ $con = $this->getCon();
17
+ if ( $con->getModule_Integrations()->getControllerMWP()->isServerExtensionLoaded()
18
+ && 'mainwp_page_'.$con->mwpVO->extension->page === $hook ) {
19
 
20
  $enqueues[ Enqueue::JS ][] = 'shield/integrations/mainwp-server';
21
  $enqueues[ Enqueue::CSS ][] = 'shield/integrations/mainwp-server';
60
  do_action( 'mainwp_pagefooter_extensions', $this->getCon()->getRootFile() );
61
  $mainwpFooter = ob_get_clean();
62
 
63
+ $currentTab = empty( $req->query( 'tab' ) ) ? 'sites_list' : $req->query( 'tab' );
64
  if ( !$con->isPremiumActive() ) {
65
+ $pageRenderer = new TabRender\NotShieldPro();
66
  }
67
  elseif ( $this->serverPluginNeedsUpdate() ) {
68
+ $pageRenderer = new TabRender\PluginOutOfDate();
69
  }
70
  elseif ( !Controller::isMainWPServerVersionSupported() ) {
71
+ $pageRenderer = new TabRender\MwpOutOfDate();
72
  }
73
  else {
74
+ /** @var TabRender\BaseTab[] $pages */
75
+ $pages = [
76
+ TabRender\SitesList::class,
77
+ TabRender\SiteManageFrame::class,
78
+ ];
79
+
80
+ foreach ( $pages as $page ) {
81
+ if ( $currentTab == $page::TAB_SLUG ) {
82
+ $pageRenderer = new $page();
83
  break;
84
+ }
85
+ }
86
+
87
+ if ( empty( $pageRenderer ) ) {
88
+ throw new \Exception( 'Not a supported tab: '.$currentTab );
89
  }
90
  }
91
 
96
  'mainwp_footer' => $mainwpFooter,
97
  'page_inner' => $pageRenderer->setMod( $this->getMod() )->render(),
98
  ],
 
 
 
 
 
 
 
 
 
 
99
  ] );
100
  }
101
  catch ( \Exception $e ) {
src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/ManageSites/SitesListTableHandler.php CHANGED
@@ -7,12 +7,10 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Comm
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\Data\ClientPluginStatus;
8
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\Data\LoadShieldSyncData;
9
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\UI\BaseRender;
10
- use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
11
  use FernleafSystems\Wordpress\Services\Services;
12
 
13
  class SitesListTableHandler extends BaseRender {
14
 
15
- use ModConsumer;
16
  use ExecOnce;
17
 
18
  /**
@@ -22,18 +20,21 @@ class SitesListTableHandler extends BaseRender {
22
 
23
  protected function run() {
24
  add_filter( 'mainwp_sitestable_getcolumns', function ( $columns ) {
25
- $columns[ 'shield' ] = 'Shield';
26
- return $columns;
27
- }, 10, 1 );
28
- add_filter( 'mainwp_sitestable_item', function ( array $item ) {
29
- $item[ 'shield' ] = $this->renderShieldColumnEntryForItem( $item );
30
- return $item;
31
- }, 10, 1 );
32
- }
33
 
34
- private function renderShieldColumnEntryForItem( array $item ) :string {
35
- $this->workingSite = ( new MWPSiteVO() )->applyFromArray( $item );
36
- return $this->render();
 
 
 
 
 
 
 
 
 
 
 
37
  }
38
 
39
  protected function getData() :array {
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\Data\ClientPluginStatus;
8
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\Data\LoadShieldSyncData;
9
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\UI\BaseRender;
 
10
  use FernleafSystems\Wordpress\Services\Services;
11
 
12
  class SitesListTableHandler extends BaseRender {
13
 
 
14
  use ExecOnce;
15
 
16
  /**
20
 
21
  protected function run() {
22
  add_filter( 'mainwp_sitestable_getcolumns', function ( $columns ) {
 
 
 
 
 
 
 
 
23
 
24
+ // We double-check to ensure that our extension has been successfully registered by this stage.
25
+ // Prevents a fatal error that can be caused if we can't get our extension data when the extension reg has failed.
26
+ if ( $this->getCon()->getModule_Integrations()->getControllerMWP()->isServerExtensionLoaded() ) {
27
+ $columns[ 'shield' ] = 'Shield';
28
+
29
+ add_filter( 'mainwp_sitestable_item', function ( array $item ) {
30
+ $this->workingSite = ( new MWPSiteVO() )->applyFromArray( $item );
31
+ $item[ 'shield' ] = $this->render();
32
+ return $item;
33
+ } );
34
+ }
35
+
36
+ return $columns;
37
+ } );
38
  }
39
 
40
  protected function getData() :array {
src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/BaseTab.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\UI\TabRender;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Common\MWPSiteVO;
6
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\UI\BaseRender;
7
+ use FernleafSystems\Wordpress\Services\Services;
8
+
9
+ abstract class BaseTab extends BaseRender {
10
+
11
+ const TAB_SLUG = '';
12
+
13
+ protected function getBaseData() :array {
14
+ return Services::DataManipulation()->mergeArraysRecursive(
15
+ parent::getBaseData(),
16
+ [
17
+ 'ajax' => [
18
+ 'actions' => json_encode( (object)$this->getAjaxActionsData() )
19
+ ],
20
+ 'vars' => [
21
+ 'menu_topnav' => $this->getMenuTopNavItems(),
22
+ ]
23
+ ]
24
+ );
25
+ }
26
+
27
+ protected function getCurrentTab() :string {
28
+ $req = Services::Request();
29
+ return empty( $req->query( 'tab' ) ) ? 'sites' : $req->query( 'tab' );
30
+ }
31
+
32
+ protected function getMenuTopNavItems() :array {
33
+ return [
34
+ [
35
+ 'title' => 'Sites Dashboard',
36
+ 'href' => $this->createInternalExtensionHref( [ 'tab' => SitesList::TAB_SLUG ] ),
37
+ 'icon' => 'globe',
38
+ 'active' => $this->getCurrentTab() === 'sites',
39
+ ]
40
+ ];
41
+ }
42
+
43
+ protected function getAjaxActionsData() :array {
44
+ $mod = $this->getMod();
45
+ return [
46
+ 'site_action' => $mod->getAjaxActionData( 'site_action' ),
47
+ 'ext_table' => $mod->getAjaxActionData( 'ext_table' ),
48
+ ];
49
+ }
50
+
51
+ protected function getRootUri() :string {
52
+ $req = Services::Request();
53
+ return add_query_arg( [
54
+ 'page' => $req->query( 'page' )
55
+ ], $req->getPath() );
56
+ }
57
+
58
+ protected function createInternalExtensionHref( array $params ) :string {
59
+ return add_query_arg( $params, $this->getRootUri() );
60
+ }
61
+
62
+ protected function getSites() :string {
63
+ $mwp = $this->getCon()->mwpVO;
64
+ return apply_filters( 'mainwp_getsites', $mwp->child_file, $mwp->child_key );
65
+ }
66
+
67
+ protected function getSiteByID( int $id ) :MWPSiteVO {
68
+ return MWPSiteVO::LoadByID( $id );
69
+ }
70
+ }
src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/MwpOutOfDate.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\UI\TabRender;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Controller;
6
+ use FernleafSystems\Wordpress\Services\Services;
7
+
8
+ class MwpOutOfDate extends BaseTab {
9
+
10
+ protected function getPageSpecificData() :array {
11
+ return [
12
+ 'strings' => [
13
+ 'update' => __( "The MainWP Security plugin doesn't meet Shield's minimum requirements." ),
14
+ 'min_version' => __( 'Minimum required MainWP server version' ),
15
+ 'go_here' => __( 'Go to WordPress Updates' ),
16
+ ],
17
+ 'hrefs' => [
18
+ 'update' => Services::WpGeneral()->getAdminUrl_Updates()
19
+ ],
20
+ 'vars' => [
21
+ 'min_version' => Controller::MIN_VERSION_MAINWP
22
+ ],
23
+ ];
24
+ }
25
+
26
+ protected function getTemplateSlug() :string {
27
+ return 'pages/mwp_outofdate';
28
+ }
29
+ }
src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/NotShieldPro.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\UI\TabRender;
4
+
5
+ class NotShieldPro extends BaseTab {
6
+
7
+ protected function getPageSpecificData() :array {
8
+ return [
9
+ 'strings' => [
10
+ 'not_pro' => __( "Sorry, the MainWP server integration is available only for ShieldPRO clients." ),
11
+ 'go_pro' => __( 'Upgrade To ShieldPRO' ),
12
+ ],
13
+ 'hrefs' => [
14
+ 'go_pro' => 'https://shsec.io/mainwpservergopro'
15
+ ],
16
+ ];
17
+ }
18
+
19
+ protected function getTemplateSlug() :string {
20
+ return 'pages/mwp_for_pro';
21
+ }
22
+ }
src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/PluginOutOfDate.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\UI\TabRender;
4
+
5
+ use FernleafSystems\Wordpress\Services\Services;
6
+
7
+ class PluginOutOfDate extends BaseTab {
8
+
9
+ protected function getPageSpecificData() :array {
10
+ return [
11
+ 'strings' => [
12
+ 'update' => __( 'The Shield Security plugin on this site needs to be upgraded.' ),
13
+ 'go_here' => __( 'Go to WordPress Updates' )
14
+ ],
15
+ 'hrefs' => [
16
+ 'update' => Services::WpGeneral()->getAdminUrl_Updates()
17
+ ],
18
+ ];
19
+ }
20
+
21
+ protected function getTemplateSlug() :string {
22
+ return 'pages/shield_outofdate';
23
+ }
24
+ }
src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/SiteManageFrame.php ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\UI\TabRender;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Common\MWPSiteVO;
6
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\Data\ClientPluginStatus;
7
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\Data\LoadShieldSyncData;
8
+ use FernleafSystems\Wordpress\Services\Services;
9
+
10
+ class SiteManageFrame extends BaseTab {
11
+
12
+ const TAB_SLUG = 'site_manage';
13
+
14
+ protected function getPageSpecificData() :array {
15
+ $mod = $this->getMod();
16
+ $mwp = $this->getCon()->mwpVO;
17
+ $WP = Services::WpGeneral();
18
+ $req = Services::Request();
19
+
20
+ // var_dump( $this->getSiteByID( (int)$req->query( 'site_id' ) ) );
21
+ $statsHead = [
22
+ 'connected' => 0,
23
+ 'disconnected' => 0,
24
+ 'with_issues' => 0,
25
+ 'needs_update' => 0,
26
+ ];
27
+ $sites = apply_filters( 'mainwp_getsites', $mwp->child_file, $mwp->child_key );
28
+ foreach ( $sites as &$site ) {
29
+ $mwpSite = MWPSiteVO::LoadByID( (int)$site[ 'id' ] );
30
+ $sync = LoadShieldSyncData::Load( $mwpSite );
31
+ $meta = $sync->meta;
32
+
33
+ $shd = $sync->getRawData();
34
+ $status = ( new ClientPluginStatus() )
35
+ ->setMod( $this->getMod() )
36
+ ->setMwpSite( $mwpSite )
37
+ ->detect();
38
+ $shd[ 'status_key' ] = key( $status );
39
+ $shd[ 'status' ] = current( $status );
40
+
41
+ $shd[ 'is_active' ] = $shd[ 'status_key' ] === ClientPluginStatus::ACTIVE;
42
+ $shd[ 'is_inactive' ] = $shd[ 'status_key' ] === ClientPluginStatus::INACTIVE;
43
+ $shd[ 'is_notinstalled' ] = $shd[ 'status_key' ] === ClientPluginStatus::NOT_INSTALLED;
44
+ $shd[ 'is_notpro' ] = $shd[ 'status_key' ] === ClientPluginStatus::NOT_PRO;
45
+ $shd[ 'is_mwpnoton' ] = $shd[ 'status_key' ] === ClientPluginStatus::MWP_NOT_ON;
46
+ $shd[ 'is_sync_rqd' ] = $shd[ 'status_key' ] === ClientPluginStatus::NEED_SYNC;
47
+ $shd[ 'is_version_mismatch' ] = in_array( $shd[ 'status_key' ], [
48
+ ClientPluginStatus::VERSION_NEWER_THAN_SERVER,
49
+ ClientPluginStatus::VERSION_OLDER_THAN_SERVER,
50
+ ] );
51
+ $shd[ 'can_sync' ] = in_array( $shd[ 'status_key' ], [
52
+ ClientPluginStatus::ACTIVE,
53
+ ClientPluginStatus::NEED_SYNC,
54
+ ] );
55
+
56
+ if ( $shd[ 'is_active' ] ) {
57
+
58
+ $statsHead[ 'connected' ]++;
59
+ $shd[ 'sync_at_text' ] = $WP->getTimeStringForDisplay( $meta->sync_at );
60
+ $shd[ 'sync_at_diff' ] = $req->carbon()->setTimestamp( $meta->sync_at )->diffForHumans();
61
+
62
+ if ( empty( $sync->modules[ 'hack_protect' ][ 'scan_issues' ] ) ) {
63
+ $shd[ 'issues' ] = __( 'No Issues', 'wp-simple-firewall' );
64
+ $shd[ 'has_issues' ] = false;
65
+ }
66
+ else {
67
+ $shd[ 'has_issues' ] = true;
68
+ $shd[ 'issues' ] = array_sum( $sync->modules[ 'hack_protect' ][ 'scan_issues' ] );
69
+ $statsHead[ 'with_issues' ]++;
70
+ }
71
+ }
72
+ else {
73
+ $statsHead[ 'disconnected' ]++;
74
+ }
75
+
76
+ $statsHead[ 'needs_update' ] += $meta->has_update ? 1 : 0;
77
+
78
+ $site[ 'shield' ] = $shd;
79
+ }
80
+
81
+ return [
82
+ 'vars' => [
83
+ 'sites' => $sites,
84
+ 'stats_head' => $statsHead,
85
+ ],
86
+ 'strings' => [
87
+ 'actions' => __( 'Actions', 'wp-simple-firewall' ),
88
+ 'site' => __( 'Site', 'wp-simple-firewall' ),
89
+ 'url' => __( 'URL', 'wp-simple-firewall' ),
90
+ 'issues' => __( 'Issues', 'wp-simple-firewall' ),
91
+ 'status' => __( 'Status', 'wp-simple-firewall' ),
92
+ 'last_sync' => __( 'Last Sync', 'wp-simple-firewall' ),
93
+ 'last_scan' => __( 'Last Scan', 'wp-simple-firewall' ),
94
+ 'version' => __( 'Version', 'wp-simple-firewall' ),
95
+ 'connected' => __( 'Connected', 'wp-simple-firewall' ),
96
+ 'disconnected' => __( 'Disconnected', 'wp-simple-firewall' ),
97
+ 'with_issues' => __( 'With Issues', 'wp-simple-firewall' ),
98
+ 'needs_update' => __( 'Needs Update', 'wp-simple-firewall' ),
99
+ 'st_inactive' => __( 'Shield Security plugin is installed but not activated.', 'wp-simple-firewall' ),
100
+ 'st_notinstalled' => __( "Shield Security plugin not detected in last sync.", 'wp-simple-firewall' ),
101
+ 'st_notpro' => __( "ShieldPRO isn't activated on this site.", 'wp-simple-firewall' ),
102
+ 'st_mwpnoton' => __( "Shield's MainWP integration isn't enabled for this site.", 'wp-simple-firewall' ),
103
+ 'st_sync_rqd' => __( 'Shield Security plugin needs to sync.', 'wp-simple-firewall' ),
104
+ 'st_version_mismatch' => __( 'Shield Security plugin versions are out of sync.', 'wp-simple-firewall' ),
105
+ 'st_unknown' => __( "Couldn't determine Shield plugin status.", 'wp-simple-firewall' ),
106
+ 'act_sync' => __( 'Sync Shield', 'wp-simple-firewall' ),
107
+ 'act_activate' => __( 'Activate Shield', 'wp-simple-firewall' ),
108
+ 'act_align' => __( 'Align Shield', 'wp-simple-firewall' ),
109
+ 'act_deactivate' => __( 'Deactivate Shield', 'wp-simple-firewall' ),
110
+ 'act_install' => __( 'Install Shield', 'wp-simple-firewall' ),
111
+ 'act_upgrade' => __( 'Upgrade Shield', 'wp-simple-firewall' ),
112
+ 'act_uninstall' => __( 'Uninstall Shield', 'wp-simple-firewall' ),
113
+ 'act_license' => __( 'Check ShieldPRO License', 'wp-simple-firewall' ),
114
+ 'act_mwp' => __( 'Switch-On MainWP Integration', 'wp-simple-firewall' ),
115
+ ]
116
+ ];
117
+ }
118
+
119
+ protected function getAjaxActionsData() :array {
120
+ $renderManageSiteAjax = $this->getMod()->getAjaxActionData( 'render_manage_site' );
121
+ $renderManageSiteAjax[ 'site_id' ] = Services::Request()->query( 'site_id' );
122
+
123
+ $data = parent::getAjaxActionsData();
124
+ $data[ 'render_manage_site' ] = $renderManageSiteAjax;
125
+ return $data;
126
+ }
127
+
128
+ protected function getMenuTopNavItems() :array {
129
+ $req = Services::Request();
130
+ $items = parent::getMenuTopNavItems();
131
+ $items[] = [
132
+ 'title' => 'www.google.com',
133
+ 'href' => add_query_arg( [
134
+ 'tab' => 'site',
135
+ 'site_id' => 123,
136
+ ], $req->getUri() ),
137
+ 'icon' => 'globe',
138
+ 'active' => true
139
+ ];
140
+ return $items;
141
+ }
142
+
143
+ protected function getTemplateSlug() :string {
144
+ return 'pages/site.twig';
145
+ }
146
+ }
src/lib/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/SitesList.php ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\UI\TabRender;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Common\MWPSiteVO;
6
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\Data\ClientPluginStatus;
7
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\MainWP\Server\Data\LoadShieldSyncData;
8
+ use FernleafSystems\Wordpress\Services\Services;
9
+
10
+ class SitesList extends BaseTab {
11
+
12
+ const TAB_SLUG = 'sites_list';
13
+
14
+ protected function getPageSpecificData() :array {
15
+ $modInsights = $this->getCon()->getModule_Insights();
16
+ $mwp = $this->getCon()->mwpVO;
17
+ $WP = Services::WpGeneral();
18
+ $req = Services::Request();
19
+
20
+ $statsHead = [
21
+ 'connected' => 0,
22
+ 'disconnected' => 0,
23
+ 'with_issues' => 0,
24
+ 'needs_update' => 0,
25
+ ];
26
+ $sites = apply_filters( 'mainwp_getsites', $mwp->child_file, $mwp->child_key );
27
+ foreach ( $sites as &$site ) {
28
+ $mwpSite = MWPSiteVO::LoadByID( (int)$site[ 'id' ] );
29
+ $sync = LoadShieldSyncData::Load( $mwpSite );
30
+ $meta = $sync->meta;
31
+
32
+ $shd = $sync->getRawData();
33
+ $status = ( new ClientPluginStatus() )
34
+ ->setMod( $this->getMod() )
35
+ ->setMwpSite( $mwpSite )
36
+ ->detect();
37
+ $shd[ 'status_key' ] = key( $status );
38
+ $shd[ 'status' ] = current( $status );
39
+
40
+ $shd[ 'is_active' ] = $shd[ 'status_key' ] === ClientPluginStatus::ACTIVE;
41
+ $shd[ 'is_inactive' ] = $shd[ 'status_key' ] === ClientPluginStatus::INACTIVE;
42
+ $shd[ 'is_notinstalled' ] = $shd[ 'status_key' ] === ClientPluginStatus::NOT_INSTALLED;
43
+ $shd[ 'is_notpro' ] = $shd[ 'status_key' ] === ClientPluginStatus::NOT_PRO;
44
+ $shd[ 'is_mwpnoton' ] = $shd[ 'status_key' ] === ClientPluginStatus::MWP_NOT_ON;
45
+ $shd[ 'is_sync_rqd' ] = $shd[ 'status_key' ] === ClientPluginStatus::NEED_SYNC;
46
+ $shd[ 'is_version_mismatch' ] = in_array( $shd[ 'status_key' ], [
47
+ ClientPluginStatus::VERSION_NEWER_THAN_SERVER,
48
+ ClientPluginStatus::VERSION_OLDER_THAN_SERVER,
49
+ ] );
50
+ $shd[ 'can_sync' ] = in_array( $shd[ 'status_key' ], [
51
+ ClientPluginStatus::ACTIVE,
52
+ ClientPluginStatus::NEED_SYNC,
53
+ ] );
54
+
55
+ if ( $shd[ 'is_active' ] ) {
56
+
57
+ $statsHead[ 'connected' ]++;
58
+ $shd[ 'sync_at_text' ] = $WP->getTimeStringForDisplay( $meta->sync_at );
59
+ $shd[ 'sync_at_diff' ] = $req->carbon()->setTimestamp( $meta->sync_at )->diffForHumans();
60
+
61
+ if ( empty( $sync->modules[ 'hack_protect' ][ 'scan_issues' ] ) ) {
62
+ $shd[ 'issues' ] = __( 'No Issues', 'wp-simple-firewall' );
63
+ $shd[ 'has_issues' ] = false;
64
+ }
65
+ else {
66
+ $shd[ 'has_issues' ] = true;
67
+ $shd[ 'issues' ] = array_sum( $sync->modules[ 'hack_protect' ][ 'scan_issues' ] );
68
+ $statsHead[ 'with_issues' ]++;
69
+ }
70
+
71
+ $shd[ 'href_issues' ] = $this->getJumpUrlFor( (string)$site[ 'id' ], $modInsights->getUrl_ScansResults() );
72
+ $gradeLetter = $sync->modules[ 'insights' ][ 'grades' ][ 'integrity' ][ 'letter_score' ] ?? '-';
73
+ $shd[ 'grades' ] = [
74
+ 'href' => $this->getJumpUrlFor( (string)$site[ 'id' ], $modInsights->getUrl_SubInsightsPage( 'overview' ) ),
75
+ 'integrity' => $gradeLetter,
76
+ 'good' => in_array( $gradeLetter, [ 'A', 'B' ] ),
77
+ ];
78
+
79
+ $shd[ 'href_manage' ] = $this->createInternalExtensionHref( [
80
+ 'tab' => 'site_manage',
81
+ 'site_id' => $site[ 'id' ],
82
+ ] );
83
+ }
84
+ else {
85
+ $statsHead[ 'disconnected' ]++;
86
+ }
87
+
88
+ $statsHead[ 'needs_update' ] += $meta->has_update ? 1 : 0;
89
+
90
+ $site[ 'shield' ] = $shd;
91
+ }
92
+
93
+ return [
94
+ 'vars' => [
95
+ 'sites' => $sites,
96
+ 'stats_head' => $statsHead,
97
+ ],
98
+ 'strings' => [
99
+ 'manage' => __( 'Manage', 'wp-simple-firewall' ),
100
+ 'actions' => __( 'Actions', 'wp-simple-firewall' ),
101
+ 'site' => __( 'Site', 'wp-simple-firewall' ),
102
+ 'url' => __( 'URL', 'wp-simple-firewall' ),
103
+ 'issues' => __( 'Issues', 'wp-simple-firewall' ),
104
+ 'status' => __( 'Status', 'wp-simple-firewall' ),
105
+ 'last_sync' => __( 'Last Sync', 'wp-simple-firewall' ),
106
+ 'last_scan' => __( 'Last Scan', 'wp-simple-firewall' ),
107
+ 'version' => __( 'Version', 'wp-simple-firewall' ),
108
+ 'connected' => __( 'Connected', 'wp-simple-firewall' ),
109
+ 'disconnected' => __( 'Disconnected', 'wp-simple-firewall' ),
110
+ 'with_issues' => __( 'With Issues', 'wp-simple-firewall' ),
111
+ 'needs_update' => __( 'Needs Update', 'wp-simple-firewall' ),
112
+ 'st_inactive' => __( 'Shield Security plugin is installed but not activated.', 'wp-simple-firewall' ),
113
+ 'st_notinstalled' => __( "Shield Security plugin not detected in last sync.", 'wp-simple-firewall' ),
114
+ 'st_notpro' => __( "ShieldPRO isn't activated on this site.", 'wp-simple-firewall' ),
115
+ 'st_mwpnoton' => __( "Shield's MainWP integration isn't enabled for this site.", 'wp-simple-firewall' ),
116
+ 'st_sync_rqd' => __( 'Shield Security plugin needs to sync.', 'wp-simple-firewall' ),
117
+ 'st_version_mismatch' => __( 'Shield Security plugin versions are out of sync.', 'wp-simple-firewall' ),
118
+ 'st_unknown' => __( "Couldn't determine Shield plugin status.", 'wp-simple-firewall' ),
119
+ 'act_sync' => __( 'Sync Shield', 'wp-simple-firewall' ),
120
+ 'act_activate' => __( 'Activate Shield', 'wp-simple-firewall' ),
121
+ 'act_align' => __( 'Align Shield', 'wp-simple-firewall' ),
122
+ 'act_deactivate' => __( 'Deactivate Shield', 'wp-simple-firewall' ),
123
+ 'act_install' => __( 'Install Shield', 'wp-simple-firewall' ),
124
+ 'act_upgrade' => __( 'Upgrade Shield', 'wp-simple-firewall' ),
125
+ 'act_uninstall' => __( 'Uninstall Shield', 'wp-simple-firewall' ),
126
+ 'act_license' => __( 'Check ShieldPRO License', 'wp-simple-firewall' ),
127
+ 'act_mwp' => __( 'Switch-On MainWP Integration', 'wp-simple-firewall' ),
128
+ 'overall_grade' => __( 'Grade', 'wp-simple-firewall' ),
129
+ ]
130
+ ];
131
+ }
132
+
133
+ private function getScanPageUrlPart() :string {
134
+ $WP = Services::WpGeneral();
135
+ return str_replace(
136
+ $WP->getAdminUrl(),
137
+ '',
138
+ $this->getCon()->getModule_Insights()->getUrl_ScansResults()
139
+ );
140
+ }
141
+
142
+ private function getJumpUrlFor( string $siteID, string $page ) :string {
143
+ return add_query_arg(
144
+ [
145
+ 'newWindow' => 'yes',
146
+ 'websiteid' => $siteID,
147
+ '_opennonce' => wp_create_nonce( 'mainwp-admin-nonce' ),
148
+ 'location' => base64_encode( str_replace( Services::WpGeneral()->getAdminUrl(), '', $page ) )
149
+ ],
150
+ Services::WpGeneral()->getUrl_AdminPage( 'SiteOpen' )
151
+ );
152
+ }
153
+
154
+ protected function getTemplateSlug() :string {
155
+ return 'pages/sites.twig';
156
+ }
157
+ }
src/lib/src/Modules/License/AdminNotices.php CHANGED
@@ -26,7 +26,7 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
26
  'notice_attributes' => [],
27
  'strings' => [
28
  'title' => sprintf( '%s: %s', __( 'Warning', 'wp-simple-firewall' ),
29
- sprintf( __( '%s API Token Missing', 'wp-simple-firewall' ), 'WPHashes.com' ) ),
30
  'messages' => [
31
  __( "This site appears to be activated for PRO, but there's been a problem obtaining an API token.", 'wp-simple-firewall' ),
32
  implode( ' ', [
26
  'notice_attributes' => [],
27
  'strings' => [
28
  'title' => sprintf( '%s: %s', __( 'Warning', 'wp-simple-firewall' ),
29
+ sprintf( __( '%s API Token Missing', 'wp-simple-firewall' ), 'ShieldPRO' ) ),
30
  'messages' => [
31
  __( "This site appears to be activated for PRO, but there's been a problem obtaining an API token.", 'wp-simple-firewall' ),
32
  implode( ' ', [
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/GoogleAuth.php CHANGED
@@ -4,7 +4,6 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFact
4
 
5
  use Dolondro\GoogleAuthenticator\{
6
  GoogleAuthenticator,
7
- QrImageGenerator\GoogleQrImageGenerator,
8
  Secret,
9
  SecretFactory
10
  };
@@ -40,7 +39,8 @@ class GoogleAuth extends BaseProvider {
40
  $validatedProfile = $this->hasValidatedProfile();
41
  return [
42
  'hrefs' => [
43
- 'src_chart_url' => $validatedProfile ? '' : $this->getQrImage(),
 
44
  ],
45
  'vars' => [
46
  'ga_secret' => $validatedProfile ? $this->getSecret() : $this->resetSecret(),
@@ -65,20 +65,18 @@ class GoogleAuth extends BaseProvider {
65
  ];
66
  }
67
 
68
- private function getQrImage() :string {
69
  $secret = $this->getGaSecret();
70
- try {
71
- $qrImage = $this->getGaRegisterChartUrl( $secret );
72
- }
73
- catch ( \Exception $e ) {
74
- $qrImage = $this->getGaRegisterChartUrlShieldNet( $secret );
75
- }
76
 
77
- return 'data:image/png;base64, '.$qrImage;
 
78
  }
79
 
80
  /**
81
  * @throws \Exception
 
82
  */
83
  private function getGaRegisterChartUrl( Secret $secret ) :string {
84
  $rawImage = Services::HttpRequest()
@@ -92,7 +90,8 @@ class GoogleAuth extends BaseProvider {
92
  return base64_encode( $rawImage );
93
  }
94
 
95
- private function getGaRegisterChartUrlShieldNet( Secret $secret ) :string {
 
96
  return ( new GenerateGoogleAuthQrCode() )
97
  ->setMod( $this->getCon()->getModule_Plugin() )
98
  ->getCode(
4
 
5
  use Dolondro\GoogleAuthenticator\{
6
  GoogleAuthenticator,
 
7
  Secret,
8
  SecretFactory
9
  };
39
  $validatedProfile = $this->hasValidatedProfile();
40
  return [
41
  'hrefs' => [
42
+ 'qr_code_auth' => $validatedProfile ? '' : $this->getQrUrl(),
43
+ // 'src_chart_url' => $validatedProfile ? '' : $this->getQrImage(), // opt now for JS-based render
44
  ],
45
  'vars' => [
46
  'ga_secret' => $validatedProfile ? $this->getSecret() : $this->resetSecret(),
65
  ];
66
  }
67
 
68
+ private function getQrUrl() :string {
69
  $secret = $this->getGaSecret();
70
+ return sprintf( 'otpauth://totp/test?secret=%s&issuer=%s&label=%s', $secret->getSecretKey(), $secret->getIssuer(), $secret->getLabel() );
71
+ }
 
 
 
 
72
 
73
+ private function getQrImage() :string {
74
+ return 'data:image/png;base64, '.$this->getGaRegisterChartUrlShieldNet();
75
  }
76
 
77
  /**
78
  * @throws \Exception
79
+ * @deprecated 16.2
80
  */
81
  private function getGaRegisterChartUrl( Secret $secret ) :string {
82
  $rawImage = Services::HttpRequest()
90
  return base64_encode( $rawImage );
91
  }
92
 
93
+ private function getGaRegisterChartUrlShieldNet() :string {
94
+ $secret = $this->getGaSecret();
95
  return ( new GenerateGoogleAuthQrCode() )
96
  ->setMod( $this->getCon()->getModule_Plugin() )
97
  ->getCode(
src/lib/src/Modules/Plugin/Debug.php CHANGED
@@ -16,7 +16,7 @@ class Debug extends Modules\Base\Debug {
16
 
17
  public function run() {
18
  // $this->testAAAA( 'fwdproxy-odn-017.fbsv.net' );
19
- $this->crowdsec();
20
  die( 'finish' );
21
  }
22
 
16
 
17
  public function run() {
18
  // $this->testAAAA( 'fwdproxy-odn-017.fbsv.net' );
19
+ // $this->crowdsec();
20
  die( 'finish' );
21
  }
22
 
src/lib/src/Modules/Traffic/Rules/Build/IsRateLimitExceeded.php CHANGED
@@ -33,6 +33,10 @@ class IsRateLimitExceeded extends BuildRuleCoreShieldBase {
33
  'rule' => RequestBypassesAllRestrictions::SLUG,
34
  'invert_match' => true
35
  ],
 
 
 
 
36
  [
37
  'condition' => Conditions\IsRateLimitExceeded::SLUG,
38
  'params' => [
33
  'rule' => RequestBypassesAllRestrictions::SLUG,
34
  'invert_match' => true
35
  ],
36
+ [
37
+ 'rule' => Conditions\IsLoggedInNormal::SLUG,
38
+ 'invert_match' => true
39
+ ],
40
  [
41
  'condition' => Conditions\IsRateLimitExceeded::SLUG,
42
  'params' => [
src/lib/src/Scans/Afs/Processing/MalFalsePositiveReporter.php CHANGED
@@ -94,6 +94,7 @@ class MalFalsePositiveReporter {
94
  /** @var Modules\HackGuard\Options $opts */
95
  $opts = $this->getOptions();
96
  return $this->getCon()->is_mode_live
 
97
  && $opts->isMalUseNetworkIntelligence()
98
  && !$this->getReportCache()
99
  ->setReportHash( $reportHash )
94
  /** @var Modules\HackGuard\Options $opts */
95
  $opts = $this->getOptions();
96
  return $this->getCon()->is_mode_live
97
+ && version_compare( $this->getCon()->getVersion(), '16.2', '>=' )
98
  && $opts->isMalUseNetworkIntelligence()
99
  && !$this->getReportCache()
100
  ->setReportHash( $reportHash )
src/lib/vendor/composer/autoload_classmap.php CHANGED
@@ -754,13 +754,16 @@ return array(
754
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\Data\\LoadShieldSyncData' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/Data/LoadShieldSyncData.php',
755
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\Data\\SyncHandler' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/Data/SyncHandler.php',
756
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\Init' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/Init.php',
 
757
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\BaseRender' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/UI/BaseRender.php',
758
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\ExtensionSettingsPage' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/UI/ExtensionSettingsPage.php',
759
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\ManageSites\\SitesListTableHandler' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/UI/ManageSites/SitesListTableHandler.php',
760
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\PageRender\\MwpOutOfDate' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/UI/PageRender/MwpOutOfDate.php',
761
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\PageRender\\NotShieldPro' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/UI/PageRender/NotShieldPro.php',
762
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\PageRender\\PluginOutOfDate' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/UI/PageRender/PluginOutOfDate.php',
763
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\PageRender\\SitesList' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/UI/PageRender/SitesList.php',
 
 
764
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\ModCon' => $baseDir . '/src/Modules/Integrations/ModCon.php',
765
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Options' => $baseDir . '/src/Modules/Integrations/Options.php',
766
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Processor' => $baseDir . '/src/Modules/Integrations/Processor.php',
754
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\Data\\LoadShieldSyncData' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/Data/LoadShieldSyncData.php',
755
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\Data\\SyncHandler' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/Data/SyncHandler.php',
756
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\Init' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/Init.php',
757
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\MwpExtensionLoader' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/MwpExtensionLoader.php',
758
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\BaseRender' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/UI/BaseRender.php',
759
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\ExtensionSettingsPage' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/UI/ExtensionSettingsPage.php',
760
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\ManageSites\\SitesListTableHandler' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/UI/ManageSites/SitesListTableHandler.php',
761
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\TabRender\\BaseTab' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/BaseTab.php',
762
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\TabRender\\MwpOutOfDate' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/MwpOutOfDate.php',
763
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\TabRender\\NotShieldPro' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/NotShieldPro.php',
764
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\TabRender\\PluginOutOfDate' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/PluginOutOfDate.php',
765
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\TabRender\\SiteManageFrame' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/SiteManageFrame.php',
766
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\TabRender\\SitesList' => $baseDir . '/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/SitesList.php',
767
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\ModCon' => $baseDir . '/src/Modules/Integrations/ModCon.php',
768
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Options' => $baseDir . '/src/Modules/Integrations/Options.php',
769
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Processor' => $baseDir . '/src/Modules/Integrations/Processor.php',
src/lib/vendor/composer/autoload_static.php CHANGED
@@ -949,13 +949,16 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
949
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\Data\\LoadShieldSyncData' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/Data/LoadShieldSyncData.php',
950
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\Data\\SyncHandler' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/Data/SyncHandler.php',
951
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\Init' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/Init.php',
 
952
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\BaseRender' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/UI/BaseRender.php',
953
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\ExtensionSettingsPage' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/UI/ExtensionSettingsPage.php',
954
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\ManageSites\\SitesListTableHandler' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/UI/ManageSites/SitesListTableHandler.php',
955
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\PageRender\\MwpOutOfDate' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/UI/PageRender/MwpOutOfDate.php',
956
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\PageRender\\NotShieldPro' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/UI/PageRender/NotShieldPro.php',
957
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\PageRender\\PluginOutOfDate' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/UI/PageRender/PluginOutOfDate.php',
958
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\PageRender\\SitesList' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/UI/PageRender/SitesList.php',
 
 
959
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\ModCon' => __DIR__ . '/../..' . '/src/Modules/Integrations/ModCon.php',
960
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Options' => __DIR__ . '/../..' . '/src/Modules/Integrations/Options.php',
961
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Processor' => __DIR__ . '/../..' . '/src/Modules/Integrations/Processor.php',
949
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\Data\\LoadShieldSyncData' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/Data/LoadShieldSyncData.php',
950
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\Data\\SyncHandler' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/Data/SyncHandler.php',
951
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\Init' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/Init.php',
952
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\MwpExtensionLoader' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/MwpExtensionLoader.php',
953
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\BaseRender' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/UI/BaseRender.php',
954
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\ExtensionSettingsPage' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/UI/ExtensionSettingsPage.php',
955
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\ManageSites\\SitesListTableHandler' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/UI/ManageSites/SitesListTableHandler.php',
956
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\TabRender\\BaseTab' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/BaseTab.php',
957
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\TabRender\\MwpOutOfDate' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/MwpOutOfDate.php',
958
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\TabRender\\NotShieldPro' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/NotShieldPro.php',
959
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\TabRender\\PluginOutOfDate' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/PluginOutOfDate.php',
960
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\TabRender\\SiteManageFrame' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/SiteManageFrame.php',
961
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\MainWP\\Server\\UI\\TabRender\\SitesList' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/MainWP/Server/UI/TabRender/SitesList.php',
962
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\ModCon' => __DIR__ . '/../..' . '/src/Modules/Integrations/ModCon.php',
963
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Options' => __DIR__ . '/../..' . '/src/Modules/Integrations/Options.php',
964
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Processor' => __DIR__ . '/../..' . '/src/Modules/Integrations/Processor.php',
src/lib/vendor/composer/installed.json CHANGED
@@ -288,17 +288,17 @@
288
  },
289
  {
290
  "name": "fernleafsystems/wordpress-services",
291
- "version": "2.30.3",
292
- "version_normalized": "2.30.3.0",
293
  "source": {
294
  "type": "git",
295
  "url": "git@gitlab.com:fernleafsystems/wordpress/wordpress-services.git",
296
- "reference": "34e9e70321792811571efa0dea1ccf422484f3e9"
297
  },
298
  "dist": {
299
  "type": "zip",
300
- "url": "https://gitlab.com/api/v4/projects/fernleafsystems%2Fwordpress%2Fwordpress-services/repository/archive.zip?sha=34e9e70321792811571efa0dea1ccf422484f3e9",
301
- "reference": "34e9e70321792811571efa0dea1ccf422484f3e9",
302
  "shasum": ""
303
  },
304
  "require": {
@@ -317,7 +317,7 @@
317
  "symfony/yaml": "~3.0",
318
  "twig/twig": "^1.42"
319
  },
320
- "time": "2022-09-13T09:24:49+00:00",
321
  "type": "library",
322
  "installation-source": "dist",
323
  "autoload": {
288
  },
289
  {
290
  "name": "fernleafsystems/wordpress-services",
291
+ "version": "2.30.4",
292
+ "version_normalized": "2.30.4.0",
293
  "source": {
294
  "type": "git",
295
  "url": "git@gitlab.com:fernleafsystems/wordpress/wordpress-services.git",
296
+ "reference": "efae7303c68bbaa96785f7f4fc7fc42e1dbfbe31"
297
  },
298
  "dist": {
299
  "type": "zip",
300
+ "url": "https://gitlab.com/api/v4/projects/fernleafsystems%2Fwordpress%2Fwordpress-services/repository/archive.zip?sha=efae7303c68bbaa96785f7f4fc7fc42e1dbfbe31",
301
+ "reference": "efae7303c68bbaa96785f7f4fc7fc42e1dbfbe31",
302
  "shasum": ""
303
  },
304
  "require": {
317
  "symfony/yaml": "~3.0",
318
  "twig/twig": "^1.42"
319
  },
320
+ "time": "2022-09-15T09:56:36+00:00",
321
  "type": "library",
322
  "installation-source": "dist",
323
  "autoload": {
src/lib/vendor/composer/installed.php CHANGED
@@ -5,7 +5,7 @@
5
  'type' => 'library',
6
  'install_path' => __DIR__ . '/../../',
7
  'aliases' => array(),
8
- 'reference' => '2ec6ed3be8e4285ee1e10f6afafd8f4b3e4d2402',
9
  'name' => 'apto-shield/requirements',
10
  'dev' => true,
11
  ),
@@ -25,7 +25,7 @@
25
  'type' => 'library',
26
  'install_path' => __DIR__ . '/../../',
27
  'aliases' => array(),
28
- 'reference' => '2ec6ed3be8e4285ee1e10f6afafd8f4b3e4d2402',
29
  'dev_requirement' => false,
30
  ),
31
  'christian-riesen/base32' => array(
@@ -74,12 +74,12 @@
74
  'dev_requirement' => false,
75
  ),
76
  'fernleafsystems/wordpress-services' => array(
77
- 'pretty_version' => '2.30.3',
78
- 'version' => '2.30.3.0',
79
  'type' => 'library',
80
  'install_path' => __DIR__ . '/../fernleafsystems/wordpress-services',
81
  'aliases' => array(),
82
- 'reference' => '34e9e70321792811571efa0dea1ccf422484f3e9',
83
  'dev_requirement' => false,
84
  ),
85
  'fernleafsystems/zxcvbn-php' => array(
5
  'type' => 'library',
6
  'install_path' => __DIR__ . '/../../',
7
  'aliases' => array(),
8
+ 'reference' => 'f2a7bb169f0054c6c14b8895945a1b1b18253394',
9
  'name' => 'apto-shield/requirements',
10
  'dev' => true,
11
  ),
25
  'type' => 'library',
26
  'install_path' => __DIR__ . '/../../',
27
  'aliases' => array(),
28
+ 'reference' => 'f2a7bb169f0054c6c14b8895945a1b1b18253394',
29
  'dev_requirement' => false,
30
  ),
31
  'christian-riesen/base32' => array(
74
  'dev_requirement' => false,
75
  ),
76
  'fernleafsystems/wordpress-services' => array(
77
+ 'pretty_version' => '2.30.4',
78
+ 'version' => '2.30.4.0',
79
  'type' => 'library',
80
  'install_path' => __DIR__ . '/../fernleafsystems/wordpress-services',
81
  'aliases' => array(),
82
+ 'reference' => 'efae7303c68bbaa96785f7f4fc7fc42e1dbfbe31',
83
  'dev_requirement' => false,
84
  ),
85
  'fernleafsystems/zxcvbn-php' => array(
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Encrypt/OpenSslEncrypt.php CHANGED
@@ -33,7 +33,6 @@ class OpenSslEncrypt {
33
 
34
  /**
35
  * @param \OpenSSLAsymmetricKey|string $privateKey
36
- * @return string
37
  * @throws \Exception
38
  */
39
  public function getPublicKeyFromPrivateKey( $privateKey ) :string {
@@ -54,7 +53,6 @@ class OpenSslEncrypt {
54
  }
55
 
56
  /**
57
- * @param OpenSslEncryptVo $VO
58
  * @param \OpenSSLAsymmetricKey|string $privateKey
59
  * @return string|false
60
  */
@@ -84,9 +82,8 @@ class OpenSslEncrypt {
84
  /**
85
  * @param mixed $mDataToEncrypt
86
  * @param string $publicKey
87
- * @return OpenSslEncryptVo
88
  */
89
- public function sealData( $mDataToEncrypt, $publicKey, $cipher = 'rc4' ) {
90
 
91
  $VO = $this->getStandardEncryptResponse();
92
 
@@ -138,6 +135,12 @@ class OpenSslEncrypt {
138
  $VO->sealed_data = $encryptedData;
139
  $VO->sealed_password = $passwordKeys[ 0 ];
140
  }
 
 
 
 
 
 
141
 
142
  if ( $cipher !== 'rc4' ) {
143
  // we do a backup seal as rc4 while we determine availability of other cipers
33
 
34
  /**
35
  * @param \OpenSSLAsymmetricKey|string $privateKey
 
36
  * @throws \Exception
37
  */
38
  public function getPublicKeyFromPrivateKey( $privateKey ) :string {
53
  }
54
 
55
  /**
 
56
  * @param \OpenSSLAsymmetricKey|string $privateKey
57
  * @return string|false
58
  */
82
  /**
83
  * @param mixed $mDataToEncrypt
84
  * @param string $publicKey
 
85
  */
86
+ public function sealData( $mDataToEncrypt, $publicKey, $cipher = 'rc4' ) :OpenSslEncryptVo {
87
 
88
  $VO = $this->getStandardEncryptResponse();
89
 
135
  $VO->sealed_data = $encryptedData;
136
  $VO->sealed_password = $passwordKeys[ 0 ];
137
  }
138
+ else {
139
+ $VO->message = sprintf( 'openssl_seal() result was "%s".', var_export( $mResult, true ) );
140
+ if ( is_null( $encryptedData ) ) {
141
+ $VO->message .= ' Encrypted data was null.';
142
+ }
143
+ }
144
 
145
  if ( $cipher !== 'rc4' ) {
146
  // we do a backup seal as rc4 while we determine availability of other cipers
templates/twig/admin/user/profile/mfa/mfa_ga.twig CHANGED
@@ -35,15 +35,17 @@
35
  <tr>
36
  <th><label for="shield_gacode" class="form-label">{{ strings.title }}</label></th>
37
  <td>
38
- <div style="width: 350px; margin-bottom: 15px; text-align: center">
39
- <img src="{{ hrefs.src_chart_url }}" alt="{{ strings.description_chart_url }}"
40
- title="{{ strings.description_chart_url }}"
41
- class="shield-mfa-googleauth"
42
- style="display:block;margin:0 auto 10px" />
43
  <div style="margin: auto;width: fit-content;text-align: center;"
44
  id="shield_ga_secret">{{ vars.ga_secret }}</div>
45
  </div>
46
 
 
 
 
 
 
 
47
  <input class="regular-text"
48
  type="text"
49
  id="shield_gacode"
35
  <tr>
36
  <th><label for="shield_gacode" class="form-label">{{ strings.title }}</label></th>
37
  <td>
38
+ <div style="width: 350px; margin-bottom: 15px; text-align: center" id="SvgQrCode">
 
 
 
 
39
  <div style="margin: auto;width: fit-content;text-align: center;"
40
  id="shield_ga_secret">{{ vars.ga_secret }}</div>
41
  </div>
42
 
43
+ <script>
44
+ /** https://github.com/datalog/qrcode-svg */
45
+ svgNode = QRCode( '{{ hrefs.qr_code_auth|raw }}' );
46
+ document.getElementById( "SvgQrCode" ).prepend( svgNode );
47
+ </script>
48
+
49
  <input class="regular-text"
50
  type="text"
51
  id="shield_gacode"
templates/twig/integration/mainwp/page_extension.twig CHANGED
@@ -1,17 +1,5 @@
1
  {{ content.mainwp_header|raw }}
2
 
3
- <div class="row">
4
- <div class="column one">
5
- <div class="ui labeled icon inverted menu mainwp-sub-submenu" id="mainwp-shield-menu">
6
- {% for submenu_item in vars.submenu %}
7
- <a href="{{ submenu_item.href }}"
8
- class="item {% if submenu_item.active %}active{% endif %}">
9
- <i class="{{ submenu_item.icon }} icon"></i>{{ submenu_item.title }}</a>
10
- {% endfor %}
11
- </div>
12
- </div>
13
- </div>
14
-
15
  {{ content.page_inner|raw }}
16
 
17
  {{ content.mainwp_footer|raw }}
1
  {{ content.mainwp_header|raw }}
2
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  {{ content.page_inner|raw }}
4
 
5
  {{ content.mainwp_footer|raw }}
templates/twig/integration/mainwp/pages/page_base.twig ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div id="ShieldMainwpExtension">
2
+ {% block body_header %}
3
+
4
+ {% block menu_topnav %}
5
+ <div class="row">
6
+ <div class="column one">
7
+ <div class="ui labeled icon inverted menu mainwp-sub-submenu" id="mainwp-shield-menu">
8
+ {% for menu_topnav_item in vars.menu_topnav %}
9
+ <a href="{{ menu_topnav_item.href }}"
10
+ class="item {% if menu_topnav_item.active %}active{% endif %}">
11
+ <i class="{{ menu_topnav_item.icon }} icon"></i>{{ menu_topnav_item.title }}</a>
12
+ {% endfor %}
13
+ </div>
14
+ </div>
15
+ </div>
16
+ {% endblock %}
17
+
18
+ {% block actions_bar %}
19
+ {% endblock %}
20
+
21
+ {% endblock %}
22
+
23
+ {% block body_main %}
24
+ {% endblock %}
25
+
26
+ {% block body_footer %}
27
+ {% endblock %}
28
+
29
+ {% block inline_js %}
30
+ <script type="text/javascript">
31
+ jQuery( document ).ready( function () {
32
+ jQuery( '#ShieldMainwpExtension' ).icwpWpsfMainwpExt( {
33
+ 'ajax_actions':{{ ajax.actions|raw }}
34
+ } );
35
+ } );
36
+ </script>
37
+ {% endblock %}
38
+ </div>
templates/twig/integration/mainwp/pages/site.twig ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ {% extends '/integration/mainwp/pages/page_base.twig' %}
2
+
3
+ {% block body_main %}
4
+ <iframe id="SiteContent" srcdoc="<p>Please wait while the content loads..."></iframe>
5
+ {% endblock %}
6
+
7
+ {% block body_footer %}
8
+ {% endblock %}
templates/twig/integration/mainwp/pages/sites.twig CHANGED
@@ -1,153 +1,187 @@
 
1
 
2
- <div class="mainwp_shield_tabs_content" data-tab="dashboard">
3
- <div class="mainwp-actions-bar">
4
- <div class="ui grid">
5
- <div class="ui two column row">
6
- <div class="middle aligned column ui mini form">
7
- <div class="ui dropdown selection" tabindex="0">
8
- <select id="mwp_shield_plugin_action">
9
- <option value="-1">Bulk Actions</option>
10
- <option value="activate-selected">Activate</option>
11
- <option value="update-selected">Update</option>
12
- <option value="hide-selected">Hide</option>
13
- <option value="show-selected">Unhide</option>
14
- </select><i class="dropdown icon"></i><div class="text">Bulk Actions</div><div class="menu" tabindex="-1"><div class="item active selected" data-value="-1" data-text="Bulk Actions">Bulk Actions</div><div class="item" data-value="activate-selected" data-text="Activate">Activate</div><div class="item" data-value="update-selected" data-text="Update">Update</div><div class="item" data-value="hide-selected" data-text="Hide">Hide</div><div class="item" data-value="show-selected" data-text="Unhide">Unhide</div></div></div>
15
- <input type="button" value="Apply" class="ui basic mini button action" id="shield_plugin_doaction_btn" name="shield_plugin_doaction_btn">
16
- </div>
17
- <div class="right aligned middle aligned column">
18
- <span id="mainwp_shield_remind_change_status"></span>
19
- <a href="#" id="mainwp-shield-kill-scan" class="ui mini button">Stop Scan Process</a>
20
- <a href="#" id="mainwp-shield-run-scan" class="ui mini green button shield-run-scan" title="Start a Wordfence Scan">Scan all Child Sites</a>
21
- </div>
22
- </div>
23
- </div>
24
- </div>
25
- </div>
26
-
27
-
28
- <div class="ui stackable grid">
29
-
30
- <div class="row">
31
- <div class="sixteen column">
32
-
33
- <table id="mainwp-shield-extension-table-sites" class="mainwp-shield-ext-table ui single line table"
34
- style="width:100%">
35
- <thead>
36
- <tr>
37
- <th class="collapsing no-sort check-column">
38
- <span class="ui checkbox">
39
- <input type="checkbox" name="checkall" class="url_checkall" id="url_checkall" />
40
- </span>
41
- </th>
42
- <th>{{ strings.site }}</th>
43
- <th>{{ strings.url }}</th>
44
- <th>{{ strings.status }}</th>
45
- <th>{{ strings.issues }}</th>
46
- <th>{{ strings.version }}</th>
47
- <th>{{ strings.last_sync }}</th>
48
- <th>&nbsp;</th>
49
- </tr>
50
- </thead>
51
- <tbody>
52
- {% for site in vars.sites %}
53
- <tr class="shield_site_row" data-shield_status="{{ site.shield.status_key }}">
54
- <td class="check-column">
55
- <span class="ui checkbox"><input type="checkbox" name="checkbox_url"
56
- class="checkbox_url"></span>
57
- </td>
58
- <td>{{ site.name }}</td>
59
- <td><a href="{{ site.url }}" target="_blank">{{ site.url }}</a></td>
60
- {% if site.shield.is_active %}
61
- <td>
62
- {{ site.shield.status }}
63
- </td>
64
 
65
- <td>
66
- <a href="{{ site.shield.issues_href }}"
67
- class="ui mini compact button {{ site.shield.has_issues ? 'red':'green' }}"
68
- target="_blank">{{ site.shield.issues }}</a>
69
- </td>
70
 
71
- <td>
72
- {{ site.shield.meta.version }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  </td>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  <td>
75
- {{ site.shield.sync_at_diff }}
76
- <br /><small>{{ site.shield.sync_at_text }}</small>
77
- </td>
78
- {% elseif site.shield.is_inactive %}
79
- <td colspan="4" class="cell-span-issue">{{ strings.st_inactive }}</td>
80
- {% elseif site.shield.is_notpro %}
81
- <td colspan="4" class="cell-span-issue">{{ strings.st_notpro }}</td>
82
- {% elseif site.shield.is_mwpnoton %}
83
- <td colspan="4" class="cell-span-issue">{{ strings.st_mwpnoton }}</td>
84
- {% elseif site.shield.is_sync_rqd %}
85
- <td colspan="4" class="cell-span-issue">{{ strings.st_sync_rqd }}</td>
86
- {% elseif site.shield.is_version_mismatch %}
87
- <td colspan="4" class="cell-span-issue">{{ strings.st_version_mismatch }}</td>
88
- {% elseif site.shield.is_notinstalled %}
89
- <td colspan="4" class="cell-span-issue">{{ strings.st_notinstalled }}</td>
90
- {% else %}
91
- <td colspan="4" class="cell-span-issue">{{ strings.st_unknown }}</td>
92
- {% endif %}
93
- <td>
94
- <div class="site-dropdown ui left pointing dropdown icon mini basic green button"
95
- style="z-index: 999;" tabindex="0">
96
- <i class="ellipsis horizontal icon"></i>
97
- <div class="menu" tabindex="-1" data-sid="{{ site.id }}">
98
-
99
- <a href="#"
100
- data-saction="sync"
101
- class="item site_action {% if not site.shield.can_sync %}disabled{% endif %}"
102
- >{{ strings.act_sync }}</a>
103
-
104
- {% if site.shield.is_inactive %}
105
- <a href="#"
106
- data-saction="activate"
107
- class="item site_action"
108
- >{{ strings.act_activate }}</a>
109
 
110
- {% elseif site.shield.is_notinstalled %}
111
  <a href="#"
112
- data-saction="install"
113
- class="item site_action"
114
- >{{ strings.act_install }}</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
 
116
- {% else %}
117
  <a href="#"
118
- data-saction="deactivate"
119
- class="item site_action"
120
- >{{ strings.act_deactivate }}</a>
121
- {% endif %}
122
-
123
- <a href="#"
124
- class="item site_action {% if not site.shield.is_active %}disabled{% endif %}"
125
- {% if site.shield.is_mwpnoton %}
126
- data-saction="mwp"
127
- {% set linktxt = strings.act_mwp %}
128
- {% else %}
129
- data-saction="license"
130
- {% set linktxt = strings.act_license %}
131
- {% endif %}
132
- >{{ linktxt }}</a>
133
  </div>
134
- </div>
135
- </td>
136
- </tr>
137
- {% endfor %}
138
- </tbody>
139
- </table>
140
- </div>
141
- </div>
142
 
143
- </div>
 
144
 
 
145
 
146
- <script type="text/javascript">
147
- jQuery( document ).ready( function () {
148
- jQuery( '#mainwp-shield-extension-table-sites' ).icwpWpsfMainwpExt( {
149
- 'ajax_sh_site_action': {{ ajax.mwp_sh_site_action|raw }},
150
- 'ajax_sh_ext_table': {{ ajax.mwp_sh_ext_table|raw }},
151
- } );
152
- } );
153
- </script>
1
+ {% extends '/integration/mainwp/pages/page_base.twig' %}
2
 
3
+ {% block actions_bar %}
4
+ {# <div class="mainwp_shield_tabs_content" data-tab="dashboard">#}
5
+ {# <div class="mainwp-actions-bar">#}
6
+ {# <div class="ui grid">#}
7
+ {# <div class="ui two column row">#}
8
+ {# <div class="middle aligned column ui mini form">#}
9
+ {# #}
10
+ {# <div class="ui dropdown selection" tabindex="0">#}
11
+ {# <select id="mwp_shield_plugin_action">#}
12
+ {# <option value="-1">Bulk Actions</option>#}
13
+ {# <option value="activate-selected">Activate</option>#}
14
+ {# <option value="update-selected">Update</option>#}
15
+ {# <option value="hide-selected">Hide</option>#}
16
+ {# <option value="show-selected">Unhide</option>#}
17
+ {# </select>#}
18
+ {# <i class="dropdown icon"></i>#}
19
+ {# <div class="text">Bulk Actions</div>#}
20
+ {# <div class="menu" tabindex="-1">#}
21
+ {# <div#}
22
+ {# class="item active selected" data-value="-1" data-text="Bulk Actions">Bulk Actions</div>#}
23
+ {# <div#}
24
+ {# class="item" data-value="activate-selected" data-text="Activate">Activate</div>#}
25
+ {# <div class="item" data-value="update-selected" data-text="Update">Update</div>#}
26
+ {# <div class="item" data-value="hide-selected" data-text="Hide">Hide</div>#}
27
+ {# <div class="item" data-value="show-selected" data-text="Unhide">Unhide</div>#}
28
+ {# </div>#}
29
+ {# </div>#}
30
+ {# #}
31
+ {# <input type="button" value="Apply"#}
32
+ {# class="ui basic mini button action"#}
33
+ {# id="shield_plugin_doaction_btn"#}
34
+ {# name="shield_plugin_doaction_btn">#}
35
+ {# </div>#}
36
+ {# #}
37
+ {# <div class="right aligned middle aligned column">#}
38
+ {# <span id="mainwp_shield_remind_change_status"></span>#}
39
+ {# <a href="#" id="mainwp-shield-kill-scan" class="ui mini button">Stop Scan Process</a>#}
40
+ {# <a href="#" id="mainwp-shield-run-scan" class="ui mini green button shield-run-scan"#}
41
+ {# title="Start a Wordfence Scan">Scan all Child Sites</a>#}
42
+ {# </div>#}
43
+ {# #}
44
+ {# </div>#}
45
+ {# </div>#}
46
+ {# </div>#}
47
+ {# </div>#}
48
+ {% endblock %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
+ {% block body_main %}
51
+ <div class="ui stackable grid">
 
 
 
52
 
53
+ <div class="row">
54
+ <div class="sixteen column">
55
+
56
+ <table id="mainwp-shield-extension-table-sites" class="mainwp-shield-ext-table ui single line table"
57
+ style="width:100%">
58
+ <thead>
59
+ <tr>
60
+ <th class="collapsing no-sort check-column">
61
+ <span class="ui checkbox">
62
+ <input type="checkbox" name="checkall" class="url_checkall" id="url_checkall" />
63
+ </span>
64
+ </th>
65
+ {# <th>{{ strings.site }}</th>#}
66
+ <th>{{ strings.url }}</th>
67
+ <th>{{ strings.status }}</th>
68
+ <th>{{ strings.overall_grade }}</th>
69
+ <th>{{ strings.issues }}</th>
70
+ <th>{{ strings.version }}</th>
71
+ <th>{{ strings.last_sync }}</th>
72
+ <th>&nbsp;</th>
73
+ </tr>
74
+ </thead>
75
+ <tbody>
76
+ {% for site in vars.sites %}
77
+ <tr class="shield_site_row" data-shield_status="{{ site.shield.status_key }}">
78
+
79
+ <td class="check-column">
80
+ <span class="ui checkbox">
81
+ <input type="checkbox" name="checkbox_url" class="checkbox_url" />
82
+ </span>
83
  </td>
84
+
85
+ {# <td>#}
86
+ {# {% if site.shield.is_active %}#}
87
+ {# <a href="{{ site.shield.href_manage }}"#}
88
+ {# class="ui mini compact button">{{ strings.manage }}</a>#}
89
+ {# {% else %}#}
90
+ {# {{ site.name }}#}
91
+ {# {% endif %}#}
92
+ {# </td>#}
93
+
94
+ <td><a href="{{ site.url }}" target="_blank">{{ site.url }}</a></td>
95
+ {% if site.shield.is_active %}
96
+ <td>
97
+ {{ site.shield.status }}
98
+ </td>
99
+
100
+ <td>
101
+ <a href="{{ site.shield.grades.href }}"
102
+ class="ui mini compact button {{ site.shield.grades.good ? 'green':'red' }}"
103
+ target="_blank">{{ site.shield.grades.integrity }}</a>
104
+ </td>
105
+
106
+ <td>
107
+ <a href="{{ site.shield.href_issues }}"
108
+ class="ui mini compact button {{ site.shield.has_issues ? 'red':'green' }}"
109
+ target="_blank">{{ site.shield.issues }}</a>
110
+ </td>
111
+
112
+ <td>
113
+ {{ site.shield.meta.version }}
114
+ </td>
115
+ <td>
116
+ {{ site.shield.sync_at_diff }}
117
+ <br /><small>{{ site.shield.sync_at_text }}</small>
118
+ </td>
119
+ {% elseif site.shield.is_inactive %}
120
+ <td colspan="4" class="cell-span-issue">{{ strings.st_inactive }}</td>
121
+ {% elseif site.shield.is_notpro %}
122
+ <td colspan="4" class="cell-span-issue">{{ strings.st_notpro }}</td>
123
+ {% elseif site.shield.is_mwpnoton %}
124
+ <td colspan="4" class="cell-span-issue">{{ strings.st_mwpnoton }}</td>
125
+ {% elseif site.shield.is_sync_rqd %}
126
+ <td colspan="4" class="cell-span-issue">{{ strings.st_sync_rqd }}</td>
127
+ {% elseif site.shield.is_version_mismatch %}
128
+ <td colspan="4" class="cell-span-issue">{{ strings.st_version_mismatch }}</td>
129
+ {% elseif site.shield.is_notinstalled %}
130
+ <td colspan="4" class="cell-span-issue">{{ strings.st_notinstalled }}</td>
131
+ {% else %}
132
+ <td colspan="4" class="cell-span-issue">{{ strings.st_unknown }}</td>
133
+ {% endif %}
134
  <td>
135
+ <div class="site-dropdown ui left pointing dropdown icon mini basic green button"
136
+ style="z-index: 999;" tabindex="0">
137
+ <i class="ellipsis horizontal icon"></i>
138
+ <div class="menu" tabindex="-1" data-sid="{{ site.id }}">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
 
 
140
  <a href="#"
141
+ data-saction="sync"
142
+ class="item site_action {% if not site.shield.can_sync %}disabled{% endif %}"
143
+ >{{ strings.act_sync }}</a>
144
+
145
+ {% if site.shield.is_inactive %}
146
+ <a href="#"
147
+ data-saction="activate"
148
+ class="item site_action"
149
+ >{{ strings.act_activate }}</a>
150
+
151
+ {% elseif site.shield.is_notinstalled %}
152
+ <a href="#"
153
+ data-saction="install"
154
+ class="item site_action"
155
+ >{{ strings.act_install }}</a>
156
+
157
+ {% else %}
158
+ <a href="#"
159
+ data-saction="deactivate"
160
+ class="item site_action"
161
+ >{{ strings.act_deactivate }}</a>
162
+ {% endif %}
163
 
 
164
  <a href="#"
165
+ class="item site_action {% if not site.shield.is_active %}disabled{% endif %}"
166
+ {% if site.shield.is_mwpnoton %}
167
+ data-saction="mwp"
168
+ {% set linktxt = strings.act_mwp %}
169
+ {% else %}
170
+ data-saction="license"
171
+ {% set linktxt = strings.act_license %}
172
+ {% endif %}
173
+ >{{ linktxt }}</a>
174
+ </div>
 
 
 
 
 
175
  </div>
176
+ </td>
177
+ </tr>
178
+ {% endfor %}
179
+ </tbody>
180
+ </table>
 
 
 
181
 
182
+ </div>
183
+ </div>
184
 
185
+ </div>
186
 
187
+ {% endblock %}