Version Description
Download this release
Release Info
Developer | paultgoodchild |
Plugin | Shield Security for WordPress |
Version | 13.0.5 |
Comparing to | |
See all releases |
Code changes from version 13.0.4 to 13.0.5
- cl.json +36 -0
- config/deprecated/hack_protect.php +3 -3
- config/deprecated/login_protect.php +1 -43
- config/deprecated/plugin.php +1 -6
- config/login_protect.json +1 -43
- icwp-wpsf.php +2 -2
- plugin-spec.php +28 -24
- plugin.json +28 -24
- readme.txt +1 -1
- resources/css/shield/userprofile.css +15 -0
- resources/js/shield/notbot.js +42 -45
- src/lib/src/Controller/Controller.php +6 -14
- src/lib/src/Modules/Autoupdates/AjaxHandler.php +0 -9
- src/lib/src/Modules/Base/AdminNotices.php +35 -53
- src/lib/src/Modules/Base/Options.php +3 -7
- src/lib/src/Modules/Data/DB/IPs/Ops/Insert.php +0 -1
- src/lib/src/Modules/IPs/Lib/Bots/NotBot/InsertNotBotJs.php +12 -9
- src/lib/src/Modules/Integrations/Lib/Bots/Common/BaseBotDetectionController.php +18 -19
- src/lib/src/Modules/Integrations/Lib/Bots/Common/BaseHandler.php +41 -19
- src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/Base.php +8 -12
- src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/ContactForm7.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/ElementorPro.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/FluentForms.php +15 -14
- src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/FormidableForms.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/Forminator.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/GravityForms.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/Groundhogg.php +1 -6
- src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/KaliForms.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/NinjaForms.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/SuperForms.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/SupportCandy.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/WPForms.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/WpForo.php +10 -11
- src/lib/src/Modules/Integrations/Lib/Bots/Spam/SpamController.php +16 -16
- src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/Base.php +8 -7
- src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/Buddyboss.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/Buddypress.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/EasyDigitalDownloads.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/LearnPress.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/LifterLMS.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/MemberPress.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/PaidMemberSubscriptions.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/ProfileBuilder.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/UltimateMember.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/WPMembers.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/WooCommerce.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/WordPress.php +0 -4
- src/lib/src/Modules/Integrations/Lib/Bots/UserForms/UserFormsController.php +15 -17
- src/lib/src/Modules/Integrations/ModCon.php +14 -3
- src/lib/src/Modules/Integrations/Options.php +3 -3
- src/lib/src/Modules/Integrations/Processor.php +1 -3
- src/lib/src/Modules/Integrations/Strings.php +3 -7
- src/lib/src/Modules/Integrations/UI.php +34 -3
- src/lib/src/Modules/Integrations/Upgrade.php +0 -16
- src/lib/src/Modules/License/AjaxHandler.php +6 -6
- src/lib/src/Modules/License/Lib/LicenseHandler.php +30 -20
- src/lib/src/Modules/License/WpCli/License.php +6 -6
- src/lib/src/Modules/LoginGuard/Lib/AntiBot/AntibotSetup.php +3 -1
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/LoginIntentPage.php +6 -9
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/MfaController.php +11 -18
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/MfaProfilesController.php +80 -14
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/MfaSkip.php +30 -35
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Profiles/RenderCustomForms.php +16 -9
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/BaseProvider.php +0 -9
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/UserProfile.php +6 -71
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/ValidateLoginIntentRequest.php +0 -1
- src/lib/src/Modules/LoginGuard/ModCon.php +7 -17
- src/lib/src/Modules/LoginGuard/Options.php +9 -11
- src/lib/src/Modules/LoginGuard/Processor.php +19 -10
- src/lib/src/Modules/LoginGuard/Strings.php +8 -2
- src/lib/src/Modules/LoginGuard/UI.php +40 -16
- src/lib/src/Modules/ModConsumer.php +0 -4
- src/lib/src/Modules/OptsConsumer.php +0 -4
- src/lib/src/Modules/Plugin/AdminNotices.php +2 -12
- src/lib/src/Modules/Plugin/Processor.php +3 -0
- src/lib/src/Scans/Afs/ResultItem.php +1 -1
- src/lib/src/ShieldNetApi/HandshakingNonce.php +2 -4
- src/lib/src/ShieldNetApi/ShieldNetApiController.php +0 -2
- src/lib/src/ShieldNetApi/ShieldNetApiDataVO.php +0 -2
- src/lib/vendor/composer/ClassLoader.php +14 -109
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Email.php +0 -2
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/GeoIp.php +0 -4
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Html.php +0 -4
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Licenses/EddLicenseVO.php +1 -2
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Obfuscate.php +0 -4
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/ServiceProviders.php +0 -4
- templates/twig/admin/user/profile/mfa/mfa_container.twig +0 -12
- templates/twig/admin/user/profile/mfa/mfa_email.twig +1 -1
- templates/twig/components/options_form/main.twig +1 -1
- templates/twig/notices/plugin-mailing-list-signup.twig +2 -6
- templates/twig/user/profile/mfa/main.twig +6 -1
cl.json
CHANGED
@@ -129,6 +129,42 @@
|
|
129 |
"title": "Error with MainWP loading in certain cases.",
|
130 |
"description": [],
|
131 |
"patch": "13.0.4"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
}
|
133 |
]
|
134 |
},
|
129 |
"title": "Error with MainWP loading in certain cases.",
|
130 |
"description": [],
|
131 |
"patch": "13.0.4"
|
132 |
+
},
|
133 |
+
{
|
134 |
+
"type": "improved",
|
135 |
+
"title": "Options to provide custom roles for Email 2FA enforcement is now free-form.",
|
136 |
+
"description": [],
|
137 |
+
"patch": "13.0.5"
|
138 |
+
},
|
139 |
+
{
|
140 |
+
"type": "improved",
|
141 |
+
"title": "Multi-factor authentication settings are available even when your IP is on the bypass lists.",
|
142 |
+
"description": [],
|
143 |
+
"patch": "13.0.5"
|
144 |
+
},
|
145 |
+
{
|
146 |
+
"type": "improved",
|
147 |
+
"title": "ShieldPRO license lookups when using separate domains for multilingual site versions.",
|
148 |
+
"description": [],
|
149 |
+
"patch": "13.0.5"
|
150 |
+
},
|
151 |
+
{
|
152 |
+
"type": "improved",
|
153 |
+
"title": "FluentForms integration wasn't always loading and so SPAM submissions could still come through.",
|
154 |
+
"description": [],
|
155 |
+
"patch": "13.0.5"
|
156 |
+
},
|
157 |
+
{
|
158 |
+
"type": "improved",
|
159 |
+
"title": "NotBot Javascript is improved to better handle server timeouts and work around Page Caching limitations.",
|
160 |
+
"description": [],
|
161 |
+
"patch": "13.0.5"
|
162 |
+
},
|
163 |
+
{
|
164 |
+
"type": "fixed",
|
165 |
+
"title": "Prevent some fatal errors when integrating with 3rd parties and their data isn't as expected.",
|
166 |
+
"description": [],
|
167 |
+
"patch": "13.0.5"
|
168 |
}
|
169 |
]
|
170 |
},
|
config/deprecated/hack_protect.php
CHANGED
@@ -98,7 +98,7 @@
|
|
98 |
"default": "Y",
|
99 |
"type": "checkbox",
|
100 |
"link_info": "https://shsec.io/wpsf38",
|
101 |
-
"link_blog": "
|
102 |
"beacon_id": 217,
|
103 |
"name": "Enable Hack Guard",
|
104 |
"summary": "Enable (or Disable) The Hack Guard Module",
|
@@ -111,7 +111,7 @@
|
|
111 |
"type": "checkbox",
|
112 |
"link_info": "https://shsec.io/hd",
|
113 |
"link_blog": "https://shsec.io/wpsf37",
|
114 |
-
"beacon_id":
|
115 |
"name": "WP Core File Scanner",
|
116 |
"summary": "Automatically Scans WordPress Core Files For Alterations",
|
117 |
"description": "Compares all WordPress core files on your site against the official WordPress files. WordPress Core files should never be altered for any reason."
|
@@ -203,7 +203,7 @@
|
|
203 |
"default": "Y",
|
204 |
"link_info": "https://shsec.io/du",
|
205 |
"link_blog": "https://shsec.io/ah",
|
206 |
-
"beacon_id":
|
207 |
"name": "Vulnerability Scanner",
|
208 |
"summary": "Enable The Vulnerability Scanner",
|
209 |
"description": "Scan all your WordPress assets for known security vulnerabilities."
|
98 |
"default": "Y",
|
99 |
"type": "checkbox",
|
100 |
"link_info": "https://shsec.io/wpsf38",
|
101 |
+
"link_blog": "",
|
102 |
"beacon_id": 217,
|
103 |
"name": "Enable Hack Guard",
|
104 |
"summary": "Enable (or Disable) The Hack Guard Module",
|
111 |
"type": "checkbox",
|
112 |
"link_info": "https://shsec.io/hd",
|
113 |
"link_blog": "https://shsec.io/wpsf37",
|
114 |
+
"beacon_id": 454,
|
115 |
"name": "WP Core File Scanner",
|
116 |
"summary": "Automatically Scans WordPress Core Files For Alterations",
|
117 |
"description": "Compares all WordPress core files on your site against the official WordPress files. WordPress Core files should never be altered for any reason."
|
203 |
"default": "Y",
|
204 |
"link_info": "https://shsec.io/du",
|
205 |
"link_blog": "https://shsec.io/ah",
|
206 |
+
"beacon_id": 134,
|
207 |
"name": "Vulnerability Scanner",
|
208 |
"summary": "Enable The Vulnerability Scanner",
|
209 |
"description": "Scan all your WordPress assets for known security vulnerabilities."
|
config/deprecated/login_protect.php
CHANGED
@@ -213,55 +213,13 @@
|
|
213 |
"key": "two_factor_auth_user_roles",
|
214 |
"section": "section_2fa_email",
|
215 |
"advanced": true,
|
216 |
-
"type": "
|
217 |
"default": [
|
218 |
"contributor",
|
219 |
"author",
|
220 |
"editor",
|
221 |
"administrator"
|
222 |
],
|
223 |
-
"value_options": [
|
224 |
-
{
|
225 |
-
"value_key": "subscriber",
|
226 |
-
"text": "Subscribers"
|
227 |
-
},
|
228 |
-
{
|
229 |
-
"value_key": "contributor",
|
230 |
-
"text": "Contributors"
|
231 |
-
},
|
232 |
-
{
|
233 |
-
"value_key": "author",
|
234 |
-
"text": "Authors"
|
235 |
-
},
|
236 |
-
{
|
237 |
-
"value_key": "editor",
|
238 |
-
"text": "Editors"
|
239 |
-
},
|
240 |
-
{
|
241 |
-
"value_key": "administrator",
|
242 |
-
"text": "Administrators"
|
243 |
-
},
|
244 |
-
{
|
245 |
-
"value_key": "customer",
|
246 |
-
"text": "[Woo] Customer"
|
247 |
-
},
|
248 |
-
{
|
249 |
-
"value_key": "shop_manager",
|
250 |
-
"text": "[Woo/EDD] Shop Manager"
|
251 |
-
},
|
252 |
-
{
|
253 |
-
"value_key": "shop_accountant",
|
254 |
-
"text": "[EDD] Shop Accountant"
|
255 |
-
},
|
256 |
-
{
|
257 |
-
"value_key": "shop_worker",
|
258 |
-
"text": "[EDD] Shop Worker"
|
259 |
-
},
|
260 |
-
{
|
261 |
-
"value_key": "edd_subscriber",
|
262 |
-
"text": "[EDD] Customer"
|
263 |
-
}
|
264 |
-
],
|
265 |
"link_info": "https://shsec.io/4v",
|
266 |
"link_blog": "",
|
267 |
"beacon_id": 243,
|
213 |
"key": "two_factor_auth_user_roles",
|
214 |
"section": "section_2fa_email",
|
215 |
"advanced": true,
|
216 |
+
"type": "array",
|
217 |
"default": [
|
218 |
"contributor",
|
219 |
"author",
|
220 |
"editor",
|
221 |
"administrator"
|
222 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
223 |
"link_info": "https://shsec.io/4v",
|
224 |
"link_blog": "",
|
225 |
"beacon_id": 243,
|
config/deprecated/plugin.php
CHANGED
@@ -107,11 +107,6 @@
|
|
107 |
"title_short": "Import / Export",
|
108 |
"beacon_id": 129
|
109 |
},
|
110 |
-
{
|
111 |
-
"slug": "section_integrations",
|
112 |
-
"title": "Integrations",
|
113 |
-
"title_short": "Integrations"
|
114 |
-
},
|
115 |
{
|
116 |
"slug": "section_global_security_options",
|
117 |
"title": "Global Plugin Security Options",
|
@@ -397,7 +392,7 @@
|
|
397 |
],
|
398 |
"link_info": "https://shsec.io/dq",
|
399 |
"link_blog": "",
|
400 |
-
"beacon_id":
|
401 |
"name": "CAPTCHA Provider",
|
402 |
"summary": "Which CAPTCHA Provider To Use Throughout",
|
403 |
"description": "You can choose the CAPTCHA provider depending on your preferences."
|
107 |
"title_short": "Import / Export",
|
108 |
"beacon_id": 129
|
109 |
},
|
|
|
|
|
|
|
|
|
|
|
110 |
{
|
111 |
"slug": "section_global_security_options",
|
112 |
"title": "Global Plugin Security Options",
|
392 |
],
|
393 |
"link_info": "https://shsec.io/dq",
|
394 |
"link_blog": "",
|
395 |
+
"beacon_id": 390,
|
396 |
"name": "CAPTCHA Provider",
|
397 |
"summary": "Which CAPTCHA Provider To Use Throughout",
|
398 |
"description": "You can choose the CAPTCHA provider depending on your preferences."
|
config/login_protect.json
CHANGED
@@ -213,55 +213,13 @@
|
|
213 |
"key": "two_factor_auth_user_roles",
|
214 |
"section": "section_2fa_email",
|
215 |
"advanced": true,
|
216 |
-
"type": "
|
217 |
"default": [
|
218 |
"contributor",
|
219 |
"author",
|
220 |
"editor",
|
221 |
"administrator"
|
222 |
],
|
223 |
-
"value_options": [
|
224 |
-
{
|
225 |
-
"value_key": "subscriber",
|
226 |
-
"text": "Subscribers"
|
227 |
-
},
|
228 |
-
{
|
229 |
-
"value_key": "contributor",
|
230 |
-
"text": "Contributors"
|
231 |
-
},
|
232 |
-
{
|
233 |
-
"value_key": "author",
|
234 |
-
"text": "Authors"
|
235 |
-
},
|
236 |
-
{
|
237 |
-
"value_key": "editor",
|
238 |
-
"text": "Editors"
|
239 |
-
},
|
240 |
-
{
|
241 |
-
"value_key": "administrator",
|
242 |
-
"text": "Administrators"
|
243 |
-
},
|
244 |
-
{
|
245 |
-
"value_key": "customer",
|
246 |
-
"text": "[Woo] Customer"
|
247 |
-
},
|
248 |
-
{
|
249 |
-
"value_key": "shop_manager",
|
250 |
-
"text": "[Woo/EDD] Shop Manager"
|
251 |
-
},
|
252 |
-
{
|
253 |
-
"value_key": "shop_accountant",
|
254 |
-
"text": "[EDD] Shop Accountant"
|
255 |
-
},
|
256 |
-
{
|
257 |
-
"value_key": "shop_worker",
|
258 |
-
"text": "[EDD] Shop Worker"
|
259 |
-
},
|
260 |
-
{
|
261 |
-
"value_key": "edd_subscriber",
|
262 |
-
"text": "[EDD] Customer"
|
263 |
-
}
|
264 |
-
],
|
265 |
"link_info": "https://shsec.io/4v",
|
266 |
"link_blog": "",
|
267 |
"beacon_id": 243,
|
213 |
"key": "two_factor_auth_user_roles",
|
214 |
"section": "section_2fa_email",
|
215 |
"advanced": true,
|
216 |
+
"type": "array",
|
217 |
"default": [
|
218 |
"contributor",
|
219 |
"author",
|
220 |
"editor",
|
221 |
"administrator"
|
222 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
223 |
"link_info": "https://shsec.io/4v",
|
224 |
"link_blog": "",
|
225 |
"beacon_id": 243,
|
icwp-wpsf.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: Shield Security
|
4 |
* Plugin URI: https://shsec.io/2f
|
5 |
* Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
|
6 |
-
* Version: 13.0.
|
7 |
* Text Domain: wp-simple-firewall
|
8 |
* Domain Path: /languages
|
9 |
* Author: Shield Security
|
@@ -11,7 +11,7 @@
|
|
11 |
*/
|
12 |
|
13 |
/**
|
14 |
-
* Copyright (c)
|
15 |
* All rights reserved.
|
16 |
* "Shield" (formerly WordPress Simple Firewall) is distributed under the GNU
|
17 |
* General Public License, Version 2, June 1991. Copyright (C) 1989, 1991 Free
|
3 |
* Plugin Name: Shield Security
|
4 |
* Plugin URI: https://shsec.io/2f
|
5 |
* Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
|
6 |
+
* Version: 13.0.5
|
7 |
* Text Domain: wp-simple-firewall
|
8 |
* Domain Path: /languages
|
9 |
* Author: Shield Security
|
11 |
*/
|
12 |
|
13 |
/**
|
14 |
+
* Copyright (c) 2022 Shield Security <support@getshieldsecurity.com>
|
15 |
* All rights reserved.
|
16 |
* "Shield" (formerly WordPress Simple Firewall) is distributed under the GNU
|
17 |
* General Public License, Version 2, June 1991. Copyright (C) 1989, 1991 Free
|
plugin-spec.php
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
{
|
2 |
"properties": {
|
3 |
-
"version": "13.0.
|
4 |
-
"release_timestamp":
|
5 |
-
"build": "
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield Security",
|
@@ -83,91 +83,95 @@
|
|
83 |
},
|
84 |
"register": {
|
85 |
"css": {
|
86 |
-
"bootstrap":
|
87 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.1/css/bootstrap.min.css"
|
88 |
},
|
89 |
-
"bootstrap-datepicker":
|
90 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker.min.css",
|
91 |
"deps": [
|
92 |
"bootstrap"
|
93 |
]
|
94 |
},
|
95 |
-
"bootstrap-select":
|
96 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.18/css/bootstrap-select.min.css",
|
97 |
"deps": [
|
98 |
"bootstrap"
|
99 |
]
|
100 |
},
|
101 |
-
"select2":
|
102 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css",
|
103 |
"deps": [
|
104 |
"plugin"
|
105 |
]
|
106 |
},
|
107 |
-
"datatables-bootstrap":
|
108 |
"url": "https://cdn.datatables.net/1.11.3/css/dataTables.bootstrap4.min.css",
|
109 |
"deps": [
|
110 |
"bootstrap"
|
111 |
]
|
112 |
},
|
113 |
-
"datatables-searchpanes":
|
114 |
"url": "https://cdn.datatables.net/searchpanes/1.4.0/css/searchPanes.dataTables.min.css",
|
115 |
"deps": [
|
116 |
"datatables-bootstrap"
|
117 |
]
|
118 |
},
|
119 |
-
"datatables-select":
|
120 |
"url": "https://cdn.datatables.net/select/1.3.3/css/select.dataTables.min.css",
|
121 |
"deps": [
|
122 |
"datatables-bootstrap"
|
123 |
]
|
124 |
},
|
125 |
-
"datatables-buttons":
|
126 |
"url": "https://cdn.datatables.net/buttons/1.7.1/css/buttons.dataTables.min.css",
|
127 |
"deps": [
|
128 |
"datatables-bootstrap"
|
129 |
]
|
130 |
},
|
131 |
-
"global-plugin":
|
132 |
-
"plugin":
|
133 |
"deps": [
|
134 |
"bootstrap",
|
135 |
"global-plugin"
|
136 |
]
|
137 |
},
|
138 |
-
"shield/wizard":
|
139 |
"deps": [
|
140 |
"bootstrap",
|
141 |
"global-plugin"
|
142 |
]
|
143 |
},
|
144 |
-
"jquery/featherlight":
|
145 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/featherlight/1.7.13/featherlight.min.css"
|
146 |
},
|
147 |
-
"chartist":
|
148 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/chartist/0.11.4/chartist.min.css"
|
149 |
},
|
150 |
-
"chartist-plugin-legend":
|
151 |
"deps": [
|
152 |
"chartist"
|
153 |
]
|
154 |
},
|
155 |
-
"introjs":
|
156 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/intro.js/3.3.1/introjs.min.css"
|
157 |
},
|
158 |
-
"shield/
|
|
|
|
|
|
|
|
|
159 |
"deps": [
|
160 |
"plugin"
|
161 |
]
|
162 |
},
|
163 |
-
"shield/dialog":
|
164 |
"deps": [
|
165 |
"wp-wp-jquery-ui-dialog"
|
166 |
],
|
167 |
"footer": true
|
168 |
},
|
169 |
-
"shield/mainwp":
|
170 |
-
"shield/datatables":
|
171 |
"deps": [
|
172 |
"datatables-select",
|
173 |
"datatables-buttons",
|
@@ -176,7 +180,7 @@
|
|
176 |
"tp/highlightjs"
|
177 |
]
|
178 |
},
|
179 |
-
"shield/scanners":
|
180 |
"deps": [
|
181 |
"datatables-select",
|
182 |
"datatables-buttons",
|
@@ -184,7 +188,7 @@
|
|
184 |
"tp/highlightjs"
|
185 |
]
|
186 |
},
|
187 |
-
"tp/highlightjs":
|
188 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.1.0/styles/default.min.css"
|
189 |
}
|
190 |
},
|
1 |
{
|
2 |
"properties": {
|
3 |
+
"version": "13.0.5",
|
4 |
+
"release_timestamp": 1641981192,
|
5 |
+
"build": "202201.1201",
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield Security",
|
83 |
},
|
84 |
"register": {
|
85 |
"css": {
|
86 |
+
"bootstrap": {
|
87 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.1/css/bootstrap.min.css"
|
88 |
},
|
89 |
+
"bootstrap-datepicker": {
|
90 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker.min.css",
|
91 |
"deps": [
|
92 |
"bootstrap"
|
93 |
]
|
94 |
},
|
95 |
+
"bootstrap-select": {
|
96 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.18/css/bootstrap-select.min.css",
|
97 |
"deps": [
|
98 |
"bootstrap"
|
99 |
]
|
100 |
},
|
101 |
+
"select2": {
|
102 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css",
|
103 |
"deps": [
|
104 |
"plugin"
|
105 |
]
|
106 |
},
|
107 |
+
"datatables-bootstrap": {
|
108 |
"url": "https://cdn.datatables.net/1.11.3/css/dataTables.bootstrap4.min.css",
|
109 |
"deps": [
|
110 |
"bootstrap"
|
111 |
]
|
112 |
},
|
113 |
+
"datatables-searchpanes": {
|
114 |
"url": "https://cdn.datatables.net/searchpanes/1.4.0/css/searchPanes.dataTables.min.css",
|
115 |
"deps": [
|
116 |
"datatables-bootstrap"
|
117 |
]
|
118 |
},
|
119 |
+
"datatables-select": {
|
120 |
"url": "https://cdn.datatables.net/select/1.3.3/css/select.dataTables.min.css",
|
121 |
"deps": [
|
122 |
"datatables-bootstrap"
|
123 |
]
|
124 |
},
|
125 |
+
"datatables-buttons": {
|
126 |
"url": "https://cdn.datatables.net/buttons/1.7.1/css/buttons.dataTables.min.css",
|
127 |
"deps": [
|
128 |
"datatables-bootstrap"
|
129 |
]
|
130 |
},
|
131 |
+
"global-plugin": {},
|
132 |
+
"plugin": {
|
133 |
"deps": [
|
134 |
"bootstrap",
|
135 |
"global-plugin"
|
136 |
]
|
137 |
},
|
138 |
+
"shield/wizard": {
|
139 |
"deps": [
|
140 |
"bootstrap",
|
141 |
"global-plugin"
|
142 |
]
|
143 |
},
|
144 |
+
"jquery/featherlight": {
|
145 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/featherlight/1.7.13/featherlight.min.css"
|
146 |
},
|
147 |
+
"chartist": {
|
148 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/chartist/0.11.4/chartist.min.css"
|
149 |
},
|
150 |
+
"chartist-plugin-legend": {
|
151 |
"deps": [
|
152 |
"chartist"
|
153 |
]
|
154 |
},
|
155 |
+
"introjs": {
|
156 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/intro.js/3.3.1/introjs.min.css"
|
157 |
},
|
158 |
+
"shield/userprofile": {
|
159 |
+
"deps": [],
|
160 |
+
"footer": true
|
161 |
+
},
|
162 |
+
"shield/charts": {
|
163 |
"deps": [
|
164 |
"plugin"
|
165 |
]
|
166 |
},
|
167 |
+
"shield/dialog": {
|
168 |
"deps": [
|
169 |
"wp-wp-jquery-ui-dialog"
|
170 |
],
|
171 |
"footer": true
|
172 |
},
|
173 |
+
"shield/mainwp": {},
|
174 |
+
"shield/datatables": {
|
175 |
"deps": [
|
176 |
"datatables-select",
|
177 |
"datatables-buttons",
|
180 |
"tp/highlightjs"
|
181 |
]
|
182 |
},
|
183 |
+
"shield/scanners": {
|
184 |
"deps": [
|
185 |
"datatables-select",
|
186 |
"datatables-buttons",
|
188 |
"tp/highlightjs"
|
189 |
]
|
190 |
},
|
191 |
+
"tp/highlightjs": {
|
192 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.1.0/styles/default.min.css"
|
193 |
}
|
194 |
},
|
plugin.json
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
{
|
2 |
"properties": {
|
3 |
-
"version": "13.0.
|
4 |
-
"release_timestamp":
|
5 |
-
"build": "
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield Security",
|
@@ -83,91 +83,95 @@
|
|
83 |
},
|
84 |
"register": {
|
85 |
"css": {
|
86 |
-
"bootstrap":
|
87 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.1/css/bootstrap.min.css"
|
88 |
},
|
89 |
-
"bootstrap-datepicker":
|
90 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker.min.css",
|
91 |
"deps": [
|
92 |
"bootstrap"
|
93 |
]
|
94 |
},
|
95 |
-
"bootstrap-select":
|
96 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.18/css/bootstrap-select.min.css",
|
97 |
"deps": [
|
98 |
"bootstrap"
|
99 |
]
|
100 |
},
|
101 |
-
"select2":
|
102 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css",
|
103 |
"deps": [
|
104 |
"plugin"
|
105 |
]
|
106 |
},
|
107 |
-
"datatables-bootstrap":
|
108 |
"url": "https://cdn.datatables.net/1.11.3/css/dataTables.bootstrap4.min.css",
|
109 |
"deps": [
|
110 |
"bootstrap"
|
111 |
]
|
112 |
},
|
113 |
-
"datatables-searchpanes":
|
114 |
"url": "https://cdn.datatables.net/searchpanes/1.4.0/css/searchPanes.dataTables.min.css",
|
115 |
"deps": [
|
116 |
"datatables-bootstrap"
|
117 |
]
|
118 |
},
|
119 |
-
"datatables-select":
|
120 |
"url": "https://cdn.datatables.net/select/1.3.3/css/select.dataTables.min.css",
|
121 |
"deps": [
|
122 |
"datatables-bootstrap"
|
123 |
]
|
124 |
},
|
125 |
-
"datatables-buttons":
|
126 |
"url": "https://cdn.datatables.net/buttons/1.7.1/css/buttons.dataTables.min.css",
|
127 |
"deps": [
|
128 |
"datatables-bootstrap"
|
129 |
]
|
130 |
},
|
131 |
-
"global-plugin":
|
132 |
-
"plugin":
|
133 |
"deps": [
|
134 |
"bootstrap",
|
135 |
"global-plugin"
|
136 |
]
|
137 |
},
|
138 |
-
"shield/wizard":
|
139 |
"deps": [
|
140 |
"bootstrap",
|
141 |
"global-plugin"
|
142 |
]
|
143 |
},
|
144 |
-
"jquery/featherlight":
|
145 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/featherlight/1.7.13/featherlight.min.css"
|
146 |
},
|
147 |
-
"chartist":
|
148 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/chartist/0.11.4/chartist.min.css"
|
149 |
},
|
150 |
-
"chartist-plugin-legend":
|
151 |
"deps": [
|
152 |
"chartist"
|
153 |
]
|
154 |
},
|
155 |
-
"introjs":
|
156 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/intro.js/3.3.1/introjs.min.css"
|
157 |
},
|
158 |
-
"shield/
|
|
|
|
|
|
|
|
|
159 |
"deps": [
|
160 |
"plugin"
|
161 |
]
|
162 |
},
|
163 |
-
"shield/dialog":
|
164 |
"deps": [
|
165 |
"wp-wp-jquery-ui-dialog"
|
166 |
],
|
167 |
"footer": true
|
168 |
},
|
169 |
-
"shield/mainwp":
|
170 |
-
"shield/datatables":
|
171 |
"deps": [
|
172 |
"datatables-select",
|
173 |
"datatables-buttons",
|
@@ -176,7 +180,7 @@
|
|
176 |
"tp/highlightjs"
|
177 |
]
|
178 |
},
|
179 |
-
"shield/scanners":
|
180 |
"deps": [
|
181 |
"datatables-select",
|
182 |
"datatables-buttons",
|
@@ -184,7 +188,7 @@
|
|
184 |
"tp/highlightjs"
|
185 |
]
|
186 |
},
|
187 |
-
"tp/highlightjs":
|
188 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.1.0/styles/default.min.css"
|
189 |
}
|
190 |
},
|
1 |
{
|
2 |
"properties": {
|
3 |
+
"version": "13.0.5",
|
4 |
+
"release_timestamp": 1641981192,
|
5 |
+
"build": "202201.1201",
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield Security",
|
83 |
},
|
84 |
"register": {
|
85 |
"css": {
|
86 |
+
"bootstrap": {
|
87 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.1/css/bootstrap.min.css"
|
88 |
},
|
89 |
+
"bootstrap-datepicker": {
|
90 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker.min.css",
|
91 |
"deps": [
|
92 |
"bootstrap"
|
93 |
]
|
94 |
},
|
95 |
+
"bootstrap-select": {
|
96 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.18/css/bootstrap-select.min.css",
|
97 |
"deps": [
|
98 |
"bootstrap"
|
99 |
]
|
100 |
},
|
101 |
+
"select2": {
|
102 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css",
|
103 |
"deps": [
|
104 |
"plugin"
|
105 |
]
|
106 |
},
|
107 |
+
"datatables-bootstrap": {
|
108 |
"url": "https://cdn.datatables.net/1.11.3/css/dataTables.bootstrap4.min.css",
|
109 |
"deps": [
|
110 |
"bootstrap"
|
111 |
]
|
112 |
},
|
113 |
+
"datatables-searchpanes": {
|
114 |
"url": "https://cdn.datatables.net/searchpanes/1.4.0/css/searchPanes.dataTables.min.css",
|
115 |
"deps": [
|
116 |
"datatables-bootstrap"
|
117 |
]
|
118 |
},
|
119 |
+
"datatables-select": {
|
120 |
"url": "https://cdn.datatables.net/select/1.3.3/css/select.dataTables.min.css",
|
121 |
"deps": [
|
122 |
"datatables-bootstrap"
|
123 |
]
|
124 |
},
|
125 |
+
"datatables-buttons": {
|
126 |
"url": "https://cdn.datatables.net/buttons/1.7.1/css/buttons.dataTables.min.css",
|
127 |
"deps": [
|
128 |
"datatables-bootstrap"
|
129 |
]
|
130 |
},
|
131 |
+
"global-plugin": {},
|
132 |
+
"plugin": {
|
133 |
"deps": [
|
134 |
"bootstrap",
|
135 |
"global-plugin"
|
136 |
]
|
137 |
},
|
138 |
+
"shield/wizard": {
|
139 |
"deps": [
|
140 |
"bootstrap",
|
141 |
"global-plugin"
|
142 |
]
|
143 |
},
|
144 |
+
"jquery/featherlight": {
|
145 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/featherlight/1.7.13/featherlight.min.css"
|
146 |
},
|
147 |
+
"chartist": {
|
148 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/chartist/0.11.4/chartist.min.css"
|
149 |
},
|
150 |
+
"chartist-plugin-legend": {
|
151 |
"deps": [
|
152 |
"chartist"
|
153 |
]
|
154 |
},
|
155 |
+
"introjs": {
|
156 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/intro.js/3.3.1/introjs.min.css"
|
157 |
},
|
158 |
+
"shield/userprofile": {
|
159 |
+
"deps": [],
|
160 |
+
"footer": true
|
161 |
+
},
|
162 |
+
"shield/charts": {
|
163 |
"deps": [
|
164 |
"plugin"
|
165 |
]
|
166 |
},
|
167 |
+
"shield/dialog": {
|
168 |
"deps": [
|
169 |
"wp-wp-jquery-ui-dialog"
|
170 |
],
|
171 |
"footer": true
|
172 |
},
|
173 |
+
"shield/mainwp": {},
|
174 |
+
"shield/datatables": {
|
175 |
"deps": [
|
176 |
"datatables-select",
|
177 |
"datatables-buttons",
|
180 |
"tp/highlightjs"
|
181 |
]
|
182 |
},
|
183 |
+
"shield/scanners": {
|
184 |
"deps": [
|
185 |
"datatables-select",
|
186 |
"datatables-buttons",
|
188 |
"tp/highlightjs"
|
189 |
]
|
190 |
},
|
191 |
+
"tp/highlightjs": {
|
192 |
"url": "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.1.0/styles/default.min.css"
|
193 |
}
|
194 |
},
|
readme.txt
CHANGED
@@ -7,7 +7,7 @@ Tags: scan, malware, firewall, two factor authentication, login protection
|
|
7 |
Requires at least: 3.7
|
8 |
Requires PHP: 7.0
|
9 |
Recommended PHP: 7.4
|
10 |
-
Tested up to: 5.
|
11 |
Stable tag: 13.0.4
|
12 |
|
13 |
No-Nonsense Security Hardening that protects WordPress against hackers, malicious bots, and spammers (no captchas!). Now with exclusive ShieldNET Technology.
|
7 |
Requires at least: 3.7
|
8 |
Requires PHP: 7.0
|
9 |
Recommended PHP: 7.4
|
10 |
+
Tested up to: 5.9
|
11 |
Stable tag: 13.0.4
|
12 |
|
13 |
No-Nonsense Security Hardening that protects WordPress against hackers, malicious bots, and spammers (no captchas!). Now with exclusive ShieldNET Technology.
|
resources/css/shield/userprofile.css
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#ShieldUserProfileMFA {
|
2 |
+
margin-top: 1em;
|
3 |
+
}
|
4 |
+
#ShieldUserProfileMFA th {
|
5 |
+
text-align: left;
|
6 |
+
vertical-align: top;
|
7 |
+
padding: 20px 10px 20px 0;
|
8 |
+
width: 200px;
|
9 |
+
line-height: 1.3;
|
10 |
+
font-weight: 600;
|
11 |
+
}
|
12 |
+
#ShieldUserProfileMFA td {
|
13 |
+
padding: 20px 0;
|
14 |
+
vertical-align: top;
|
15 |
+
}
|
resources/js/shield/notbot.js
CHANGED
@@ -1,85 +1,82 @@
|
|
|
|
|
|
|
|
1 |
if ( typeof Shield_Antibot === typeof undefined && typeof shield_vars_notbotjs !== typeof undefined ) {
|
2 |
-
|
3 |
-
var Shield_Antibot = new function () {
|
4 |
|
5 |
let request_count = 0;
|
6 |
-
let
|
7 |
-
|
8 |
-
|
9 |
-
if ( document.readyState !== 'loading' ) {
|
10 |
-
fn();
|
11 |
-
}
|
12 |
-
else if ( document.addEventListener ) {
|
13 |
-
document.addEventListener( 'DOMContentLoaded', fn );
|
14 |
-
}
|
15 |
-
else {
|
16 |
-
document.attachEvent( 'onreadystatechange', function () {
|
17 |
-
if ( document.readyState !== 'loading' )
|
18 |
-
fn();
|
19 |
-
} );
|
20 |
-
}
|
21 |
-
}
|
22 |
|
23 |
this.initialise = function () {
|
24 |
/**
|
25 |
* @since 11.2 we no longer wait until DOM is ready.
|
26 |
* @since 12.0.10 we return to using cookies to optimise whether the AJAX request is sent.
|
27 |
-
* This is mainly AJAX so it's asynchronous and
|
28 |
* Early execution also helps mitigate the case where login requests are
|
29 |
* sent quickly, before browser has fired NotBot request.
|
30 |
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
if ( shield_vars_notbotjs.flags.run ) {
|
32 |
fire();
|
33 |
}
|
34 |
-
/**
|
35 |
-
* @since 11.2 this script is only loaded if a not bot signal doesn't exist for this IP.
|
36 |
-
*/
|
37 |
-
domReady( function () {
|
38 |
-
// fire();
|
39 |
-
} );
|
40 |
};
|
41 |
|
42 |
/**
|
43 |
* @since 12.0.10 - rather than auto send request every page load, check for cookie repeatedly and send if
|
44 |
* absent.
|
45 |
*/
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
window.setTimeout( fire, 10000 );
|
53 |
}
|
|
|
54 |
};
|
55 |
|
56 |
-
|
|
|
|
|
|
|
57 |
request_count++;
|
58 |
|
59 |
let xhr = new XMLHttpRequest();
|
|
|
|
|
60 |
|
61 |
/**
|
62 |
-
* Ensures that if there's an error with the AJAX, we don't
|
63 |
-
* to keep trying the requests.
|
64 |
*/
|
65 |
xhr.onreadystatechange = function () {
|
66 |
if ( xhr.readyState === 4 ) {
|
67 |
-
let
|
68 |
-
|
69 |
-
|
70 |
-
|
|
|
|
|
|
|
71 |
}
|
72 |
}
|
|
|
|
|
|
|
73 |
}
|
74 |
|
75 |
-
xhr.
|
76 |
-
xhr.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded;' );
|
77 |
-
xhr.send( shield_vars_notbotjs.ajax.not_bot );
|
78 |
};
|
79 |
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
if ( parts.length === 2 ) return parts.pop().split( ";" ).shift();
|
84 |
};
|
85 |
}();
|
1 |
+
/**
|
2 |
+
* @var shield_vars_notbotjs object
|
3 |
+
*/
|
4 |
if ( typeof Shield_Antibot === typeof undefined && typeof shield_vars_notbotjs !== typeof undefined ) {
|
5 |
+
let Shield_Antibot = new function () {
|
|
|
6 |
|
7 |
let request_count = 0;
|
8 |
+
let can_send_request = true;
|
9 |
+
let nonce_cook = '';
|
10 |
+
let ajaxurl = shield_vars_notbotjs.ajax.not_bot.ajaxurl;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
|
12 |
this.initialise = function () {
|
13 |
/**
|
14 |
* @since 11.2 we no longer wait until DOM is ready.
|
15 |
* @since 12.0.10 we return to using cookies to optimise whether the AJAX request is sent.
|
16 |
+
* This is mainly AJAX so it's asynchronous and won't hold up any other part of the page load.
|
17 |
* Early execution also helps mitigate the case where login requests are
|
18 |
* sent quickly, before browser has fired NotBot request.
|
19 |
*/
|
20 |
+
delete shield_vars_notbotjs.ajax.not_bot.ajaxurl;
|
21 |
+
nonce_cook = getCookie( 'shield-notbot-nonce' );
|
22 |
+
if ( typeof nonce_cook !== typeof undefined && nonce_cook.length > 0 ) {
|
23 |
+
/** Overcome limitations of page caching by passing nonce via cookie **/
|
24 |
+
shield_vars_notbotjs.ajax.not_bot.exec_nonce = nonce_cook;
|
25 |
+
}
|
26 |
if ( shield_vars_notbotjs.flags.run ) {
|
27 |
fire();
|
28 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
};
|
30 |
|
31 |
/**
|
32 |
* @since 12.0.10 - rather than auto send request every page load, check for cookie repeatedly and send if
|
33 |
* absent.
|
34 |
*/
|
35 |
+
let fire = function () {
|
36 |
+
if ( can_send_request && request_count < 10 ) {
|
37 |
+
let current = getCookie( 'icwp-wpsf-notbot' );
|
38 |
+
if ( current === undefined || typeof (current) === 'undefined' ) {
|
39 |
+
sendReq();
|
40 |
+
}
|
|
|
41 |
}
|
42 |
+
window.setTimeout( fire, 30000 );
|
43 |
};
|
44 |
|
45 |
+
/**
|
46 |
+
* We use the cookie to help ensure we don't send unnecessary requests and keep checking
|
47 |
+
*/
|
48 |
+
let sendReq = function () {
|
49 |
request_count++;
|
50 |
|
51 |
let xhr = new XMLHttpRequest();
|
52 |
+
xhr.open( "POST", ajaxurl, true );
|
53 |
+
xhr.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded;' );
|
54 |
|
55 |
/**
|
56 |
+
* Ensures that if there's an error with the AJAX, we don't keep retrying the requests.
|
|
|
57 |
*/
|
58 |
xhr.onreadystatechange = function () {
|
59 |
if ( xhr.readyState === 4 ) {
|
60 |
+
let rawResp = xhr.response;
|
61 |
+
if ( rawResp != null && rawResp !== '' && rawResp.charAt( 0 ) === '{' ) {
|
62 |
+
let resp = JSON.parse( rawResp )
|
63 |
+
can_send_request = resp && resp.success;
|
64 |
+
if ( !can_send_request ) {
|
65 |
+
console.log( xhr.response );
|
66 |
+
}
|
67 |
}
|
68 |
}
|
69 |
+
else {
|
70 |
+
can_send_request = false;
|
71 |
+
}
|
72 |
}
|
73 |
|
74 |
+
xhr.send( (new URLSearchParams( shield_vars_notbotjs.ajax.not_bot )).toString() );
|
|
|
|
|
75 |
};
|
76 |
|
77 |
+
let getCookie = function ( name ) {
|
78 |
+
let value = "; " + document.cookie;
|
79 |
+
let parts = value.split( "; " + name + "=" );
|
80 |
if ( parts.length === 2 ) return parts.pop().split( ";" ).shift();
|
81 |
};
|
82 |
}();
|
src/lib/src/Controller/Controller.php
CHANGED
@@ -545,8 +545,6 @@ class Controller extends DynPropertiesClass {
|
|
545 |
}
|
546 |
|
547 |
/**
|
548 |
-
* @param string $action
|
549 |
-
* @return array
|
550 |
* @throws \Exception
|
551 |
*/
|
552 |
public function getNonceActionData( string $action = '' ) :array {
|
@@ -754,24 +752,24 @@ class Controller extends DynPropertiesClass {
|
|
754 |
}
|
755 |
|
756 |
/**
|
757 |
-
* @param array $
|
758 |
* @return array
|
759 |
*/
|
760 |
-
public function doPluginLabels( $
|
761 |
$labels = $this->getLabels();
|
762 |
if ( empty( $labels ) ) {
|
763 |
-
return $
|
764 |
}
|
765 |
|
766 |
$file = $this->base_file;
|
767 |
// For this plugin, overwrite any specified settings
|
768 |
-
if ( array_key_exists( $file, $
|
769 |
foreach ( $labels as $sLabelKey => $sLabel ) {
|
770 |
-
$
|
771 |
}
|
772 |
}
|
773 |
|
774 |
-
return $
|
775 |
}
|
776 |
|
777 |
public function getLabels() :array {
|
@@ -863,7 +861,6 @@ class Controller extends DynPropertiesClass {
|
|
863 |
}
|
864 |
|
865 |
/**
|
866 |
-
* @return Config\ConfigVO
|
867 |
* @throws \Exception
|
868 |
*/
|
869 |
private function loadConfig() :Config\ConfigVO {
|
@@ -882,7 +879,6 @@ class Controller extends DynPropertiesClass {
|
|
882 |
}
|
883 |
|
884 |
/**
|
885 |
-
* @param string $key
|
886 |
* @return string|null
|
887 |
*/
|
888 |
public function getPluginSpec_Path( string $key ) {
|
@@ -890,7 +886,6 @@ class Controller extends DynPropertiesClass {
|
|
890 |
}
|
891 |
|
892 |
/**
|
893 |
-
* @param string $key
|
894 |
* @return mixed|null
|
895 |
*/
|
896 |
protected function getCfgProperty( string $key ) {
|
@@ -1165,7 +1160,6 @@ class Controller extends DynPropertiesClass {
|
|
1165 |
}
|
1166 |
|
1167 |
/**
|
1168 |
-
* @return bool
|
1169 |
* @throws \Exception
|
1170 |
*/
|
1171 |
public function loadAllFeatures() :bool {
|
@@ -1195,7 +1189,6 @@ class Controller extends DynPropertiesClass {
|
|
1195 |
}
|
1196 |
|
1197 |
/**
|
1198 |
-
* @param string $slug
|
1199 |
* @return Shield\Modules\Base\ModCon|null|mixed
|
1200 |
*/
|
1201 |
public function getModule( string $slug ) {
|
@@ -1294,7 +1287,6 @@ class Controller extends DynPropertiesClass {
|
|
1294 |
}
|
1295 |
|
1296 |
/**
|
1297 |
-
* @param array $modProps
|
1298 |
* @return Shield\Modules\Base\ModCon|mixed
|
1299 |
* @throws \Exception
|
1300 |
*/
|
545 |
}
|
546 |
|
547 |
/**
|
|
|
|
|
548 |
* @throws \Exception
|
549 |
*/
|
550 |
public function getNonceActionData( string $action = '' ) :array {
|
752 |
}
|
753 |
|
754 |
/**
|
755 |
+
* @param array $plugins
|
756 |
* @return array
|
757 |
*/
|
758 |
+
public function doPluginLabels( $plugins ) {
|
759 |
$labels = $this->getLabels();
|
760 |
if ( empty( $labels ) ) {
|
761 |
+
return $plugins;
|
762 |
}
|
763 |
|
764 |
$file = $this->base_file;
|
765 |
// For this plugin, overwrite any specified settings
|
766 |
+
if ( array_key_exists( $file, $plugins ) ) {
|
767 |
foreach ( $labels as $sLabelKey => $sLabel ) {
|
768 |
+
$plugins[ $file ][ $sLabelKey ] = $sLabel;
|
769 |
}
|
770 |
}
|
771 |
|
772 |
+
return $plugins;
|
773 |
}
|
774 |
|
775 |
public function getLabels() :array {
|
861 |
}
|
862 |
|
863 |
/**
|
|
|
864 |
* @throws \Exception
|
865 |
*/
|
866 |
private function loadConfig() :Config\ConfigVO {
|
879 |
}
|
880 |
|
881 |
/**
|
|
|
882 |
* @return string|null
|
883 |
*/
|
884 |
public function getPluginSpec_Path( string $key ) {
|
886 |
}
|
887 |
|
888 |
/**
|
|
|
889 |
* @return mixed|null
|
890 |
*/
|
891 |
protected function getCfgProperty( string $key ) {
|
1160 |
}
|
1161 |
|
1162 |
/**
|
|
|
1163 |
* @throws \Exception
|
1164 |
*/
|
1165 |
public function loadAllFeatures() :bool {
|
1189 |
}
|
1190 |
|
1191 |
/**
|
|
|
1192 |
* @return Shield\Modules\Base\ModCon|null|mixed
|
1193 |
*/
|
1194 |
public function getModule( string $slug ) {
|
1287 |
}
|
1288 |
|
1289 |
/**
|
|
|
1290 |
* @return Shield\Modules\Base\ModCon|mixed
|
1291 |
* @throws \Exception
|
1292 |
*/
|
src/lib/src/Modules/Autoupdates/AjaxHandler.php
DELETED
@@ -1,9 +0,0 @@
|
|
1 |
-
<?php declare( strict_types=1 );
|
2 |
-
|
3 |
-
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Autoupdates;
|
4 |
-
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
-
|
7 |
-
class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
8 |
-
|
9 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/lib/src/Modules/Base/AdminNotices.php
CHANGED
@@ -26,14 +26,14 @@ class AdminNotices {
|
|
26 |
}
|
27 |
|
28 |
protected function ajaxExec_DismissAdminNotice() :array {
|
29 |
-
$
|
30 |
|
31 |
-
$
|
32 |
|
33 |
foreach ( $this->getAdminNotices() as $notice ) {
|
34 |
-
if ( $
|
35 |
$this->setNoticeDismissed( $notice );
|
36 |
-
$
|
37 |
'success' => true,
|
38 |
'message' => 'Admin notice dismissed', //not currently seen
|
39 |
'notice_id' => $notice->id,
|
@@ -43,22 +43,22 @@ class AdminNotices {
|
|
43 |
}
|
44 |
|
45 |
// leave response empty if it doesn't apply here, so other modules can process it.
|
46 |
-
return $
|
47 |
}
|
48 |
|
49 |
/**
|
50 |
-
* @param Shield\Utilities\AdminNotices\NoticeVO[] $
|
51 |
* @return Shield\Utilities\AdminNotices\NoticeVO[]
|
52 |
*/
|
53 |
-
public function addNotices( $
|
54 |
-
return array_merge( $
|
55 |
}
|
56 |
|
57 |
/**
|
58 |
* @return Shield\Utilities\AdminNotices\NoticeVO[]
|
59 |
*/
|
60 |
-
protected function buildNotices() {
|
61 |
-
$
|
62 |
|
63 |
foreach ( $this->getAdminNotices() as $notice ) {
|
64 |
$this->preProcessNotice( $notice );
|
@@ -66,7 +66,7 @@ class AdminNotices {
|
|
66 |
try {
|
67 |
$this->processNotice( $notice );
|
68 |
if ( $notice->display ) {
|
69 |
-
$
|
70 |
}
|
71 |
}
|
72 |
catch ( \Exception $e ) {
|
@@ -74,7 +74,7 @@ class AdminNotices {
|
|
74 |
}
|
75 |
}
|
76 |
|
77 |
-
return $
|
78 |
}
|
79 |
|
80 |
/**
|
@@ -145,21 +145,17 @@ class AdminNotices {
|
|
145 |
$notice->template = '/notices/'.$notice->id;
|
146 |
}
|
147 |
|
148 |
-
|
149 |
-
|
150 |
-
* @return bool
|
151 |
-
*/
|
152 |
-
protected function isNoticeDismissed( $notice ) {
|
153 |
-
$bDismissedUser = $this->isNoticeDismissedForCurrentUser( $notice );
|
154 |
|
155 |
-
$
|
156 |
-
$
|
157 |
|
158 |
-
if ( !$notice->per_user && $
|
159 |
$this->setNoticeDismissed( $notice );
|
160 |
}
|
161 |
|
162 |
-
return $
|
163 |
}
|
164 |
|
165 |
/**
|
@@ -170,72 +166,58 @@ class AdminNotices {
|
|
170 |
return true;
|
171 |
}
|
172 |
|
173 |
-
|
174 |
-
|
175 |
-
* @return bool
|
176 |
-
*/
|
177 |
-
protected function isNoticeDismissedForCurrentUser( $notice ) {
|
178 |
-
$bDismissed = false;
|
179 |
|
180 |
$meta = $this->getCon()->getCurrentUserMeta();
|
181 |
if ( $meta instanceof PluginUserMeta ) {
|
182 |
-
$
|
183 |
|
184 |
-
if ( isset( $meta->{$
|
185 |
-
$
|
186 |
|
187 |
// migrate from old-style array storage to plain Timestamp
|
188 |
-
if ( is_array( $meta->{$
|
189 |
-
$meta->{$
|
190 |
}
|
191 |
}
|
192 |
}
|
193 |
|
194 |
-
return $
|
195 |
}
|
196 |
|
197 |
/**
|
198 |
-
* @param NoticeVO $notice
|
199 |
* @throws \Exception
|
200 |
*/
|
201 |
protected function processNotice( NoticeVO $notice ) {
|
202 |
throw new \Exception( 'Unsupported Notice ID: '.$notice->id );
|
203 |
}
|
204 |
|
205 |
-
|
206 |
-
|
207 |
-
* @return $this
|
208 |
-
*/
|
209 |
-
protected function setNoticeDismissed( $notice ) {
|
210 |
-
$nTs = Services::Request()->ts();
|
211 |
|
212 |
$meta = $this->getCon()->getCurrentUserMeta();
|
213 |
-
$
|
214 |
|
215 |
if ( $notice->per_user ) {
|
216 |
if ( $meta instanceof PluginUserMeta ) {
|
217 |
-
$meta->{$
|
218 |
}
|
219 |
}
|
220 |
else {
|
221 |
$mod = $this->getMod();
|
222 |
-
$
|
223 |
-
$
|
224 |
-
$mod->setDismissedNotices( $
|
225 |
|
226 |
// Clear out any old
|
227 |
if ( $meta instanceof PluginUserMeta ) {
|
228 |
-
unset( $meta->{$
|
229 |
}
|
230 |
}
|
231 |
-
return $this;
|
232 |
}
|
233 |
|
234 |
-
|
235 |
-
* @param NoticeVO $notice
|
236 |
-
* @return string
|
237 |
-
*/
|
238 |
-
private function getNoticeMetaKey( $notice ) {
|
239 |
return 'notice_'.str_replace( [ '-', '_' ], '', $notice->id );
|
240 |
}
|
241 |
}
|
26 |
}
|
27 |
|
28 |
protected function ajaxExec_DismissAdminNotice() :array {
|
29 |
+
$ajaxResponse = [];
|
30 |
|
31 |
+
$noticeID = sanitize_key( Services::Request()->query( 'notice_id', '' ) );
|
32 |
|
33 |
foreach ( $this->getAdminNotices() as $notice ) {
|
34 |
+
if ( $noticeID == $notice->id ) {
|
35 |
$this->setNoticeDismissed( $notice );
|
36 |
+
$ajaxResponse = [
|
37 |
'success' => true,
|
38 |
'message' => 'Admin notice dismissed', //not currently seen
|
39 |
'notice_id' => $notice->id,
|
43 |
}
|
44 |
|
45 |
// leave response empty if it doesn't apply here, so other modules can process it.
|
46 |
+
return $ajaxResponse;
|
47 |
}
|
48 |
|
49 |
/**
|
50 |
+
* @param Shield\Utilities\AdminNotices\NoticeVO[] $notices
|
51 |
* @return Shield\Utilities\AdminNotices\NoticeVO[]
|
52 |
*/
|
53 |
+
public function addNotices( $notices ) {
|
54 |
+
return array_merge( $notices, $this->buildNotices() );
|
55 |
}
|
56 |
|
57 |
/**
|
58 |
* @return Shield\Utilities\AdminNotices\NoticeVO[]
|
59 |
*/
|
60 |
+
protected function buildNotices() :array {
|
61 |
+
$notices = [];
|
62 |
|
63 |
foreach ( $this->getAdminNotices() as $notice ) {
|
64 |
$this->preProcessNotice( $notice );
|
66 |
try {
|
67 |
$this->processNotice( $notice );
|
68 |
if ( $notice->display ) {
|
69 |
+
$notices[] = $notice;
|
70 |
}
|
71 |
}
|
72 |
catch ( \Exception $e ) {
|
74 |
}
|
75 |
}
|
76 |
|
77 |
+
return $notices;
|
78 |
}
|
79 |
|
80 |
/**
|
145 |
$notice->template = '/notices/'.$notice->id;
|
146 |
}
|
147 |
|
148 |
+
protected function isNoticeDismissed( NoticeVO $notice ) :bool {
|
149 |
+
$dismissedUser = $this->isNoticeDismissedForCurrentUser( $notice );
|
|
|
|
|
|
|
|
|
150 |
|
151 |
+
$allDisd = $this->getMod()->getDismissedNotices();
|
152 |
+
$dismissedMod = isset( $allDisd[ $notice->id ] ) && $allDisd[ $notice->id ] > 0;
|
153 |
|
154 |
+
if ( !$notice->per_user && $dismissedUser && !$dismissedMod ) {
|
155 |
$this->setNoticeDismissed( $notice );
|
156 |
}
|
157 |
|
158 |
+
return $dismissedUser || $dismissedMod;
|
159 |
}
|
160 |
|
161 |
/**
|
166 |
return true;
|
167 |
}
|
168 |
|
169 |
+
protected function isNoticeDismissedForCurrentUser( NoticeVO $notice ) :bool {
|
170 |
+
$dismissed = false;
|
|
|
|
|
|
|
|
|
171 |
|
172 |
$meta = $this->getCon()->getCurrentUserMeta();
|
173 |
if ( $meta instanceof PluginUserMeta ) {
|
174 |
+
$noticeMetaKey = $this->getNoticeMetaKey( $notice );
|
175 |
|
176 |
+
if ( isset( $meta->{$noticeMetaKey} ) ) {
|
177 |
+
$dismissed = true;
|
178 |
|
179 |
// migrate from old-style array storage to plain Timestamp
|
180 |
+
if ( is_array( $meta->{$noticeMetaKey} ) ) {
|
181 |
+
$meta->{$noticeMetaKey} = $meta->{$noticeMetaKey}[ 'time' ];
|
182 |
}
|
183 |
}
|
184 |
}
|
185 |
|
186 |
+
return $dismissed;
|
187 |
}
|
188 |
|
189 |
/**
|
|
|
190 |
* @throws \Exception
|
191 |
*/
|
192 |
protected function processNotice( NoticeVO $notice ) {
|
193 |
throw new \Exception( 'Unsupported Notice ID: '.$notice->id );
|
194 |
}
|
195 |
|
196 |
+
protected function setNoticeDismissed( NoticeVO $notice ) {
|
197 |
+
$ts = Services::Request()->ts();
|
|
|
|
|
|
|
|
|
198 |
|
199 |
$meta = $this->getCon()->getCurrentUserMeta();
|
200 |
+
$noticeMetaKey = $this->getNoticeMetaKey( $notice );
|
201 |
|
202 |
if ( $notice->per_user ) {
|
203 |
if ( $meta instanceof PluginUserMeta ) {
|
204 |
+
$meta->{$noticeMetaKey} = $ts;
|
205 |
}
|
206 |
}
|
207 |
else {
|
208 |
$mod = $this->getMod();
|
209 |
+
$allDismissed = $mod->getDismissedNotices();
|
210 |
+
$allDismissed[ $notice->id ] = $ts;
|
211 |
+
$mod->setDismissedNotices( $allDismissed );
|
212 |
|
213 |
// Clear out any old
|
214 |
if ( $meta instanceof PluginUserMeta ) {
|
215 |
+
unset( $meta->{$noticeMetaKey} );
|
216 |
}
|
217 |
}
|
|
|
218 |
}
|
219 |
|
220 |
+
private function getNoticeMetaKey( NoticeVO $notice ) :string {
|
|
|
|
|
|
|
|
|
221 |
return 'notice_'.str_replace( [ '-', '_' ], '', $notice->id );
|
222 |
}
|
223 |
}
|
src/lib/src/Modules/Base/Options.php
CHANGED
@@ -202,6 +202,7 @@ class Options {
|
|
202 |
public function isValidOptionValueType( string $key, $value ) :bool {
|
203 |
switch ( $this->getOptionType( $key ) ) {
|
204 |
case 'array':
|
|
|
205 |
$valid = is_array( $value );
|
206 |
break;
|
207 |
default:
|
@@ -398,8 +399,7 @@ class Options {
|
|
398 |
}
|
399 |
|
400 |
/**
|
401 |
-
* @param
|
402 |
-
* @param mixed $mDefault
|
403 |
* @return mixed
|
404 |
*/
|
405 |
public function getOpt( string $key, $mDefault = false ) {
|
@@ -413,7 +413,6 @@ class Options {
|
|
413 |
}
|
414 |
|
415 |
/**
|
416 |
-
* @param string $key
|
417 |
* @param mixed $mDefault
|
418 |
* @return mixed|null
|
419 |
*/
|
@@ -427,20 +426,17 @@ class Options {
|
|
427 |
}
|
428 |
|
429 |
/**
|
430 |
-
* @param string $key
|
431 |
* @param mixed $mValueToTest
|
432 |
* @param bool $strict
|
433 |
-
* @return bool
|
434 |
*/
|
435 |
public function isOpt( string $key, $mValueToTest, $strict = false ) :bool {
|
436 |
return $strict ? $this->getOpt( $key ) === $mValueToTest : $this->getOpt( $key ) == $mValueToTest;
|
437 |
}
|
438 |
|
439 |
/**
|
440 |
-
* @param string $key
|
441 |
* @return string|null
|
442 |
*/
|
443 |
-
public function getOptionType( $key ) {
|
444 |
return $this->getOptDefinition( $key )[ 'type' ] ?? null;
|
445 |
}
|
446 |
|
202 |
public function isValidOptionValueType( string $key, $value ) :bool {
|
203 |
switch ( $this->getOptionType( $key ) ) {
|
204 |
case 'array':
|
205 |
+
case 'multiple_select':
|
206 |
$valid = is_array( $value );
|
207 |
break;
|
208 |
default:
|
399 |
}
|
400 |
|
401 |
/**
|
402 |
+
* @param mixed $mDefault
|
|
|
403 |
* @return mixed
|
404 |
*/
|
405 |
public function getOpt( string $key, $mDefault = false ) {
|
413 |
}
|
414 |
|
415 |
/**
|
|
|
416 |
* @param mixed $mDefault
|
417 |
* @return mixed|null
|
418 |
*/
|
426 |
}
|
427 |
|
428 |
/**
|
|
|
429 |
* @param mixed $mValueToTest
|
430 |
* @param bool $strict
|
|
|
431 |
*/
|
432 |
public function isOpt( string $key, $mValueToTest, $strict = false ) :bool {
|
433 |
return $strict ? $this->getOpt( $key ) === $mValueToTest : $this->getOpt( $key ) == $mValueToTest;
|
434 |
}
|
435 |
|
436 |
/**
|
|
|
437 |
* @return string|null
|
438 |
*/
|
439 |
+
public function getOptionType( string $key ) {
|
440 |
return $this->getOptDefinition( $key )[ 'type' ] ?? null;
|
441 |
}
|
442 |
|
src/lib/src/Modules/Data/DB/IPs/Ops/Insert.php
CHANGED
@@ -9,7 +9,6 @@ class Insert extends Base\Insert {
|
|
9 |
|
10 |
/**
|
11 |
* @param Record $record
|
12 |
-
* @return bool
|
13 |
*/
|
14 |
public function insert( $record ) :bool {
|
15 |
return (bool)Services::WpDb()->doSql( sprintf(
|
9 |
|
10 |
/**
|
11 |
* @param Record $record
|
|
|
12 |
*/
|
13 |
public function insert( $record ) :bool {
|
14 |
return (bool)Services::WpDb()->doSql( sprintf(
|
src/lib/src/Modules/IPs/Lib/Bots/NotBot/InsertNotBotJs.php
CHANGED
@@ -42,10 +42,21 @@ class InsertNotBotJs extends ExecOnceModConsumer {
|
|
42 |
}
|
43 |
|
44 |
protected function run() {
|
|
|
45 |
$this->enqueueJS();
|
46 |
$this->nonceJs();
|
47 |
}
|
48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
protected function enqueueJS() {
|
50 |
add_filter( 'shield/custom_enqueues', function ( array $enqueues ) {
|
51 |
$enqueues[ Enqueue::JS ][] = 'shield/notbot';
|
@@ -58,20 +69,12 @@ class InsertNotBotJs extends ExecOnceModConsumer {
|
|
58 |
*/
|
59 |
private function nonceJs() {
|
60 |
add_filter( 'shield/custom_localisations', function ( array $localz ) {
|
61 |
-
|
62 |
-
$ajaxData = $this->getMod()->getAjaxActionData( 'not_bot' );
|
63 |
-
$ajaxHref = $ajaxData[ 'ajaxurl' ];
|
64 |
-
unset( $ajaxData[ 'ajaxurl' ] );
|
65 |
-
|
66 |
$localz[] = [
|
67 |
'shield/notbot',
|
68 |
'shield_vars_notbotjs',
|
69 |
apply_filters( 'shield/notbot_data_js', [
|
70 |
'ajax' => [
|
71 |
-
'not_bot' =>
|
72 |
-
],
|
73 |
-
'hrefs' => [
|
74 |
-
'ajax' => $ajaxHref
|
75 |
],
|
76 |
'flags' => [
|
77 |
'run' => !in_array( Services::IP()->getIpDetector()->getIPIdentity(), [ 'gtmetrix' ] ),
|
42 |
}
|
43 |
|
44 |
protected function run() {
|
45 |
+
$this->sendNonceCookie();
|
46 |
$this->enqueueJS();
|
47 |
$this->nonceJs();
|
48 |
}
|
49 |
|
50 |
+
protected function sendNonceCookie() {
|
51 |
+
if ( $this->isForcedForOptimisationPlugins() ) {
|
52 |
+
Services::Response()->cookieSet(
|
53 |
+
'shield-notbot-nonce',
|
54 |
+
$this->getMod()->getAjaxActionData( 'not_bot' )[ 'exec_nonce' ],
|
55 |
+
10
|
56 |
+
);
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
protected function enqueueJS() {
|
61 |
add_filter( 'shield/custom_enqueues', function ( array $enqueues ) {
|
62 |
$enqueues[ Enqueue::JS ][] = 'shield/notbot';
|
69 |
*/
|
70 |
private function nonceJs() {
|
71 |
add_filter( 'shield/custom_localisations', function ( array $localz ) {
|
|
|
|
|
|
|
|
|
|
|
72 |
$localz[] = [
|
73 |
'shield/notbot',
|
74 |
'shield_vars_notbotjs',
|
75 |
apply_filters( 'shield/notbot_data_js', [
|
76 |
'ajax' => [
|
77 |
+
'not_bot' => $this->getMod()->getAjaxActionData( 'not_bot' )
|
|
|
|
|
|
|
78 |
],
|
79 |
'flags' => [
|
80 |
'run' => !in_array( Services::IP()->getIpDetector()->getIPIdentity(), [ 'gtmetrix' ] ),
|
src/lib/src/Modules/Integrations/Lib/Bots/Common/BaseBotDetectionController.php
CHANGED
@@ -15,39 +15,38 @@ abstract class BaseBotDetectionController extends ExecOnceModConsumer {
|
|
15 |
|
16 |
protected function run() {
|
17 |
array_map(
|
18 |
-
function ( $
|
19 |
-
$
|
20 |
-
},
|
21 |
-
$this->getInstalledProviders()
|
22 |
-
);
|
23 |
-
}
|
24 |
-
|
25 |
-
/**
|
26 |
-
* Inserts the ModCon;
|
27 |
-
* @return BaseHandler[]
|
28 |
-
*/
|
29 |
-
public function getInstalledProviders() :array {
|
30 |
-
return array_map(
|
31 |
-
function ( $provider ) {
|
32 |
-
return $provider->setMod( $this->getMod() );
|
33 |
},
|
34 |
array_filter(
|
35 |
-
|
|
|
|
|
|
|
36 |
function ( $provider ) {
|
37 |
-
return $provider::IsProviderInstalled
|
38 |
}
|
39 |
)
|
40 |
);
|
41 |
}
|
42 |
|
43 |
/**
|
44 |
-
* @return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
*/
|
46 |
public function enumProviders() :array {
|
47 |
return [];
|
48 |
}
|
49 |
|
50 |
protected function isEnabled() :bool {
|
51 |
-
return
|
52 |
}
|
53 |
}
|
15 |
|
16 |
protected function run() {
|
17 |
array_map(
|
18 |
+
function ( $providerClass ) {
|
19 |
+
( new $providerClass() )->setMod( $this->getMod() )->execute();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
},
|
21 |
array_filter(
|
22 |
+
array_intersect_key(
|
23 |
+
$this->enumProviders(),
|
24 |
+
array_flip( $this->getSelectedProviders() )
|
25 |
+
),
|
26 |
function ( $provider ) {
|
27 |
+
return call_user_func( $provider.'::IsProviderInstalled' );
|
28 |
}
|
29 |
)
|
30 |
);
|
31 |
}
|
32 |
|
33 |
/**
|
34 |
+
* @return string[]
|
35 |
+
*/
|
36 |
+
public function getSelectedProviders() :array {
|
37 |
+
return $this->getOptions()->getOpt( $this->getSelectedProvidersOptKey(), [] );
|
38 |
+
}
|
39 |
+
|
40 |
+
abstract public function getSelectedProvidersOptKey() :string;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @return string[]
|
44 |
*/
|
45 |
public function enumProviders() :array {
|
46 |
return [];
|
47 |
}
|
48 |
|
49 |
protected function isEnabled() :bool {
|
50 |
+
return !empty( $this->getSelectedProviders() );
|
51 |
}
|
52 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/Common/BaseHandler.php
CHANGED
@@ -7,11 +7,43 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
7 |
|
8 |
abstract class BaseHandler extends ExecOnceModConsumer {
|
9 |
|
10 |
-
const SLUG = '';
|
11 |
-
|
12 |
protected function canRun() :bool {
|
13 |
-
return (
|
14 |
-
&& $this->isEnabled()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
}
|
16 |
|
17 |
protected function isBot() :bool {
|
@@ -21,26 +53,16 @@ abstract class BaseHandler extends ExecOnceModConsumer {
|
|
21 |
->isBot( Services::IP()->getRequestIp() );
|
22 |
}
|
23 |
|
24 |
-
|
25 |
-
return false;
|
26 |
-
}
|
27 |
-
|
28 |
-
public static function IsProviderInstalled() :bool {
|
29 |
return false;
|
30 |
}
|
31 |
|
32 |
-
|
33 |
-
return
|
34 |
}
|
35 |
|
36 |
-
public function
|
37 |
-
|
38 |
-
$slug = strtolower( ( new \ReflectionClass( $this ) )->getShortName() );
|
39 |
-
}
|
40 |
-
catch ( \Exception $e ) {
|
41 |
-
$slug = '';
|
42 |
-
}
|
43 |
-
return $slug;
|
44 |
}
|
45 |
|
46 |
protected function isProOnly() :bool {
|
7 |
|
8 |
abstract class BaseHandler extends ExecOnceModConsumer {
|
9 |
|
|
|
|
|
10 |
protected function canRun() :bool {
|
11 |
+
return static::IsProviderInstalled()
|
12 |
+
&& $this->isEnabled()
|
13 |
+
&& ( $this->getCon()->isPremiumActive() || !$this->isProOnly() );
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @return BaseBotDetectionController|mixed
|
18 |
+
*/
|
19 |
+
abstract public function getHandlerController();
|
20 |
+
|
21 |
+
public function getHandlerSlug() :string {
|
22 |
+
try {
|
23 |
+
$slug = strtolower( ( new \ReflectionClass( $this ) )->getShortName() );
|
24 |
+
}
|
25 |
+
catch ( \Exception $e ) {
|
26 |
+
$slug = '';
|
27 |
+
}
|
28 |
+
return $slug;
|
29 |
+
}
|
30 |
+
|
31 |
+
public function getHandlerName() :string {
|
32 |
+
$name = 'Undefined Name';
|
33 |
+
$slug = $this->getHandlerSlug();
|
34 |
+
|
35 |
+
$valueOptions = $this->getOptions()
|
36 |
+
->getOptDefinition(
|
37 |
+
$this->getHandlerController()->getSelectedProvidersOptKey()
|
38 |
+
)[ 'value_options' ];
|
39 |
+
|
40 |
+
foreach ( $valueOptions as $valueOption ) {
|
41 |
+
if ( $valueOption[ 'value_key' ] === $slug ) {
|
42 |
+
$name = __( $valueOption[ 'text' ], 'wp-simple-firewall' );
|
43 |
+
break;
|
44 |
+
}
|
45 |
+
}
|
46 |
+
return $name;
|
47 |
}
|
48 |
|
49 |
protected function isBot() :bool {
|
53 |
->isBot( Services::IP()->getRequestIp() );
|
54 |
}
|
55 |
|
56 |
+
protected function isSpam_Human() :bool {
|
|
|
|
|
|
|
|
|
57 |
return false;
|
58 |
}
|
59 |
|
60 |
+
public function isEnabled() :bool {
|
61 |
+
return in_array( $this->getHandlerSlug(), $this->getHandlerController()->getSelectedProviders() );
|
62 |
}
|
63 |
|
64 |
+
public static function IsProviderInstalled() :bool {
|
65 |
+
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
}
|
67 |
|
68 |
protected function isProOnly() :bool {
|
src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/Base.php
CHANGED
@@ -2,31 +2,27 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\Bots\Spam\Handlers;
|
4 |
|
5 |
-
use FernleafSystems\Utilities\Logic\ExecOnce;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\Bots\Common\BaseHandler;
|
7 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\
|
8 |
-
use FernleafSystems\Wordpress\Services\Services;
|
9 |
|
10 |
abstract class Base extends BaseHandler {
|
11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
public function isSpam() :bool {
|
13 |
$isSpam = $this->isBot();
|
14 |
$this->getCon()->fireEvent(
|
15 |
sprintf( 'spam_form_%s', $isSpam ? 'fail' : 'pass' ),
|
16 |
[
|
17 |
'audit_params' => [
|
18 |
-
'form_provider' => $this->
|
19 |
]
|
20 |
]
|
21 |
);
|
22 |
return $isSpam;
|
23 |
}
|
24 |
-
|
25 |
-
protected function isSpam_Human() :bool {
|
26 |
-
return false;
|
27 |
-
}
|
28 |
-
|
29 |
-
public function isEnabled() :bool {
|
30 |
-
return in_array( $this->getHandlerSlug(), $this->getOptions()->getOpt( 'form_spam_providers', [] ) );
|
31 |
-
}
|
32 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\Bots\Spam\Handlers;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\Bots\Common\BaseHandler;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\ModCon;
|
|
|
7 |
|
8 |
abstract class Base extends BaseHandler {
|
9 |
|
10 |
+
public function getHandlerController() {
|
11 |
+
/** @var ModCon $mod */
|
12 |
+
$mod = $this->getMod();
|
13 |
+
return $mod->getController_SpamForms();
|
14 |
+
}
|
15 |
+
|
16 |
public function isSpam() :bool {
|
17 |
$isSpam = $this->isBot();
|
18 |
$this->getCon()->fireEvent(
|
19 |
sprintf( 'spam_form_%s', $isSpam ? 'fail' : 'pass' ),
|
20 |
[
|
21 |
'audit_params' => [
|
22 |
+
'form_provider' => $this->getHandlerName(),
|
23 |
]
|
24 |
]
|
25 |
);
|
26 |
return $isSpam;
|
27 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/ContactForm7.php
CHANGED
@@ -10,10 +10,6 @@ class ContactForm7 extends Base {
|
|
10 |
}, 1000, 2 );
|
11 |
}
|
12 |
|
13 |
-
protected function getProviderName() :string {
|
14 |
-
return 'Contact Form 7';
|
15 |
-
}
|
16 |
-
|
17 |
public static function IsProviderInstalled() :bool {
|
18 |
return defined( 'WPCF7_TEXT_DOMAIN' ) && WPCF7_TEXT_DOMAIN === 'contact-form-7';
|
19 |
}
|
10 |
}, 1000, 2 );
|
11 |
}
|
12 |
|
|
|
|
|
|
|
|
|
13 |
public static function IsProviderInstalled() :bool {
|
14 |
return defined( 'WPCF7_TEXT_DOMAIN' ) && WPCF7_TEXT_DOMAIN === 'contact-form-7';
|
15 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/ElementorPro.php
CHANGED
@@ -16,10 +16,6 @@ class ElementorPro extends Base {
|
|
16 |
}, 1000, 2 );
|
17 |
}
|
18 |
|
19 |
-
protected function getProviderName() :string {
|
20 |
-
return 'Elementor Pro';
|
21 |
-
}
|
22 |
-
|
23 |
public static function IsProviderInstalled() :bool {
|
24 |
return defined( 'ELEMENTOR_PRO_VERSION' ) && @function_exists( 'elementor_pro_load_plugin' );
|
25 |
}
|
16 |
}, 1000, 2 );
|
17 |
}
|
18 |
|
|
|
|
|
|
|
|
|
19 |
public static function IsProviderInstalled() :bool {
|
20 |
return defined( 'ELEMENTOR_PRO_VERSION' ) && @function_exists( 'elementor_pro_load_plugin' );
|
21 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/FluentForms.php
CHANGED
@@ -3,26 +3,27 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\Bots\Spam\Handlers;
|
4 |
|
5 |
/**
|
6 |
-
*
|
7 |
-
*
|
8 |
-
* Luckily the error message within the plugin is non-Akismet specific.
|
9 |
-
*
|
10 |
-
* Class FluentForms
|
11 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\Bots\Spam\Handlers
|
12 |
*/
|
13 |
class FluentForms extends Base {
|
14 |
|
15 |
protected function run() {
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
|
|
|
|
23 |
}
|
24 |
|
25 |
public static function IsProviderInstalled() :bool {
|
26 |
-
return defined( 'FLUENTFORM' )
|
|
|
|
|
|
|
27 |
}
|
28 |
}
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\Bots\Spam\Handlers;
|
4 |
|
5 |
/**
|
6 |
+
* It's a little convoluted, but we use the same approach as they use for their own HoneyPot.
|
7 |
+
* See Hooks/Ajax.php in their plugin.
|
|
|
|
|
|
|
|
|
8 |
*/
|
9 |
class FluentForms extends Base {
|
10 |
|
11 |
protected function run() {
|
12 |
+
\FluentForm\App::getApplication()->addAction( 'fluentform_before_insert_submission',
|
13 |
+
function () {
|
14 |
+
if ( $this->isSpam() ) {
|
15 |
+
wp_send_json( [
|
16 |
+
'errors' => sprintf( __( "This appears to be spam - failed %s AntiBot protection checks.", 'wp-simple-firewall' ),
|
17 |
+
$this->getCon()->getHumanName() )
|
18 |
+
], 422 );
|
19 |
+
}
|
20 |
+
}, 9, 0 );
|
21 |
}
|
22 |
|
23 |
public static function IsProviderInstalled() :bool {
|
24 |
+
return defined( 'FLUENTFORM' )
|
25 |
+
&& @class_exists( '\FluentForm\App' )
|
26 |
+
&& @method_exists( '\FluentForm\App', 'getApplication' )
|
27 |
+
&& @method_exists( \FluentForm\App::getApplication(), 'addPublicAjaxAction' );
|
28 |
}
|
29 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/FormidableForms.php
CHANGED
@@ -19,10 +19,6 @@ class FormidableForms extends Base {
|
|
19 |
}, 1000 );
|
20 |
}
|
21 |
|
22 |
-
protected function getProviderName() :string {
|
23 |
-
return 'Formidable Forms';
|
24 |
-
}
|
25 |
-
|
26 |
public static function IsProviderInstalled() :bool {
|
27 |
return function_exists( 'load_formidable_forms' ) && @class_exists( '\FrmHooksController' );
|
28 |
}
|
19 |
}, 1000 );
|
20 |
}
|
21 |
|
|
|
|
|
|
|
|
|
22 |
public static function IsProviderInstalled() :bool {
|
23 |
return function_exists( 'load_formidable_forms' ) && @class_exists( '\FrmHooksController' );
|
24 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/Forminator.php
CHANGED
@@ -10,10 +10,6 @@ class Forminator extends Base {
|
|
10 |
}, 1000 );
|
11 |
}
|
12 |
|
13 |
-
protected function getProviderName() :string {
|
14 |
-
return 'Forminator';
|
15 |
-
}
|
16 |
-
|
17 |
public static function IsProviderInstalled() :bool {
|
18 |
return defined( 'FORMINATOR_VERSION' ) && @class_exists( '\Forminator' );
|
19 |
}
|
10 |
}, 1000 );
|
11 |
}
|
12 |
|
|
|
|
|
|
|
|
|
13 |
public static function IsProviderInstalled() :bool {
|
14 |
return defined( 'FORMINATOR_VERSION' ) && @class_exists( '\Forminator' );
|
15 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/GravityForms.php
CHANGED
@@ -10,10 +10,6 @@ class GravityForms extends Base {
|
|
10 |
}, 1000 );
|
11 |
}
|
12 |
|
13 |
-
protected function getProviderName() :string {
|
14 |
-
return 'Gravity Forms';
|
15 |
-
}
|
16 |
-
|
17 |
public static function IsProviderInstalled() :bool {
|
18 |
return @class_exists( '\GFForms' )
|
19 |
&& isset( \GFForms::$version )
|
10 |
}, 1000 );
|
11 |
}
|
12 |
|
|
|
|
|
|
|
|
|
13 |
public static function IsProviderInstalled() :bool {
|
14 |
return @class_exists( '\GFForms' )
|
15 |
&& isset( \GFForms::$version )
|
src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/Groundhogg.php
CHANGED
@@ -10,12 +10,7 @@ class Groundhogg extends Base {
|
|
10 |
}, 1000 );
|
11 |
}
|
12 |
|
13 |
-
protected function getProviderName() :string {
|
14 |
-
return 'Groundhogg';
|
15 |
-
}
|
16 |
-
|
17 |
public static function IsProviderInstalled() :bool {
|
18 |
-
return defined( '
|
19 |
-
&& version_compare( GROUNDHOGG_VERSION, '2.4.5.5', '>=' );
|
20 |
}
|
21 |
}
|
10 |
}, 1000 );
|
11 |
}
|
12 |
|
|
|
|
|
|
|
|
|
13 |
public static function IsProviderInstalled() :bool {
|
14 |
+
return defined( 'GROUNDHOGG_VERSION' ) && version_compare( GROUNDHOGG_VERSION, '2.4.5.5', '>=' );
|
|
|
15 |
}
|
16 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/KaliForms.php
CHANGED
@@ -17,10 +17,6 @@ class KaliForms extends Base {
|
|
17 |
}, 1000 );
|
18 |
}
|
19 |
|
20 |
-
protected function getProviderName() :string {
|
21 |
-
return 'Kali Forms';
|
22 |
-
}
|
23 |
-
|
24 |
public static function IsProviderInstalled() :bool {
|
25 |
return defined( 'KALIFORMS_PLUGIN_FILE' ) && @class_exists( '\KaliForms\Inc\KaliForms' );
|
26 |
}
|
17 |
}, 1000 );
|
18 |
}
|
19 |
|
|
|
|
|
|
|
|
|
20 |
public static function IsProviderInstalled() :bool {
|
21 |
return defined( 'KALIFORMS_PLUGIN_FILE' ) && @class_exists( '\KaliForms\Inc\KaliForms' );
|
22 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/NinjaForms.php
CHANGED
@@ -38,10 +38,6 @@ class NinjaForms extends Base {
|
|
38 |
}, 1000 );
|
39 |
}
|
40 |
|
41 |
-
protected function getProviderName() :string {
|
42 |
-
return 'Ninja Forms';
|
43 |
-
}
|
44 |
-
|
45 |
public static function IsProviderInstalled() :bool {
|
46 |
return @class_exists( '\Ninja_Forms' );
|
47 |
}
|
38 |
}, 1000 );
|
39 |
}
|
40 |
|
|
|
|
|
|
|
|
|
41 |
public static function IsProviderInstalled() :bool {
|
42 |
return @class_exists( '\Ninja_Forms' );
|
43 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/SuperForms.php
CHANGED
@@ -12,10 +12,6 @@ class SuperForms extends Base {
|
|
12 |
}, 1000 );
|
13 |
}
|
14 |
|
15 |
-
protected function getProviderName() :string {
|
16 |
-
return 'Super Forms';
|
17 |
-
}
|
18 |
-
|
19 |
public static function IsProviderInstalled() :bool {
|
20 |
return @class_exists( '\SUPER_Forms' )
|
21 |
&& isset( \SUPER_Forms::$version )
|
12 |
}, 1000 );
|
13 |
}
|
14 |
|
|
|
|
|
|
|
|
|
15 |
public static function IsProviderInstalled() :bool {
|
16 |
return @class_exists( '\SUPER_Forms' )
|
17 |
&& isset( \SUPER_Forms::$version )
|
src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/SupportCandy.php
CHANGED
@@ -16,10 +16,6 @@ class SupportCandy extends Base {
|
|
16 |
}, 1000 );
|
17 |
}
|
18 |
|
19 |
-
protected function getProviderName() :string {
|
20 |
-
return 'SupportCandy';
|
21 |
-
}
|
22 |
-
|
23 |
public static function IsProviderInstalled() :bool {
|
24 |
return @class_exists( 'Support_Candy' )
|
25 |
&& defined( 'WPSC_VERSION' ) && version_compare( WPSC_VERSION, '2.2.3', '>=' );
|
16 |
}, 1000 );
|
17 |
}
|
18 |
|
|
|
|
|
|
|
|
|
19 |
public static function IsProviderInstalled() :bool {
|
20 |
return @class_exists( 'Support_Candy' )
|
21 |
&& defined( 'WPSC_VERSION' ) && version_compare( WPSC_VERSION, '2.2.3', '>=' );
|
src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/WPForms.php
CHANGED
@@ -27,10 +27,6 @@ class WPForms extends Base {
|
|
27 |
}, 1000, 2 );
|
28 |
}
|
29 |
|
30 |
-
protected function getProviderName() :string {
|
31 |
-
return 'WP Forms';
|
32 |
-
}
|
33 |
-
|
34 |
public static function IsProviderInstalled() :bool {
|
35 |
return defined( 'WPFORMS_VERSION' ) && function_exists( 'wpforms' );
|
36 |
}
|
27 |
}, 1000, 2 );
|
28 |
}
|
29 |
|
|
|
|
|
|
|
|
|
30 |
public static function IsProviderInstalled() :bool {
|
31 |
return defined( 'WPFORMS_VERSION' ) && function_exists( 'wpforms' );
|
32 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/Spam/Handlers/WpForo.php
CHANGED
@@ -6,14 +6,17 @@ class WpForo extends Base {
|
|
6 |
|
7 |
protected function run() {
|
8 |
foreach ( $this->getFiltersToMonitor() as $filter ) {
|
9 |
-
add_filter( $filter, function (
|
10 |
-
|
11 |
-
|
12 |
-
if ( $
|
13 |
-
|
14 |
-
|
|
|
|
|
|
|
|
|
15 |
}
|
16 |
-
$args[ 'status' ] = 1; // 1 signifies not approved
|
17 |
}
|
18 |
|
19 |
return $args;
|
@@ -30,10 +33,6 @@ class WpForo extends Base {
|
|
30 |
];
|
31 |
}
|
32 |
|
33 |
-
protected function getProviderName() :string {
|
34 |
-
return 'wpForo';
|
35 |
-
}
|
36 |
-
|
37 |
public static function IsProviderInstalled() :bool {
|
38 |
return function_exists( 'WPF' ) && @class_exists( 'wpForo' ) && !empty( WPF()->tools_antispam[ 'spam_filter' ] );
|
39 |
}
|
6 |
|
7 |
protected function run() {
|
8 |
foreach ( $this->getFiltersToMonitor() as $filter ) {
|
9 |
+
add_filter( $filter, function ( $args = [] ) {
|
10 |
+
|
11 |
+
// It should be an array, but customer reported fatal error with a boolean passed
|
12 |
+
if ( is_array( $args ) ) {
|
13 |
+
$status = $args[ 'status' ] ?? null;
|
14 |
+
if ( $status !== 1 && $this->isSpam() ) {
|
15 |
+
if ( !empty( WPF()->current_userid ) ) {
|
16 |
+
WPF()->moderation->ban_for_spam( WPF()->current_userid );
|
17 |
+
}
|
18 |
+
$args[ 'status' ] = 1; // 1 signifies not approved
|
19 |
}
|
|
|
20 |
}
|
21 |
|
22 |
return $args;
|
33 |
];
|
34 |
}
|
35 |
|
|
|
|
|
|
|
|
|
36 |
public static function IsProviderInstalled() :bool {
|
37 |
return function_exists( 'WPF' ) && @class_exists( 'wpForo' ) && !empty( WPF()->tools_antispam[ 'spam_filter' ] );
|
38 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/Spam/SpamController.php
CHANGED
@@ -6,28 +6,28 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\Bots\Common
|
|
6 |
|
7 |
class SpamController extends BaseBotDetectionController {
|
8 |
|
9 |
-
|
10 |
-
return
|
11 |
}
|
12 |
|
13 |
/**
|
14 |
-
* @
|
15 |
*/
|
16 |
public function enumProviders() :array {
|
17 |
return [
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
];
|
32 |
}
|
33 |
}
|
6 |
|
7 |
class SpamController extends BaseBotDetectionController {
|
8 |
|
9 |
+
public function getSelectedProvidersOptKey() :string {
|
10 |
+
return 'form_spam_providers';
|
11 |
}
|
12 |
|
13 |
/**
|
14 |
+
* @inheritDoc
|
15 |
*/
|
16 |
public function enumProviders() :array {
|
17 |
return [
|
18 |
+
'contactform7' => Handlers\ContactForm7::class,
|
19 |
+
'elementorpro' => Handlers\ElementorPro::class,
|
20 |
+
'fluentforms' => Handlers\FluentForms::class,
|
21 |
+
'formidableforms' => Handlers\FormidableForms::class,
|
22 |
+
'forminator' => Handlers\Forminator::class,
|
23 |
+
'gravityforms' => Handlers\GravityForms::class,
|
24 |
+
'groundhogg' => Handlers\Groundhogg::class,
|
25 |
+
'kaliforms' => Handlers\KaliForms::class,
|
26 |
+
'ninjaforms' => Handlers\NinjaForms::class,
|
27 |
+
'superforms' => Handlers\SuperForms::class,
|
28 |
+
'supportcandy' => Handlers\SupportCandy::class,
|
29 |
+
'wpforms' => Handlers\WPForms::class,
|
30 |
+
'wpforo' => Handlers\WpForo::class,
|
31 |
];
|
32 |
}
|
33 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/Base.php
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\Bots\UserForms\Handlers;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations;
|
|
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
7 |
|
8 |
abstract class Base extends Integrations\Lib\Bots\Common\BaseHandler {
|
@@ -54,6 +55,12 @@ abstract class Base extends Integrations\Lib\Bots\Common\BaseHandler {
|
|
54 |
return empty( $this->auditUser ) ? 'unknown' : $this->auditUser;
|
55 |
}
|
56 |
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
/**
|
58 |
* @param string $action
|
59 |
* @return $this
|
@@ -79,7 +86,7 @@ abstract class Base extends Integrations\Lib\Bots\Common\BaseHandler {
|
|
79 |
sprintf( 'user_form_bot_%s', self::$isBot ? 'fail' : 'pass' ),
|
80 |
[
|
81 |
'audit_params' => [
|
82 |
-
'form_provider' => $this->
|
83 |
'action' => $this->getAuditAction(),
|
84 |
'username' => $this->getAuditUser(),
|
85 |
]
|
@@ -89,12 +96,6 @@ abstract class Base extends Integrations\Lib\Bots\Common\BaseHandler {
|
|
89 |
return self::$isBot;
|
90 |
}
|
91 |
|
92 |
-
public function isEnabled() :bool {
|
93 |
-
/** @var Integrations\Options $opts */
|
94 |
-
$opts = $this->getOptions();
|
95 |
-
return in_array( $this->getHandlerSlug(), $opts->getUserFormProviders() );
|
96 |
-
}
|
97 |
-
|
98 |
protected function getErrorMessage() :string {
|
99 |
return sprintf( __( '%s Bot Check Failed.', 'wp-simple-firewall' ), $this->getCon()->getHumanName() );
|
100 |
}
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\Bots\UserForms\Handlers;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\ModCon;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
8 |
|
9 |
abstract class Base extends Integrations\Lib\Bots\Common\BaseHandler {
|
55 |
return empty( $this->auditUser ) ? 'unknown' : $this->auditUser;
|
56 |
}
|
57 |
|
58 |
+
public function getHandlerController() {
|
59 |
+
/** @var ModCon $mod */
|
60 |
+
$mod = $this->getMod();
|
61 |
+
return $mod->getController_UserForms();
|
62 |
+
}
|
63 |
+
|
64 |
/**
|
65 |
* @param string $action
|
66 |
* @return $this
|
86 |
sprintf( 'user_form_bot_%s', self::$isBot ? 'fail' : 'pass' ),
|
87 |
[
|
88 |
'audit_params' => [
|
89 |
+
'form_provider' => $this->getHandlerName(),
|
90 |
'action' => $this->getAuditAction(),
|
91 |
'username' => $this->getAuditUser(),
|
92 |
]
|
96 |
return self::$isBot;
|
97 |
}
|
98 |
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
protected function getErrorMessage() :string {
|
100 |
return sprintf( __( '%s Bot Check Failed.', 'wp-simple-firewall' ), $this->getCon()->getHumanName() );
|
101 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/Buddyboss.php
CHANGED
@@ -17,10 +17,6 @@ class Buddyboss extends Base {
|
|
17 |
}
|
18 |
}
|
19 |
|
20 |
-
protected function getProviderName() :string {
|
21 |
-
return 'BuddyBoss';
|
22 |
-
}
|
23 |
-
|
24 |
public static function IsProviderInstalled() :bool {
|
25 |
return @class_exists( '\BuddyPress' )
|
26 |
&& method_exists( '\BuddyPress', 'instance' )
|
17 |
}
|
18 |
}
|
19 |
|
|
|
|
|
|
|
|
|
20 |
public static function IsProviderInstalled() :bool {
|
21 |
return @class_exists( '\BuddyPress' )
|
22 |
&& method_exists( '\BuddyPress', 'instance' )
|
src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/Buddypress.php
CHANGED
@@ -14,10 +14,6 @@ class Buddypress extends Base {
|
|
14 |
}
|
15 |
}
|
16 |
|
17 |
-
protected function getProviderName() :string {
|
18 |
-
return 'BuddyPress';
|
19 |
-
}
|
20 |
-
|
21 |
public static function IsProviderInstalled() :bool {
|
22 |
return @class_exists( '\BuddyPress' );
|
23 |
}
|
14 |
}
|
15 |
}
|
16 |
|
|
|
|
|
|
|
|
|
17 |
public static function IsProviderInstalled() :bool {
|
18 |
return @class_exists( '\BuddyPress' );
|
19 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/EasyDigitalDownloads.php
CHANGED
@@ -14,10 +14,6 @@ class EasyDigitalDownloads extends Base {
|
|
14 |
}
|
15 |
}
|
16 |
|
17 |
-
protected function getProviderName() :string {
|
18 |
-
return 'Easy Digital Downloads';
|
19 |
-
}
|
20 |
-
|
21 |
public static function IsProviderInstalled() :bool {
|
22 |
return function_exists( 'edd_set_error' ) && @class_exists( 'Easy_Digital_Downloads' );
|
23 |
}
|
14 |
}
|
15 |
}
|
16 |
|
|
|
|
|
|
|
|
|
17 |
public static function IsProviderInstalled() :bool {
|
18 |
return function_exists( 'edd_set_error' ) && @class_exists( 'Easy_Digital_Downloads' );
|
19 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/LearnPress.php
CHANGED
@@ -34,10 +34,6 @@ class LearnPress extends Base {
|
|
34 |
return $maybeError;
|
35 |
}
|
36 |
|
37 |
-
protected function getProviderName() :string {
|
38 |
-
return 'LearnPress';
|
39 |
-
}
|
40 |
-
|
41 |
public static function IsProviderInstalled() :bool {
|
42 |
return @class_exists( 'LearnPress' );
|
43 |
}
|
34 |
return $maybeError;
|
35 |
}
|
36 |
|
|
|
|
|
|
|
|
|
37 |
public static function IsProviderInstalled() :bool {
|
38 |
return @class_exists( 'LearnPress' );
|
39 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/LifterLMS.php
CHANGED
@@ -37,10 +37,6 @@ class LifterLMS extends Base {
|
|
37 |
return $valid;
|
38 |
}
|
39 |
|
40 |
-
protected function getProviderName() :string {
|
41 |
-
return 'LifterLMS';
|
42 |
-
}
|
43 |
-
|
44 |
public static function IsProviderInstalled() :bool {
|
45 |
return defined( 'LLMS_PLUGIN_FILE' ) && @class_exists( 'LifterLMS' )
|
46 |
&& defined( 'LLMS_VERSION' ) && version_compare( LLMS_VERSION, '4.20', '>' );
|
37 |
return $valid;
|
38 |
}
|
39 |
|
|
|
|
|
|
|
|
|
40 |
public static function IsProviderInstalled() :bool {
|
41 |
return defined( 'LLMS_PLUGIN_FILE' ) && @class_exists( 'LifterLMS' )
|
42 |
&& defined( 'LLMS_VERSION' ) && version_compare( LLMS_VERSION, '4.20', '>' );
|
src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/MemberPress.php
CHANGED
@@ -61,10 +61,6 @@ class MemberPress extends Base {
|
|
61 |
return $errors;
|
62 |
}
|
63 |
|
64 |
-
protected function getProviderName() :string {
|
65 |
-
return 'MemberPress';
|
66 |
-
}
|
67 |
-
|
68 |
public static function IsProviderInstalled() :bool {
|
69 |
return function_exists( 'mepr_autoloader' ) || @class_exists( '\MeprAccountCtrl' );
|
70 |
}
|
61 |
return $errors;
|
62 |
}
|
63 |
|
|
|
|
|
|
|
|
|
64 |
public static function IsProviderInstalled() :bool {
|
65 |
return function_exists( 'mepr_autoloader' ) || @class_exists( '\MeprAccountCtrl' );
|
66 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/PaidMemberSubscriptions.php
CHANGED
@@ -14,10 +14,6 @@ class PaidMemberSubscriptions extends Base {
|
|
14 |
}
|
15 |
}
|
16 |
|
17 |
-
protected function getProviderName() :string {
|
18 |
-
return 'Paid Member Subscriptions';
|
19 |
-
}
|
20 |
-
|
21 |
public static function IsProviderInstalled() :bool {
|
22 |
return @class_exists( 'Paid_Member_Subscriptions' ) && function_exists( 'pms_errors' );
|
23 |
}
|
14 |
}
|
15 |
}
|
16 |
|
|
|
|
|
|
|
|
|
17 |
public static function IsProviderInstalled() :bool {
|
18 |
return @class_exists( 'Paid_Member_Subscriptions' ) && function_exists( 'pms_errors' );
|
19 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/ProfileBuilder.php
CHANGED
@@ -22,10 +22,6 @@ class ProfileBuilder extends Base {
|
|
22 |
return $errors;
|
23 |
}
|
24 |
|
25 |
-
protected function getProviderName() :string {
|
26 |
-
return 'Profile Builder';
|
27 |
-
}
|
28 |
-
|
29 |
public static function IsProviderInstalled() :bool {
|
30 |
return defined( 'PROFILE_BUILDER_VERSION' );
|
31 |
}
|
22 |
return $errors;
|
23 |
}
|
24 |
|
|
|
|
|
|
|
|
|
25 |
public static function IsProviderInstalled() :bool {
|
26 |
return defined( 'PROFILE_BUILDER_VERSION' );
|
27 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/UltimateMember.php
CHANGED
@@ -37,10 +37,6 @@ class UltimateMember extends Base {
|
|
37 |
}
|
38 |
}
|
39 |
|
40 |
-
protected function getProviderName() :string {
|
41 |
-
return 'Ultimate Member';
|
42 |
-
}
|
43 |
-
|
44 |
public static function IsProviderInstalled() :bool {
|
45 |
return function_exists( '\UM' ) && @class_exists( '\UM' ) && method_exists( '\UM', 'form' );
|
46 |
}
|
37 |
}
|
38 |
}
|
39 |
|
|
|
|
|
|
|
|
|
40 |
public static function IsProviderInstalled() :bool {
|
41 |
return function_exists( '\UM' ) && @class_exists( '\UM' ) && method_exists( '\UM', 'form' );
|
42 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/WPMembers.php
CHANGED
@@ -39,10 +39,6 @@ class WPMembers extends Base {
|
|
39 |
}
|
40 |
}
|
41 |
|
42 |
-
protected function getProviderName() :string {
|
43 |
-
return 'WP Members';
|
44 |
-
}
|
45 |
-
|
46 |
public static function IsProviderInstalled() :bool {
|
47 |
return defined( 'WPMEM_VERSION' ) && function_exists( 'wpmem_init' );
|
48 |
}
|
39 |
}
|
40 |
}
|
41 |
|
|
|
|
|
|
|
|
|
42 |
public static function IsProviderInstalled() :bool {
|
43 |
return defined( 'WPMEM_VERSION' ) && function_exists( 'wpmem_init' );
|
44 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/WooCommerce.php
CHANGED
@@ -52,10 +52,6 @@ class WooCommerce extends Base {
|
|
52 |
return $wpError;
|
53 |
}
|
54 |
|
55 |
-
protected function getProviderName() :string {
|
56 |
-
return 'WooCommerce';
|
57 |
-
}
|
58 |
-
|
59 |
public static function IsProviderInstalled() :bool {
|
60 |
return @class_exists( 'WooCommerce' );
|
61 |
}
|
52 |
return $wpError;
|
53 |
}
|
54 |
|
|
|
|
|
|
|
|
|
55 |
public static function IsProviderInstalled() :bool {
|
56 |
return @class_exists( 'WooCommerce' );
|
57 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/WordPress.php
CHANGED
@@ -74,10 +74,6 @@ class WordPress extends Base {
|
|
74 |
return $wpError;
|
75 |
}
|
76 |
|
77 |
-
protected function getProviderName() :string {
|
78 |
-
return 'WordPress';
|
79 |
-
}
|
80 |
-
|
81 |
public static function IsProviderInstalled() :bool {
|
82 |
return true;
|
83 |
}
|
74 |
return $wpError;
|
75 |
}
|
76 |
|
|
|
|
|
|
|
|
|
77 |
public static function IsProviderInstalled() :bool {
|
78 |
return true;
|
79 |
}
|
src/lib/src/Modules/Integrations/Lib/Bots/UserForms/UserFormsController.php
CHANGED
@@ -16,29 +16,27 @@ class UserFormsController extends Integrations\Lib\Bots\Common\BaseBotDetectionC
|
|
16 |
&& $loginOpts->isEnabledAntiBot();
|
17 |
}
|
18 |
|
19 |
-
|
20 |
-
|
21 |
-
$opts = $this->getOptions();
|
22 |
-
return !empty( $opts->getUserFormProviders() );
|
23 |
}
|
24 |
|
25 |
/**
|
26 |
-
* @
|
27 |
*/
|
28 |
public function enumProviders() :array {
|
29 |
return [
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
];
|
43 |
}
|
44 |
}
|
16 |
&& $loginOpts->isEnabledAntiBot();
|
17 |
}
|
18 |
|
19 |
+
public function getSelectedProvidersOptKey() :string {
|
20 |
+
return 'user_form_providers';
|
|
|
|
|
21 |
}
|
22 |
|
23 |
/**
|
24 |
+
* @inheritDoc
|
25 |
*/
|
26 |
public function enumProviders() :array {
|
27 |
return [
|
28 |
+
'buddyboss' => Handlers\Buddyboss::class,
|
29 |
+
'buddypress' => Handlers\Buddypress::class,
|
30 |
+
'easydigitaldownloads' => Handlers\EasyDigitalDownloads::class,
|
31 |
+
'learnpress' => Handlers\LearnPress::class,
|
32 |
+
'lifterlms' => Handlers\LifterLMS::class,
|
33 |
+
'memberpress' => Handlers\MemberPress::class,
|
34 |
+
'paidmembersubscriptions' => Handlers\PaidMemberSubscriptions::class,
|
35 |
+
'profilebuilder' => Handlers\ProfileBuilder::class,
|
36 |
+
'ultimatemember' => Handlers\UltimateMember::class,
|
37 |
+
'woocommerce' => Handlers\WooCommerce::class,
|
38 |
+
'wordpress' => Handlers\WordPress::class,
|
39 |
+
'wpmembers' => Handlers\WPMembers::class,
|
40 |
];
|
41 |
}
|
42 |
}
|
src/lib/src/Modules/Integrations/ModCon.php
CHANGED
@@ -17,6 +17,11 @@ class ModCon extends BaseShield\ModCon {
|
|
17 |
*/
|
18 |
private $userFormsCon;
|
19 |
|
|
|
|
|
|
|
|
|
|
|
20 |
public function getControllerMWP() :Lib\MainWP\Controller {
|
21 |
if ( empty( $this->mwp ) ) {
|
22 |
$this->mwp = ( new Lib\MainWP\Controller() )
|
@@ -25,10 +30,16 @@ class ModCon extends BaseShield\ModCon {
|
|
25 |
return $this->mwp;
|
26 |
}
|
27 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
public function getController_UserForms() :Lib\Bots\UserForms\UserFormsController {
|
29 |
-
if (
|
30 |
-
$this->userFormsCon = ( new Lib\Bots\UserForms\UserFormsController() )
|
31 |
-
->setMod( $this );
|
32 |
}
|
33 |
return $this->userFormsCon;
|
34 |
}
|
17 |
*/
|
18 |
private $userFormsCon;
|
19 |
|
20 |
+
/**
|
21 |
+
* @var Lib\Bots\Spam\SpamController
|
22 |
+
*/
|
23 |
+
private $spamFormsCon;
|
24 |
+
|
25 |
public function getControllerMWP() :Lib\MainWP\Controller {
|
26 |
if ( empty( $this->mwp ) ) {
|
27 |
$this->mwp = ( new Lib\MainWP\Controller() )
|
30 |
return $this->mwp;
|
31 |
}
|
32 |
|
33 |
+
public function getController_SpamForms() :Lib\Bots\Spam\SpamController {
|
34 |
+
if ( empty( $this->spamFormsCon ) ) {
|
35 |
+
$this->spamFormsCon = ( new Lib\Bots\Spam\SpamController() )->setMod( $this );
|
36 |
+
}
|
37 |
+
return $this->spamFormsCon;
|
38 |
+
}
|
39 |
+
|
40 |
public function getController_UserForms() :Lib\Bots\UserForms\UserFormsController {
|
41 |
+
if ( empty( $this->userFormsCon ) ) {
|
42 |
+
$this->userFormsCon = ( new Lib\Bots\UserForms\UserFormsController() )->setMod( $this );
|
|
|
43 |
}
|
44 |
return $this->userFormsCon;
|
45 |
}
|
src/lib/src/Modules/Integrations/Options.php
CHANGED
@@ -10,11 +10,11 @@ class Options extends BaseShield\Options {
|
|
10 |
return $this->isOpt( 'enable_mainwp', 'Y' );
|
11 |
}
|
12 |
|
|
|
|
|
|
|
13 |
public function getUserFormProviders() :array {
|
14 |
$userForms = $this->getOpt( 'user_form_providers' );
|
15 |
-
if ( !is_array( $userForms ) ) {
|
16 |
-
$userForms = [];
|
17 |
-
}
|
18 |
if ( !in_array( 'wordpress', $userForms ) ) {
|
19 |
$userForms[] = 'wordpress';
|
20 |
$this->setOpt( 'user_form_providers', $userForms );
|
10 |
return $this->isOpt( 'enable_mainwp', 'Y' );
|
11 |
}
|
12 |
|
13 |
+
/**
|
14 |
+
* @deprecated 13.0.5
|
15 |
+
*/
|
16 |
public function getUserFormProviders() :array {
|
17 |
$userForms = $this->getOpt( 'user_form_providers' );
|
|
|
|
|
|
|
18 |
if ( !in_array( 'wordpress', $userForms ) ) {
|
19 |
$userForms[] = 'wordpress';
|
20 |
$this->setOpt( 'user_form_providers', $userForms );
|
src/lib/src/Modules/Integrations/Processor.php
CHANGED
@@ -13,9 +13,7 @@ class Processor extends BaseShield\Processor {
|
|
13 |
$mod->getControllerMWP()->execute();
|
14 |
|
15 |
if ( !empty( Services::IP()->getRequestIp() ) ) {
|
16 |
-
(
|
17 |
-
->setMod( $this->getMod() )
|
18 |
-
->execute();
|
19 |
|
20 |
add_action( 'init', function () use ( $mod ) {
|
21 |
$mod->getController_UserForms()->execute();
|
13 |
$mod->getControllerMWP()->execute();
|
14 |
|
15 |
if ( !empty( Services::IP()->getRequestIp() ) ) {
|
16 |
+
$mod->getController_SpamForms()->execute();
|
|
|
|
|
17 |
|
18 |
add_action( 'init', function () use ( $mod ) {
|
19 |
$mod->getController_UserForms()->execute();
|
src/lib/src/Modules/Integrations/Strings.php
CHANGED
@@ -39,9 +39,7 @@ class Strings extends Base\Strings {
|
|
39 |
}
|
40 |
|
41 |
/**
|
42 |
-
* @
|
43 |
-
* @return array
|
44 |
-
* @throws \Exception
|
45 |
*/
|
46 |
public function getSectionStrings( string $section ) :array {
|
47 |
|
@@ -80,14 +78,12 @@ class Strings extends Base\Strings {
|
|
80 |
return [
|
81 |
'title' => $title,
|
82 |
'title_short' => $titleShort,
|
83 |
-
'summary' =>
|
84 |
];
|
85 |
}
|
86 |
|
87 |
/**
|
88 |
-
* @
|
89 |
-
* @return array
|
90 |
-
* @throws \Exception
|
91 |
*/
|
92 |
public function getOptionStrings( string $key ) :array {
|
93 |
$con = $this->getCon();
|
39 |
}
|
40 |
|
41 |
/**
|
42 |
+
* @inheritDoc
|
|
|
|
|
43 |
*/
|
44 |
public function getSectionStrings( string $section ) :array {
|
45 |
|
78 |
return [
|
79 |
'title' => $title,
|
80 |
'title_short' => $titleShort,
|
81 |
+
'summary' => $summary,
|
82 |
];
|
83 |
}
|
84 |
|
85 |
/**
|
86 |
+
* @inheritDoc
|
|
|
|
|
87 |
*/
|
88 |
public function getOptionStrings( string $key ) :array {
|
89 |
$con = $this->getCon();
|
src/lib/src/Modules/Integrations/UI.php
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
|
|
6 |
|
7 |
class UI extends Modules\BaseShield\UI {
|
8 |
|
@@ -32,7 +33,7 @@ class UI extends Modules\BaseShield\UI {
|
|
32 |
if ( $loginGuardOpts->isEnabledAntiBot() ) {
|
33 |
$notices[] = sprintf( '%s: %s %s', __( 'Note', 'wp-simple-firewall' ),
|
34 |
sprintf(
|
35 |
-
__( "The following forms are protected by AntiBot Detection: %s.", 'wp-simple-firewall' ),
|
36 |
$locations
|
37 |
),
|
38 |
sprintf( '<a href="%s" target="_blank">%s</a>',
|
@@ -48,9 +49,10 @@ class UI extends Modules\BaseShield\UI {
|
|
48 |
|
49 |
protected function getSectionWarnings( string $section ) :array {
|
50 |
$warnings = [];
|
|
|
51 |
|
52 |
/** @var Modules\LoginGuard\Options $loginGuardOpts */
|
53 |
-
$loginGuardOpts = $
|
54 |
|
55 |
switch ( $section ) {
|
56 |
|
@@ -59,11 +61,40 @@ class UI extends Modules\BaseShield\UI {
|
|
59 |
$warnings[] = sprintf( '%s: %s %s', __( 'Important', 'wp-simple-firewall' ),
|
60 |
__( "Use of the AntiBot Detection Engine for user forms isn't turned on in the Login Guard module.", 'wp-simple-firewall' ),
|
61 |
sprintf( '<a href="%s" target="_blank">%s</a>',
|
62 |
-
$
|
63 |
__( 'Click here to review those settings.', 'wp-simple-firewall' ) )
|
64 |
);
|
65 |
}
|
66 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
}
|
68 |
|
69 |
return $warnings;
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\Bots\Common\BaseHandler;
|
7 |
|
8 |
class UI extends Modules\BaseShield\UI {
|
9 |
|
33 |
if ( $loginGuardOpts->isEnabledAntiBot() ) {
|
34 |
$notices[] = sprintf( '%s: %s %s', __( 'Note', 'wp-simple-firewall' ),
|
35 |
sprintf(
|
36 |
+
__( "The following types of user forms are protected by AntiBot Detection: %s.", 'wp-simple-firewall' ),
|
37 |
$locations
|
38 |
),
|
39 |
sprintf( '<a href="%s" target="_blank">%s</a>',
|
49 |
|
50 |
protected function getSectionWarnings( string $section ) :array {
|
51 |
$warnings = [];
|
52 |
+
$con = $this->getCon();
|
53 |
|
54 |
/** @var Modules\LoginGuard\Options $loginGuardOpts */
|
55 |
+
$loginGuardOpts = $con->getModule_LoginGuard()->getOptions();
|
56 |
|
57 |
switch ( $section ) {
|
58 |
|
61 |
$warnings[] = sprintf( '%s: %s %s', __( 'Important', 'wp-simple-firewall' ),
|
62 |
__( "Use of the AntiBot Detection Engine for user forms isn't turned on in the Login Guard module.", 'wp-simple-firewall' ),
|
63 |
sprintf( '<a href="%s" target="_blank">%s</a>',
|
64 |
+
$con->getModule_LoginGuard()->getUrl_AdminPage(),
|
65 |
__( 'Click here to review those settings.', 'wp-simple-firewall' ) )
|
66 |
);
|
67 |
}
|
68 |
break;
|
69 |
+
|
70 |
+
case 'section_spam':
|
71 |
+
/** @var ModCon $mod */
|
72 |
+
$mod = $this->getMod();
|
73 |
+
/** @var BaseHandler[] $installedButNotEnabledProviders */
|
74 |
+
$installedButNotEnabledProviders = array_filter(
|
75 |
+
array_map(
|
76 |
+
function ( $providerClass ) {
|
77 |
+
return ( new $providerClass() )->setMod( $this->getMod() );
|
78 |
+
},
|
79 |
+
$mod->getController_SpamForms()->enumProviders()
|
80 |
+
),
|
81 |
+
function ( $provider ) {
|
82 |
+
/** @var BaseHandler $provider */
|
83 |
+
return !$provider->isEnabled() && $provider::IsProviderInstalled();
|
84 |
+
}
|
85 |
+
);
|
86 |
+
|
87 |
+
if ( !empty( $installedButNotEnabledProviders ) ) {
|
88 |
+
$warnings[] = sprintf( __( "%s has an integration available to protect the forms of a 3rd party plugin you're using: %s", 'wp-simple-firewall' ),
|
89 |
+
$con->getHumanName(),
|
90 |
+
implode( ', ', array_map(
|
91 |
+
function ( $provider ) {
|
92 |
+
return $provider->getHandlerName();
|
93 |
+
}, $installedButNotEnabledProviders
|
94 |
+
) )
|
95 |
+
);
|
96 |
+
}
|
97 |
+
break;
|
98 |
}
|
99 |
|
100 |
return $warnings;
|
src/lib/src/Modules/Integrations/Upgrade.php
CHANGED
@@ -3,23 +3,7 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
6 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\Bots\UserForms\UserFormsController;
|
7 |
|
8 |
class Upgrade extends Base\Upgrade {
|
9 |
|
10 |
-
protected function upgrade_1120() {
|
11 |
-
/** @var Options $opts */
|
12 |
-
$opts = $this->getOptions();
|
13 |
-
$providers = ( new UserFormsController() )
|
14 |
-
->setMod( $this->getMod() )
|
15 |
-
->enumProviders();
|
16 |
-
|
17 |
-
$enabledProviders = $opts->getUserFormProviders();
|
18 |
-
foreach ( $providers as $provider ) {
|
19 |
-
if ( $provider::IsProviderInstalled() ) {
|
20 |
-
$enabledProviders[] = $provider->getHandlerSlug();
|
21 |
-
}
|
22 |
-
}
|
23 |
-
$opts->setOpt( 'user_form_providers', array_unique( $enabledProviders ) );
|
24 |
-
}
|
25 |
}
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
|
|
6 |
|
7 |
class Upgrade extends Base\Upgrade {
|
8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
}
|
src/lib/src/Modules/License/AjaxHandler.php
CHANGED
@@ -58,7 +58,7 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
58 |
private function ajaxExec_LicenseHandling() {
|
59 |
/** @var ModCon $mod */
|
60 |
$mod = $this->getMod();
|
61 |
-
$
|
62 |
|
63 |
$success = false;
|
64 |
$msg = 'Unsupported license action';
|
@@ -67,14 +67,14 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
67 |
|
68 |
if ( $sLicenseAction == 'clear' ) {
|
69 |
$success = true;
|
70 |
-
$
|
71 |
-
$
|
72 |
$msg = __( 'Success', 'wp-simple-firewall' ).'! '
|
73 |
.__( 'Reloading page', 'wp-simple-firewall' ).'...';
|
74 |
}
|
75 |
elseif ( $sLicenseAction == 'check' ) {
|
76 |
|
77 |
-
$nCheckInterval = $
|
78 |
if ( $nCheckInterval < 20 ) {
|
79 |
$nWait = 20 - $nCheckInterval;
|
80 |
$msg = sprintf(
|
@@ -84,8 +84,8 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
|
|
84 |
}
|
85 |
else {
|
86 |
try {
|
87 |
-
$success = $
|
88 |
-
|
89 |
$msg = $success ? __( 'Valid license found.', 'wp-simple-firewall' ) : __( "Valid license couldn't be found.", 'wp-simple-firewall' );
|
90 |
}
|
91 |
catch ( \Exception $e ) {
|
58 |
private function ajaxExec_LicenseHandling() {
|
59 |
/** @var ModCon $mod */
|
60 |
$mod = $this->getMod();
|
61 |
+
$licHandler = $mod->getLicenseHandler();
|
62 |
|
63 |
$success = false;
|
64 |
$msg = 'Unsupported license action';
|
67 |
|
68 |
if ( $sLicenseAction == 'clear' ) {
|
69 |
$success = true;
|
70 |
+
$licHandler->deactivate( false );
|
71 |
+
$licHandler->clearLicense();
|
72 |
$msg = __( 'Success', 'wp-simple-firewall' ).'! '
|
73 |
.__( 'Reloading page', 'wp-simple-firewall' ).'...';
|
74 |
}
|
75 |
elseif ( $sLicenseAction == 'check' ) {
|
76 |
|
77 |
+
$nCheckInterval = $licHandler->getLicenseNotCheckedForInterval();
|
78 |
if ( $nCheckInterval < 20 ) {
|
79 |
$nWait = 20 - $nCheckInterval;
|
80 |
$msg = sprintf(
|
84 |
}
|
85 |
else {
|
86 |
try {
|
87 |
+
$success = $licHandler->verify( true )
|
88 |
+
->hasValidWorkingLicense();
|
89 |
$msg = $success ? __( 'Valid license found.', 'wp-simple-firewall' ) : __( "Valid license couldn't be found.", 'wp-simple-firewall' );
|
90 |
}
|
91 |
catch ( \Exception $e ) {
|
src/lib/src/Modules/License/Lib/LicenseHandler.php
CHANGED
@@ -2,17 +2,13 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\License\Lib;
|
4 |
|
5 |
-
use FernleafSystems\Utilities\Logic\ExecOnce;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\License\EddLicenseVO;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
8 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\License\ModCon;
|
9 |
use FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\HandshakingNonce;
|
10 |
use FernleafSystems\Wordpress\Services\Services;
|
11 |
|
12 |
-
class LicenseHandler {
|
13 |
-
|
14 |
-
use Modules\ModConsumer;
|
15 |
-
use ExecOnce;
|
16 |
|
17 |
protected function run() {
|
18 |
add_action( $this->getCon()->prefix( 'shield_action' ), function ( $action ) {
|
@@ -44,14 +40,31 @@ class LicenseHandler {
|
|
44 |
|
45 |
// performs the license check on-demand
|
46 |
add_action( $this->getCon()->prefix( 'adhoc_cron_license_check' ), function () {
|
47 |
-
|
48 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
try {
|
50 |
-
$mod->getLicenseHandler()->verify(
|
51 |
}
|
52 |
catch ( \Exception $e ) {
|
53 |
}
|
54 |
-
}
|
55 |
}
|
56 |
|
57 |
private function canCheck() :bool {
|
@@ -70,13 +83,13 @@ class LicenseHandler {
|
|
70 |
}
|
71 |
|
72 |
/**
|
73 |
-
* @param bool $
|
74 |
*/
|
75 |
-
public function deactivate( $
|
76 |
if ( $this->isActive() ) {
|
77 |
$this->clearLicense();
|
78 |
$this->getOptions()->setOptAt( 'license_deactivated_at' );
|
79 |
-
if ( $
|
80 |
( new LicenseEmails() )
|
81 |
->setMod( $this->getMod() )
|
82 |
->sendLicenseDeactivatedEmail();
|
@@ -134,11 +147,9 @@ class LicenseHandler {
|
|
134 |
* 3) the license is marked as "active"
|
135 |
* 4) the license hasn't expired
|
136 |
* 5) the time since the last check hasn't expired
|
137 |
-
* @return bool
|
138 |
*/
|
139 |
public function hasValidWorkingLicense() :bool {
|
140 |
-
$
|
141 |
-
return $oLic->isValid() && $this->isActive();
|
142 |
}
|
143 |
|
144 |
public function isActive() :bool {
|
@@ -179,12 +190,11 @@ class LicenseHandler {
|
|
179 |
}
|
180 |
|
181 |
/**
|
182 |
-
* @param bool $bForceCheck
|
183 |
* @return $this
|
184 |
* @throws \Exception
|
185 |
*/
|
186 |
-
public function verify( $
|
187 |
-
if ( $
|
188 |
( new Verify() )
|
189 |
->setMod( $this->getMod() )
|
190 |
->run();
|
@@ -197,9 +207,9 @@ class LicenseHandler {
|
|
197 |
}
|
198 |
|
199 |
private function canLicenseCheck_FileFlag() :bool {
|
200 |
-
$
|
201 |
$this->getCon()->paths->forFlag( 'license_check' )
|
202 |
);
|
203 |
-
return ( Services::Request()->ts() - $
|
204 |
}
|
205 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\License\Lib;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\License\EddLicenseVO;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\License\ModCon;
|
8 |
use FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\HandshakingNonce;
|
9 |
use FernleafSystems\Wordpress\Services\Services;
|
10 |
|
11 |
+
class LicenseHandler extends Modules\Base\Common\ExecOnceModConsumer {
|
|
|
|
|
|
|
12 |
|
13 |
protected function run() {
|
14 |
add_action( $this->getCon()->prefix( 'shield_action' ), function ( $action ) {
|
40 |
|
41 |
// performs the license check on-demand
|
42 |
add_action( $this->getCon()->prefix( 'adhoc_cron_license_check' ), function () {
|
43 |
+
$this->runAdhocLicenseCheck();
|
44 |
+
} );
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Customer reported that they're using a multilingual system with different hostnames for each language.
|
49 |
+
* This meant that adhoc lookups that happen on the wrong hostname name request would fail and remove
|
50 |
+
* the license. So now we tie ad-hoc lookups to the hostname.
|
51 |
+
*
|
52 |
+
* This doesn't solve all problems since the ad-hoc lookup is cron-based, and the cron may get triggered
|
53 |
+
* on the wrong hostname.
|
54 |
+
*/
|
55 |
+
private function runAdhocLicenseCheck() {
|
56 |
+
/** @var ModCon $mod */
|
57 |
+
$mod = $this->getMod();
|
58 |
+
|
59 |
+
$licHost = wp_parse_url( $this->getLicense()->url, PHP_URL_HOST );
|
60 |
+
$reqHost = Services::Request()->getHost();
|
61 |
+
if ( !$this->hasValidWorkingLicense() || empty( $licHost ) || empty( $reqHost ) || ( $licHost === $reqHost ) ) {
|
62 |
try {
|
63 |
+
$mod->getLicenseHandler()->verify();
|
64 |
}
|
65 |
catch ( \Exception $e ) {
|
66 |
}
|
67 |
+
}
|
68 |
}
|
69 |
|
70 |
private function canCheck() :bool {
|
83 |
}
|
84 |
|
85 |
/**
|
86 |
+
* @param bool $sendEmail
|
87 |
*/
|
88 |
+
public function deactivate( bool $sendEmail = true ) {
|
89 |
if ( $this->isActive() ) {
|
90 |
$this->clearLicense();
|
91 |
$this->getOptions()->setOptAt( 'license_deactivated_at' );
|
92 |
+
if ( $sendEmail ) {
|
93 |
( new LicenseEmails() )
|
94 |
->setMod( $this->getMod() )
|
95 |
->sendLicenseDeactivatedEmail();
|
147 |
* 3) the license is marked as "active"
|
148 |
* 4) the license hasn't expired
|
149 |
* 5) the time since the last check hasn't expired
|
|
|
150 |
*/
|
151 |
public function hasValidWorkingLicense() :bool {
|
152 |
+
return $this->getLicense()->isValid() && $this->isActive();
|
|
|
153 |
}
|
154 |
|
155 |
public function isActive() :bool {
|
190 |
}
|
191 |
|
192 |
/**
|
|
|
193 |
* @return $this
|
194 |
* @throws \Exception
|
195 |
*/
|
196 |
+
public function verify( bool $force = true ) {
|
197 |
+
if ( $force || ( $this->isVerifyRequired() && $this->canCheck() ) ) {
|
198 |
( new Verify() )
|
199 |
->setMod( $this->getMod() )
|
200 |
->run();
|
207 |
}
|
208 |
|
209 |
private function canLicenseCheck_FileFlag() :bool {
|
210 |
+
$mtime = Services::WpFs()->getModifiedTime(
|
211 |
$this->getCon()->paths->forFlag( 'license_check' )
|
212 |
);
|
213 |
+
return ( Services::Request()->ts() - $mtime ) > MINUTE_IN_SECONDS;
|
214 |
}
|
215 |
}
|
src/lib/src/Modules/License/WpCli/License.php
CHANGED
@@ -98,24 +98,24 @@ class License extends Base\WpCli\BaseWpCliCmd {
|
|
98 |
if ( $this->getCon()->isPremiumActive() ) {
|
99 |
WP_CLI::log( 'Premium license is already active. Re-checking...' );
|
100 |
}
|
101 |
-
$
|
102 |
->getLicenseHandler()
|
103 |
->verify()
|
104 |
->hasValidWorkingLicense();
|
105 |
-
$
|
|
|
106 |
}
|
107 |
catch ( \Exception $e ) {
|
108 |
-
$
|
109 |
-
$
|
110 |
}
|
111 |
|
112 |
-
$
|
113 |
}
|
114 |
|
115 |
/**
|
116 |
* License checking WP-CLI cmds may be run if you're not premium,
|
117 |
* or you're premium and you haven't switched it off (parent).
|
118 |
-
* @inheritDoc
|
119 |
*/
|
120 |
protected function canRun() :bool {
|
121 |
return !$this->getCon()->isPremiumActive() || parent::canRun();
|
98 |
if ( $this->getCon()->isPremiumActive() ) {
|
99 |
WP_CLI::log( 'Premium license is already active. Re-checking...' );
|
100 |
}
|
101 |
+
$success = $mod
|
102 |
->getLicenseHandler()
|
103 |
->verify()
|
104 |
->hasValidWorkingLicense();
|
105 |
+
$msg = $success ? __( 'Valid license found and installed.', 'wp-simple-firewall' )
|
106 |
+
: __( "Valid license couldn't be found.", 'wp-simple-firewall' );
|
107 |
}
|
108 |
catch ( \Exception $e ) {
|
109 |
+
$success = false;
|
110 |
+
$msg = $e->getMessage();
|
111 |
}
|
112 |
|
113 |
+
$success ? WP_CLI::success( $msg ) : WP_CLI::error( $msg );
|
114 |
}
|
115 |
|
116 |
/**
|
117 |
* License checking WP-CLI cmds may be run if you're not premium,
|
118 |
* or you're premium and you haven't switched it off (parent).
|
|
|
119 |
*/
|
120 |
protected function canRun() :bool {
|
121 |
return !$this->getCon()->isPremiumActive() || parent::canRun();
|
src/lib/src/Modules/LoginGuard/Lib/AntiBot/AntibotSetup.php
CHANGED
@@ -11,7 +11,9 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
11 |
class AntibotSetup extends ExecOnceModConsumer {
|
12 |
|
13 |
protected function canRun() :bool {
|
14 |
-
|
|
|
|
|
15 |
}
|
16 |
|
17 |
protected function run() {
|
11 |
class AntibotSetup extends ExecOnceModConsumer {
|
12 |
|
13 |
protected function canRun() :bool {
|
14 |
+
/** @var LoginGuard\ModCon $mod */
|
15 |
+
$mod = $this->getMod();
|
16 |
+
return !$mod->isVisitorWhitelisted() && !Services::WpUsers()->isUserLoggedIn();
|
17 |
}
|
18 |
|
19 |
protected function run() {
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/LoginIntentPage.php
CHANGED
@@ -15,10 +15,7 @@ class LoginIntentPage {
|
|
15 |
echo $this->renderPage();
|
16 |
}
|
17 |
|
18 |
-
|
19 |
-
* @return string
|
20 |
-
*/
|
21 |
-
public function renderForm() {
|
22 |
$mfaCon = $this->getMfaCon();
|
23 |
/** @var LoginGuard\ModCon $mod */
|
24 |
$mod = $mfaCon->getMod();
|
@@ -114,15 +111,15 @@ class LoginIntentPage {
|
|
114 |
}
|
115 |
|
116 |
private function renderPage() :string {
|
117 |
-
$
|
118 |
/** @var LoginGuard\ModCon $mod */
|
119 |
-
$mod = $
|
120 |
-
$con = $
|
121 |
$req = Services::Request();
|
122 |
|
123 |
$labels = $con->getLabels();
|
124 |
$bannerURL = empty( $labels[ 'url_login2fa_logourl' ] ) ? $con->urls->forImage( 'shield/banner-2FA.png' ) : $labels[ 'url_login2fa_logourl' ];
|
125 |
-
$timeRemaining = $
|
126 |
|
127 |
$data = [
|
128 |
'strings' => [
|
@@ -144,7 +141,7 @@ class LoginIntentPage {
|
|
144 |
],
|
145 |
'flags' => [
|
146 |
'show_branded_links' => !$con->getModule_SecAdmin()->getWhiteLabelController()->isEnabled(),
|
147 |
-
'has_u2f' => isset( $
|
148 |
Services::WpUsers()->getCurrentWpUser(), true )[ LoginGuard\Lib\TwoFactor\Provider\U2F::SLUG ] )
|
149 |
],
|
150 |
'content' => [
|
15 |
echo $this->renderPage();
|
16 |
}
|
17 |
|
18 |
+
public function renderForm() :string {
|
|
|
|
|
|
|
19 |
$mfaCon = $this->getMfaCon();
|
20 |
/** @var LoginGuard\ModCon $mod */
|
21 |
$mod = $mfaCon->getMod();
|
111 |
}
|
112 |
|
113 |
private function renderPage() :string {
|
114 |
+
$IC = $this->getMfaCon();
|
115 |
/** @var LoginGuard\ModCon $mod */
|
116 |
+
$mod = $IC->getMod();
|
117 |
+
$con = $IC->getCon();
|
118 |
$req = Services::Request();
|
119 |
|
120 |
$labels = $con->getLabels();
|
121 |
$bannerURL = empty( $labels[ 'url_login2fa_logourl' ] ) ? $con->urls->forImage( 'shield/banner-2FA.png' ) : $labels[ 'url_login2fa_logourl' ];
|
122 |
+
$timeRemaining = $IC->getLoginIntentExpiresAt() - $req->ts();
|
123 |
|
124 |
$data = [
|
125 |
'strings' => [
|
141 |
],
|
142 |
'flags' => [
|
143 |
'show_branded_links' => !$con->getModule_SecAdmin()->getWhiteLabelController()->isEnabled(),
|
144 |
+
'has_u2f' => isset( $IC->getProvidersForUser(
|
145 |
Services::WpUsers()->getCurrentWpUser(), true )[ LoginGuard\Lib\TwoFactor\Provider\U2F::SLUG ] )
|
146 |
],
|
147 |
'content' => [
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/MfaController.php
CHANGED
@@ -3,17 +3,14 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor;
|
4 |
|
5 |
use FernleafSystems\Utilities\Data\Response\StdResponse;
|
6 |
-
use FernleafSystems\Utilities\Logic\ExecOnce;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
8 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
9 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor\Provider;
|
10 |
use FernleafSystems\Wordpress\Services\Services;
|
11 |
|
12 |
-
class MfaController {
|
13 |
|
14 |
-
use Shield\Modules\ModConsumer;
|
15 |
use Shield\Utilities\Consumer\WpLoginCapture;
|
16 |
-
use ExecOnce;
|
17 |
|
18 |
/**
|
19 |
* @var Provider\BaseProvider[]
|
@@ -23,7 +20,7 @@ class MfaController {
|
|
23 |
/**
|
24 |
* @var LoginIntentPage
|
25 |
*/
|
26 |
-
private $
|
27 |
|
28 |
protected function run() {
|
29 |
add_action( 'init', [ $this, 'onWpInit' ] );
|
@@ -40,11 +37,7 @@ class MfaController {
|
|
40 |
}
|
41 |
|
42 |
public function onWpLoaded() {
|
43 |
-
( new UserProfile() )
|
44 |
-
->setMfaController( $this )
|
45 |
-
->run();
|
46 |
( new MfaProfilesController() )->setMfaController( $this )->execute();
|
47 |
-
|
48 |
add_shortcode( 'SHIELD_2FA_LOGIN', function () {
|
49 |
return $this->getLoginIntentPageHandler()->renderForm();
|
50 |
} );
|
@@ -143,10 +136,10 @@ class MfaController {
|
|
143 |
}
|
144 |
|
145 |
private function getLoginIntentPageHandler() :LoginIntentPage {
|
146 |
-
if ( !isset( $this->
|
147 |
-
$this->
|
148 |
}
|
149 |
-
return $this->
|
150 |
}
|
151 |
|
152 |
/**
|
@@ -172,16 +165,14 @@ class MfaController {
|
|
172 |
|
173 |
/**
|
174 |
* Ensures that BackupCode provider isn't supplied on its own, and the user profile is setup for each.
|
175 |
-
* @param \WP_User $user
|
176 |
-
* @param bool $onlyActiveProfiles
|
177 |
* @return Provider\BaseProvider[]
|
178 |
*/
|
179 |
-
public function getProvidersForUser( \WP_User $user, $
|
180 |
$Ps = array_filter( $this->getProviders(),
|
181 |
-
function ( $provider ) use ( $user, $
|
182 |
/** @var Provider\BaseProvider $provider */
|
183 |
return $provider->isProviderAvailableToUser( $user )
|
184 |
-
&& ( !$
|
185 |
}
|
186 |
);
|
187 |
|
@@ -284,7 +275,9 @@ class MfaController {
|
|
284 |
}
|
285 |
|
286 |
public function isSubjectToLoginIntent( \WP_User $user ) :bool {
|
287 |
-
|
|
|
|
|
288 |
}
|
289 |
|
290 |
public function removeAllFactorsForUser( int $userID ) :StdResponse {
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor;
|
4 |
|
5 |
use FernleafSystems\Utilities\Data\Response\StdResponse;
|
|
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
8 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor\Provider;
|
9 |
use FernleafSystems\Wordpress\Services\Services;
|
10 |
|
11 |
+
class MfaController extends Shield\Modules\Base\Common\ExecOnceModConsumer {
|
12 |
|
|
|
13 |
use Shield\Utilities\Consumer\WpLoginCapture;
|
|
|
14 |
|
15 |
/**
|
16 |
* @var Provider\BaseProvider[]
|
20 |
/**
|
21 |
* @var LoginIntentPage
|
22 |
*/
|
23 |
+
private $loginIntentPageHandler;
|
24 |
|
25 |
protected function run() {
|
26 |
add_action( 'init', [ $this, 'onWpInit' ] );
|
37 |
}
|
38 |
|
39 |
public function onWpLoaded() {
|
|
|
|
|
|
|
40 |
( new MfaProfilesController() )->setMfaController( $this )->execute();
|
|
|
41 |
add_shortcode( 'SHIELD_2FA_LOGIN', function () {
|
42 |
return $this->getLoginIntentPageHandler()->renderForm();
|
43 |
} );
|
136 |
}
|
137 |
|
138 |
private function getLoginIntentPageHandler() :LoginIntentPage {
|
139 |
+
if ( !isset( $this->loginIntentPageHandler ) ) {
|
140 |
+
$this->loginIntentPageHandler = ( new LoginIntentPage() )->setMfaController( $this );
|
141 |
}
|
142 |
+
return $this->loginIntentPageHandler;
|
143 |
}
|
144 |
|
145 |
/**
|
165 |
|
166 |
/**
|
167 |
* Ensures that BackupCode provider isn't supplied on its own, and the user profile is setup for each.
|
|
|
|
|
168 |
* @return Provider\BaseProvider[]
|
169 |
*/
|
170 |
+
public function getProvidersForUser( \WP_User $user, bool $onlyActive = false ) :array {
|
171 |
$Ps = array_filter( $this->getProviders(),
|
172 |
+
function ( $provider ) use ( $user, $onlyActive ) {
|
173 |
/** @var Provider\BaseProvider $provider */
|
174 |
return $provider->isProviderAvailableToUser( $user )
|
175 |
+
&& ( !$onlyActive || $provider->isProfileActive( $user ) );
|
176 |
}
|
177 |
);
|
178 |
|
275 |
}
|
276 |
|
277 |
public function isSubjectToLoginIntent( \WP_User $user ) :bool {
|
278 |
+
/** @var LoginGuard\ModCon $mod */
|
279 |
+
$mod = $this->getMod();
|
280 |
+
return !$mod->isVisitorWhitelisted() && count( $this->getProvidersForUser( $user, true ) ) > 0;
|
281 |
}
|
282 |
|
283 |
public function removeAllFactorsForUser( int $userID ) :StdResponse {
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/MfaProfilesController.php
CHANGED
@@ -17,7 +17,7 @@ class MfaProfilesController {
|
|
17 |
private $isFrontend = false;
|
18 |
|
19 |
protected function run() {
|
20 |
-
$this->
|
21 |
if ( Services::WpUsers()->isUserLoggedIn() ) {
|
22 |
add_action( 'wp', function () {
|
23 |
$this->enqueueAssets( true );
|
@@ -35,16 +35,16 @@ class MfaProfilesController {
|
|
35 |
if ( $this->isFrontend || in_array( $hook, [ 'profile.php', 'user-edit.php' ] ) ) {
|
36 |
$enqueues[ Enqueue::JS ][] = 'shield/userprofile';
|
37 |
$enqueues[ Enqueue::CSS ][] = 'shield/dialog';
|
|
|
38 |
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
}
|
48 |
|
49 |
add_filter( 'shield/custom_localisations', function ( array $localz ) {
|
50 |
$mfaCon = $this->getMfaCon();
|
@@ -75,19 +75,85 @@ class MfaProfilesController {
|
|
75 |
}, 10, $this->isFrontend ? 1 : 2 );
|
76 |
}
|
77 |
|
78 |
-
private function loadUserProfileMFA( $attributes = [] ) :string {
|
79 |
$this->rendered = true;
|
80 |
return ( new Profiles\RenderCustomForms() )
|
81 |
->setMfaController( $this->getMfaCon() )
|
82 |
->setWpUser( Services::WpUsers()->getCurrentWpUser() )
|
83 |
-
->render(
|
84 |
}
|
85 |
|
86 |
-
private function
|
|
|
|
|
87 |
if ( $this->getMfaCon()->getCon()->isPremiumActive() ) {
|
88 |
add_shortcode( 'SHIELD_USER_PROFILE_MFA', function ( $attributes ) {
|
89 |
-
return $this->loadUserProfileMFA( $attributes );
|
90 |
} );
|
91 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
}
|
93 |
}
|
17 |
private $isFrontend = false;
|
18 |
|
19 |
protected function run() {
|
20 |
+
$this->addHooks();
|
21 |
if ( Services::WpUsers()->isUserLoggedIn() ) {
|
22 |
add_action( 'wp', function () {
|
23 |
$this->enqueueAssets( true );
|
35 |
if ( $this->isFrontend || in_array( $hook, [ 'profile.php', 'user-edit.php' ] ) ) {
|
36 |
$enqueues[ Enqueue::JS ][] = 'shield/userprofile';
|
37 |
$enqueues[ Enqueue::CSS ][] = 'shield/dialog';
|
38 |
+
$enqueues[ Enqueue::CSS ][] = 'shield/userprofile';
|
39 |
|
40 |
+
add_filter( 'shield/custom_dequeues', function ( $assets ) {
|
41 |
+
if ( !$this->rendered ) {
|
42 |
+
$assets[ Enqueue::JS ][] = 'shield/userprofile';
|
43 |
+
$assets[ Enqueue::CSS ][] = 'shield/dialog';
|
44 |
+
$assets[ Enqueue::CSS ][] = 'shield/userprofile';
|
45 |
+
}
|
46 |
+
return $assets;
|
47 |
+
} );
|
|
|
48 |
|
49 |
add_filter( 'shield/custom_localisations', function ( array $localz ) {
|
50 |
$mfaCon = $this->getMfaCon();
|
75 |
}, 10, $this->isFrontend ? 1 : 2 );
|
76 |
}
|
77 |
|
78 |
+
private function loadUserProfileMFA( array $attributes = [] ) :string {
|
79 |
$this->rendered = true;
|
80 |
return ( new Profiles\RenderCustomForms() )
|
81 |
->setMfaController( $this->getMfaCon() )
|
82 |
->setWpUser( Services::WpUsers()->getCurrentWpUser() )
|
83 |
+
->render( $attributes );
|
84 |
}
|
85 |
|
86 |
+
private function addHooks() {
|
87 |
+
|
88 |
+
// shortcode for placing user authentication handling anywhere
|
89 |
if ( $this->getMfaCon()->getCon()->isPremiumActive() ) {
|
90 |
add_shortcode( 'SHIELD_USER_PROFILE_MFA', function ( $attributes ) {
|
91 |
+
return $this->loadUserProfileMFA( is_array( $attributes ) ? $attributes : [] );
|
92 |
} );
|
93 |
}
|
94 |
+
|
95 |
+
// Standard WordPress User Profile Editing
|
96 |
+
add_action( 'show_user_profile', function () {
|
97 |
+
$this->addOptionsToUserProfile();
|
98 |
+
}, 7, 0 );
|
99 |
+
add_action( 'edit_user_profile', function ( $user ) {
|
100 |
+
if ( $user instanceof \WP_User ) {
|
101 |
+
$this->addOptionsToUserEditProfile( $user );
|
102 |
+
}
|
103 |
+
} );
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* This MUST only ever be hooked into when the User is looking at their OWN profile, so we can use "current user"
|
108 |
+
* functions. Otherwise we need to be careful of mixing up users.
|
109 |
+
*/
|
110 |
+
public function addOptionsToUserProfile() {
|
111 |
+
echo $this->loadUserProfileMFA( [
|
112 |
+
'title'=>__( 'Multi-Factor Authentication', 'wp-simple-firewall' ),
|
113 |
+
'subtitle' => sprintf( __( 'Provided by %s', 'wp-simple-firewall' ),
|
114 |
+
$this->getMfaCon()->getCon()->getHumanName() )
|
115 |
+
] );
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* ONLY TO BE HOOKED TO USER PROFILE EDIT
|
120 |
+
*/
|
121 |
+
public function addOptionsToUserEditProfile( \WP_User $user ) {
|
122 |
+
$mfaCon = $this->getMfaCon();
|
123 |
+
$con = $mfaCon->getCon();
|
124 |
+
$WPU = Services::WpUsers();
|
125 |
+
$pluginName = $con->getHumanName();
|
126 |
+
|
127 |
+
$providers = array_map(
|
128 |
+
function ( $provider ) {
|
129 |
+
return $provider->getProviderName();
|
130 |
+
},
|
131 |
+
$mfaCon->getProvidersForUser( $user, true )
|
132 |
+
);
|
133 |
+
|
134 |
+
echo $mfaCon->getMod()->renderTemplate( '/admin/user/profile/mfa/remove_for_other_user.twig', [
|
135 |
+
'flags' => [
|
136 |
+
'has_factors' => count( $providers ) > 0,
|
137 |
+
'is_admin_profile' => $WPU->isUserAdmin( $user ),
|
138 |
+
'can_remove' => $con->isPluginAdmin() || !$WPU->isUserAdmin( $user ),
|
139 |
+
],
|
140 |
+
'vars' => [
|
141 |
+
'user_id' => $user->ID,
|
142 |
+
'mfa_factor_names' => $providers,
|
143 |
+
],
|
144 |
+
'strings' => [
|
145 |
+
'title' => __( 'Multi-Factor Authentication', 'wp-simple-firewall' ),
|
146 |
+
'provided_by' => sprintf( __( 'Provided by %s', 'wp-simple-firewall' ), $pluginName ),
|
147 |
+
'currently_active' => __( 'Currently active MFA Providers on this profile are' ),
|
148 |
+
'remove_all' => __( 'Remove All MFA Providers' ),
|
149 |
+
'remove_all_from' => __( 'Remove All MFA Providers From This User Profile' ),
|
150 |
+
'remove_warning' => __( "Certain providers may not be removed if they're enforced." ),
|
151 |
+
'no_providers' => __( 'There are no MFA providers active on this user account.' ),
|
152 |
+
'only_secadmin' => sprintf( __( 'Only %s Security Admins may modify the MFA settings of another admin account.' ),
|
153 |
+
$pluginName ),
|
154 |
+
'authenticate' => sprintf( __( 'You may authenticate with the %s Security Admin system and return here.' ),
|
155 |
+
$pluginName ),
|
156 |
+
],
|
157 |
+
] );
|
158 |
}
|
159 |
}
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/MfaSkip.php
CHANGED
@@ -10,58 +10,53 @@ class MfaSkip {
|
|
10 |
|
11 |
use Shield\Modules\ModConsumer;
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
public function addMfaSkip( \WP_User $oUser ) {
|
17 |
-
/** @var LoginGuard\Options $oOpts */
|
18 |
-
$oOpts = $this->getOptions();
|
19 |
|
20 |
-
$
|
21 |
-
$
|
22 |
-
$
|
23 |
|
24 |
-
$
|
25 |
-
if ( $
|
26 |
-
$
|
27 |
-
function ( $
|
28 |
-
return Services::Request()->ts() - $
|
29 |
}
|
30 |
);
|
31 |
}
|
32 |
|
33 |
-
$
|
34 |
}
|
35 |
|
36 |
-
|
37 |
-
* @param \WP_User $oUser
|
38 |
-
* @return bool
|
39 |
-
*/
|
40 |
-
public function canMfaSkip( \WP_User $oUser ) {
|
41 |
/** @var LoginGuard\Options $opts */
|
42 |
$opts = $this->getOptions();
|
43 |
$req = Services::Request();
|
44 |
|
45 |
-
$
|
46 |
|
47 |
if ( $opts->isMfaSkip() ) {
|
48 |
-
$
|
49 |
-
$
|
50 |
-
$
|
51 |
-
$
|
52 |
-
|
53 |
}
|
54 |
|
55 |
-
return $
|
|
|
|
|
|
|
|
|
|
|
56 |
}
|
57 |
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
Services::IP()->getRequestIp(),
|
64 |
-
Services::Request()->getUserAgent()
|
65 |
-
] ) );
|
66 |
}
|
67 |
}
|
10 |
|
11 |
use Shield\Modules\ModConsumer;
|
12 |
|
13 |
+
public function addMfaSkip( \WP_User $user ) {
|
14 |
+
/** @var LoginGuard\Options $opts */
|
15 |
+
$opts = $this->getOptions();
|
|
|
|
|
|
|
16 |
|
17 |
+
$meta = $this->getCon()->getUserMeta( $user );
|
18 |
+
$hashes = is_array( $meta->hash_loginmfa ) ? $meta->hash_loginmfa : [];
|
19 |
+
$hashes[ $this->getAgentHash() ] = Services::Request()->ts();
|
20 |
|
21 |
+
$maxExpires = $opts->getMfaSkip();
|
22 |
+
if ( $maxExpires > 0 ) {
|
23 |
+
$hashes = array_filter( $hashes,
|
24 |
+
function ( $ts ) use ( $maxExpires ) {
|
25 |
+
return Services::Request()->ts() - $ts < $maxExpires;
|
26 |
}
|
27 |
);
|
28 |
}
|
29 |
|
30 |
+
$meta->hash_loginmfa = $hashes;
|
31 |
}
|
32 |
|
33 |
+
public function canMfaSkip( \WP_User $user ) :bool {
|
|
|
|
|
|
|
|
|
34 |
/** @var LoginGuard\Options $opts */
|
35 |
$opts = $this->getOptions();
|
36 |
$req = Services::Request();
|
37 |
|
38 |
+
$canSkip = false;
|
39 |
|
40 |
if ( $opts->isMfaSkip() ) {
|
41 |
+
$agentHash = $this->getAgentHash();
|
42 |
+
$meta = $this->getCon()->getUserMeta( $user );
|
43 |
+
$hashes = is_array( $meta->hash_loginmfa ) ? $meta->hash_loginmfa : [];
|
44 |
+
$canSkip = isset( $hashes[ $agentHash ] )
|
45 |
+
&& ( (int)$hashes[ $agentHash ] + $opts->getMfaSkip() ) > $req->ts();
|
46 |
}
|
47 |
|
48 |
+
return $canSkip;
|
49 |
+
}
|
50 |
+
|
51 |
+
private function getAgentHash() :string {
|
52 |
+
$hashData = apply_filters( 'shield/2fa_remember_me_params', $this->getDefaultHashParams() );
|
53 |
+
return md5( serialize( empty( $hashData ) ? $this->getDefaultHashParams() : $hashData ) );
|
54 |
}
|
55 |
|
56 |
+
private function getDefaultHashParams() :array {
|
57 |
+
return [
|
58 |
+
'ip' => Services::IP()->getRequestIp(),
|
59 |
+
'user_agent' => Services::Request()->getUserAgent()
|
60 |
+
];
|
|
|
|
|
|
|
61 |
}
|
62 |
}
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Profiles/RenderCustomForms.php
CHANGED
@@ -13,17 +13,25 @@ class RenderCustomForms {
|
|
13 |
private $attributes;
|
14 |
|
15 |
public function render( array $attributes ) :string {
|
16 |
-
$this->
|
17 |
return $this->getMfaCon()
|
18 |
->getMod()
|
19 |
->renderTemplate( '/user/profile/mfa/main.twig', $this->buildRenderData() );
|
20 |
}
|
21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
private function buildRenderData() :array {
|
23 |
$mfaCon = $this->getMfaCon();
|
24 |
-
$con = $mfaCon->getCon();
|
25 |
-
$pluginName = $con->getHumanName();
|
26 |
-
|
27 |
$user = $this->getWpUser();
|
28 |
$providers = $user instanceof \WP_User ? $mfaCon->getProvidersForUser( $user ) : [];
|
29 |
$providerRenders = $user instanceof \WP_User ?
|
@@ -32,7 +40,7 @@ class RenderCustomForms {
|
|
32 |
}, $providers )
|
33 |
: [];
|
34 |
|
35 |
-
|
36 |
'content' => [
|
37 |
'providers' => $providerRenders,
|
38 |
],
|
@@ -41,15 +49,14 @@ class RenderCustomForms {
|
|
41 |
'logged_in' => $user instanceof \WP_User,
|
42 |
],
|
43 |
'strings' => [
|
44 |
-
'title' =>
|
|
|
45 |
'not_logged_in' => __( 'Not currently logged-in.', 'wp-simple-firewall' ),
|
46 |
'no_providers' => __( 'There are currently no 2FA providers available on your account.', 'wp-simple-firewall' ),
|
47 |
],
|
48 |
'vars' => [
|
49 |
'provider_data' => ''
|
50 |
],
|
51 |
-
];
|
52 |
-
|
53 |
-
return apply_filters( 'shield/render_data_custom_profiles_mfa', $data );
|
54 |
}
|
55 |
}
|
13 |
private $attributes;
|
14 |
|
15 |
public function render( array $attributes ) :string {
|
16 |
+
$this->setAttributes( $attributes );
|
17 |
return $this->getMfaCon()
|
18 |
->getMod()
|
19 |
->renderTemplate( '/user/profile/mfa/main.twig', $this->buildRenderData() );
|
20 |
}
|
21 |
|
22 |
+
public function setAttributes( array $attributes ) {
|
23 |
+
$con = $this->getMfaCon()->getCon();
|
24 |
+
$this->attributes = shortcode_atts(
|
25 |
+
[
|
26 |
+
'title' => sprintf( __( '%s MFA Options', 'wp-simple-firewall' ), $con->getHumanName() ),
|
27 |
+
'subtitle' => '',
|
28 |
+
],
|
29 |
+
$attributes
|
30 |
+
);
|
31 |
+
}
|
32 |
+
|
33 |
private function buildRenderData() :array {
|
34 |
$mfaCon = $this->getMfaCon();
|
|
|
|
|
|
|
35 |
$user = $this->getWpUser();
|
36 |
$providers = $user instanceof \WP_User ? $mfaCon->getProvidersForUser( $user ) : [];
|
37 |
$providerRenders = $user instanceof \WP_User ?
|
40 |
}, $providers )
|
41 |
: [];
|
42 |
|
43 |
+
return apply_filters( 'shield/render_data_custom_profiles_mfa', [
|
44 |
'content' => [
|
45 |
'providers' => $providerRenders,
|
46 |
],
|
49 |
'logged_in' => $user instanceof \WP_User,
|
50 |
],
|
51 |
'strings' => [
|
52 |
+
'title' => esc_html( $this->attributes[ 'title' ] ),
|
53 |
+
'subtitle' => esc_html( $this->attributes[ 'subtitle' ] ),
|
54 |
'not_logged_in' => __( 'Not currently logged-in.', 'wp-simple-firewall' ),
|
55 |
'no_providers' => __( 'There are currently no 2FA providers available on your account.', 'wp-simple-firewall' ),
|
56 |
],
|
57 |
'vars' => [
|
58 |
'provider_data' => ''
|
59 |
],
|
60 |
+
] );
|
|
|
|
|
61 |
}
|
62 |
}
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/BaseProvider.php
CHANGED
@@ -49,7 +49,6 @@ abstract class BaseProvider {
|
|
49 |
}
|
50 |
|
51 |
/**
|
52 |
-
* @param \WP_User $user
|
53 |
* @return string|array
|
54 |
*/
|
55 |
protected function getSecret( \WP_User $user ) {
|
@@ -66,7 +65,6 @@ abstract class BaseProvider {
|
|
66 |
}
|
67 |
|
68 |
/**
|
69 |
-
* @param \WP_User $user
|
70 |
* @return bool
|
71 |
*/
|
72 |
protected function hasValidSecret( \WP_User $user ) {
|
@@ -106,7 +104,6 @@ abstract class BaseProvider {
|
|
106 |
}
|
107 |
|
108 |
/**
|
109 |
-
* @param \WP_User $user
|
110 |
* @return string
|
111 |
*/
|
112 |
public function resetSecret( \WP_User $user ) {
|
@@ -144,7 +141,6 @@ abstract class BaseProvider {
|
|
144 |
}
|
145 |
|
146 |
/**
|
147 |
-
* @param \WP_User $user
|
148 |
* @return string|mixed
|
149 |
*/
|
150 |
protected function genNewSecret( \WP_User $user ) {
|
@@ -155,7 +151,6 @@ abstract class BaseProvider {
|
|
155 |
|
156 |
/**
|
157 |
* Only to be fired if and when Login has been completely verified.
|
158 |
-
* @param \WP_User $user
|
159 |
* @return $this
|
160 |
*/
|
161 |
public function postSuccessActions( \WP_User $user ) {
|
@@ -165,8 +160,6 @@ abstract class BaseProvider {
|
|
165 |
/**
|
166 |
* This MUST only ever be hooked into when the User is looking at their OWN profile, so we can use "current user"
|
167 |
* functions. Otherwise we need to be careful of mixing up users.
|
168 |
-
* @param \WP_User $user
|
169 |
-
* @return string
|
170 |
*/
|
171 |
public function renderUserProfileOptions( \WP_User $user ) :string {
|
172 |
return $this->getMod()
|
@@ -179,8 +172,6 @@ abstract class BaseProvider {
|
|
179 |
/**
|
180 |
* This MUST only ever be hooked into when the User is looking at their OWN profile, so we can use "current user"
|
181 |
* functions. Otherwise we need to be careful of mixing up users.
|
182 |
-
* @param \WP_User $user
|
183 |
-
* @return string
|
184 |
*/
|
185 |
public function renderUserProfileCustomForm( \WP_User $user ) :string {
|
186 |
$data = $this->getProfileRenderData( $user );
|
49 |
}
|
50 |
|
51 |
/**
|
|
|
52 |
* @return string|array
|
53 |
*/
|
54 |
protected function getSecret( \WP_User $user ) {
|
65 |
}
|
66 |
|
67 |
/**
|
|
|
68 |
* @return bool
|
69 |
*/
|
70 |
protected function hasValidSecret( \WP_User $user ) {
|
104 |
}
|
105 |
|
106 |
/**
|
|
|
107 |
* @return string
|
108 |
*/
|
109 |
public function resetSecret( \WP_User $user ) {
|
141 |
}
|
142 |
|
143 |
/**
|
|
|
144 |
* @return string|mixed
|
145 |
*/
|
146 |
protected function genNewSecret( \WP_User $user ) {
|
151 |
|
152 |
/**
|
153 |
* Only to be fired if and when Login has been completely verified.
|
|
|
154 |
* @return $this
|
155 |
*/
|
156 |
public function postSuccessActions( \WP_User $user ) {
|
160 |
/**
|
161 |
* This MUST only ever be hooked into when the User is looking at their OWN profile, so we can use "current user"
|
162 |
* functions. Otherwise we need to be careful of mixing up users.
|
|
|
|
|
163 |
*/
|
164 |
public function renderUserProfileOptions( \WP_User $user ) :string {
|
165 |
return $this->getMod()
|
172 |
/**
|
173 |
* This MUST only ever be hooked into when the User is looking at their OWN profile, so we can use "current user"
|
174 |
* functions. Otherwise we need to be careful of mixing up users.
|
|
|
|
|
175 |
*/
|
176 |
public function renderUserProfileCustomForm( \WP_User $user ) :string {
|
177 |
$data = $this->getProfileRenderData( $user );
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/UserProfile.php
CHANGED
@@ -2,18 +2,18 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
-
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
|
|
|
|
|
|
8 |
class UserProfile {
|
9 |
|
10 |
use MfaControllerConsumer;
|
|
|
11 |
|
12 |
-
|
13 |
-
if ( is_admin() ) {
|
14 |
-
add_action( 'show_user_profile', [ $this, 'addOptionsToUserProfile' ] );
|
15 |
-
add_action( 'edit_user_profile', [ $this, 'addOptionsToUserEditProfile' ] );
|
16 |
-
}
|
17 |
}
|
18 |
|
19 |
/**
|
@@ -22,30 +22,6 @@ class UserProfile {
|
|
22 |
* @param \WP_User $user
|
23 |
*/
|
24 |
public function addOptionsToUserProfile( $user ) {
|
25 |
-
$oMC = $this->getMfaCon();
|
26 |
-
$WPU = Services::WpUsers();
|
27 |
-
$providers = $oMC->getProvidersForUser( $user );
|
28 |
-
if ( count( $providers ) > 0 ) {
|
29 |
-
$rows = [];
|
30 |
-
foreach ( $providers as $provider ) {
|
31 |
-
$rows[ $provider::SLUG ] = $provider->renderUserProfileOptions( $user );
|
32 |
-
}
|
33 |
-
|
34 |
-
echo $oMC->getMod()
|
35 |
-
->renderTemplate(
|
36 |
-
'/admin/user/profile/mfa/mfa_container.twig',
|
37 |
-
[
|
38 |
-
'user_to_edit_is_admin' => $WPU->isUserAdmin( $user ),
|
39 |
-
'strings' => [
|
40 |
-
'title' => __( 'Multi-Factor Authentication', 'wp-simple-firewall' ),
|
41 |
-
'provided_by' => sprintf( __( 'Provided by %s', 'wp-simple-firewall' ), $oMC->getCon()
|
42 |
-
->getHumanName() )
|
43 |
-
],
|
44 |
-
'mfa_rows' => $rows,
|
45 |
-
],
|
46 |
-
true
|
47 |
-
);
|
48 |
-
}
|
49 |
}
|
50 |
|
51 |
/**
|
@@ -53,46 +29,5 @@ class UserProfile {
|
|
53 |
* @param \WP_User $user
|
54 |
*/
|
55 |
public function addOptionsToUserEditProfile( $user ) {
|
56 |
-
$mfaCon = $this->getMfaCon();
|
57 |
-
$con = $mfaCon->getCon();
|
58 |
-
$WPU = Services::WpUsers();
|
59 |
-
$pluginName = $con->getHumanName();
|
60 |
-
|
61 |
-
$providers = array_map(
|
62 |
-
function ( $provider ) {
|
63 |
-
return $provider->getProviderName();
|
64 |
-
},
|
65 |
-
$mfaCon->getProvidersForUser( $user, true )
|
66 |
-
);
|
67 |
-
|
68 |
-
echo $mfaCon->getMod()
|
69 |
-
->renderTemplate(
|
70 |
-
'/admin/user/profile/mfa/remove_for_other_user.twig',
|
71 |
-
[
|
72 |
-
'flags' => [
|
73 |
-
'has_factors' => count( $providers ) > 0,
|
74 |
-
'is_admin_profile' => $WPU->isUserAdmin( $user ),
|
75 |
-
'can_remove' => $con->isPluginAdmin() || !$WPU->isUserAdmin( $user ),
|
76 |
-
],
|
77 |
-
'vars' => [
|
78 |
-
'user_id' => $user->ID,
|
79 |
-
'mfa_factor_names' => $providers,
|
80 |
-
],
|
81 |
-
'strings' => [
|
82 |
-
'title' => __( 'Multi-Factor Authentication', 'wp-simple-firewall' ),
|
83 |
-
'provided_by' => sprintf( __( 'Provided by %s', 'wp-simple-firewall' ), $pluginName ),
|
84 |
-
'currently_active' => __( 'Currently active MFA Providers on this profile are' ),
|
85 |
-
'remove_all' => __( 'Remove All MFA Providers' ),
|
86 |
-
'remove_all_from' => __( 'Remove All MFA Providers From This User Profile' ),
|
87 |
-
'remove_warning' => __( "Certain providers may not be removed if they're enforced." ),
|
88 |
-
'no_providers' => __( 'There are no MFA providers active on this user account.' ),
|
89 |
-
'only_secadmin' => sprintf( __( 'Only %s Security Admins may modify the MFA settings of another admin account.' ),
|
90 |
-
$pluginName ),
|
91 |
-
'authenticate' => sprintf( __( 'You may authenticate with the %s Security Admin system and return here.' ),
|
92 |
-
$pluginName ),
|
93 |
-
],
|
94 |
-
],
|
95 |
-
true
|
96 |
-
);
|
97 |
}
|
98 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor;
|
4 |
|
5 |
+
use FernleafSystems\Utilities\Logic\ExecOnce;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
|
|
7 |
|
8 |
+
/**
|
9 |
+
* @deprecated 13.0.5
|
10 |
+
*/
|
11 |
class UserProfile {
|
12 |
|
13 |
use MfaControllerConsumer;
|
14 |
+
use ExecOnce;
|
15 |
|
16 |
+
protected function run() {
|
|
|
|
|
|
|
|
|
17 |
}
|
18 |
|
19 |
/**
|
22 |
* @param \WP_User $user
|
23 |
*/
|
24 |
public function addOptionsToUserProfile( $user ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
}
|
26 |
|
27 |
/**
|
29 |
* @param \WP_User $user
|
30 |
*/
|
31 |
public function addOptionsToUserEditProfile( $user ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
}
|
33 |
}
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/ValidateLoginIntentRequest.php
CHANGED
@@ -11,7 +11,6 @@ class ValidateLoginIntentRequest {
|
|
11 |
use MfaControllerConsumer;
|
12 |
|
13 |
/**
|
14 |
-
* @return bool
|
15 |
* @throws \Exception
|
16 |
*/
|
17 |
public function run() :bool {
|
11 |
use MfaControllerConsumer;
|
12 |
|
13 |
/**
|
|
|
14 |
* @throws \Exception
|
15 |
*/
|
16 |
public function run() :bool {
|
src/lib/src/Modules/LoginGuard/ModCon.php
CHANGED
@@ -48,6 +48,8 @@ class ModCon extends BaseShield\ModCon {
|
|
48 |
$opts->setOpt( 'enable_google_recaptcha_login', 'disabled' );
|
49 |
$opts->setOpt( 'enable_login_gasp_check', 'N' );
|
50 |
}
|
|
|
|
|
51 |
}
|
52 |
|
53 |
public function ensureCorrectCaptchaConfig() {
|
@@ -148,24 +150,12 @@ class ModCon extends BaseShield\ModCon {
|
|
148 |
}
|
149 |
|
150 |
/**
|
151 |
-
* @
|
152 |
-
* @return array
|
153 |
*/
|
154 |
-
public function getOptEmailTwoFactorRolesDefaults(
|
155 |
-
$
|
156 |
-
|
157 |
-
|
158 |
-
1 => __( 'Contributors', 'wp-simple-firewall' ),
|
159 |
-
2 => __( 'Authors', 'wp-simple-firewall' ),
|
160 |
-
3 => __( 'Editors', 'wp-simple-firewall' ),
|
161 |
-
8 => __( 'Administrators', 'wp-simple-firewall' )
|
162 |
-
];
|
163 |
-
if ( $bAsOptDefaults ) {
|
164 |
-
unset( $aTwoAuthRoles[ 'type' ] );
|
165 |
-
unset( $aTwoAuthRoles[ 0 ] );
|
166 |
-
return array_keys( $aTwoAuthRoles );
|
167 |
-
}
|
168 |
-
return $aTwoAuthRoles;
|
169 |
}
|
170 |
|
171 |
public function getGaspKey() :string {
|
48 |
$opts->setOpt( 'enable_google_recaptcha_login', 'disabled' );
|
49 |
$opts->setOpt( 'enable_login_gasp_check', 'N' );
|
50 |
}
|
51 |
+
|
52 |
+
$opts->setOpt( 'two_factor_auth_user_roles', $opts->getEmail2FaRoles() );
|
53 |
}
|
54 |
|
55 |
public function ensureCorrectCaptchaConfig() {
|
150 |
}
|
151 |
|
152 |
/**
|
153 |
+
* @deprecated 13.0.5
|
|
|
154 |
*/
|
155 |
+
public function getOptEmailTwoFactorRolesDefaults() {
|
156 |
+
/** @var Options $opts */
|
157 |
+
$opts = $this->getOptions();
|
158 |
+
return $opts->getEmail2FaRoles();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
159 |
}
|
160 |
|
161 |
public function getGaspKey() :string {
|
src/lib/src/Modules/LoginGuard/Options.php
CHANGED
@@ -31,17 +31,15 @@ class Options extends BaseShield\Options {
|
|
31 |
}
|
32 |
|
33 |
public function getEmail2FaRoles() :array {
|
34 |
-
/** @var
|
35 |
-
$
|
36 |
-
$roles =
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
}
|
44 |
-
return is_array( $roles ) ? $roles : $mod->getOptEmailTwoFactorRolesDefaults();
|
45 |
}
|
46 |
|
47 |
public function getIfCanSendEmailVerified() :bool {
|
31 |
}
|
32 |
|
33 |
public function getEmail2FaRoles() :array {
|
34 |
+
/** @var Options $opts */
|
35 |
+
$opts = $this->getOptions();
|
36 |
+
$roles = apply_filters(
|
37 |
+
'shield/2fa_email_enforced_user_roles',
|
38 |
+
apply_filters( 'odp-shield-2fa_email_user_roles', $this->getOpt( 'two_factor_auth_user_roles' ) )
|
39 |
+
);
|
40 |
+
return array_unique( array_filter( array_map( 'sanitize_key',
|
41 |
+
is_array( $roles ) ? $roles : $opts->getOptDefault( 'two_factor_auth_user_roles' )
|
42 |
+
) ) );
|
|
|
|
|
43 |
}
|
44 |
|
45 |
public function getIfCanSendEmailVerified() :bool {
|
src/lib/src/Modules/LoginGuard/Processor.php
CHANGED
@@ -15,24 +15,33 @@ class Processor extends BaseShield\Processor {
|
|
15 |
if ( Services::WpGeneral()->isXmlrpc() && $mod->isXmlrpcBypass() ) {
|
16 |
return;
|
17 |
}
|
18 |
-
|
|
|
|
|
|
|
|
|
|
|
19 |
( new Lib\Rename\RenameLogin() )
|
20 |
->setMod( $mod )
|
21 |
->execute();
|
22 |
|
23 |
-
|
24 |
-
|
25 |
-
add_action( 'init', function () {
|
26 |
-
$this->launchAntiBot();
|
27 |
-
}, -100 );
|
28 |
-
|
29 |
-
$mod->getLoginIntentController()->execute();
|
30 |
-
}
|
31 |
}
|
32 |
|
33 |
-
|
34 |
( new Lib\AntiBot\AntibotSetup() )
|
35 |
->setMod( $this->getMod() )
|
36 |
->execute();
|
37 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
}
|
15 |
if ( Services::WpGeneral()->isXmlrpc() && $mod->isXmlrpcBypass() ) {
|
16 |
return;
|
17 |
}
|
18 |
+
//
|
19 |
+
// /** @var Options $opts */
|
20 |
+
// $opts = $this->getOptions();
|
21 |
+
// var_dump( $opts->getEmail2FaRoles() );
|
22 |
+
// die(0);
|
23 |
+
//;
|
24 |
( new Lib\Rename\RenameLogin() )
|
25 |
->setMod( $mod )
|
26 |
->execute();
|
27 |
|
28 |
+
$mod->getLoginIntentController()->execute();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
}
|
30 |
|
31 |
+
public function onWpInit() {
|
32 |
( new Lib\AntiBot\AntibotSetup() )
|
33 |
->setMod( $this->getMod() )
|
34 |
->execute();
|
35 |
}
|
36 |
+
|
37 |
+
protected function getWpHookPriority( string $hook ) :int {
|
38 |
+
switch ( $hook ) {
|
39 |
+
case 'init':
|
40 |
+
$pri = -100;
|
41 |
+
break;
|
42 |
+
default:
|
43 |
+
$pri = parent::getWpHookPriority( $hook );
|
44 |
+
}
|
45 |
+
return $pri;
|
46 |
+
}
|
47 |
}
|
src/lib/src/Modules/LoginGuard/Strings.php
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
|
|
6 |
|
7 |
class Strings extends Base\Strings {
|
8 |
|
@@ -215,8 +216,13 @@ class Strings extends Base\Strings {
|
|
215 |
case 'two_factor_auth_user_roles' :
|
216 |
$name = sprintf( '%s - %s', __( 'Enforce', 'wp-simple-firewall' ), __( 'Email Authentication', 'wp-simple-firewall' ) );
|
217 |
$summary = __( 'All User Roles Subject To Email Authentication', 'wp-simple-firewall' );
|
218 |
-
$desc =
|
219 |
-
|
|
|
|
|
|
|
|
|
|
|
220 |
break;
|
221 |
|
222 |
case 'enable_google_recaptcha_login' :
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
8 |
class Strings extends Base\Strings {
|
9 |
|
216 |
case 'two_factor_auth_user_roles' :
|
217 |
$name = sprintf( '%s - %s', __( 'Enforce', 'wp-simple-firewall' ), __( 'Email Authentication', 'wp-simple-firewall' ) );
|
218 |
$summary = __( 'All User Roles Subject To Email Authentication', 'wp-simple-firewall' );
|
219 |
+
$desc = [
|
220 |
+
sprintf( '<strong>%s</strong>: %s', __( 'Important', 'wp-simple-firewall' ), sprintf( __( 'This setting only applies to %s.', 'wp-simple-firewall' ), __( 'Email Authentication', 'wp-simple-firewall' ) ) ),
|
221 |
+
__( 'Enforces email-based authentication on all users with the selected roles.', 'wp-simple-firewall' ),
|
222 |
+
__( 'If a user has multiple roles assigned to it, all roles will be checked against this list.', 'wp-simple-firewall' ),
|
223 |
+
sprintf( '%s:<br /><ul><li><code>%s</code></li></ul>', __( 'All User Roles Available On This Site', 'wp-simple-firewall' ),
|
224 |
+
implode( '</code></li><li><code>', Services::WpUsers()->getAvailableUserRoles() ) )
|
225 |
+
];
|
226 |
break;
|
227 |
|
228 |
case 'enable_google_recaptcha_login' :
|
src/lib/src/Modules/LoginGuard/UI.php
CHANGED
@@ -3,10 +3,34 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield;
|
|
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Utilities\Time\WorldTimeApi;
|
|
|
7 |
|
8 |
class UI extends BaseShield\UI {
|
9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
protected function getSectionWarnings( string $section ) :array {
|
11 |
$con = $this->getCon();
|
12 |
/** @var Options $opts */
|
@@ -20,14 +44,16 @@ class UI extends BaseShield\UI {
|
|
20 |
$warnings[] = __( "AntiBot detection isn't being applied to your site because you haven't selected any forms to protect, such as Login or Register.", 'wp-simple-firewall' );
|
21 |
}
|
22 |
|
|
|
23 |
$installedButNotEnabledProviders = array_filter(
|
24 |
-
$
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
return !$provider->isEnabled();
|
29 |
}
|
30 |
);
|
|
|
31 |
if ( !empty( $installedButNotEnabledProviders ) ) {
|
32 |
$warnings[] = sprintf( __( "%s has an integration available to protect the login forms of a 3rd party plugin you're using: %s", 'wp-simple-firewall' ),
|
33 |
$con->getHumanName(),
|
@@ -49,18 +75,16 @@ class UI extends BaseShield\UI {
|
|
49 |
catch ( \Exception $e ) {
|
50 |
}
|
51 |
}
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
|
|
|
|
|
|
58 |
}
|
59 |
-
|
60 |
-
$warnings[] =
|
61 |
-
__( '2FA by email demands that your WP site is properly configured to send email.', 'wp-simple-firewall' )
|
62 |
-
.'<br/>'.__( 'This is a common problem and you may get locked out in the future if you ignore this.', 'wp-simple-firewall' )
|
63 |
-
.' '.sprintf( '<a href="%s" target="_blank" class="alert-link">%s</a>', 'https://shsec.io/dd', trim( __( 'Learn More.', 'wp-simple-firewall' ), '.' ) );
|
64 |
}
|
65 |
|
66 |
return $warnings;
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\Bots\Common\BaseHandler;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Utilities\Time\WorldTimeApi;
|
8 |
+
use FernleafSystems\Wordpress\Services\Services;
|
9 |
|
10 |
class UI extends BaseShield\UI {
|
11 |
|
12 |
+
protected function getSectionNotices( string $section ) :array {
|
13 |
+
/** @var Options $opts */
|
14 |
+
$opts = $this->getOptions();
|
15 |
+
|
16 |
+
$notices = [];
|
17 |
+
|
18 |
+
if ( $section == 'section_2fa_email' ) {
|
19 |
+
|
20 |
+
if ( $opts->isEnabledEmailAuth() && !$opts->getIfCanSendEmailVerified() ) {
|
21 |
+
$notices[] = __( "The ability of this site to send email hasn't been verified.", 'wp-simple-firewall' )
|
22 |
+
.'<br/>'.__( 'Please click to re-save your settings to trigger another verification email.', 'wp-simple-firewall' );
|
23 |
+
}
|
24 |
+
|
25 |
+
$notices[] =
|
26 |
+
__( '2FA by email demands that your WP site is properly configured to send email.', 'wp-simple-firewall' )
|
27 |
+
.'<br/>'.__( 'This is a common problem and you may get locked out in the future if you ignore this.', 'wp-simple-firewall' )
|
28 |
+
.' '.sprintf( '<a href="%s" target="_blank" class="alert-link">%s</a>', 'https://shsec.io/dd', trim( __( 'Learn More.', 'wp-simple-firewall' ), '.' ) );
|
29 |
+
}
|
30 |
+
|
31 |
+
return $notices;
|
32 |
+
}
|
33 |
+
|
34 |
protected function getSectionWarnings( string $section ) :array {
|
35 |
$con = $this->getCon();
|
36 |
/** @var Options $opts */
|
44 |
$warnings[] = __( "AntiBot detection isn't being applied to your site because you haven't selected any forms to protect, such as Login or Register.", 'wp-simple-firewall' );
|
45 |
}
|
46 |
|
47 |
+
$modIntegrations = $con->getModule_Integrations();
|
48 |
$installedButNotEnabledProviders = array_filter(
|
49 |
+
$modIntegrations->getController_UserForms()->enumProviders(),
|
50 |
+
function ( $providerClass ) use ( $modIntegrations ) {
|
51 |
+
/** @var BaseHandler $provider */
|
52 |
+
$provider = ( new $providerClass() )->setMod( $modIntegrations );
|
53 |
+
return !$provider->isEnabled() && $provider::IsProviderInstalled();
|
54 |
}
|
55 |
);
|
56 |
+
|
57 |
if ( !empty( $installedButNotEnabledProviders ) ) {
|
58 |
$warnings[] = sprintf( __( "%s has an integration available to protect the login forms of a 3rd party plugin you're using: %s", 'wp-simple-firewall' ),
|
59 |
$con->getHumanName(),
|
75 |
catch ( \Exception $e ) {
|
76 |
}
|
77 |
}
|
78 |
+
elseif ( $section == 'section_2fa_email' ) {
|
79 |
+
$nonRoles = array_diff(
|
80 |
+
$opts->getEmail2FaRoles(),
|
81 |
+
Services::WpUsers()->getAvailableUserRoles()
|
82 |
+
);
|
83 |
+
if ( count( $nonRoles ) > 0 ) {
|
84 |
+
$warnings[] = sprintf( '%s: %s',
|
85 |
+
__( "Certain user roles are set for email authentication enforcement that aren't currently available" ),
|
86 |
+
implode( ', ', $nonRoles ) );
|
87 |
}
|
|
|
|
|
|
|
|
|
|
|
88 |
}
|
89 |
|
90 |
return $warnings;
|
src/lib/src/Modules/ModConsumer.php
CHANGED
@@ -5,10 +5,6 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Controller\Controller;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
7 |
|
8 |
-
/**
|
9 |
-
* Trait ModConsumer
|
10 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Modules
|
11 |
-
*/
|
12 |
trait ModConsumer {
|
13 |
|
14 |
/**
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Controller\Controller;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
7 |
|
|
|
|
|
|
|
|
|
8 |
trait ModConsumer {
|
9 |
|
10 |
/**
|
src/lib/src/Modules/OptsConsumer.php
CHANGED
@@ -4,10 +4,6 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Options;
|
6 |
|
7 |
-
/**
|
8 |
-
* Trait OptsConsumer
|
9 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Modules
|
10 |
-
*/
|
11 |
trait OptsConsumer {
|
12 |
|
13 |
/**
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Options;
|
6 |
|
|
|
|
|
|
|
|
|
7 |
trait OptsConsumer {
|
8 |
|
9 |
/**
|
src/lib/src/Modules/Plugin/AdminNotices.php
CHANGED
@@ -179,27 +179,17 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
|
|
179 |
'notice_attributes' => [],
|
180 |
'strings' => [
|
181 |
'yes' => "Yes please! I'd love to join in and learn more",
|
182 |
-
'
|
183 |
-
'your_name' => __( 'Your Name', 'wp-simple-firewall' ),
|
184 |
-
'your_email' => __( 'Your Email', 'wp-simple-firewall' ),
|
185 |
-
'signup' => __( 'Sign-Up', 'wp-simple-firewall' ),
|
186 |
-
'dismiss' => "No thanks, I'm not interested in such informative groups",
|
187 |
'summary' => sprintf( 'The %s team is helping raise awareness of WP Security issues
|
188 |
and to provide guidance with the %s plugin.', $name, $name ),
|
189 |
-
'privacy_policy' => sprintf(
|
190 |
-
'I certify that I have read and agree to the <a href="%s" target="_blank">Privacy Policy</a>',
|
191 |
-
$opts->getDef( 'href_privacy_policy' )
|
192 |
-
),
|
193 |
-
'consent' => __( 'I agree to Ts & Cs', 'wp-simple-firewall' )
|
194 |
],
|
195 |
'hrefs' => [
|
196 |
-
'
|
197 |
],
|
198 |
'install_days' => $opts->getInstallationDays(),
|
199 |
'vars' => [
|
200 |
'name' => $user->first_name,
|
201 |
'user_email' => $user->user_email,
|
202 |
-
'drip_form_id' => $notice->drip_form_id
|
203 |
]
|
204 |
];
|
205 |
}
|
179 |
'notice_attributes' => [],
|
180 |
'strings' => [
|
181 |
'yes' => "Yes please! I'd love to join in and learn more",
|
182 |
+
'dismiss' => "No thanks",
|
|
|
|
|
|
|
|
|
183 |
'summary' => sprintf( 'The %s team is helping raise awareness of WP Security issues
|
184 |
and to provide guidance with the %s plugin.', $name, $name ),
|
|
|
|
|
|
|
|
|
|
|
185 |
],
|
186 |
'hrefs' => [
|
187 |
+
'form' => 'https://shsec.io/shieldpluginnewsletter'
|
188 |
],
|
189 |
'install_days' => $opts->getInstallationDays(),
|
190 |
'vars' => [
|
191 |
'name' => $user->first_name,
|
192 |
'user_email' => $user->user_email,
|
|
|
193 |
]
|
194 |
];
|
195 |
}
|
src/lib/src/Modules/Plugin/Processor.php
CHANGED
@@ -74,5 +74,8 @@ class Processor extends BaseShield\Processor {
|
|
74 |
if ( class_exists( 'AIO_WP_Security' ) && isset( $GLOBALS[ 'aio_wp_security' ] ) ) {
|
75 |
remove_action( 'init', [ $GLOBALS[ 'aio_wp_security' ], 'wp_security_plugin_init' ], 0 );
|
76 |
}
|
|
|
|
|
|
|
77 |
}
|
78 |
}
|
74 |
if ( class_exists( 'AIO_WP_Security' ) && isset( $GLOBALS[ 'aio_wp_security' ] ) ) {
|
75 |
remove_action( 'init', [ $GLOBALS[ 'aio_wp_security' ], 'wp_security_plugin_init' ], 0 );
|
76 |
}
|
77 |
+
if ( @function_exists( '\wp_cache_setting' ) ) {
|
78 |
+
@wp_cache_setting( 'wp_super_cache_late_init', 1 );
|
79 |
+
}
|
80 |
}
|
81 |
}
|
src/lib/src/Scans/Afs/ResultItem.php
CHANGED
@@ -71,7 +71,7 @@ class ResultItem extends Base\ResultItem {
|
|
71 |
$value = json_encode( $value );
|
72 |
break;
|
73 |
case 'mal_file_lines':
|
74 |
-
$value = base64_encode( json_encode( $value ) );
|
75 |
break;
|
76 |
case 'mal_sig':
|
77 |
$value = base64_encode( $value );
|
71 |
$value = json_encode( $value );
|
72 |
break;
|
73 |
case 'mal_file_lines':
|
74 |
+
$value = base64_encode( json_encode( is_array( $value ) ? $value : [] ) );
|
75 |
break;
|
76 |
case 'mal_sig':
|
77 |
$value = base64_encode( $value );
|
src/lib/src/ShieldNetApi/HandshakingNonce.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<?php
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi;
|
4 |
|
@@ -33,7 +33,7 @@ class HandshakingNonce {
|
|
33 |
/**
|
34 |
* @return int[]
|
35 |
*/
|
36 |
-
private function getNonces() {
|
37 |
return $this->getCon()
|
38 |
->getModule_Plugin()
|
39 |
->getShieldNetApiController()->vo->nonces;
|
@@ -42,7 +42,6 @@ class HandshakingNonce {
|
|
42 |
/**
|
43 |
* Also filters out expired nonces on-save
|
44 |
* @param int[] $nonces
|
45 |
-
* @return $this
|
46 |
*/
|
47 |
private function storeNonces( array $nonces ) {
|
48 |
$snapiCon = $this->getCon()
|
@@ -55,6 +54,5 @@ class HandshakingNonce {
|
|
55 |
}
|
56 |
);
|
57 |
$snapiCon->storeVoData();
|
58 |
-
return $this;
|
59 |
}
|
60 |
}
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi;
|
4 |
|
33 |
/**
|
34 |
* @return int[]
|
35 |
*/
|
36 |
+
private function getNonces() :array {
|
37 |
return $this->getCon()
|
38 |
->getModule_Plugin()
|
39 |
->getShieldNetApiController()->vo->nonces;
|
42 |
/**
|
43 |
* Also filters out expired nonces on-save
|
44 |
* @param int[] $nonces
|
|
|
45 |
*/
|
46 |
private function storeNonces( array $nonces ) {
|
47 |
$snapiCon = $this->getCon()
|
54 |
}
|
55 |
);
|
56 |
$snapiCon->storeVoData();
|
|
|
57 |
}
|
58 |
}
|
src/lib/src/ShieldNetApi/ShieldNetApiController.php
CHANGED
@@ -13,8 +13,6 @@ use FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\Reputation\SendIPReputa
|
|
13 |
use FernleafSystems\Wordpress\Services\Services;
|
14 |
|
15 |
/**
|
16 |
-
* Class ShieldNetApiController
|
17 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi
|
18 |
* @property ShieldNetApiDataVO $vo
|
19 |
*/
|
20 |
class ShieldNetApiController extends DynPropertiesClass {
|
13 |
use FernleafSystems\Wordpress\Services\Services;
|
14 |
|
15 |
/**
|
|
|
|
|
16 |
* @property ShieldNetApiDataVO $vo
|
17 |
*/
|
18 |
class ShieldNetApiController extends DynPropertiesClass {
|
src/lib/src/ShieldNetApi/ShieldNetApiDataVO.php
CHANGED
@@ -5,8 +5,6 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi;
|
|
5 |
use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
|
6 |
|
7 |
/**
|
8 |
-
* Class ShieldNetApiDataVO
|
9 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi
|
10 |
* @property int $last_handshake_at
|
11 |
* @property int $last_handshake_attempt_at
|
12 |
* @property int $last_send_iprep_at
|
5 |
use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
|
6 |
|
7 |
/**
|
|
|
|
|
8 |
* @property int $last_handshake_at
|
9 |
* @property int $last_handshake_attempt_at
|
10 |
* @property int $last_send_iprep_at
|
src/lib/vendor/composer/ClassLoader.php
CHANGED
@@ -42,75 +42,30 @@ namespace Composer\Autoload;
|
|
42 |
*/
|
43 |
class ClassLoader
|
44 |
{
|
45 |
-
/** @var ?string */
|
46 |
private $vendorDir;
|
47 |
|
48 |
// PSR-4
|
49 |
-
/**
|
50 |
-
* @var array[]
|
51 |
-
* @psalm-var array<string, array<string, int>>
|
52 |
-
*/
|
53 |
private $prefixLengthsPsr4 = array();
|
54 |
-
/**
|
55 |
-
* @var array[]
|
56 |
-
* @psalm-var array<string, array<int, string>>
|
57 |
-
*/
|
58 |
private $prefixDirsPsr4 = array();
|
59 |
-
/**
|
60 |
-
* @var array[]
|
61 |
-
* @psalm-var array<string, string>
|
62 |
-
*/
|
63 |
private $fallbackDirsPsr4 = array();
|
64 |
|
65 |
// PSR-0
|
66 |
-
/**
|
67 |
-
* @var array[]
|
68 |
-
* @psalm-var array<string, array<string, string[]>>
|
69 |
-
*/
|
70 |
private $prefixesPsr0 = array();
|
71 |
-
/**
|
72 |
-
* @var array[]
|
73 |
-
* @psalm-var array<string, string>
|
74 |
-
*/
|
75 |
private $fallbackDirsPsr0 = array();
|
76 |
|
77 |
-
/** @var bool */
|
78 |
private $useIncludePath = false;
|
79 |
-
|
80 |
-
/**
|
81 |
-
* @var string[]
|
82 |
-
* @psalm-var array<string, string>
|
83 |
-
*/
|
84 |
private $classMap = array();
|
85 |
-
|
86 |
-
/** @var bool */
|
87 |
private $classMapAuthoritative = false;
|
88 |
-
|
89 |
-
/**
|
90 |
-
* @var bool[]
|
91 |
-
* @psalm-var array<string, bool>
|
92 |
-
*/
|
93 |
private $missingClasses = array();
|
94 |
-
|
95 |
-
/** @var ?string */
|
96 |
private $apcuPrefix;
|
97 |
|
98 |
-
/**
|
99 |
-
* @var self[]
|
100 |
-
*/
|
101 |
private static $registeredLoaders = array();
|
102 |
|
103 |
-
/**
|
104 |
-
* @param ?string $vendorDir
|
105 |
-
*/
|
106 |
public function __construct($vendorDir = null)
|
107 |
{
|
108 |
$this->vendorDir = $vendorDir;
|
109 |
}
|
110 |
|
111 |
-
/**
|
112 |
-
* @return string[]
|
113 |
-
*/
|
114 |
public function getPrefixes()
|
115 |
{
|
116 |
if (!empty($this->prefixesPsr0)) {
|
@@ -120,47 +75,28 @@ class ClassLoader
|
|
120 |
return array();
|
121 |
}
|
122 |
|
123 |
-
/**
|
124 |
-
* @return array[]
|
125 |
-
* @psalm-return array<string, array<int, string>>
|
126 |
-
*/
|
127 |
public function getPrefixesPsr4()
|
128 |
{
|
129 |
return $this->prefixDirsPsr4;
|
130 |
}
|
131 |
|
132 |
-
/**
|
133 |
-
* @return array[]
|
134 |
-
* @psalm-return array<string, string>
|
135 |
-
*/
|
136 |
public function getFallbackDirs()
|
137 |
{
|
138 |
return $this->fallbackDirsPsr0;
|
139 |
}
|
140 |
|
141 |
-
/**
|
142 |
-
* @return array[]
|
143 |
-
* @psalm-return array<string, string>
|
144 |
-
*/
|
145 |
public function getFallbackDirsPsr4()
|
146 |
{
|
147 |
return $this->fallbackDirsPsr4;
|
148 |
}
|
149 |
|
150 |
-
/**
|
151 |
-
* @return string[] Array of classname => path
|
152 |
-
* @psalm-var array<string, string>
|
153 |
-
*/
|
154 |
public function getClassMap()
|
155 |
{
|
156 |
return $this->classMap;
|
157 |
}
|
158 |
|
159 |
/**
|
160 |
-
* @param
|
161 |
-
* @psalm-param array<string, string> $classMap
|
162 |
-
*
|
163 |
-
* @return void
|
164 |
*/
|
165 |
public function addClassMap(array $classMap)
|
166 |
{
|
@@ -175,11 +111,9 @@ class ClassLoader
|
|
175 |
* Registers a set of PSR-0 directories for a given prefix, either
|
176 |
* appending or prepending to the ones previously set for this prefix.
|
177 |
*
|
178 |
-
* @param string
|
179 |
-
* @param
|
180 |
-
* @param bool
|
181 |
-
*
|
182 |
-
* @return void
|
183 |
*/
|
184 |
public function add($prefix, $paths, $prepend = false)
|
185 |
{
|
@@ -222,13 +156,11 @@ class ClassLoader
|
|
222 |
* Registers a set of PSR-4 directories for a given namespace, either
|
223 |
* appending or prepending to the ones previously set for this namespace.
|
224 |
*
|
225 |
-
* @param string
|
226 |
-
* @param
|
227 |
-
* @param bool
|
228 |
*
|
229 |
* @throws \InvalidArgumentException
|
230 |
-
*
|
231 |
-
* @return void
|
232 |
*/
|
233 |
public function addPsr4($prefix, $paths, $prepend = false)
|
234 |
{
|
@@ -272,10 +204,8 @@ class ClassLoader
|
|
272 |
* Registers a set of PSR-0 directories for a given prefix,
|
273 |
* replacing any others previously set for this prefix.
|
274 |
*
|
275 |
-
* @param string
|
276 |
-
* @param
|
277 |
-
*
|
278 |
-
* @return void
|
279 |
*/
|
280 |
public function set($prefix, $paths)
|
281 |
{
|
@@ -290,12 +220,10 @@ class ClassLoader
|
|
290 |
* Registers a set of PSR-4 directories for a given namespace,
|
291 |
* replacing any others previously set for this namespace.
|
292 |
*
|
293 |
-
* @param string
|
294 |
-
* @param
|
295 |
*
|
296 |
* @throws \InvalidArgumentException
|
297 |
-
*
|
298 |
-
* @return void
|
299 |
*/
|
300 |
public function setPsr4($prefix, $paths)
|
301 |
{
|
@@ -315,8 +243,6 @@ class ClassLoader
|
|
315 |
* Turns on searching the include path for class files.
|
316 |
*
|
317 |
* @param bool $useIncludePath
|
318 |
-
*
|
319 |
-
* @return void
|
320 |
*/
|
321 |
public function setUseIncludePath($useIncludePath)
|
322 |
{
|
@@ -339,8 +265,6 @@ class ClassLoader
|
|
339 |
* that have not been registered with the class map.
|
340 |
*
|
341 |
* @param bool $classMapAuthoritative
|
342 |
-
*
|
343 |
-
* @return void
|
344 |
*/
|
345 |
public function setClassMapAuthoritative($classMapAuthoritative)
|
346 |
{
|
@@ -361,8 +285,6 @@ class ClassLoader
|
|
361 |
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
362 |
*
|
363 |
* @param string|null $apcuPrefix
|
364 |
-
*
|
365 |
-
* @return void
|
366 |
*/
|
367 |
public function setApcuPrefix($apcuPrefix)
|
368 |
{
|
@@ -383,18 +305,14 @@ class ClassLoader
|
|
383 |
* Registers this instance as an autoloader.
|
384 |
*
|
385 |
* @param bool $prepend Whether to prepend the autoloader or not
|
386 |
-
*
|
387 |
-
* @return void
|
388 |
*/
|
389 |
public function register($prepend = false)
|
390 |
{
|
391 |
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
392 |
|
393 |
if (null === $this->vendorDir) {
|
394 |
-
|
395 |
-
}
|
396 |
-
|
397 |
-
if ($prepend) {
|
398 |
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
|
399 |
} else {
|
400 |
unset(self::$registeredLoaders[$this->vendorDir]);
|
@@ -404,8 +322,6 @@ class ClassLoader
|
|
404 |
|
405 |
/**
|
406 |
* Unregisters this instance as an autoloader.
|
407 |
-
*
|
408 |
-
* @return void
|
409 |
*/
|
410 |
public function unregister()
|
411 |
{
|
@@ -420,7 +336,7 @@ class ClassLoader
|
|
420 |
* Loads the given class or interface.
|
421 |
*
|
422 |
* @param string $class The name of the class
|
423 |
-
* @return
|
424 |
*/
|
425 |
public function loadClass($class)
|
426 |
{
|
@@ -429,8 +345,6 @@ class ClassLoader
|
|
429 |
|
430 |
return true;
|
431 |
}
|
432 |
-
|
433 |
-
return null;
|
434 |
}
|
435 |
|
436 |
/**
|
@@ -485,11 +399,6 @@ class ClassLoader
|
|
485 |
return self::$registeredLoaders;
|
486 |
}
|
487 |
|
488 |
-
/**
|
489 |
-
* @param string $class
|
490 |
-
* @param string $ext
|
491 |
-
* @return string|false
|
492 |
-
*/
|
493 |
private function findFileWithExtension($class, $ext)
|
494 |
{
|
495 |
// PSR-4 lookup
|
@@ -561,10 +470,6 @@ class ClassLoader
|
|
561 |
* Scope isolated include.
|
562 |
*
|
563 |
* Prevents access to $this/self from included files.
|
564 |
-
*
|
565 |
-
* @param string $file
|
566 |
-
* @return void
|
567 |
-
* @private
|
568 |
*/
|
569 |
function includeFile($file)
|
570 |
{
|
42 |
*/
|
43 |
class ClassLoader
|
44 |
{
|
|
|
45 |
private $vendorDir;
|
46 |
|
47 |
// PSR-4
|
|
|
|
|
|
|
|
|
48 |
private $prefixLengthsPsr4 = array();
|
|
|
|
|
|
|
|
|
49 |
private $prefixDirsPsr4 = array();
|
|
|
|
|
|
|
|
|
50 |
private $fallbackDirsPsr4 = array();
|
51 |
|
52 |
// PSR-0
|
|
|
|
|
|
|
|
|
53 |
private $prefixesPsr0 = array();
|
|
|
|
|
|
|
|
|
54 |
private $fallbackDirsPsr0 = array();
|
55 |
|
|
|
56 |
private $useIncludePath = false;
|
|
|
|
|
|
|
|
|
|
|
57 |
private $classMap = array();
|
|
|
|
|
58 |
private $classMapAuthoritative = false;
|
|
|
|
|
|
|
|
|
|
|
59 |
private $missingClasses = array();
|
|
|
|
|
60 |
private $apcuPrefix;
|
61 |
|
|
|
|
|
|
|
62 |
private static $registeredLoaders = array();
|
63 |
|
|
|
|
|
|
|
64 |
public function __construct($vendorDir = null)
|
65 |
{
|
66 |
$this->vendorDir = $vendorDir;
|
67 |
}
|
68 |
|
|
|
|
|
|
|
69 |
public function getPrefixes()
|
70 |
{
|
71 |
if (!empty($this->prefixesPsr0)) {
|
75 |
return array();
|
76 |
}
|
77 |
|
|
|
|
|
|
|
|
|
78 |
public function getPrefixesPsr4()
|
79 |
{
|
80 |
return $this->prefixDirsPsr4;
|
81 |
}
|
82 |
|
|
|
|
|
|
|
|
|
83 |
public function getFallbackDirs()
|
84 |
{
|
85 |
return $this->fallbackDirsPsr0;
|
86 |
}
|
87 |
|
|
|
|
|
|
|
|
|
88 |
public function getFallbackDirsPsr4()
|
89 |
{
|
90 |
return $this->fallbackDirsPsr4;
|
91 |
}
|
92 |
|
|
|
|
|
|
|
|
|
93 |
public function getClassMap()
|
94 |
{
|
95 |
return $this->classMap;
|
96 |
}
|
97 |
|
98 |
/**
|
99 |
+
* @param array $classMap Class to filename map
|
|
|
|
|
|
|
100 |
*/
|
101 |
public function addClassMap(array $classMap)
|
102 |
{
|
111 |
* Registers a set of PSR-0 directories for a given prefix, either
|
112 |
* appending or prepending to the ones previously set for this prefix.
|
113 |
*
|
114 |
+
* @param string $prefix The prefix
|
115 |
+
* @param array|string $paths The PSR-0 root directories
|
116 |
+
* @param bool $prepend Whether to prepend the directories
|
|
|
|
|
117 |
*/
|
118 |
public function add($prefix, $paths, $prepend = false)
|
119 |
{
|
156 |
* Registers a set of PSR-4 directories for a given namespace, either
|
157 |
* appending or prepending to the ones previously set for this namespace.
|
158 |
*
|
159 |
+
* @param string $prefix The prefix/namespace, with trailing '\\'
|
160 |
+
* @param array|string $paths The PSR-4 base directories
|
161 |
+
* @param bool $prepend Whether to prepend the directories
|
162 |
*
|
163 |
* @throws \InvalidArgumentException
|
|
|
|
|
164 |
*/
|
165 |
public function addPsr4($prefix, $paths, $prepend = false)
|
166 |
{
|
204 |
* Registers a set of PSR-0 directories for a given prefix,
|
205 |
* replacing any others previously set for this prefix.
|
206 |
*
|
207 |
+
* @param string $prefix The prefix
|
208 |
+
* @param array|string $paths The PSR-0 base directories
|
|
|
|
|
209 |
*/
|
210 |
public function set($prefix, $paths)
|
211 |
{
|
220 |
* Registers a set of PSR-4 directories for a given namespace,
|
221 |
* replacing any others previously set for this namespace.
|
222 |
*
|
223 |
+
* @param string $prefix The prefix/namespace, with trailing '\\'
|
224 |
+
* @param array|string $paths The PSR-4 base directories
|
225 |
*
|
226 |
* @throws \InvalidArgumentException
|
|
|
|
|
227 |
*/
|
228 |
public function setPsr4($prefix, $paths)
|
229 |
{
|
243 |
* Turns on searching the include path for class files.
|
244 |
*
|
245 |
* @param bool $useIncludePath
|
|
|
|
|
246 |
*/
|
247 |
public function setUseIncludePath($useIncludePath)
|
248 |
{
|
265 |
* that have not been registered with the class map.
|
266 |
*
|
267 |
* @param bool $classMapAuthoritative
|
|
|
|
|
268 |
*/
|
269 |
public function setClassMapAuthoritative($classMapAuthoritative)
|
270 |
{
|
285 |
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
286 |
*
|
287 |
* @param string|null $apcuPrefix
|
|
|
|
|
288 |
*/
|
289 |
public function setApcuPrefix($apcuPrefix)
|
290 |
{
|
305 |
* Registers this instance as an autoloader.
|
306 |
*
|
307 |
* @param bool $prepend Whether to prepend the autoloader or not
|
|
|
|
|
308 |
*/
|
309 |
public function register($prepend = false)
|
310 |
{
|
311 |
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
312 |
|
313 |
if (null === $this->vendorDir) {
|
314 |
+
//no-op
|
315 |
+
} elseif ($prepend) {
|
|
|
|
|
316 |
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
|
317 |
} else {
|
318 |
unset(self::$registeredLoaders[$this->vendorDir]);
|
322 |
|
323 |
/**
|
324 |
* Unregisters this instance as an autoloader.
|
|
|
|
|
325 |
*/
|
326 |
public function unregister()
|
327 |
{
|
336 |
* Loads the given class or interface.
|
337 |
*
|
338 |
* @param string $class The name of the class
|
339 |
+
* @return bool|null True if loaded, null otherwise
|
340 |
*/
|
341 |
public function loadClass($class)
|
342 |
{
|
345 |
|
346 |
return true;
|
347 |
}
|
|
|
|
|
348 |
}
|
349 |
|
350 |
/**
|
399 |
return self::$registeredLoaders;
|
400 |
}
|
401 |
|
|
|
|
|
|
|
|
|
|
|
402 |
private function findFileWithExtension($class, $ext)
|
403 |
{
|
404 |
// PSR-4 lookup
|
470 |
* Scope isolated include.
|
471 |
*
|
472 |
* Prevents access to $this/self from included files.
|
|
|
|
|
|
|
|
|
473 |
*/
|
474 |
function includeFile($file)
|
475 |
{
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Email.php
CHANGED
@@ -7,8 +7,6 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
7 |
use Html2Text\Html2Text;
|
8 |
|
9 |
/**
|
10 |
-
* Class Email
|
11 |
-
* @package FernleafSystems\Wordpress\Services\Utilities
|
12 |
* @property string $to_email
|
13 |
* @property string $to_name
|
14 |
* @property string $from_email
|
7 |
use Html2Text\Html2Text;
|
8 |
|
9 |
/**
|
|
|
|
|
10 |
* @property string $to_email
|
11 |
* @property string $to_name
|
12 |
* @property string $from_email
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/GeoIp.php
CHANGED
@@ -4,10 +4,6 @@ namespace FernleafSystems\Wordpress\Services\Utilities;
|
|
4 |
|
5 |
use FernleafSystems\Wordpress\Services\Services;
|
6 |
|
7 |
-
/**
|
8 |
-
* Class GeoIp
|
9 |
-
* @package FernleafSystems\Wordpress\Services\Utilities
|
10 |
-
*/
|
11 |
class GeoIp {
|
12 |
|
13 |
const URL_REDIRECTLI = 'https://api.redirect.li/v1/ip/';
|
4 |
|
5 |
use FernleafSystems\Wordpress\Services\Services;
|
6 |
|
|
|
|
|
|
|
|
|
7 |
class GeoIp {
|
8 |
|
9 |
const URL_REDIRECTLI = 'https://api.redirect.li/v1/ip/';
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Html.php
CHANGED
@@ -2,10 +2,6 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Services\Utilities;
|
4 |
|
5 |
-
/**
|
6 |
-
* Class Html
|
7 |
-
* @package FernleafSystems\Wordpress\Services\Utilities
|
8 |
-
*/
|
9 |
class Html {
|
10 |
|
11 |
/**
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Services\Utilities;
|
4 |
|
|
|
|
|
|
|
|
|
5 |
class Html {
|
6 |
|
7 |
/**
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Licenses/EddLicenseVO.php
CHANGED
@@ -6,8 +6,6 @@ use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
|
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
8 |
/**
|
9 |
-
* Class EddLicenseVO
|
10 |
-
* @package FernleafSystems\Wordpress\Services\Utilities\Licenses
|
11 |
* @property int $activations_left
|
12 |
* @property string $customer_email
|
13 |
* @property string $checksum
|
@@ -21,6 +19,7 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
21 |
* @property int $site_count
|
22 |
* @property string $license
|
23 |
* @property string $payment_id
|
|
|
24 |
* @property bool $success
|
25 |
* @property bool $is_staging
|
26 |
* @property bool $has_support
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
8 |
/**
|
|
|
|
|
9 |
* @property int $activations_left
|
10 |
* @property string $customer_email
|
11 |
* @property string $checksum
|
19 |
* @property int $site_count
|
20 |
* @property string $license
|
21 |
* @property string $payment_id
|
22 |
+
* @property string $url
|
23 |
* @property bool $success
|
24 |
* @property bool $is_staging
|
25 |
* @property bool $has_support
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Obfuscate.php
CHANGED
@@ -4,10 +4,6 @@ namespace FernleafSystems\Wordpress\Services\Utilities;
|
|
4 |
|
5 |
class Obfuscate {
|
6 |
|
7 |
-
/**
|
8 |
-
* @param string $email
|
9 |
-
* @return string
|
10 |
-
*/
|
11 |
public static function Email( string $email ) :string {
|
12 |
list( $left, $right ) = explode( '@', $email, 2 );
|
13 |
return substr( $left, 0, 1 ).'****'.substr( $left, -1, 1 )
|
4 |
|
5 |
class Obfuscate {
|
6 |
|
|
|
|
|
|
|
|
|
7 |
public static function Email( string $email ) :string {
|
8 |
list( $left, $right ) = explode( '@', $email, 2 );
|
9 |
return substr( $left, 0, 1 ).'****'.substr( $left, -1, 1 )
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/ServiceProviders.php
CHANGED
@@ -9,10 +9,6 @@ use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Services\
|
|
9 |
};
|
10 |
use FernleafSystems\Wordpress\Services\Utilities\Options\Transient;
|
11 |
|
12 |
-
/**
|
13 |
-
* Class ServiceProviders
|
14 |
-
* @package FernleafSystems\Wordpress\Services\Utilities
|
15 |
-
*/
|
16 |
class ServiceProviders {
|
17 |
|
18 |
/**
|
9 |
};
|
10 |
use FernleafSystems\Wordpress\Services\Utilities\Options\Transient;
|
11 |
|
|
|
|
|
|
|
|
|
12 |
class ServiceProviders {
|
13 |
|
14 |
/**
|
templates/twig/admin/user/profile/mfa/mfa_container.twig
DELETED
@@ -1,12 +0,0 @@
|
|
1 |
-
<div id="shield-options-mfa-authentication" class="shield-user-options-block">
|
2 |
-
<h3>{{ strings.title }}<small style="margin-left: 10px">({{ strings.provided_by }})</small></h3>
|
3 |
-
|
4 |
-
<table class="form-table">
|
5 |
-
<tbody>
|
6 |
-
{% for mfa_slug,mfa_row in mfa_rows %}
|
7 |
-
{{ mfa_row|raw }}
|
8 |
-
{% endfor %}
|
9 |
-
</tbody>
|
10 |
-
</table>
|
11 |
-
</div>
|
12 |
-
{% include '/admin/user/profile/mfa/mfa_dialog.twig' %}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
templates/twig/admin/user/profile/mfa/mfa_email.twig
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
height: 34px;
|
5 |
position: relative;
|
6 |
width: 60px;
|
7 |
-
margin: 20px;
|
8 |
}
|
9 |
.switch.disabled {
|
10 |
opacity: 0.5;
|
4 |
height: 34px;
|
5 |
position: relative;
|
6 |
width: 60px;
|
7 |
+
margin: 0 20px;
|
8 |
}
|
9 |
.switch.disabled {
|
10 |
opacity: 0.5;
|
templates/twig/components/options_form/main.twig
CHANGED
@@ -78,7 +78,7 @@
|
|
78 |
{% for section_notice in opt_section.notices %}
|
79 |
<div class="row">
|
80 |
<div class="col">
|
81 |
-
<div class="alert alert-
|
82 |
</div>
|
83 |
</div>
|
84 |
{% endfor %}
|
78 |
{% for section_notice in opt_section.notices %}
|
79 |
<div class="row">
|
80 |
<div class="col">
|
81 |
+
<div class="alert alert-info text-center">{{ section_notice|raw }}</div>
|
82 |
</div>
|
83 |
</div>
|
84 |
{% endfor %}
|
templates/twig/notices/plugin-mailing-list-signup.twig
CHANGED
@@ -3,12 +3,8 @@
|
|
3 |
{% block notice_body %}
|
4 |
<div class="row">
|
5 |
<div class="col">
|
6 |
-
{
|
7 |
-
|
8 |
-
</div>
|
9 |
-
<div class="row">
|
10 |
-
<div class="col">
|
11 |
-
{{ strings.summary }}
|
12 |
</div>
|
13 |
</div>
|
14 |
{% endblock %}
|
3 |
{% block notice_body %}
|
4 |
<div class="row">
|
5 |
<div class="col">
|
6 |
+
<p>{{ strings.summary }}</p>
|
7 |
+
<p><a class="button" target="_blank" href="{{ hrefs.form }}">{{ strings.yes }}</a></p>
|
|
|
|
|
|
|
|
|
8 |
</div>
|
9 |
</div>
|
10 |
{% endblock %}
|
templates/twig/user/profile/mfa/main.twig
CHANGED
@@ -1,6 +1,11 @@
|
|
1 |
<div id="ShieldUserProfileMFA">
|
2 |
|
3 |
-
<h3>
|
|
|
|
|
|
|
|
|
|
|
4 |
|
5 |
<table>
|
6 |
{% if flags.logged_in %}
|
1 |
<div id="ShieldUserProfileMFA">
|
2 |
|
3 |
+
<h3>
|
4 |
+
{{ strings.title }}
|
5 |
+
{% if strings.subtitle|default('') is not empty %}
|
6 |
+
<small style="margin-left: 10px">({{ strings.subtitle }})</small>
|
7 |
+
{% endif %}
|
8 |
+
</h3>
|
9 |
|
10 |
<table>
|
11 |
{% if flags.logged_in %}
|