From b9e0014d471df2dd2f83b91f2ca45316b5f1c615 Mon Sep 17 00:00:00 2001
From: Sapayth Hossain
Date: Tue, 29 Oct 2024 13:14:50 +0600
Subject: [PATCH 1/4] toggle button styling and data save in settings
---
Lib/WeDevs_Settings_API.php | 30 ++++++++++++
assets/css/admin.css | 44 ++++++++++++++++++
assets/css/admin/wpuf-module.css | 59 ------------------------
assets/less/admin.less | 53 +++++++++++++++++++++
includes/Admin/Plugin_Upgrade_Notice.php | 2 +-
includes/functions/settings-options.php | 6 +++
6 files changed, 134 insertions(+), 60 deletions(-)
diff --git a/Lib/WeDevs_Settings_API.php b/Lib/WeDevs_Settings_API.php
index 7a5cd9ad5..5a29b0c5f 100644
--- a/Lib/WeDevs_Settings_API.php
+++ b/Lib/WeDevs_Settings_API.php
@@ -460,6 +460,36 @@ function callback_color( $args ) {
echo $html;
}
+ /**
+ * Displays a toggle field for a settings field
+ *
+ * @param array $args settings field args
+ */
+ public function callback_toggle( $args ) {
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
+ $disabled = ! empty( $args['is_pro_preview'] ) && $args['is_pro_preview'] ? 'disabled' : '';
+ $name = $args['section'] . '[' . $args['id'] . ']';
+ ?>
+
+ =' ) ) {
+ if ( version_compare( WPUF_VERSION, $min_version, '>=' ) ) {
return;
}
diff --git a/includes/functions/settings-options.php b/includes/functions/settings-options.php
index 16d75bb82..753748a83 100644
--- a/includes/functions/settings-options.php
+++ b/includes/functions/settings-options.php
@@ -159,6 +159,12 @@ function wpuf_settings_fields() {
'desc' => __( 'Register here to get reCaptcha Site and Secret keys.',
'wp-user-frontend' ),
],
+ [
+ 'name' => 'enable_turnstile',
+ 'label' => __( 'Enable Turnstile', 'wp-user-frontend' ),
+ 'type' => 'toggle',
+ 'default' => 'off',
+ ],
[
'name' => 'custom_css',
'label' => __( 'Custom CSS codes', 'wp-user-frontend' ),
From 6b01a8c2c1c7ce0f35ee49c037eeff9dba24f143 Mon Sep 17 00:00:00 2001
From: Sapayth Hossain
Date: Tue, 29 Oct 2024 16:09:33 +0600
Subject: [PATCH 2/4] show/hide dependent field conditionally
---
Lib/WeDevs_Settings_API.php | 47 +++++++++++++++++++++++--
includes/functions/settings-options.php | 17 +++++++++
2 files changed, 62 insertions(+), 2 deletions(-)
diff --git a/Lib/WeDevs_Settings_API.php b/Lib/WeDevs_Settings_API.php
index 5a29b0c5f..90b8638f7 100644
--- a/Lib/WeDevs_Settings_API.php
+++ b/Lib/WeDevs_Settings_API.php
@@ -140,6 +140,7 @@ function admin_init() {
'max' => isset( $option['max'] ) ? $option['max'] : '',
'step' => isset( $option['step'] ) ? $option['step'] : '',
'is_pro_preview' => ! empty( $option['is_pro_preview'] ) ? $option['is_pro_preview'] : false,
+ 'depends_on' => ! empty( $option['depends_on'] ) ? $option['depends_on'] : '',
);
add_settings_field( $section . '[' . $option['name'] . ']', $option['label'], (isset($option['callback']) ? $option['callback'] : array($this, 'callback_' . $type )), $section, $section, $args );
@@ -173,14 +174,17 @@ public function get_field_description( $args ) {
* @param array $args settings field args
*/
function callback_text( $args ) {
-
$value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
$size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
$type = isset( $args['type'] ) ? $args['type'] : 'text';
$placeholder = empty( $args['placeholder'] ) ? '' : ' placeholder="' . $args['placeholder'] . '"';
$disabled = ! empty( $args['is_pro_preview'] ) && $args['is_pro_preview'] ? 'disabled' : '';
+ $depends_on = ! empty( $args['depends_on'] ) ? $args['depends_on'] : '';
- $html = sprintf( '', $type, $size, $args['section'], $args['id'], $value, $placeholder, $disabled );
+ $html = sprintf(
+ '',
+ $type, $size, $args['section'], $args['id'], $value, $placeholder, $disabled, $depends_on
+ );
$html .= $this->get_field_description( $args );
if ( ! empty( $args['is_pro_preview'] ) && $args['is_pro_preview'] ) {
@@ -703,6 +707,45 @@ function(){
// disable the pro preview checkboxes
$('span.pro-icon-title').siblings('input[type="checkbox"]').prop('disabled', true);
+
+
+ var fields = $('table.form-table input, table.form-table select, table.form-table textarea');
+
+ // iterate over each field and check if it depends on another field
+ fields.each(function() {
+ var $this = $(this);
+ var data_depends_on = $this.data('depends-on');
+
+ if (!data_depends_on) {
+ return;
+ }
+
+ var $depends_on = $("input[id*='"+ data_depends_on +"']");
+ var $depends_on_type = $depends_on.attr('type');
+
+ if ($depends_on_type === 'checkbox') {
+ if ($depends_on.is(':checked')) {
+ $this.closest('tr').show();
+ } else {
+ $this.closest('tr').hide();
+ }
+ $depends_on.on('change', function() {
+ if ($(this).is(':checked')) {
+ $this.closest('tr').show();
+ } else {
+ $this.closest('tr').hide();
+ }
+ });
+ } else {
+ $depends_on.on('keyup change', function() {
+ if ($(this).val() === $this.data('depends-on-value')) {
+ $this.closest('tr').show();
+ } else {
+ $this.closest('tr').hide();
+ }
+ });
+ }
+ });
});
diff --git a/includes/functions/settings-options.php b/includes/functions/settings-options.php
index 753748a83..b2915141e 100644
--- a/includes/functions/settings-options.php
+++ b/includes/functions/settings-options.php
@@ -165,6 +165,23 @@ function wpuf_settings_fields() {
'type' => 'toggle',
'default' => 'off',
],
+ [
+ 'name' => 'turnstile_site_key',
+ 'label' => __( 'Turnstile Site Key', 'wp-user-frontend' ),
+ 'depends_on' => 'enable_turnstile',
+ ],
+ [
+ 'name' => 'turnstile_secret_key',
+ 'label' => __( 'Turnstile Site Key', 'wp-user-frontend' ),
+ 'depends_on' => 'enable_turnstile',
+ 'desc' => sprintf(
+ // translators: %s is a link
+ __(
+ 'Register here to get Turnstile Site and Secret keys.',
+ 'wp-user-frontend'
+ ), esc_url( 'https://developers.cloudflare.com/turnstile/' )
+ ),
+ ],
[
'name' => 'custom_css',
'label' => __( 'Custom CSS codes', 'wp-user-frontend' ),
From 0dbd738ae68d0ab025b8168b4a88496ae3c21474 Mon Sep 17 00:00:00 2001
From: Sapayth Hossain
Date: Wed, 30 Oct 2024 10:29:52 +0600
Subject: [PATCH 3/4] client side rendering and validation
---
Lib/WeDevs_Settings_API.php | 32 +++++++++++++------------
includes/Assets.php | 5 +++-
includes/Free/Simple_Login.php | 7 +++++-
includes/functions/settings-options.php | 13 +++++++++-
templates/login-form.php | 25 +++++++++++++++++--
5 files changed, 62 insertions(+), 20 deletions(-)
diff --git a/Lib/WeDevs_Settings_API.php b/Lib/WeDevs_Settings_API.php
index 90b8638f7..eac841279 100644
--- a/Lib/WeDevs_Settings_API.php
+++ b/Lib/WeDevs_Settings_API.php
@@ -475,22 +475,24 @@ public function callback_toggle( $args ) {
$name = $args['section'] . '[' . $args['id'] . ']';
?>
+
+
'1.6.0',
'in_footer' => true,
],
- 'admin-shortcode' => [
+ 'admin-shortcode' => [
'src' => WPUF_ASSET_URI . '/js/admin-shortcode.js',
'deps' => [ 'jquery' ],
],
@@ -374,6 +374,9 @@ public function get_scripts() {
'headway' => [
'src' => '//cdn.headwayapp.co/widget.js',
],
+ 'turnstile' => [
+ 'src' => 'https://challenges.cloudflare.com/turnstile/v0/api.js?onload=onloadTurnstileCallback',
+ ],
];
if ( ! empty( $api_key ) ) {
diff --git a/includes/Free/Simple_Login.php b/includes/Free/Simple_Login.php
index 200e7f638..d44f64ce0 100644
--- a/includes/Free/Simple_Login.php
+++ b/includes/Free/Simple_Login.php
@@ -339,7 +339,7 @@ public function login_form() {
$reset = isset( $getdata['reset'] ) ? sanitize_text_field( $getdata['reset'] ) : '';
if ( false === $login_page ) {
- return;
+ return '';
}
ob_start();
@@ -394,6 +394,11 @@ public function login_form() {
default:
$loggedout = isset( $getdata['loggedout'] ) ? sanitize_text_field( $getdata['loggedout'] ) : '';
+ $enable_turnstile = wpuf_get_option( 'enable_turnstile', 'wpuf_general', 'off' );
+
+ if ( 'on' === $enable_turnstile ) {
+ wp_enqueue_script( 'wpuf-turnstile' );
+ }
if ( $loggedout === 'true' ) {
$this->messages[] = __( 'You are now logged out.', 'wp-user-frontend' );
diff --git a/includes/functions/settings-options.php b/includes/functions/settings-options.php
index b2915141e..315862b35 100644
--- a/includes/functions/settings-options.php
+++ b/includes/functions/settings-options.php
@@ -172,7 +172,7 @@ function wpuf_settings_fields() {
],
[
'name' => 'turnstile_secret_key',
- 'label' => __( 'Turnstile Site Key', 'wp-user-frontend' ),
+ 'label' => __( 'Turnstile Secret Key', 'wp-user-frontend' ),
'depends_on' => 'enable_turnstile',
'desc' => sprintf(
// translators: %s is a link
@@ -454,6 +454,17 @@ function wpuf_settings_fields() {
'type' => 'checkbox',
'default' => 'off',
],
+ [
+ 'name' => 'login_form_turnstile',
+ 'label' => __( 'Turnstile in Login Form', 'wp-user-frontend' ),
+ 'desc' => __(
+ 'If enabled, users have to verify Cloudflare Turnstile in login page. Also, make sure that Turnstile is configured properly from General Options',
+ 'wp-user-frontend'
+ ),
+ 'type' => 'toggle',
+ 'default' => 'off',
+ 'depends_on' => 'enable_turnstile',
+ ],
] ),
'wpuf_payment' => apply_filters( 'wpuf_options_payment', [
[
diff --git a/templates/login-form.php b/templates/login-form.php
index c23aaacb1..2b12921ea 100644
--- a/templates/login-form.php
+++ b/templates/login-form.php
@@ -30,8 +30,13 @@
-
-
+
+
+
+
+
+
+
From 89e7c2469dc2db1b0a3646449bfef04bdee8282d Mon Sep 17 00:00:00 2001
From: Sapayth Hossain
Date: Wed, 30 Oct 2024 12:14:46 +0600
Subject: [PATCH 4/4] server side verification done
---
assets/css/frontend-forms.css | 2 +-
assets/less/frontend-forms.less | 2 +-
includes/Free/Simple_Login.php | 71 ++++++++++++++++++++++++++++++++-
3 files changed, 71 insertions(+), 4 deletions(-)
diff --git a/assets/css/frontend-forms.css b/assets/css/frontend-forms.css
index 0ff853676..39fb30fe9 100644
--- a/assets/css/frontend-forms.css
+++ b/assets/css/frontend-forms.css
@@ -84,7 +84,7 @@ body .wpuf-error {
background-color: #f2dede;
color: #a94442;
border: 1px solid #ebccd1;
- margin: 10px 10px 20px;
+ margin: 10px 0 20px 0;
padding: 10px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
diff --git a/assets/less/frontend-forms.less b/assets/less/frontend-forms.less
index 6954c3b8a..902907249 100644
--- a/assets/less/frontend-forms.less
+++ b/assets/less/frontend-forms.less
@@ -116,7 +116,7 @@ body {
background-color: #f2dede;
color: #a94442;
border: 1px solid #ebccd1;
- margin: 10px 10px 20px;
+ margin: 10px 0 20px 0;
padding: 10px;
.border-radius(3px);
font-size: 13px;
diff --git a/includes/Free/Simple_Login.php b/includes/Free/Simple_Login.php
index d44f64ce0..2afac5da4 100644
--- a/includes/Free/Simple_Login.php
+++ b/includes/Free/Simple_Login.php
@@ -19,6 +19,13 @@ class Simple_Login {
private $messages = [];
+ /**
+ * Cloudflare Turnstile messages
+ *
+ * @var array
+ */
+ private $cf_messages = [];
+
private static $_instance;
public function __construct() {
@@ -415,6 +422,52 @@ public function login_form() {
return ob_get_clean();
}
+ /**
+ * Verify if cloudflare turnstile request is successful
+ *
+ * @since WPUF_SINCE
+ *
+ * @return bool
+ */
+ private function verify_cloudflare_turnstile_on_login() {
+ $nonce = isset( $_POST['wpuf-login-nonce'] ) ? sanitize_key( wp_unslash( $_POST['wpuf-login-nonce'] ) ) : '';
+
+ if ( isset( $nonce ) && ! wp_verify_nonce( $nonce, 'wpuf_login_action' ) ) {
+ return false;
+ }
+
+ $secret = wpuf_get_option( 'turnstile_secret_key', 'wpuf_general', '' );
+
+ if ( empty( $secret ) ) {
+ return false;
+ }
+
+ $remote_addr = ! empty( $_SERVER['REMOTE_ADDR'] ) ? sanitize_url(
+ wp_unslash( $_SERVER['REMOTE_ADDR'] )
+ ) : '';
+
+ $cf_url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
+ $token = ! empty( $_POST['cf-turnstile-response'] ) ? sanitize_text_field( wp_unslash( $_POST['cf-turnstile-response'] ) ) : '';
+
+ // Request data
+ $data = [
+ 'secret' => $secret,
+ 'response' => $token,
+ 'remoteip' => $remote_addr,
+ ];
+
+ $response = wp_remote_post( $cf_url, [ 'body' => $data ] );
+ $body = json_decode( wp_remote_retrieve_body( $response ), true );
+
+ if ( ! empty( $body['success'] ) ) {
+ return true;
+ } else {
+ $this->cf_messages[] = ! empty( $body['error-codes'] ) ? $body['error-codes'] : '';
+
+ return false;
+ }
+ }
+
/**
* Remove selected cookie to have consistency with the login nonce.
* fixes WooCommerce Stripe Gateway plugin conflict
@@ -452,10 +505,24 @@ public function process_login() {
return;
}
- $log = isset( $_POST['log'] ) ? esc_attr( wp_unslash( $_POST['log'] ) ) : '';
- $pwd = isset( $_POST['pwd'] ) ? trim( $_POST['pwd'] ) : '';
+ $log = isset( $_POST['log'] ) ? sanitize_text_field( wp_unslash( $_POST['log'] ) ) : '';
+ $pwd = isset( $_POST['pwd'] ) ? sanitize_text_field( ( wp_unslash( $_POST['pwd'] ) ) ) : '';
// $g_recaptcha_response = isset( $_POST['g-recaptcha-response'] ) ? sanitize_text_field( wp_unslash( $_POST['g-recaptcha-response'] ) ) : '';
+ if ( ! $this->verify_cloudflare_turnstile_on_login() ) {
+ $errors = ! empty( $this->cf_messages[0] ) ? $this->cf_messages[0] : '';
+ $errors = implode( ', ', $errors );
+ $this->login_errors[] =
+ sprintf(
+ // translators: %1$s and %2$s are strong tags, %3$s is the error message
+ __( '%1$sError%2$s: Cloudflare Turnstile verification failed. Reasons: [%3$s]', 'wp-user-frontend' ),
+ '',
+ '',
+ $errors
+ );
+ '' . __( 'Error', 'wp-user-frontend' ) . ': ' . __( 'Cloudflare Turnstile verification failed. Reasons: [', 'wp-user-frontend' );
+ }
+
$validation_error = new WP_Error();
$validation_error = apply_filters( 'wpuf_process_login_errors', $validation_error, $log, $pwd );