| @@ -77,9 +77,8 @@ | ||
| 77 | 77 | $this->woo = wd_di()->get( Woocommerce::class ); |
| 78 | 78 | $this->is_woo_activated = $this->woo->is_activated(); |
| 79 | 79 | $this->buddypress = wd_di()->get( Buddypress::class ); |
| 80 | 80 | $this->is_buddypress_activated = $this->buddypress->is_activated(); |
| 81 | - add_filter( 'wp_defender_advanced_tools_data', array( $this, 'script_data' ) ); | |
| 82 | 81 | |
| 83 | 82 | if ( $this->model->is_active() // No need the check by Woo and Buddypress are activated because we use this below. |
| 84 | 83 | && $this->service->enable_any_location( $this->is_woo_activated, $this->is_buddypress_activated ) && ! $this->service->exclude_captcha_for_requests() ) { |
| 85 | 84 | $this->add_actions(); |
| @@ -312,21 +311,8 @@ | ||
| 312 | 311 | return false; |
| 313 | 312 | } |
| 314 | 313 | |
| 315 | 314 | /** |
| 316 | - * Provide data to the frontend via localized script. | |
| 317 | - * | |
| 318 | - * @param array $data Data collection is ready to passed. | |
| 319 | - * | |
| 320 | - * @return array Modified data array with added this controller data. | |
| 321 | - */ | |
| 322 | - public function script_data( array $data ): array { | |
| 323 | - $data['captcha'] = $this->data_frontend(); | |
| 324 | - | |
| 325 | - return $data; | |
| 326 | - } | |
| 327 | - | |
| 328 | - /** | |
| 329 | 315 | * Provides data for the frontend. |
| 330 | 316 | * |
| 331 | 317 | * @return array An array of data for the frontend. |
| 332 | 318 | */ |
| @@ -378,60 +364,13 @@ | ||
| 378 | 364 | * @return Response |
| 379 | 365 | * @defender_route |
| 380 | 366 | */ |
| 381 | 367 | public function save_settings( Request $request ): Response { |
| 382 | - $data = $request->get_data_by_model( $this->model ); | |
| 383 | - $old_data = $this->model->get_active_captcha_data( $data['provider'], $data['active_type'] ); | |
| 368 | + $data = $request->get_data_by_model( $this->model ); | |
| 384 | 369 | $this->model->import( $data ); |
| 385 | 370 | if ( Captcha_Model::TURNSTILE === $this->model->provider ) { |
| 386 | 371 | $this->model->active_type = Captcha_Model::TURNSTILE; |
| 387 | 372 | } |
| 388 | - $new_data = $this->model->get_active_captcha_data(); | |
| 389 | - $old_key = $old_data['key'] ?? ''; | |
| 390 | - $old_secret = $old_data['secret'] ?? ''; | |
| 391 | - $key = $new_data['key'] ?? ''; | |
| 392 | - $secret = $new_data['secret'] ?? ''; | |
| 393 | - $provider = $this->service->get_provider(); | |
| 394 | - $is_valid = ( '' === $secret && '' === $key ) || ( '' !== $secret && '' !== $key ); | |
| 395 | - if ( ( $old_key !== $key || $old_secret !== $secret ) && '' !== $secret && '' !== $key ) { | |
| 396 | - $valid_token = $request->get_data( | |
| 397 | - array( | |
| 398 | - 'token' => array( | |
| 399 | - 'type' => 'string', | |
| 400 | - ), | |
| 401 | - ) | |
| 402 | - ); | |
| 403 | - $token = $valid_token['token'] ?? ''; | |
| 404 | - if ( '' === $token ) { | |
| 405 | - $is_valid = false; | |
| 406 | - } else { | |
| 407 | - $response = $provider->verify_response_token( | |
| 408 | - $token, | |
| 409 | - $provider->get_verify_url(), | |
| 410 | - array( | |
| 411 | - 'secret' => $secret, | |
| 412 | - ) | |
| 413 | - ); | |
| 414 | - $is_valid = isset( $response['success'] ) && true === $response['success']; | |
| 415 | - } | |
| 416 | - } | |
| 417 | - if ( ! $is_valid ) { | |
| 418 | - return new Response( | |
| 419 | - false, // Merge stored data to avoid errors. | |
| 420 | - array_merge( | |
| 421 | - array( | |
| 422 | - 'message' => sprintf( | |
| 423 | - /* translators: Provider label. */ | |
| 424 | - __( 'Please make sure your %s API keys are correct and that Preview Widget verification is successful.', 'defender-security' ), | |
| 425 | - Captcha_Model::TURNSTILE === $this->model->provider ? __( 'Cloudflare', 'defender-security' ) : __( 'reCAPTCHA', 'defender-security' ) | |
| 426 | - ), | |
| 427 | - 'error_keys' => array( 'invalid-secret' ), | |
| 428 | - ), | |
| 429 | - $this->data_frontend() | |
| 430 | - ) | |
| 431 | - ); | |
| 432 | - } | |
| 433 | - | |
| 434 | 373 | if ( $this->model->validate() ) { |
| 435 | 374 | $this->model->save(); |
| 436 | 375 | Config_Hub_Helper::set_clear_active_flag(); |
| 437 | 376 | |
| @@ -447,9 +386,10 @@ | ||
| 447 | 386 | ); |
| 448 | 387 | } |
| 449 | 388 | |
| 450 | 389 | return new Response( |
| 451 | - false, // Merge stored data to avoid errors. | |
| 390 | + false, | |
| 391 | + // Merge stored data to avoid errors. | |
| 452 | 392 | array_merge( |
| 453 | 393 | array( |
| 454 | 394 | 'message' => $this->model->get_formatted_errors(), |
| 455 | 395 | 'error_keys' => $this->model->get_error_keys(), |
| @@ -454,8 +394,80 @@ | ||
| 454 | 394 | 'message' => $this->model->get_formatted_errors(), |
| 455 | 395 | 'error_keys' => $this->model->get_error_keys(), |
| 456 | 396 | ), |
| 457 | 397 | $this->data_frontend() |
| 398 | + ) | |
| 399 | + ); | |
| 400 | + } | |
| 401 | + | |
| 402 | + /** | |
| 403 | + * Verify a CAPTCHA response token. | |
| 404 | + * | |
| 405 | + * @param Request $request The request object containing token and key data. | |
| 406 | + * | |
| 407 | + * @return Response | |
| 408 | + * @defender_route | |
| 409 | + */ | |
| 410 | + public function verify_response_token( Request $request ): Response { | |
| 411 | + $data = $request->get_data( | |
| 412 | + array( | |
| 413 | + 'token' => array( | |
| 414 | + 'type' => 'string', | |
| 415 | + 'sanitize' => 'sanitize_text_field', | |
| 416 | + ), | |
| 417 | + 'key' => array( | |
| 418 | + 'type' => 'string', | |
| 419 | + 'sanitize' => 'sanitize_text_field', | |
| 420 | + ), | |
| 421 | + ) | |
| 422 | + ); | |
| 423 | + | |
| 424 | + $token = $data['token'] ?? ''; | |
| 425 | + $key = $data['key'] ?? ''; | |
| 426 | + if ( '' === $token || '' === $key ) { | |
| 427 | + return new Response( | |
| 428 | + false, | |
| 429 | + array( | |
| 430 | + 'message' => esc_html__( 'Missing CAPTCHA verification data.', 'defender-security' ), | |
| 431 | + ) | |
| 432 | + ); | |
| 433 | + } | |
| 434 | + | |
| 435 | + $provider = $this->service->get_provider(); | |
| 436 | + $response = $provider->verify_response_token( | |
| 437 | + $token, | |
| 438 | + $provider->get_verify_url(), | |
| 439 | + array( | |
| 440 | + 'secret' => $key, | |
| 441 | + ) | |
| 442 | + ); | |
| 443 | + | |
| 444 | + $success = (bool) ( $response['success'] ?? false ); | |
| 445 | + if ( $success ) { | |
| 446 | + if ( Captcha_Model::TURNSTILE === $this->model->provider ) { | |
| 447 | + $data = $this->model->data_turnstile; | |
| 448 | + $data['verified'] = true; | |
| 449 | + $this->model->data_turnstile = $data; | |
| 450 | + } elseif ( 'v2_checkbox' === $this->model->active_type ) { | |
| 451 | + $data = $this->model->data_v2_checkbox; | |
| 452 | + $data['verified'] = true; | |
| 453 | + $this->model->data_v2_checkbox = $data; | |
| 454 | + } elseif ( 'v2_invisible' === $this->model->active_type ) { | |
| 455 | + $data = $this->model->data_v2_invisible; | |
| 456 | + $data['verified'] = true; | |
| 457 | + $this->model->data_v2_invisible = $data; | |
| 458 | + } elseif ( 'v3_recaptcha' === $this->model->active_type ) { | |
| 459 | + $data = $this->model->data_v3_recaptcha; | |
| 460 | + $data['verified'] = true; | |
| 461 | + $this->model->data_v3_recaptcha = $data; | |
| 462 | + } | |
| 463 | + $this->model->save(); | |
| 464 | + } | |
| 465 | + | |
| 466 | + return new Response( | |
| 467 | + $success, | |
| 468 | + array( | |
| 469 | + 'success' => $success, | |
| 458 | 470 | ) |
| 459 | 471 | ); |
| 460 | 472 | } |
| 461 | 473 | |