PluginProbe
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent / 3.4.9
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent v3.4.9
3.5.4 3.5.3 3.5.2 3.5.1 3.4.9 3.5.0 3.4.8 3.4.7 trunk 2.3.1 3.3.6 3.3.7 3.3.8 3.3.9 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6
supportcandy / includes / admin / settings / miscellaneous-settings / class-wpsc-ms-recaptcha.php

class-wpsc-ms-recaptcha.php in SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent 3.4.9, at includes/admin/settings/miscellaneous-settings/class-wpsc-ms-recaptcha.php

470 lines 16.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit; // Exit if accessed directly!
4 }
5
6 if ( ! class_exists( 'WPSC_MS_Recaptcha' ) ) :
7
8 final class WPSC_MS_Recaptcha {
9
10 /**
11 * Initialize this class
12 *
13 * @return void
14 */
15 public static function init() {
16
17 // User interface.
18 add_action( 'wp_ajax_wpsc_get_ms_recaptcha', array( __CLASS__, 'load_settings_ui' ) );
19 add_action( 'wp_ajax_wpsc_set_ms_recaptcha', array( __CLASS__, 'save_settings' ) );
20 add_action( 'wp_ajax_wpsc_reset_ms_recaptcha', array( __CLASS__, 'reset_settings' ) );
21
22 // Print in create ticket form and my profile.
23 add_action( 'wpsc_print_tff', array( __CLASS__, 'print_tff' ), 9 );
24 add_action( 'wpsc_my_profile', array( __CLASS__, 'print_tff' ), 9 );
25
26 // TFF! validation.
27 add_action( 'wpsc_js_validate_ticket_form', array( __CLASS__, 'js_validate_ticket_form' ) );
28 }
29
30 /**
31 * Reset settings
32 *
33 * @return void
34 */
35 public static function reset() {
36
37 $recaptcha = apply_filters(
38 'wpsc_recaptcha_settings',
39 array(
40 'captcha-provider' => '0',
41 'recaptcha-version' => 3,
42 'recaptcha-site-key' => '',
43 'recaptcha-secret-key' => '',
44 'cloudflare-site-key' => '',
45 'cloudflare-secret-key' => '',
46 )
47 );
48 update_option( 'wpsc-recaptcha-settings', $recaptcha );
49 }
50
51 /**
52 * Settings user interface
53 *
54 * @return void
55 */
56 public static function load_settings_ui() {
57
58 if ( ! WPSC_Functions::is_site_admin() ) {
59 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
60 }
61 $settings = get_option( 'wpsc-recaptcha-settings', array() );?>
62
63 <form action="#" onsubmit="return false;" class="wpsc-frm-ms-recaptcha">
64 <div class="wpsc-dock-container">
65 <?php
66 printf(
67 /* translators: Click here to see the documentation */
68 esc_attr__( '%s to see the documentation!', 'supportcandy' ),
69 '<a href="https://supportcandy.net/docs/google-recaptcha/" target="_blank">' . esc_attr__( 'Click here', 'supportcandy' ) . '</a>'
70 );
71 ?>
72 </div>
73 <div class="wpsc-input-group">
74 <div class="label-container">
75 <label for="wpsc-captcha-provider"><?php esc_attr_e( 'CAPTCHA Provider', 'supportcandy' ); ?></label>
76 </div>
77 <select id="wpsc-captcha-provider" name="captcha-provider">
78 <option <?php selected( $settings['captcha-provider'], '0' ); ?> value="0"><?php esc_attr_e( 'Disable', 'supportcandy' ); ?></option>
79 <option <?php selected( $settings['captcha-provider'], 'google-recaptcha' ); ?> value="google-recaptcha"><?php esc_attr_e( 'Google reCAPTCHA', 'supportcandy' ); ?></option>
80 <option <?php selected( $settings['captcha-provider'], 'cloudflare-turnstile' ); ?> value="cloudflare-turnstile"><?php esc_attr_e( 'Cloudflare Turnstile', 'supportcandy' ); ?></option>
81 </select>
82 </div>
83 <div class="wpsc-input-group" id="wpsc-ms-recaptcha-version">
84 <div class="label-container">
85 <label for="wpsc-recaptcha-version"><?php esc_attr_e( 'reCaptcha version', 'supportcandy' ); ?></label>
86 </div>
87 <select id="wpsc-recaptcha-version" name="recaptcha-version">
88 <option <?php selected( $settings['recaptcha-version'], '2' ); ?> value="2">2</option>
89 <option <?php selected( $settings['recaptcha-version'], '3' ); ?> value="3">3</option>
90 </select>
91 </div>
92
93 <div class="wpsc-input-group" id="wpsc-ms-recaptcha-site-key">
94 <div class="label-container">
95 <label for="wpsc-recaptcha-site-key"><?php esc_attr_e( 'Site key', 'supportcandy' ); ?></label>
96 </div>
97 <input type="text" id="wpsc-recaptcha-site-key" name="recaptcha-site-key" value="<?php echo esc_attr( $settings['recaptcha-site-key'] ); ?>" autocomplete="off">
98 </div>
99 <div class="wpsc-input-group" id="wpsc-ms-recaptcha-secret-key">
100 <div class="label-container">
101 <label for="wpsc-recaptcha-secret-key"><?php esc_attr_e( 'Secret key', 'supportcandy' ); ?></label>
102 </div>
103 <input type="text" id="wpsc-recaptcha-secret-key" name="recaptcha-secret-key" value="<?php echo esc_attr( $settings['recaptcha-secret-key'] ); ?>" autocomplete="off">
104 </div>
105
106
107 <div class="wpsc-input-group" id="wpsc-ms-cloudflare-site-key">
108 <div class="label-container">
109 <label for="wpsc-cloudflare-site-key"><?php esc_attr_e( 'Site key', 'supportcandy' ); ?></label>
110 </div>
111 <input type="text" id="wpsc-cloudflare-site-key" name="cloudflare-site-key" value="<?php echo esc_attr( $settings['cloudflare-site-key'] ); ?>" autocomplete="off">
112 </div>
113 <div class="wpsc-input-group" id="wpsc-ms-cloudflare-secret-key">
114 <div class="label-container">
115 <label for="wpsc-cloudflare-secret-key"><?php esc_attr_e( 'Secret key', 'supportcandy' ); ?></label>
116 </div>
117 <input type="text" id="wpsc-cloudflare-secret-key" name="cloudflare-secret-key" value="<?php echo esc_attr( $settings['cloudflare-secret-key'] ); ?>" autocomplete="off">
118 </div>
119
120 <script>
121 jQuery( '#wpsc-captcha-provider' ).change( function() {
122
123 var provider = jQuery( this ).val();
124 if ( provider === 'google-recaptcha' ) {
125 jQuery( '#wpsc-ms-recaptcha-allow, #wpsc-ms-recaptcha-version, #wpsc-ms-recaptcha-site-key, #wpsc-ms-recaptcha-secret-key' ).show();
126 jQuery( '#wpsc-ms-cloudflare-site-key, #wpsc-ms-cloudflare-secret-key' ).hide();
127 } else if ( provider === 'cloudflare-turnstile' ) {
128 jQuery( '#wpsc-ms-recaptcha-allow, #wpsc-ms-recaptcha-version, #wpsc-ms-recaptcha-site-key, #wpsc-ms-recaptcha-secret-key' ).hide();
129 jQuery( '#wpsc-ms-cloudflare-site-key, #wpsc-ms-cloudflare-secret-key' ).show();
130 } else {
131 jQuery( '#wpsc-ms-recaptcha-allow, #wpsc-ms-recaptcha-version, #wpsc-ms-recaptcha-site-key, #wpsc-ms-recaptcha-secret-key' ).hide();
132 jQuery( '#wpsc-ms-cloudflare-site-key, #wpsc-ms-cloudflare-secret-key' ).hide();
133 }
134 } );
135 jQuery( '#wpsc-captcha-provider' ).trigger( 'change' );
136 </script>
137
138 <?php do_action( 'wpsc_ms_recaptcha' ); ?>
139 <input type="hidden" name="action" value="wpsc_set_ms_recaptcha">
140 <input type="hidden" name="_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wpsc_set_ms_recaptcha' ) ); ?>">
141 </form>
142 <div class="setting-footer-actions">
143 <button
144 class="wpsc-button normal primary margin-right"
145 onclick="wpsc_set_ms_recaptcha(this);">
146 <?php esc_attr_e( 'Submit', 'supportcandy' ); ?></button>
147 <button
148 class="wpsc-button normal secondary"
149 onclick="wpsc_reset_ms_recaptcha(this, '<?php echo esc_attr( wp_create_nonce( 'wpsc_reset_ms_recaptcha' ) ); ?>');">
150 <?php esc_attr_e( 'Reset default', 'supportcandy' ); ?></button>
151 </div>
152 <?php
153 wp_die();
154 }
155
156 /**
157 * Save settings
158 *
159 * @return void
160 */
161 public static function save_settings() {
162
163 if ( check_ajax_referer( 'wpsc_set_ms_recaptcha', '_ajax_nonce', false ) != 1 ) {
164 wp_send_json_error( 'Unauthorized request!', 401 );
165 }
166
167 if ( ! WPSC_Functions::is_site_admin() ) {
168 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
169 }
170
171 $captcha_provider = isset( $_POST['captcha-provider'] ) ? sanitize_text_field( wp_unslash( $_POST['captcha-provider'] ) ) : '0';
172 if ( ! in_array( $captcha_provider, array( 'google-recaptcha', 'cloudflare-turnstile', '0' ), true ) ) {
173 $captcha_provider = '0';
174 }
175
176 $recaptcha = apply_filters(
177 'wpsc_set_recaptcha',
178 array(
179 'captcha-provider' => $captcha_provider,
180 'recaptcha-version' => isset( $_POST['recaptcha-version'] ) ? intval( $_POST['recaptcha-version'] ) : '3',
181 'recaptcha-site-key' => isset( $_POST['recaptcha-site-key'] ) ? sanitize_text_field( wp_unslash( $_POST['recaptcha-site-key'] ) ) : '',
182 'recaptcha-secret-key' => isset( $_POST['recaptcha-secret-key'] ) ? sanitize_text_field( wp_unslash( $_POST['recaptcha-secret-key'] ) ) : '',
183 'cloudflare-site-key' => isset( $_POST['cloudflare-site-key'] ) ? sanitize_text_field( wp_unslash( $_POST['cloudflare-site-key'] ) ) : '',
184 'cloudflare-secret-key' => isset( $_POST['cloudflare-secret-key'] ) ? sanitize_text_field( wp_unslash( $_POST['cloudflare-secret-key'] ) ) : '',
185 )
186 );
187 update_option( 'wpsc-recaptcha-settings', $recaptcha );
188 wp_die();
189 }
190
191 /**
192 * Reset settings to default
193 *
194 * @return void
195 */
196 public static function reset_settings() {
197
198 if ( check_ajax_referer( 'wpsc_reset_ms_recaptcha', '_ajax_nonce', false ) != 1 ) {
199 wp_send_json_error( 'Unauthorized request!', 401 );
200 }
201
202 if ( ! WPSC_Functions::is_site_admin() ) {
203 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
204 }
205 self::reset();
206 wp_die();
207 }
208
209 /**
210 * Print ticket form field
211 *
212 * @return void
213 */
214 public static function print_tff() {
215
216 $recaptcha = get_option( 'wpsc-recaptcha-settings' );
217 if ( $recaptcha['captcha-provider'] === 'google-recaptcha' && $recaptcha['recaptcha-version'] == 2 && $recaptcha['recaptcha-site-key'] && $recaptcha['recaptcha-secret-key'] ) {
218 ?>
219 <script src="https://www.google.com/recaptcha/api.js" async defer></script> <?php // phpcs:ignore ?>
220 <div class="wpsc-tff recaptcha wpsc-xs-12 wpsc-sm-12 wpsc-md-12 wpsc-lg-12 required wpsc-visible" data-cft="recaptcha">
221 <div class="g-recaptcha" data-sitekey="<?php echo esc_attr( $recaptcha['recaptcha-site-key'] ); ?>"></div>
222 </div>
223 <?php
224 }
225 if ( $recaptcha['captcha-provider'] === 'google-recaptcha' && $recaptcha['recaptcha-version'] == 3 && $recaptcha['recaptcha-site-key'] && $recaptcha['recaptcha-secret-key'] ) {
226 ?>
227 <script src="https://www.google.com/recaptcha/api.js?render=<?php echo esc_attr( $recaptcha['recaptcha-site-key'] ); ?>"></script> <?php // phpcs:ignore ?>
228 <?php
229 }
230 if ( $recaptcha['captcha-provider'] === 'cloudflare-turnstile' && $recaptcha['cloudflare-site-key'] && $recaptcha['cloudflare-secret-key'] ) {
231 ?>
232 <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script> <?php // phpcs:ignore ?>
233 <div class="wpsc-tff turnstile wpsc-xs-12 wpsc-sm-12 wpsc-md-12 wpsc-lg-12 required wpsc-visible" data-cft="turnstile">
234 <div class="cf-turnstile" data-sitekey="<?php echo esc_attr( $recaptcha['cloudflare-site-key'] ); ?>"></div>
235 </div>
236 <script>
237 jQuery(document).ready(function() {
238
239 function wpscInitTurnstileWidgets() {
240
241 if (
242 typeof window.turnstile === 'undefined' ||
243 typeof window.turnstile.render !== 'function'
244 ) {
245 return false;
246 }
247
248 jQuery('.cf-turnstile').each(function() {
249
250 var widget = jQuery(this);
251
252 if (
253 widget.find('input[name="cf-turnstile-response"]').length ||
254 widget.find('iframe').length ||
255 widget.attr('data-wpsc-rendered') === '1'
256 ) {
257
258 widget.attr('data-wpsc-rendered', '1');
259
260 return;
261 }
262
263 window.turnstile.render(
264 this,
265 {
266 sitekey: widget.data('sitekey')
267 }
268 );
269
270 widget.attr('data-wpsc-rendered', '1');
271 });
272
273 return true;
274 }
275
276 if (wpscInitTurnstileWidgets()) {
277 return;
278 }
279
280 var attempts = 0;
281
282 var timer = setInterval(
283 function() {
284
285 attempts++;
286
287 if (
288 wpscInitTurnstileWidgets() ||
289 attempts > 50
290 ) {
291
292 clearInterval(timer);
293 }
294
295 },
296 100
297 );
298
299 });
300 </script>
301 <?php
302 }
303 }
304
305 /**
306 * Validate this type field in create ticket
307 *
308 * @return void
309 */
310 public static function js_validate_ticket_form() {
311
312 $recaptcha = get_option( 'wpsc-recaptcha-settings' );
313 if ( $recaptcha['captcha-provider'] === 'google-recaptcha' && $recaptcha['recaptcha-version'] == 2 && $recaptcha['recaptcha-site-key'] && $recaptcha['recaptcha-secret-key'] ) :
314 ?>
315 case 'recaptcha':
316 var recaptcha = jQuery("#g-recaptcha-response").val();
317 if (recaptcha === "") {
318 isValid = false;
319 }
320 break;
321 <?php
322 echo PHP_EOL;
323 endif;
324
325 if ( $recaptcha['captcha-provider'] === 'cloudflare-turnstile' && $recaptcha['cloudflare-site-key'] && $recaptcha['cloudflare-secret-key'] ) :
326 ?>
327 case 'turnstile':
328 var turnstile = jQuery("[name='cf-turnstile-response']").val();
329 if (turnstile === "") {
330 isValid = false;
331 alert("<?php esc_attr_e( 'Security verification failed. Please refresh the page and try again.', 'supportcandy' ); ?>");
332 }
333 break;
334 <?php
335 echo PHP_EOL;
336 endif;
337 }
338
339 /**
340 * Check whether captcha is valid or not.
341 * No need of nonce varification as we already done this where it is called from.
342 *
343 * @param string $action - action string.
344 * @return void
345 */
346 public static function validate( $action = '' ) {
347
348 $server_http_host = isset( $_SERVER['HTTP_HOST'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) : '';
349
350 $recaptcha = get_option( 'wpsc-recaptcha-settings' );
351 if ( $recaptcha['captcha-provider'] === 'google-recaptcha' && $recaptcha['recaptcha-version'] == 2 && $recaptcha['recaptcha-site-key'] && $recaptcha['recaptcha-secret-key'] ) {
352
353 $recaptcha_token = isset( $_POST['g-recaptcha-response'] ) ? sanitize_text_field( wp_unslash( $_POST['g-recaptcha-response'] ) ) : ''; // phpcs:ignore
354 if ( ! $recaptcha_token ) {
355 wp_send_json_error( new WP_Error( '001', 'Recaptcha token not set' ), 400 );
356 }
357
358 $url = 'https://www.google.com/recaptcha/api/siteverify';
359 $response = wp_remote_post(
360 $url,
361 array(
362 'method' => 'POST',
363 'body' => array(
364 'secret' => $recaptcha['recaptcha-secret-key'],
365 'response' => $recaptcha_token,
366 ),
367 )
368 );
369
370 if (
371 is_wp_error( $response ) ||
372 $response['response']['code'] != 200
373 ) {
374 wp_send_json_error( new WP_Error( '002', 'Something went wrong with recaptcha!' ), 400 );
375 }
376
377 $response = json_decode( $response['body'] );
378 if ( ! (
379 $response->success &&
380 $response->hostname == $server_http_host
381 ) ) {
382 wp_send_json_error( new WP_Error( '003', 'Invalid recaptcha!' ), 400 );
383 }
384 } elseif ( $recaptcha['captcha-provider'] === 'google-recaptcha' && $recaptcha['recaptcha-version'] == 3 && $recaptcha['recaptcha-site-key'] && $recaptcha['recaptcha-secret-key'] ) {
385
386 $recaptcha_token = isset( $_POST['g-recaptcha-response'] ) ? sanitize_text_field( wp_unslash( $_POST['g-recaptcha-response'] ) ) : ''; // phpcs:ignore
387 if ( ! $recaptcha_token ) {
388 wp_send_json_error( new WP_Error( '001', 'Recaptcha token not set' ), 400 );
389 }
390
391 $url = 'https://www.google.com/recaptcha/api/siteverify';
392 $response = wp_remote_post(
393 $url,
394 array(
395 'method' => 'POST',
396 'body' => array(
397 'secret' => $recaptcha['recaptcha-secret-key'],
398 'response' => $recaptcha_token,
399 ),
400 )
401 );
402
403 if (
404 is_wp_error( $response ) ||
405 $response['response']['code'] != 200
406 ) {
407 wp_send_json_error( new WP_Error( '002', 'Something went wrong with recaptcha!' ), 400 );
408 }
409
410 $response = json_decode( $response['body'] );
411 if ( ! (
412 $response->success &&
413 $response->action == $action &&
414 $response->hostname == $server_http_host
415 ) ) {
416 wp_send_json_error( new WP_Error( '003', 'Invalid recaptcha!' ), 400 );
417 }
418 } elseif ( $recaptcha['captcha-provider'] === 'cloudflare-turnstile' && $recaptcha['cloudflare-site-key'] && $recaptcha['cloudflare-secret-key'] ) {
419
420 $server_http_host = isset( $_SERVER['HTTP_HOST'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) : '';
421 $turnstile_token = isset( $_POST['cf-turnstile-response'] ) ? sanitize_text_field( wp_unslash( $_POST['cf-turnstile-response'] ) ) : ''; // phpcs:ignore
422 $url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
423 $response = wp_remote_post(
424 $url,
425 array(
426 'method' => 'POST',
427 'timeout' => 20,
428 'body' => array(
429 'secret' => $recaptcha['cloudflare-secret-key'],
430 'response' => $turnstile_token,
431 'remoteip' => $_SERVER['REMOTE_ADDR'] ?? '', // phpcs:ignore
432 ),
433 )
434 );
435
436 if (
437 is_wp_error( $response ) ||
438 wp_remote_retrieve_response_code( $response ) !== 200
439 ) {
440
441 wp_send_json_error(
442 new WP_Error(
443 '002',
444 'Something went wrong with captcha!'
445 ),
446 400
447 );
448 }
449
450 $response = json_decode(
451 wp_remote_retrieve_body( $response )
452 );
453
454 if ( empty( $response->success ) ) {
455
456 wp_send_json_error(
457 new WP_Error(
458 '003',
459 'Invalid captcha!'
460 ),
461 400
462 );
463 }
464 }
465 }
466 }
467 endif;
468
469 WPSC_MS_Recaptcha::init();
470