Simple Google reCAPTCHA - Version 3.2

Version Description

  • Warning: Keys validation after save was not reliable, validation removed.
  • New: Added support for Google reCAPTCHA v3.
Download this release

Release Info

Developer Minor
Plugin Icon 128x128 Simple Google reCAPTCHA
Version 3.2
Comparing to
See all releases

Code changes from version 3.1 to 3.2

Files changed (5) hide show
  1. main.js +0 -6
  2. readme.txt +25 -19
  3. sgr.js +36 -0
  4. simple-google-recaptcha.php +140 -127
  5. uninstall.php +7 -6
main.js DELETED
@@ -1,6 +0,0 @@
1
- function sgr() {
2
- var recaptcha = document.getElementsByClassName("sgr-recaptcha");
3
- for (var i = 0; i < recaptcha.length; i++) {
4
- grecaptcha.render(recaptcha.item(i), {"sitekey" : sgr_recaptcha.site_key});
5
- }
6
- };
 
 
 
 
 
 
readme.txt CHANGED
@@ -1,44 +1,47 @@
1
  === Simple Google reCAPTCHA ===
2
  Contributors: Minor
3
- Tags: recaptcha, spam, block, captcha, bots, brute, force, protect, comments, secure, attack, registration, reset, form, buddypress, woocommerce, google
4
- Requires at least: 4.2
5
  Tested up to: 5.4
6
- Stable tag: 3.1
7
- Requires PHP: 5.6
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
  Donate link: https://www.paypal.me/NovaMi
11
 
12
- Simply protect your WordPress against spam comments and brute-force attacks thanks to Google reCAPTCHA v2 Checkbox for free and without ads!
13
 
14
  == Description ==
15
- Simple Google reCAPTCHA will protect your WordPress! No more spam comments and brute-force attacks against user accounts. Lightweight plugin - just few KBs to download and no ads! BuddyPress and WooCommerce support.
 
 
 
 
16
 
17
  = What is protected with reCAPTCHA? =
18
- * Comment form
19
- * New password form
20
- * Registration form
21
  * Login form
 
22
  * Reset password form
23
-
24
- reCAPTCHA verification will be required just for not registered users!
25
 
26
  = Thank you! =
27
- Thanks all of you, who are using this plugin. I really appreciate it! WordPress is amazing open-source software which I'm using for free (for business too) so this plugin is my way how to say thank you!
28
- If you write to me (on support center etc.) and expect an answer, be patient, please. I'm working on this plugin in my free time, it's my hobby.
29
 
 
30
 
31
  == Installation ==
32
- 1. Upload Simple Google reCAPTCHA files to the "/wp-content/plugins/simple-google-recaptcha" directory, or install Simple Google reCAPTCHA through the WordPress Plugins page directly.
33
- 2. Activate Simple Google reCAPTCHA through the WordPress Plugins page.
34
- 3. Use the menu Settings => reCAPTCHA to configure Simple Google reCAPTCHA. You have to insert reCAPTCHA v2 Checkbox keys.
 
35
 
36
  == Frequently Asked Questions ==
37
  = Why to install this plugin? =
38
- Just pure protection - no ads and any other unnecessary changes.
39
 
40
  = How to disable this plugin? =
41
- Just use standard Plugin overview page in WordPress admin section and deactivate it or rename plugin folder /wp-content/plugins/simple-google-recaptcha over FTP access.
42
 
43
  == Screenshots ==
44
  1. Simple Google reCAPTCHA - Add new comment form
@@ -48,6 +51,10 @@ Just use standard Plugin overview page in WordPress admin section and deactivate
48
  5. Simple Google reCAPTCHA - Settings
49
 
50
  == Changelog ==
 
 
 
 
51
  = 3.1 =
52
  * New: Keys validation after save.
53
  * New: More detailed error messages.
@@ -94,7 +101,6 @@ Just use standard Plugin overview page in WordPress admin section and deactivate
94
  * Bugfix: No more unnecessary loading reCAPTCHA on the other pages
95
  * Bugfix: No more reCAPTCHA window over Clef waves (if you are using Clef plugin) on the login page
96
 
97
-
98
  = 2.0 =
99
  * Warning: reCAPTCHA verification on the BuddyPress registration page has been removed
100
  * Warning: reCAPTCHA verification on the Add new comment form for logged in users has been removed
1
  === Simple Google reCAPTCHA ===
2
  Contributors: Minor
3
+ Tags: recaptcha, spam, captcha, protect, secure, registration, login, form, google, invisible, checkbox
4
+ Requires at least: 4.6
5
  Tested up to: 5.4
6
+ Stable tag: 3.2
7
+ Requires PHP: 7.0
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
  Donate link: https://www.paypal.me/NovaMi
11
 
12
+ Simply protect your WordPress against spam comments and brute-force attacks thanks to Google reCAPTCHA v3 or v2 Checkbox for free and without ads!
13
 
14
  == Description ==
15
+ Simple Google reCAPTCHA will protect your WordPress! You have choice between default v2 Checkbox and v3 (like invisible reCAPTCHA).
16
+
17
+ No more spam comments and brute-force attacks against user accounts. Small plugin, only necessary code - no ads or tracking!
18
+
19
+ Google reCAPTCHA verification will be required only for not logged in users.
20
 
21
  = What is protected with reCAPTCHA? =
 
 
 
22
  * Login form
23
+ * Registration form
24
  * Reset password form
25
+ * Comment form
26
+ * New password form
27
 
28
  = Thank you! =
29
+ Thanks all of you, who are using this plugin, I really appreciate it!
 
30
 
31
+ If you write me (on support forum etc.), be patient, please. I work on this plugin in my free time, it's only my hobby.
32
 
33
  == Installation ==
34
+ 1. Upload plugin folder under standard plugins directory "/wp-content/plugins/" or install through the WordPress Plugins page.
35
+ 2. Activate plugin via WordPress Plugins page.
36
+ 3. Insert reCAPTCHA v3 or v2 Checkbox keys.
37
+ 4. Done, your WordPress is protected now!
38
 
39
  == Frequently Asked Questions ==
40
  = Why to install this plugin? =
41
+ Just pure protection - no ads, no tracking and any other unnecessary changes.
42
 
43
  = How to disable this plugin? =
44
+ Use standard WordPress Plugins page. In emergency case, rename plugin folder under /wp-content/plugins/ over FTP access.
45
 
46
  == Screenshots ==
47
  1. Simple Google reCAPTCHA - Add new comment form
51
  5. Simple Google reCAPTCHA - Settings
52
 
53
  == Changelog ==
54
+ = 3.2 =
55
+ * Warning: Keys validation after save was not reliable, validation removed.
56
+ * New: Added support for Google reCAPTCHA v3.
57
+
58
  = 3.1 =
59
  * New: Keys validation after save.
60
  * New: More detailed error messages.
101
  * Bugfix: No more unnecessary loading reCAPTCHA on the other pages
102
  * Bugfix: No more reCAPTCHA window over Clef waves (if you are using Clef plugin) on the login page
103
 
 
104
  = 2.0 =
105
  * Warning: reCAPTCHA verification on the BuddyPress registration page has been removed
106
  * Warning: reCAPTCHA verification on the Add new comment form for logged in users has been removed
sgr.js ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ function sgr_2() {
2
+ console.log('SGR_2 loaded!');
3
+ let recaptcha = document.getElementsByClassName("sgr-recaptcha");
4
+ for (var i = 0; i < recaptcha.length; i++) {
5
+ grecaptcha.render(recaptcha.item(i), {"sitekey": sgr_recaptcha.site_key});
6
+ }
7
+ }
8
+
9
+ function sgr_3() {
10
+ console.log('SGR_3 loaded!');
11
+ grecaptcha.execute(sgr_recaptcha.site_key, {action: 'sgr_global'}).then(function (token) {
12
+ let recaptchaResponse = document.getElementById('sgr-response');
13
+ if (recaptchaResponse) {
14
+ recaptchaResponse.value = token;
15
+ }
16
+ });
17
+ }
18
+
19
+ document.addEventListener('DOMContentLoaded', function (event) {
20
+ let sgr_version = document.getElementById('sgr_version');
21
+
22
+ if (sgr_version) {
23
+ console.log('SGR admin loaded!');
24
+ sgr_version.addEventListener('change', removeKeys);
25
+
26
+ function removeKeys() {
27
+ let sgr_site_key = document.getElementById('sgr_site_key');
28
+ let sgr_secret_key = document.getElementById('sgr_secret_key');
29
+
30
+ if (sgr_site_key.value === sgr_recaptcha.site_key) {
31
+ sgr_site_key.value = '';
32
+ sgr_secret_key.value = '';
33
+ }
34
+ }
35
+ }
36
+ });
simple-google-recaptcha.php CHANGED
@@ -2,39 +2,52 @@
2
  /*
3
  * Plugin Name: Simple Google reCAPTCHA
4
  * Description: Simply protect your WordPress against spam comments and brute-force attacks, thanks to Google reCAPTCHA!
5
- * Version: 3.1
6
- * Author: Michal Nov&aacute;k
7
  * Author URI: https://www.novami.cz
8
  * License: GPL3
9
  * Text Domain: simple-google-recaptcha
10
- * Domain Path: /languages
11
  */
12
 
 
 
 
 
 
13
  /**
14
  * Class SimpleGoogleRecaptcha
15
  */
16
  class SimpleGoogleRecaptcha
17
  {
18
- const VERSION = '3.1';
19
- const TEXT_DOMAIN = 'simple-google-recaptcha';
20
 
21
- private $recaptcha_response;
 
 
 
 
 
 
22
 
23
  /**
24
  * SimpleGoogleRecaptcha constructor.
25
  */
26
  public function __construct()
27
  {
28
- if (!defined('ABSPATH')) {
29
- die('Direct access not allowed!');
30
- }
31
 
32
- add_action("wp_loaded", [$this, "sgr_check"]);
33
- add_filter(sprintf("plugin_action_links_%s", plugin_basename(__FILE__)), [$this, "sgr_add_plugin_action_links"]);
34
- add_action("activated_plugin", [$this, "sgr_activation"]);
35
- add_action("admin_menu", [$this, "sgr_menu"]);
36
- add_action("admin_init", [$this, "sgr_display_options"]);
37
- add_action("plugins_loaded", [$this, "load_language_sgr"]);
 
 
 
38
  }
39
 
40
  /**
@@ -43,105 +56,145 @@ class SimpleGoogleRecaptcha
43
  */
44
  public function sgr_add_plugin_action_links($links)
45
  {
46
- return array_merge(array("settings" => sprintf("<a href=\"options-general.php?page=sgr-options\">%s</a>", __("Settings", self::TEXT_DOMAIN))), $links);
47
  }
48
 
49
  public function sgr_activation($plugin)
50
  {
51
- if ($plugin == plugin_basename(__FILE__) && (!get_option("sgr_site_key") || !get_option("sgr_secret_key"))) {
52
- exit(wp_redirect(admin_url("options-general.php?page=sgr-options")));
53
  }
54
  }
55
 
56
  public function sgr_options_page()
57
  {
58
- echo sprintf("<div class=\"wrap\"><h1>%s</h1><form method=\"post\" action=\"options.php\">", __("Simple Google reCAPTCHA Options", self::TEXT_DOMAIN));
59
-
60
- settings_fields("sgr_header_section");
61
- do_settings_sections("sgr-options");
62
 
63
- $isKeysValid = $this->areKeysCorrect();
64
-
65
- if ($isKeysValid['valid'] === false) {
66
- echo sprintf("<div class=\"notice notice-error\"><p><strong>%s</strong> %s</p></div>", __("Warning:", self::TEXT_DOMAIN), $isKeysValid['message']);
67
- }
68
 
69
  submit_button();
70
 
71
- echo sprintf("</form>%s</div>", $this->messageDisablePluginViaFtp());
72
  }
73
 
74
  public function sgr_menu()
75
  {
76
- add_submenu_page("options-general.php", "reCAPTCHA", "reCAPTCHA", "manage_options", "sgr-options", [$this, "sgr_options_page"]);
 
77
  }
78
 
79
- public function sgr_display_content()
80
  {
81
- echo sprintf("<p>%s</p>", __("You have to <a href=\"https://www.google.com/recaptcha/admin\" rel=\"external\">register your domain</a> first, get required keys (reCAPTCHA V2 Checkbox) from Google and save them bellow.", self::TEXT_DOMAIN));
82
  }
83
 
84
- public function sgr_display_site_key_element()
85
  {
86
- $sgr_site_key = filter_var(get_option("sgr_site_key"), FILTER_SANITIZE_FULL_SPECIAL_CHARS);
87
- echo sprintf("<input type=\"text\" name=\"sgr_site_key\" class=\"regular-text\" id=\"sgr_site_key\" value=\"%s\" />", $sgr_site_key);
88
  }
89
 
90
- public function sgr_display_secret_key_element()
91
  {
92
- $sgr_secret_key = filter_var(get_option("sgr_secret_key"), FILTER_SANITIZE_FULL_SPECIAL_CHARS);
93
- echo sprintf("<input type=\"text\" name=\"sgr_secret_key\" class=\"regular-text\" id=\"sgr_secret_key\" value=\"%s\" />", $sgr_secret_key);
94
  }
95
 
96
- public function sgr_display_login_check_disable()
97
  {
98
- echo sprintf("<input type=\"checkbox\" name=\"sgr_login_check_disable\" id=\"sgr_login_check_disable\" value=\"1\" %s />", checked(1, get_option("sgr_login_check_disable"), false));
99
  }
100
 
101
  public function sgr_display_options()
102
  {
103
- add_settings_section("sgr_header_section", __("What first?", self::TEXT_DOMAIN), [$this, "sgr_display_content"], "sgr-options");
104
 
105
- add_settings_field("sgr_site_key", __("Site Key", self::TEXT_DOMAIN), [$this, "sgr_display_site_key_element"], "sgr-options", "sgr_header_section");
106
- add_settings_field("sgr_secret_key", __("Secret Key", self::TEXT_DOMAIN), [$this, "sgr_display_secret_key_element"], "sgr-options", "sgr_header_section");
107
- add_settings_field("sgr_login_check_disable", __("Disable reCAPTCHA for login", self::TEXT_DOMAIN), [$this, "sgr_display_login_check_disable"], "sgr-options", "sgr_header_section");
 
108
 
109
- register_setting("sgr_header_section", "sgr_site_key");
110
- register_setting("sgr_header_section", "sgr_secret_key");
111
- register_setting("sgr_header_section", "sgr_login_check_disable");
 
112
  }
113
 
114
- public function load_language_sgr()
115
  {
116
- load_plugin_textdomain(self::TEXT_DOMAIN, false, sprintf("%s/languages/", dirname(plugin_basename(__FILE__))));
 
 
 
 
 
117
  }
118
 
119
- public function frontend_sgr_script()
120
  {
121
- $sgr_site_key = filter_var(get_option("sgr_site_key"), FILTER_SANITIZE_FULL_SPECIAL_CHARS);
122
- $sgr_display_list = array("comment_form_after_fields", "register_form", "lost_password", "lostpassword_form", "retrieve_password", "resetpass_form", "woocommerce_register_form", "woocommerce_lostpassword_form", "woocommerce_after_order_notes", "bp_after_signup_profile_fields");
 
 
 
 
 
123
 
124
- if (!get_option("sgr_login_check_disable")) {
125
- array_push($sgr_display_list, "login_form", "woocommerce_login_form");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  }
127
 
 
 
128
  foreach ($sgr_display_list as $sgr_display) {
129
- add_action($sgr_display, [$this, "sgr_display"]);
 
130
  }
131
 
132
- wp_register_script("sgr_recaptcha_main", plugin_dir_url(__FILE__) . "main.js?v=" . self::VERSION);
133
- wp_enqueue_script("sgr_recaptcha_main");
134
- wp_localize_script("sgr_recaptcha_main", "sgr_recaptcha", array("site_key" => $sgr_site_key));
 
 
 
 
 
 
 
135
 
136
- wp_register_script("sgr_recaptcha", sprintf("https://www.google.com/recaptcha/api.js?hl=%s&onload=sgr&render=explicit", get_locale()));
137
- wp_enqueue_script("sgr_recaptcha");
138
 
139
- wp_enqueue_style("style", plugin_dir_url(__FILE__) . "style.css?v=" . self::VERSION);
140
  }
141
 
142
- public function sgr_display()
143
  {
144
- echo "<div class=\"sgr-recaptcha\"></div>";
145
  }
146
 
147
  public function errorMessage($error_code)
@@ -150,38 +203,34 @@ class SimpleGoogleRecaptcha
150
 
151
  switch ($error_code) {
152
  case 'missing-input-secret':
153
- $error_message = __("The secret parameter is missing.", self::TEXT_DOMAIN);
154
  break;
155
  case 'missing-input-response':
156
- $error_message = __("The response parameter is missing.", self::TEXT_DOMAIN);
157
  break;
158
  case 'invalid-input-secret':
159
- $error_message = __("The secret parameter is invalid or malformed.", self::TEXT_DOMAIN);
160
  break;
161
  case 'invalid-input-response':
162
- $error_message = __("The response parameter is invalid or malformed.", self::TEXT_DOMAIN);
163
  break;
164
  case 'bad-request':
165
- $error_message = __("The request is invalid or malformed.", self::TEXT_DOMAIN);
166
  break;
167
  case 'timeout-or-duplicate':
168
- $error_message = __("The response is no longer valid: either is too old or has been used previously.", self::TEXT_DOMAIN);
169
  break;
170
  }
171
 
172
  return $error_message;
173
  }
174
 
175
- /**
176
- * @return array|mixed
177
- */
178
  private function recaptchaResponse()
179
  {
180
- $sgr_secret_key = filter_var(get_option("sgr_secret_key"), FILTER_SANITIZE_FULL_SPECIAL_CHARS);
181
- $recaptcha_response = filter_input(INPUT_POST, "g-recaptcha-response", FILTER_SANITIZE_FULL_SPECIAL_CHARS);
182
- $response = (array)wp_remote_get("https://www.google.com/recaptcha/api/siteverify?secret={$sgr_secret_key}&response={$recaptcha_response}");
183
 
184
- return isset($response["body"]) ? json_decode($response["body"], 1) : ['success' => false, 'error-codes' => ['general-fail']];
185
  }
186
 
187
  /**
@@ -190,75 +239,39 @@ class SimpleGoogleRecaptcha
190
  */
191
  public function sgr_verify($input)
192
  {
193
- if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST["g-recaptcha-response"])) {
194
- $recaptcha_error_code = isset($this->recaptcha_response['error-codes'][0]) ? $this->recaptcha_response['error-codes'][0] : null;
 
 
195
  $error_message = $this->errorMessage($recaptcha_error_code);
196
 
197
- if ($this->recaptcha_response["success"]) {
198
  return $input;
199
  } elseif (is_array($input)) { // Array = Comment else Object
200
- wp_die(sprintf("<p><strong>%s</strong> %s %s</p>", __("ERROR:", self::TEXT_DOMAIN), __("Google reCAPTCHA verification failed.", self::TEXT_DOMAIN), $error_message), "reCAPTCHA", array("response" => 403, "back_link" => 1));
201
  } else {
202
- return new WP_Error("reCAPTCHA", sprintf("<strong>%s</strong> %s %s", __("ERROR:", self::TEXT_DOMAIN), __("Google reCAPTCHA verification failed.", self::TEXT_DOMAIN), $error_message));
203
  }
204
  } else {
205
- wp_die(sprintf("<p><strong>%s</strong> %s %s</p>", __("ERROR:", self::TEXT_DOMAIN), __("Google reCAPTCHA verification failed.", self::TEXT_DOMAIN), __("Do you have JavaScript enabled?", self::TEXT_DOMAIN)), "reCAPTCHA", array("response" => 403, "back_link" => 1));
206
  }
207
  }
208
 
209
- /**
210
- * @return array
211
- */
212
- private function areKeysCorrect()
213
  {
214
- $this->recaptcha_response = $this->recaptchaResponse();
215
-
216
- if (!get_option("sgr_site_key") || !get_option("sgr_secret_key")) {
217
- $status = [
218
- 'valid' => false,
219
- 'message' => __('You have to save reCAPTCHA keys v2 "I\'m not a robot" Checkbox first!', self::TEXT_DOMAIN)
220
- ];
221
- } elseif (isset($this->recaptcha_response['error-codes']) && in_array('invalid-input-secret', $this->recaptcha_response['error-codes'])) {
222
- $status = [
223
- 'valid' => false,
224
- 'message' => __('Saved keys are not valid! Did you really insert keys for reCAPTCHA v2 "I\'m not a robot" Checkbox?', self::TEXT_DOMAIN)
225
- ];
226
  } else {
227
- $status = [
228
- 'valid' => true,
229
- 'message' => __('Saved keys are correct, thank you!', self::TEXT_DOMAIN)
230
- ];
231
  }
232
-
233
- return $status;
234
- }
235
-
236
- public function messageDisablePluginViaFtp()
237
- {
238
- return sprintf("<div class=\"notice notice-info\"><p><strong>%s</strong> %s</p></div>", __("Notice:", self::TEXT_DOMAIN), __('Keep on mind, that in case of emergency, you can disable this plugin via FTP access, just rename the plugin folder.', self::TEXT_DOMAIN));
239
  }
240
 
241
  public function sgr_check()
242
  {
243
- if ($this->areKeysCorrect()['valid'] && !is_user_logged_in() && !function_exists("wpcf7_contact_form_shortcode")) {
244
- add_action("login_enqueue_scripts", [$this, "frontend_sgr_script"]);
245
- add_action("wp_enqueue_scripts", [$this, "frontend_sgr_script"]);
246
-
247
- $sgr_verify_list = array(
248
- "preprocess_comment",
249
- "registration_errors",
250
- "lostpassword_post",
251
- "resetpass_post",
252
- "woocommerce_register_post"
253
- );
254
-
255
- if (!get_option("sgr_login_check_disable")) {
256
- array_push($sgr_verify_list, "wp_authenticate_user", "bp_signup_validate");
257
- }
258
-
259
- foreach ($sgr_verify_list as $sgr_verify) {
260
- add_action($sgr_verify, [$this, "sgr_verify"]);
261
- }
262
  }
263
  }
264
  }
2
  /*
3
  * Plugin Name: Simple Google reCAPTCHA
4
  * Description: Simply protect your WordPress against spam comments and brute-force attacks, thanks to Google reCAPTCHA!
5
+ * Version: 3.2
6
+ * Author: Michal Novák
7
  * Author URI: https://www.novami.cz
8
  * License: GPL3
9
  * Text Domain: simple-google-recaptcha
 
10
  */
11
 
12
+ if (!defined('ABSPATH')) {
13
+ die('Direct access not allowed!');
14
+ }
15
+
16
+
17
  /**
18
  * Class SimpleGoogleRecaptcha
19
  */
20
  class SimpleGoogleRecaptcha
21
  {
22
+ const V2 = 'v2 "I\'m not a robot" Checkbox';
23
+ const V3 = 'v3';
24
 
25
+ private $pluginName;
26
+ private $version;
27
+ private $loginDisable;
28
+ private $siteKey;
29
+ private $secretKey;
30
+
31
+ private $recaptchaResponse;
32
 
33
  /**
34
  * SimpleGoogleRecaptcha constructor.
35
  */
36
  public function __construct()
37
  {
38
+ $this->pluginName = get_file_data(__FILE__, ['Name' => 'Plugin Name'])['Name'];
39
+ $this->version = (int)filter_var(get_option('sgr_version'), FILTER_SANITIZE_NUMBER_INT);
40
+ $this->loginDisable = (int)filter_var(get_option('sgr_login_disable'), FILTER_SANITIZE_NUMBER_INT);
41
 
42
+ $this->siteKey = filter_var(get_option('sgr_site_key'), FILTER_SANITIZE_FULL_SPECIAL_CHARS);
43
+ $this->secretKey = filter_var(get_option('sgr_secret_key'), FILTER_SANITIZE_FULL_SPECIAL_CHARS);
44
+
45
+ add_filter(sprintf('plugin_action_links_%s', plugin_basename(__FILE__)), [$this, 'sgr_add_plugin_action_links']);
46
+
47
+ add_action('activated_plugin', [$this, 'sgr_activation']);
48
+ add_action('admin_menu', [$this, 'sgr_menu']);
49
+ add_action('admin_init', [$this, 'sgr_display_options']);
50
+ add_action('wp_loaded', [$this, 'sgr_check']);
51
  }
52
 
53
  /**
56
  */
57
  public function sgr_add_plugin_action_links($links)
58
  {
59
+ return array_merge(['settings' => sprintf('<a href="options-general.php?page=sgr_options">%s</a>', __('Settings'))], $links);
60
  }
61
 
62
  public function sgr_activation($plugin)
63
  {
64
+ if ($plugin == plugin_basename(__FILE__) && (!$this->siteKey || !$this->secretKey)) {
65
+ exit(wp_redirect(admin_url('options-general.php?page=sgr_options')));
66
  }
67
  }
68
 
69
  public function sgr_options_page()
70
  {
71
+ echo sprintf('<div class="wrap"><h1>%s option</h1><form method="post" action="options.php">', $this->pluginName);
 
 
 
72
 
73
+ settings_fields('sgr_header_section');
74
+ do_settings_sections('sgr_options');
 
 
 
75
 
76
  submit_button();
77
 
78
+ echo sprintf('</form>%s</div>', $this->messageProtectionStatus());
79
  }
80
 
81
  public function sgr_menu()
82
  {
83
+ $this->sgr_enqueue_main();
84
+ add_submenu_page('options-general.php', $this->pluginName, 'Google reCAPTCHA', 'manage_options', 'sgr_options', [$this, 'sgr_options_page']);
85
  }
86
 
87
+ public function sgr_display_site_key_element()
88
  {
89
+ echo sprintf('<input type="text" name="sgr_site_key" class="regular-text" id="sgr_site_key" value="%s" />', $this->siteKey);
90
  }
91
 
92
+ public function sgr_display_secret_key_element()
93
  {
94
+ echo sprintf('<input type="text" name="sgr_secret_key" class="regular-text" id="sgr_secret_key" value="%s" />', $this->secretKey);
 
95
  }
96
 
97
+ public function sgr_display_version()
98
  {
99
+ echo sprintf('<input type="checkbox" name="sgr_version" id="sgr_version" value="3" %s />', checked(3, $this->version, false));
 
100
  }
101
 
102
+ public function sgr_display_login_disable()
103
  {
104
+ echo sprintf('<input type="checkbox" name="sgr_login_disable" id="sgr_login_disable" value="1" %s />', checked(1, $this->loginDisable, false));
105
  }
106
 
107
  public function sgr_display_options()
108
  {
109
+ add_settings_section('sgr_header_section', __('Google reCAPTCHA keys'), [], 'sgr_options');
110
 
111
+ add_settings_field('sgr_site_key', __('Site Key'), [$this, 'sgr_display_site_key_element'], 'sgr_options', 'sgr_header_section');
112
+ add_settings_field('sgr_secret_key', __('Secret Key'), [$this, 'sgr_display_secret_key_element'], 'sgr_options', 'sgr_header_section');
113
+ add_settings_field('sgr_login_disable', __('Disable on login form'), [$this, 'sgr_display_login_disable'], 'sgr_options', 'sgr_header_section');
114
+ add_settings_field('sgr_version', __('Enable reCAPTCHA v3'), [$this, 'sgr_display_version'], 'sgr_options', 'sgr_header_section');
115
 
116
+ register_setting('sgr_header_section', 'sgr_site_key');
117
+ register_setting('sgr_header_section', 'sgr_secret_key');
118
+ register_setting('sgr_header_section', 'sgr_login_disable');
119
+ register_setting('sgr_header_section', 'sgr_version');
120
  }
121
 
122
+ public function sgr_enqueue_main()
123
  {
124
+ $jsName = 'sgr.js';
125
+ $jsPath = sprintf('%s%s', plugin_dir_path(__FILE__), $jsName);
126
+ $jsVersion = filemtime($jsPath);
127
+
128
+ wp_enqueue_script('sgr_recaptcha_main', sprintf('%s%s', plugin_dir_url(__FILE__), $jsName), [], $jsVersion);
129
+ wp_localize_script('sgr_recaptcha_main', 'sgr_recaptcha', ['site_key' => $this->siteKey]);
130
  }
131
 
132
+ public function sgr_enqueue_scripts()
133
  {
134
+ $jsUrl = sprintf('https://www.google.com/recaptcha/api.js?hl=%s&onload=sgr_2&render=explicit', get_locale());
135
+ if ($this->version === 3) {
136
+ $jsUrl = sprintf('https://www.google.com/recaptcha/api.js?hl=%s&render=%s&onload=sgr_3', get_locale(), $this->siteKey);
137
+ }
138
+
139
+ wp_enqueue_script('sgr_recaptcha', $jsUrl);
140
+ }
141
 
142
+ public function sgr_frontend_script()
143
+ {
144
+ $this->sgr_enqueue_main();
145
+
146
+ $sgr_display_list = [
147
+ 'comment_form_after_fields',
148
+ 'register_form',
149
+ 'lost_password',
150
+ 'lostpassword_form',
151
+ 'retrieve_password',
152
+ 'resetpass_form',
153
+ 'woocommerce_register_form',
154
+ 'woocommerce_lostpassword_form',
155
+ 'woocommerce_after_order_notes',
156
+ 'bp_after_signup_profile_fields',
157
+ ];
158
+
159
+ $sgr_verify_list = [
160
+ 'preprocess_comment',
161
+ 'registration_errors',
162
+ 'lostpassword_post',
163
+ 'resetpass_post',
164
+ 'woocommerce_register_post'
165
+ ];
166
+
167
+ if (!$this->loginDisable) {
168
+ array_push($sgr_display_list, 'login_form', 'woocommerce_login_form');
169
+ array_push($sgr_verify_list, 'wp_authenticate_user', 'bp_signup_validate');
170
  }
171
 
172
+ $sgrDisplay = $this->version === 3 ? 'sgr3_display' : 'sgr_display';
173
+
174
  foreach ($sgr_display_list as $sgr_display) {
175
+ add_action($sgr_display, [$this, 'sgr_enqueue_scripts']);
176
+ add_action($sgr_display, [$this, $sgrDisplay]);
177
  }
178
 
179
+ foreach ($sgr_verify_list as $sgr_verify) {
180
+ add_action($sgr_verify, [$this, 'sgr_verify']);
181
+ }
182
+ }
183
+
184
+ public function sgr_display()
185
+ {
186
+ $cssName = 'style.css';
187
+ $cssPath = sprintf('%s%s', plugin_dir_path(__FILE__), $cssName);
188
+ $cssVersion = filemtime($cssPath);
189
 
190
+ wp_enqueue_style("style", sprintf('%s%s', plugin_dir_url(__FILE__), $cssName), [], $cssVersion);
 
191
 
192
+ echo '<div class="sgr-recaptcha"></div>';
193
  }
194
 
195
+ public function sgr3_display()
196
  {
197
+ echo '<input type="hidden" name="g-recaptcha-response" id="sgr-response">';
198
  }
199
 
200
  public function errorMessage($error_code)
203
 
204
  switch ($error_code) {
205
  case 'missing-input-secret':
206
+ $error_message = __('The secret parameter is missing.');
207
  break;
208
  case 'missing-input-response':
209
+ $error_message = __('The response parameter is missing.');
210
  break;
211
  case 'invalid-input-secret':
212
+ $error_message = __('The secret parameter is invalid or malformed.');
213
  break;
214
  case 'invalid-input-response':
215
+ $error_message = __('The response parameter is invalid or malformed.');
216
  break;
217
  case 'bad-request':
218
+ $error_message = __('The request is invalid or malformed.');
219
  break;
220
  case 'timeout-or-duplicate':
221
+ $error_message = __('The response is no longer valid: either is too old or has been used previously.');
222
  break;
223
  }
224
 
225
  return $error_message;
226
  }
227
 
 
 
 
228
  private function recaptchaResponse()
229
  {
230
+ $recaptchaResponse = filter_input(INPUT_POST, 'g-recaptcha-response', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
231
+ $response = (array)wp_remote_get(sprintf('https://www.google.com/recaptcha/api/siteverify?secret=%s&response=%s', $this->secretKey, $recaptchaResponse));
 
232
 
233
+ $this->recaptchaResponse = isset($response['body']) ? json_decode($response['body'], 1) : ['success' => false, 'error-codes' => ['general-fail']];
234
  }
235
 
236
  /**
239
  */
240
  public function sgr_verify($input)
241
  {
242
+ $this->recaptchaResponse();
243
+
244
+ if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['g-recaptcha-response'])) {
245
+ $recaptcha_error_code = isset($this->recaptchaResponse['error-codes'][0]) ? $this->recaptchaResponse['error-codes'][0] : null;
246
  $error_message = $this->errorMessage($recaptcha_error_code);
247
 
248
+ if ($this->recaptchaResponse['success']) {
249
  return $input;
250
  } elseif (is_array($input)) { // Array = Comment else Object
251
+ wp_die(sprintf('<p><strong>%s</strong> Google reCAPTCHA %s. %s</p>', __('Error:'), __('verification failed'), $error_message), 'reCAPTCHA', ['response' => 403, 'back_link' => 1]);
252
  } else {
253
+ return new WP_Error('reCAPTCHA', sprintf('<strong>%s</strong> Google reCAPTCHA %s. %s', __('Error:'), __('verification failed'), $error_message));
254
  }
255
  } else {
256
+ wp_die(sprintf('<p><strong>%s</strong> Google reCAPTCHA %s. %s</p>', __('Error:'), __('verification failed'), __('Do you have JavaScript enabled?')), 'reCAPTCHA', ['response' => 403, 'back_link' => 1]);
257
  }
258
  }
259
 
260
+ public function messageProtectionStatus()
 
 
 
261
  {
262
+ $type = $this->version === 3 ? self::V3 : self::V2;
263
+
264
+ if (!$this->siteKey || !$this->secretKey) {
265
+ return sprintf('<div class="notice notice-error"><p><strong>%s</strong> Google reCAPTCHA %s!</p><p>%s</p></div>', __('Warning:'), __('is disabled'), __(sprintf('You have to <a href="https://www.google.com/recaptcha/admin" rel="external">register your domain</a>, get required Google reCAPTCHA keys %s and save them bellow.', $type)));
 
 
 
 
 
 
 
 
266
  } else {
267
+ return sprintf('<div class="notice notice-warning"><p><strong>%s</strong> Google reCAPTCHA %s!</p><p>%s</p></div>', __('Notice:'), __('is enabled'), __('Keep on mind, that in case of emergency, you can disable this plugin via FTP access, just rename the plugin folder.'));
 
 
 
268
  }
 
 
 
 
 
 
 
269
  }
270
 
271
  public function sgr_check()
272
  {
273
+ if (!is_user_logged_in() && !wp_doing_ajax() && !function_exists('wpcf7_contact_form_shortcode') && $this->siteKey && $this->secretKey) {
274
+ $this->sgr_frontend_script();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
275
  }
276
  }
277
  }
uninstall.php CHANGED
@@ -1,5 +1,10 @@
1
  <?php
2
 
 
 
 
 
 
3
  /**
4
  * Class SimpleGoogleRecaptchaUninstall
5
  */
@@ -10,17 +15,13 @@ class SimpleGoogleRecaptchaUninstall
10
  */
11
  public function __construct()
12
  {
13
- if (!defined('WP_UNINSTALL_PLUGIN')) {
14
- die('Direct access not allowed');
15
- }
16
-
17
- $this->sgr_delete(array("site_key", "secret_key", "login_check_disable"));
18
  }
19
 
20
  private function sgr_delete($array)
21
  {
22
  foreach ($array as $item) {
23
- delete_option(sprintf("sgr_%s", $item));
24
  }
25
  }
26
  }
1
  <?php
2
 
3
+ if (!defined('WP_UNINSTALL_PLUGIN')) {
4
+ die('Direct access not allowed');
5
+ }
6
+
7
+
8
  /**
9
  * Class SimpleGoogleRecaptchaUninstall
10
  */
15
  */
16
  public function __construct()
17
  {
18
+ $this->sgr_delete(['site_key', 'secret_key', 'login_disable', 'version']);
 
 
 
 
19
  }
20
 
21
  private function sgr_delete($array)
22
  {
23
  foreach ($array as $item) {
24
+ delete_option(sprintf('sgr_%s', $item));
25
  }
26
  }
27
  }