PluginProbe
User Profile Builder – Beautiful User Registration Forms, User Profiles & User Role Editor / 3.16.3
User Profile Builder – Beautiful User Registration Forms, User Profiles & User Role Editor v3.16.3
4.0.3 4.0.2 4.0.1 4.0.0 3.16.6 3.16.5 3.16.4 3.16.3 3.16.2 3.16.1 3.16.0 3.15.9 3.9.9 3.9.5 3.9.6 3.9.7 3.9.8 1.1.7 1.1.8 1.1.9 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 All 341 releases
profile-builder / front-end / default-fields / turnstile / turnstile.php

turnstile.php in User Profile Builder – Beautiful User Registration Forms, User Profiles & User Role Editor 3.16.3, at front-end/default-fields/turnstile/turnstile.php

640 lines 30.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
3
4 /**
5 * Submits an HTTP POST to the Turnstile siteverify server.
6 * Turnstile requires POST, unlike reCAPTCHA which historically allowed GET.
7 *
8 * @param string $path
9 * @param array $data
10 */
11 function _wppb_turnstile_submitHTTPPost($path, $data)
12 {
13 $response = wp_remote_post( $path, array(
14 'body' => $data
15 ) );
16
17 if ( ! is_wp_error( $response ) )
18 return $response["body"];
19 }
20
21 /**
22 * Gets the challenge HTML wrapper for Turnstile.
23 *
24 * @param string $pubkey A public key for Turnstile
25 * @param string $form_name The name of the form
26 *
27 * @return string - The HTML to be embedded in the user's form.
28 */
29 function wppb_turnstile_get_html ( $pubkey, $form_name='' ){
30 global $wppb_turnstile_forms; // is the counter for the number of forms that have turnstile so we always have unique ids on the element
31 if( is_null( $wppb_turnstile_forms ) )
32 $wppb_turnstile_forms = 0;
33 $wppb_turnstile_forms++;
34
35 if ( empty($pubkey) )
36 echo '<span class="error">'. esc_html__("To use Cloudflare Turnstile you must get a Site Key from", "profile-builder"). " <a href='https://dash.cloudflare.com/?to=/:account/turnstile'>https://dash.cloudflare.com/?to=/:account/turnstile</a></span><br/><br/>";
37
38 $field = wppb_get_turnstile_field();
39 $theme = isset( $field['theme'] ) ? esc_attr( sanitize_text_field( $field['theme'] ) ) : 'auto';
40
41 $output = '<div id="wppb-turnstile-element-'.$form_name.$wppb_turnstile_forms.'" class="wppb-turnstile-element cf-turnstile" data-wppb-sitekey="'.esc_attr( $pubkey ).'" data-wppb-theme="'.$theme.'"></div>';
42
43 // We add a hidden field so we can easily check if Turnstile should be processed on this form
44 $output .= '<input type="hidden" name="wppb-turnstile-present" value="1">';
45
46 if( $form_name == 'pb_login' ) {
47 add_filter( 'wppb_login_submit_button_extra_attributes', 'wppb_turnstile_login_submit_button_extra_attributes' );
48 }
49
50 return $output;
51 }
52
53 /**
54 * Add disabled attribute to login form submit button when Turnstile is used.
55 * Prevent form submission before the script is loaded and a token is received.
56 *
57 * @param string $attributes
58 * @return string
59 */
60 function wppb_turnstile_login_submit_button_extra_attributes( $attributes ) {
61 return $attributes . ' disabled="disabled"';
62 }
63
64 /**
65 * Add Turnstile scripts to both front-end PB forms as well as Default WP forms
66 */
67 function wppb_turnstile_script_footer(){
68 $field = wppb_get_turnstile_field();
69 /* if we do not have a turnstile field do nothing */
70 if( empty( $field ) )
71 return;
72
73 //do not add script if there is no shortcode
74 global $wppb_shortcode_on_front;
75 if( current_filter() == 'wp_footer' && ( !isset( $wppb_shortcode_on_front ) || $wppb_shortcode_on_front === false ) )
76 return;
77
78 //do not add script if the html for the field has not been added
79 global $wppb_turnstile_present;
80 if( !isset( $wppb_turnstile_present ) || $wppb_turnstile_present === false )
81 return;
82
83 //we don't have jquery on the backend
84 if( current_filter() != 'wp_footer' ) {
85 wp_print_scripts('jquery');
86 }else if(!wp_script_is('jquery')){
87 wp_print_scripts('jquery');
88 }
89
90 //get site key
91 $pubkey = '';
92 if( isset( $field['turnstile-site-key'] ) ) {
93 $pubkey = sanitize_text_field( $field['turnstile-site-key'] );
94 }
95
96 $theme = isset( $field['theme'] ) ? sanitize_text_field( $field['theme'] ) : 'auto';
97
98 // phpcs:disable
99 echo '
100 <script>
101 window.wppbTurnstileCallbackExecuted = false;
102
103 var wppbTurnstileCallback = function() {
104 if( !window.wppbTurnstileCallbackExecuted ){
105 let $elements = jQuery(".wppb-turnstile-element");
106
107 $elements.each(function(){
108 let $turnstileElement = jQuery(this);
109
110 if ( typeof $turnstileElement.data("wppb-turnstile-id") !== "undefined" ) {
111 turnstile.reset( $turnstileElement.data("wppb-turnstile-id") );
112 return;
113 }
114
115 let widgetId = turnstile.render(
116 "#" + $turnstileElement.attr("id"),
117 {
118 "sitekey" : "' . $pubkey . '",
119 "theme": "' . $theme . '"
120 }
121 )
122
123 $turnstileElement.data("wppb-turnstile-id", widgetId);
124 });
125
126 window.wppbTurnstileCallbackExecuted = true;
127
128 // Enable login form submit button initially as Turnstile handles its own disabled state or we wait for callback
129 if( jQuery("#wppb-loginform input[type=submit]").length > 0 ) {
130 jQuery("#wppb-loginform input[type=submit]").attr("disabled", false);
131 }
132 }
133 };
134 </script>';
135 // phpcs:enable
136
137 echo '<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?onload=wppbTurnstileCallback&render=explicit" async defer></script>';
138 echo '<script>
139 /* compatibility with other plugins that may include Turnstile with an onload callback. if their script loads first then our callback will not execute so call it explicitly */
140 jQuery( window ).on( "load", function() {
141 wppbTurnstileCallback();
142 });
143 </script>';
144
145 }
146 add_action('wp_footer', 'wppb_turnstile_script_footer', 9999);
147 add_action('login_footer', 'wppb_turnstile_script_footer');
148 add_action('register_form', 'wppb_turnstile_script_footer');
149 add_action('lost_password', 'wppb_turnstile_script_footer');
150
151 /**
152 * A wppb_TurnstileResponse is returned from wppb_turnstile_check_answer()
153 */
154 class wppb_TurnstileResponse {
155 var $is_valid;
156 }
157
158 /**
159 * Calls an HTTP POST function to verify if the user\'s answer was correct
160 * @param string $privkey
161 * @param string $remoteip
162 * @param string $response
163 * @return wppb_TurnstileResponse
164 */
165 function wppb_turnstile_check_answer ( $privkey, $remoteip, $response ) {
166
167 if ( $remoteip == null || $remoteip == '' )
168 echo '<span class="error">'. esc_html__("For security reasons, you must pass the remote ip to Turnstile!", "profile-builder") .'</span><br/><br/>';
169
170 // Discard empty solution submissions
171 if ($response == null || strlen($response) == 0) {
172 $turnstileResponse = new wppb_TurnstileResponse();
173 $turnstileResponse->is_valid = false;
174
175 return $turnstileResponse;
176 }
177
178 $getResponse = _wppb_turnstile_submitHTTPPost(
179 "https://challenges.cloudflare.com/turnstile/v0/siteverify",
180 array (
181 'secret' => $privkey,
182 'remoteip' => $remoteip,
183 'response' => $response
184 )
185 );
186
187 $answers = json_decode($getResponse, true);
188 $turnstileResponse = new wppb_TurnstileResponse();
189
190 if (trim($answers ['success']) == true) {
191 $turnstileResponse->is_valid = true;
192 } else {
193 $turnstileResponse->is_valid = false;
194 }
195
196 return $turnstileResponse;
197
198 }
199
200 /* the function to validate the Turnstile response with the API */
201 function wppb_validate_turnstile_response( $publickey, $privatekey ){
202 /* If the Turnstile keys are not configured the widget cannot work for anyone, so do not enforce -
203 otherwise an incomplete setup would lock every visitor out of the form. These keys are admin-side
204 configuration, not attacker controlled, so this cannot be used to bypass a properly configured Turnstile. */
205 if ( empty( $publickey ) || empty( $privatekey ) ) {
206 return true;
207 }
208
209 if (isset($_POST['cf-turnstile-response'])){
210 $turnstile_response_field = sanitize_textarea_field( $_POST['cf-turnstile-response'] );
211 } else {
212 $turnstile_response_field = '';
213 }
214
215 $already_validated = false;
216 $saved = get_option( 'wppb_turnstile_validations', array() );
217
218 if( isset( $saved[ $turnstile_response_field ] ) && $saved[ $turnstile_response_field ] == true ){
219 $already_validated = true;
220
221 if( !wp_doing_ajax() ){
222 unset( $saved[ $turnstile_response_field ] );
223 update_option( 'wppb_turnstile_validations', $saved, false );
224 }
225 }
226
227 if( !$already_validated ){
228
229 if( isset( $_SERVER["REMOTE_ADDR"] ) ){
230 $resp = wppb_turnstile_check_answer($privatekey, sanitize_text_field( $_SERVER["REMOTE_ADDR"] ), $turnstile_response_field );
231
232 if( isset( $resp ) ){
233 $already_validated = ( ( !$resp->is_valid ) ? false : true );
234 }
235 }
236
237 }
238
239 // Save valid results when they are being triggered from an ajax request
240 if( wp_doing_ajax() && isset( $_POST['action'] ) && $_POST['action'] == 'pms_validate_checkout' ){
241
242 $saved = get_option( 'wppb_turnstile_validations', array() );
243
244 if( $already_validated === true )
245 $saved[ $turnstile_response_field ] = true;
246
247 update_option( 'wppb_turnstile_validations', $saved, false );
248
249 }
250
251 return $already_validated;
252
253 }
254
255 /* the function to add Turnstile to the registration form of PB */
256 function wppb_turnstile_handler ( $output, $form_location, $field, $user_id, $field_check_errors, $request_data ){
257 if ( $field['field'] == 'Turnstile' ){
258 $item_title = apply_filters( 'wppb_'.$form_location.'_turnstile_custom_field_'.$field['id'].'_item_title', wppb_icl_t( 'plugin profile-builder-pro', 'custom_field_'.$field['id'].'_title_translation', $field['field-title'], true ) );
259 $item_description = wppb_icl_t( 'plugin profile-builder-pro', 'custom_field_'.$field['id'].'_description_translation', $field['description'], true );
260
261 wppb_turnstile_set_default_values();
262
263 if ( ($form_location == 'register') && ( isset($field['turnstile-pb-forms']) ) && ( strpos($field['turnstile-pb-forms'],'pb_register') !== false ) ) {
264 $error_mark = ( ( $field['required'] == 'Yes' ) ? '<span class="wppb-required" title="'.wppb_required_field_error($field["field-title"]).'">*</span>' : '' );
265
266 global $wppb_turnstile_present;
267 $wppb_turnstile_present = true;
268
269 if ( array_key_exists( $field['id'], $field_check_errors ) )
270 $error_mark = '<img src="'.WPPB_PLUGIN_URL.'assets/images/pencil_delete.png" title="'.wppb_required_field_error($field["field-title"]).'"/>';
271
272 $publickey = trim( $field['turnstile-site-key'] );
273 $privatekey = trim( $field['turnstile-secret-key'] );
274
275 if ( empty( $publickey ) || empty( $privatekey ) )
276 return '<span class="custom_field_turnstile_error_message" id="'.$field['meta-name'].'_error_message">'.apply_filters( 'wppb_'.$form_location.'_turnstile_custom_field_'.$field['id'].'_error_message', __("To use Cloudflare Turnstile you must get a Site Key and Secret Key from:", "profile-builder"). '<a href="https://dash.cloudflare.com/?to=/:account/turnstile">https://dash.cloudflare.com/?to=/:account/turnstile</a>' ).'</span>';
277
278 $output = '<label for="turnstile_response_field">' . $item_title . $error_mark . '</label>' . wppb_turnstile_get_html($publickey, 'pb_register');
279 if (!empty($item_description))
280 $output .= '<span class="wppb-description-delimiter">' . $item_description . '</span>';
281
282 return $output;
283
284 }
285 }
286 }
287 add_filter( 'wppb_output_form_field_turnstile', 'wppb_turnstile_handler', 10, 6 );
288
289 /* handle Turnstile field validation on PB Register form */
290 function wppb_check_turnstile_value( $message, $field, $request_data, $form_location ){
291 if( $field['field'] == 'Turnstile' ){
292 if ( ( $form_location == 'register' ) && ( isset($field['turnstile-pb-forms']) ) && ( strpos($field['turnstile-pb-forms'],'pb_register') !== false ) ) {
293 /* theme my login plugin executes the register_errors hook on the frontend on all pages so on our register forms we might have already a turnstile response
294 so do not verify it again or it will fail */
295 global $wppb_turnstile_response;
296 if (!isset($wppb_turnstile_response)){
297 $wppb_turnstile_response = wppb_validate_turnstile_response( trim( $field['turnstile-site-key'] ), trim( $field['turnstile-secret-key'] ) );
298 }
299 /* Turnstile must fail closed: whenever it is configured to display on this form it has to be
300 verified, regardless of the "required" toggle. A missing/empty token makes
301 wppb_validate_turnstile_response() return false, so bots that omit cf-turnstile-response are blocked. */
302 if ( $wppb_turnstile_response == false ){
303 return __('Cloudflare Turnstile could not be verified. Please try again.', 'profile-builder');
304 }
305 }
306 }
307 return $message;
308 }
309 add_filter( 'wppb_check_form_field_turnstile', 'wppb_check_turnstile_value', 10, 4 );
310
311 // Get the Turnstile field information
312 function wppb_get_turnstile_field(){
313 $wppb_manage_fields = get_option( 'wppb_manage_fields', 'not_found' );
314 $field = array();
315 if ( $wppb_manage_fields != 'not_found' ) {
316 foreach ($wppb_manage_fields as $value) {
317 if ($value['field'] == 'Turnstile'){
318 $field = $value;
319 break;
320 }
321 }
322 }
323 return $field;
324 }
325
326 /* Display Turnstile on PB Recover Password form */
327 function wppb_display_turnstile_recover_password( $output ){
328 $field = wppb_get_turnstile_field();
329
330 if ( !empty($field) ) {
331 $publickey = trim($field['turnstile-site-key']);
332 $item_title = apply_filters('wppb_recover_password_turnstile_custom_field_' . $field['id'] . '_item_title', wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_title_translation', $field['field-title'], true));
333 $item_description = wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_description_translation', $field['description'], true);
334
335 // check where Turnstile should display and add Turnstile html
336 if ( isset($field['turnstile-pb-forms']) && ( strpos( $field['turnstile-pb-forms'],'pb_recover_password' ) !== false ) ) {
337
338 global $wppb_turnstile_present;
339 $wppb_turnstile_present = true;
340
341 $turnstile_output = '<label for="turnstile_response_field">' . $item_title . '</label>' . wppb_turnstile_get_html($publickey, 'pb_recover_password');
342 if (!empty($item_description))
343 $turnstile_output .= '<span class="wppb-description-delimiter">' . $item_description . '</span>';
344
345 $output = str_replace('</ul>', '<li class="wppb-form-field wppb-turnstile">' . $turnstile_output . '</li>' . '</ul>', $output);
346 }
347 }
348 return $output;
349 }
350 add_filter('wppb_recover_password_generate_password_input','wppb_display_turnstile_recover_password');
351
352 /* Function that changes the messageNo from the Recover Password form */
353 function wppb_turnstile_change_recover_password_message_no($messageNo) {
354
355 if (isset($_REQUEST['action']) && $_REQUEST['action'] === 'recover_password') {
356 $field = wppb_get_turnstile_field();
357 if (!empty($field)) {
358
359 global $wppb_turnstile_response;
360 if (!isset($wppb_turnstile_response)) $wppb_turnstile_response = wppb_validate_turnstile_response( trim( $field['turnstile-site-key'] ), trim( $field['turnstile-secret-key'] ) );
361
362 if ( isset($field['turnstile-pb-forms']) && (strpos($field['turnstile-pb-forms'], 'pb_recover_password') !== false) ) {
363
364 if ( $wppb_turnstile_response == false )
365 $messageNo = '';
366 }
367 }
368 }
369
370 return $messageNo;
371 }
372 add_filter('wppb_recover_password_message_no', 'wppb_turnstile_change_recover_password_message_no');
373
374 /* Function that adds the Turnstile error message on the Recover Password form */
375 function wppb_turnstile_recover_password_displayed_message1( $message ) {
376 $field = wppb_get_turnstile_field();
377
378 if ( !empty($field) ){
379 global $wppb_turnstile_response;
380 if (!isset($wppb_turnstile_response)) $wppb_turnstile_response = wppb_validate_turnstile_response( trim( $field['turnstile-site-key'] ), trim( $field['turnstile-secret-key'] ) );
381
382 if ( isset($field['turnstile-pb-forms']) && ( strpos( $field['turnstile-pb-forms'],'pb_recover_password' ) !== false ) && ( $wppb_turnstile_response == false )) {
383
384 $turnstile_error_message = __('Cloudflare Turnstile could not be verified. Please try again.', 'profile-builder');
385
386 if (($message == '<p class="wppb-warning">wppb_turnstile_error</p>') || ($message == '<p class="wppb-warning">wppb_captcha_error</p>'))
387 $message = '<p class="wppb-warning">' . $turnstile_error_message . '</p>';
388 else
389 $message = $message . '<p class="wppb-warning">' . $turnstile_error_message . '</p>';
390
391 }
392 }
393
394 return $message;
395 }
396 add_filter('wppb_recover_password_displayed_message1', 'wppb_turnstile_recover_password_displayed_message1');
397
398 /* Function that changes the default success message to wppb_turnstile_error if it doesn't validate */
399 function wppb_turnstile_recover_password_sent_message_1($message) {
400
401 if (isset($_REQUEST['action']) && $_REQUEST['action'] === 'recover_password') {
402 $field = wppb_get_turnstile_field();
403
404 if (!empty($field)) {
405 global $wppb_turnstile_response;
406 if (!isset($wppb_turnstile_response)) $wppb_turnstile_response = wppb_validate_turnstile_response( trim( $field['turnstile-site-key'] ), trim( $field['turnstile-secret-key'] ) );
407
408 if ( isset($field['turnstile-pb-forms']) && ( strpos($field['turnstile-pb-forms'], 'pb_recover_password') !== false ) && ( $wppb_turnstile_response == false ) ){
409 $message = 'wppb_turnstile_error';
410 }
411 }
412
413 }
414
415 return $message;
416 }
417 add_filter('wppb_recover_password_sent_message1', 'wppb_turnstile_recover_password_sent_message_1');
418
419 /* Display Turnstile html on PB Login form */
420 function wppb_display_turnstile_login_form($form_part, $args) {
421
422 if( !isset( $args['form_id'] ) || $args['form_id'] != 'wppb-loginform' )
423 return $form_part;
424
425 $field = wppb_get_turnstile_field();
426
427 if ( !empty($field) ) {
428 $item_title = apply_filters('wppb_login_turnstile_custom_field_' . $field['id'] . '_item_title', wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_title_translation', $field['field-title'], true));
429 $item_description = wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_description_translation', $field['description'], true);
430
431 if ( isset($field['turnstile-pb-forms']) && ( strpos( $field['turnstile-pb-forms'],'pb_login' ) !== false ) ) { // check where Turnstile should display
432
433 global $wppb_turnstile_present;
434 $wppb_turnstile_present = true;
435
436 $turnstile_output = '<label for="turnstile_response_field">' . $item_title . '</label>' . wppb_turnstile_get_html(trim($field['turnstile-site-key']), 'pb_login');
437 if (!empty($item_description))
438 $turnstile_output .= '<span class="wppb-description-delimiter">' . $item_description . '</span>';
439
440 $form_part .= '<div class="wppb-form-field wppb-turnstile">' . $turnstile_output . '</div>';
441
442 }
443 }
444
445 return $form_part;
446 }
447 add_filter('login_form_middle', 'wppb_display_turnstile_login_form', 10, 2);
448
449 /* Display Turnstile html on default WP Login form */
450 function wppb_display_turnstile_wp_login_form(){
451 $field = wppb_get_turnstile_field();
452
453 if ( !empty($field) ) {
454 $item_title = apply_filters('wppb_login_turnstile_custom_field_' . $field['id'] . '_item_title', wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_title_translation', $field['field-title'], true));
455 $item_description = wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_description_translation', $field['description'], true);
456
457 if ( isset($field['turnstile-wp-forms']) && (strpos( $field['turnstile-wp-forms'],'default_wp_login' ) !== false) ) {
458
459 global $wppb_turnstile_present;
460 $wppb_turnstile_present = true;
461
462 $turnstile_output = '<label for="turnstile_response_field" style="padding-left:15px; padding-bottom:7px;">' . $item_title . '</label>' . wppb_turnstile_get_html(trim($field['turnstile-site-key']));
463 if (!empty($item_description))
464 $turnstile_output .= '<span class="wppb-description-delimiter">' . $item_description . '</span>';
465
466 echo '<div class="wppb-form-field wppb-turnstile" style="margin-left:-14px; margin-bottom: 15px;">' . $turnstile_output . '</div>'; /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */ /* properly escaped when constructing the var */
467
468 }
469 }
470 }
471 add_action( 'login_form', 'wppb_display_turnstile_wp_login_form' );
472
473 //Show Turnstile error on Login form (both default and PB one)
474 function wppb_turnstile_login_wp_error_message($user){
475 //make sure you\'re on a Login form (WP or PB)
476 if ( isset( $_POST['log'] ) && !is_wp_error($user) && !isset( $_POST['pms_login'] ) ) {
477
478 $field = wppb_get_turnstile_field();
479 if ( !empty($field) ){
480 global $wppb_turnstile_response;
481
482 if (!isset($wppb_turnstile_response)) $wppb_turnstile_response = wppb_validate_turnstile_response( trim( $field['turnstile-site-key'] ), trim( $field['turnstile-secret-key'] ) );
483
484 $turnstile_error_message = __('Cloudflare Turnstile could not be verified. Please try again.','profile-builder');
485
486 //Turnstile error for displaying on the PB login form
487 if ( isset($_POST['wppb_login']) && ($_POST['wppb_login'] == true) ) {
488
489 // it\'s a PB login form, check if we have Turnstile on it and display error if not valid
490 if ((isset($field['turnstile-pb-forms'])) && (strpos($field['turnstile-pb-forms'], 'pb_login') !== false) && ($wppb_turnstile_response == false)) {
491 $user = new WP_Error('wppb_turnstile_error', $turnstile_error_message);
492 remove_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 );
493 remove_filter( 'authenticate', 'wp_authenticate_email_password', 20, 3 );
494 }
495
496 }
497 else {
498 //Turnstile error for displaying on the default WP login form
499 if (isset($field['turnstile-wp-forms']) && (strpos($field['turnstile-wp-forms'], 'default_wp_login') !== false) && ($wppb_turnstile_response == false)) {
500 $user = new WP_Error('wppb_turnstile_error', $turnstile_error_message);
501 remove_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 );
502 remove_filter( 'authenticate', 'wp_authenticate_email_password', 20, 3 );
503 }
504
505 }
506 }
507 }
508 return $user;
509 }
510 add_filter('authenticate','wppb_turnstile_login_wp_error_message', 9);
511
512 /**
513 * Add a Turnstile CSS class to the Register form field
514 *
515 * @param $classes - existing field classes
516 * @param $field - field data
517 * @return mixed|string
518 */
519 function wppb_register_form_turnstile_type_class( $classes, $field ){
520
521 if ( isset( $field['field'] ) && $field['field'] == 'Turnstile' )
522 $classes .= ' wppb-turnstile';
523
524 return $classes;
525 }
526 add_filter( 'wppb_field_css_class', 'wppb_register_form_turnstile_type_class', 20, 2);
527
528 // Display Turnstile html on default WP Recover Password form
529 function wppb_display_turnstile_default_wp_recover_password() {
530 $field = wppb_get_turnstile_field();
531
532 if (!empty($field)) {
533 $publickey = trim($field['turnstile-site-key']);
534 $item_title = apply_filters('wppb_recover_password_turnstile_custom_field_' . $field['id'] . '_item_title', wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_title_translation', $field['field-title'], true));
535 $item_description = wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_description_translation', $field['description'], true);
536
537 if ( isset($field['turnstile-wp-forms']) && (strpos( $field['turnstile-wp-forms'], 'default_wp_recover_password') !== false) ) {
538
539 global $wppb_turnstile_present;
540 $wppb_turnstile_present = true;
541
542 $turnstile_output = '<label for="turnstile_response_field" style="padding-left:15px; padding-bottom:7px;">' . $item_title . '</label>' . wppb_turnstile_get_html($publickey);
543 if (!empty($item_description))
544 $turnstile_output .= '<span class="wppb-description-delimiter">' . $item_description . '</span>';
545
546 echo '<div class="wppb-form-field wppb-turnstile" style="margin-left:-14px; margin-bottom: 15px;">' . $turnstile_output . '</div>'; /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */ /* properly escaped when constructing the var */
547
548 }
549 }
550 }
551 add_action('lostpassword_form','wppb_display_turnstile_default_wp_recover_password');
552
553 // Verify and show Turnstile errors for default WP Recover Password
554 function wppb_verify_turnstile_default_wp_recover_password(){
555
556 // If field \'username or email\' is empty - return
557 if( isset( $_REQUEST['user_login'] ) && "" === $_REQUEST['user_login'] )
558 return;
559
560 $field = wppb_get_turnstile_field();
561 if ( !empty($field) ){
562 global $wppb_turnstile_response;
563 if (!isset($wppb_turnstile_response)) $wppb_turnstile_response = wppb_validate_turnstile_response( trim( $field['turnstile-site-key'] ), trim( $field['turnstile-secret-key'] ) );
564
565 $turnstile_error_message = esc_html__('Cloudflare Turnstile could not be verified. Please try again.','profile-builder');
566
567 // Fail closed, but only where Turnstile is configured for this form. Gate on turnstile-wp-forms (as the
568 // login path does) instead of isset() of the token, so a missing token is treated as a failed verification
569 // without blocking default WP password recovery on sites that only use Turnstile on PB forms.
570 if ( isset( $field['turnstile-wp-forms'] ) && ( strpos( $field['turnstile-wp-forms'], 'default_wp_recover_password' ) !== false ) && ( $wppb_turnstile_response == false ) ) {
571 wp_die( esc_html( $turnstile_error_message ) . '<br />' . esc_html__( "Click the BACK button on your browser, and try again.", 'profile-builder' ) ) ;
572 }
573 }
574 }
575 add_action('lostpassword_post','wppb_verify_turnstile_default_wp_recover_password');
576
577 /* Display Turnstile html on default WP Register form */
578 function wppb_display_turnstile_default_wp_register(){
579 $field = wppb_get_turnstile_field();
580
581 if (!empty($field)) {
582
583 $publickey = trim($field['turnstile-site-key']);
584 $item_title = apply_filters('wppb_register_turnstile_custom_field_' . $field['id'] . '_item_title', wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_title_translation', $field['field-title'], true));
585 $item_description = wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_description_translation', $field['description'], true);
586
587 wppb_turnstile_set_default_values();
588 if (isset($field['turnstile-wp-forms']) && (strpos($field['turnstile-wp-forms'], 'default_wp_register') !== false)) {
589
590 global $wppb_turnstile_present;
591 $wppb_turnstile_present = true;
592
593 $turnstile_output = '<label for="turnstile_response_field" style="padding-left:15px; padding-bottom:7px;">' . $item_title . '</label>' . wppb_turnstile_get_html($publickey);
594 if (!empty($item_description))
595 $turnstile_output .= '<span class="wppb-description-delimiter">' . $item_description . '</span>';
596
597 echo '<div class="wppb-form-field wppb-turnstile" style="margin-left:-14px; margin-bottom: 15px;">' . $turnstile_output . '</div>'; /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */ /* properly escaped when constructing the var */
598
599 }
600 }
601 }
602 add_action( 'register_form', 'wppb_display_turnstile_default_wp_register' );
603
604 // Verify and show Turnstile errors for default WP Register form
605 function wppb_verify_turnstile_default_wp_register( $errors ){
606
607 $field = wppb_get_turnstile_field();
608 if ( !empty($field) ){
609 global $wppb_turnstile_response;
610 if (!isset($wppb_turnstile_response)) $wppb_turnstile_response = wppb_validate_turnstile_response( trim( $field['turnstile-site-key'] ), trim( $field['turnstile-secret-key'] ) );
611
612 $turnstile_error_message = esc_html__('Cloudflare Turnstile could not be verified. Please try again.','profile-builder');
613
614 // Fail closed, but only where Turnstile is configured for this form. Gate on turnstile-wp-forms (as the
615 // login path does) instead of isset() of the token, so a missing token is treated as a failed verification
616 // without blocking default WP registration on sites that only use Turnstile on PB forms.
617 if ( isset( $field['turnstile-wp-forms'] ) && ( strpos( $field['turnstile-wp-forms'], 'default_wp_register' ) !== false ) && ( $wppb_turnstile_response == false ) ) {
618 $errors->add( 'wppb_turnstile_error', $turnstile_error_message );
619 }
620 }
621
622 return $errors;
623 }
624 add_filter('registration_errors','wppb_verify_turnstile_default_wp_register');
625
626 // set default values in case there's already an existing Turnstile field in Manage fields (when upgrading)
627 function wppb_turnstile_set_default_values() {
628 $manage_fields = get_option('wppb_manage_fields', 'not_set');
629 if ($manage_fields != 'not_set') {
630 foreach ($manage_fields as $key => $value) {
631 if ($value['field'] == 'Turnstile') {
632 if ( !isset($value['turnstile-pb-forms']) ) $manage_fields[$key]['turnstile-pb-forms'] = 'pb_register';
633 if ( !isset($value['turnstile-wp-forms']) ) $manage_fields[$key]['turnstile-wp-forms'] = 'default_wp_register';
634 if ( !isset($value['theme']) ) $manage_fields[$key]['theme'] = 'auto';
635 }
636 }
637 update_option('wppb_manage_fields', $manage_fields);
638 }
639 }
640