File: /var/www/html/wp-content/plugins/loginpress/classes/class-loginpress-password-strength.php
<?php
/**
* LoginPress Password Strength Class.
*
* Handles password strength validation and requirements.
*
* @package LoginPress
* @since 4.0.0
* @version 6.2.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'LoginPress_Password_Strength' ) ) :
/**
* LoginPress Password Strength class.
*
* @since 4.0.0
*/
class LoginPress_Password_Strength {
/**
* LoginPress settings array containing password strength configuration.
*
* @var array<string, mixed> Settings array with password strength requirements and options.
*/
public $loginpress_setting;
/**
* Class constructor.
*
* @since 4.0.0
* @return void
*/
public function __construct() {
$this->loginpress_setting = get_option( 'loginpress_setting' );
$this->hooks();
}
/**
* Hook into actions and filters.
*
* @since 4.0.0
* @return void
*/
public function hooks() {
$enable_password_strength = isset( $this->loginpress_setting['enable_pass_strength'] ) ? $this->loginpress_setting['enable_pass_strength'] : 'off';
if ( 'on' === $enable_password_strength ) {
$enable_pass_strength = isset( $this->loginpress_setting['enable_pass_strength_forms'] ) ? $this->loginpress_setting['enable_pass_strength_forms'] : 'off';
$strength_meter_enable = isset( $this->loginpress_setting['password_strength_meter'] ) ? $this->loginpress_setting['password_strength_meter'] : 'off';
$register = isset( $enable_pass_strength['register'] ) ? $enable_pass_strength['register'] : false;
$wc_reset = isset( $enable_pass_strength['wc_forms'] ) ? $enable_pass_strength['wc_forms'] : false;
$wp_reset = isset( $enable_pass_strength['reset'] ) ? $enable_pass_strength['reset'] : false;
if ( $register ) {
add_action( 'registration_errors', array( $this, 'validate_password_requirements' ), 10 );
}
if ( 'on' === $strength_meter_enable && $register ) {
add_action( 'login_enqueue_scripts', array( $this, 'loginpress_password_strength_meter' ) );
}
if ( $wp_reset || $wc_reset ) {
add_action( 'validate_password_reset', array( $this, 'validate_password_requirements' ), 10 );
}
if ( $wp_reset ) {
add_filter( 'password_hint', array( $this, 'loginpress_password_hint' ) );
}
if ( $wc_reset ) {
add_filter( 'woocommerce_get_script_data', array( $this, 'loginpress_wc_reset_password_hint' ), 10, 2 );
} elseif ( ! $wc_reset ) {
add_filter( 'woocommerce_get_script_data', array( $this, 'loginpress_wc_reset_remove_hint' ), 10, 2 );
}
}
}
/**
* Handles password field errors for registration form.
*
* @param WP_Error $errors WP_Error object.
* @since 4.0.0
* @return WP_Error object.
*/
public function validate_password_requirements( $errors ) {
if ( ! is_wp_error( $errors ) ) {
$errors = new WP_Error();
}
$enable_pass_strength = isset( $this->loginpress_setting['enable_pass_strength_forms'] ) ? $this->loginpress_setting['enable_pass_strength_forms'] : 'off';
$wc_reset = isset( $enable_pass_strength['wc_forms'] ) ? $enable_pass_strength['wc_forms'] : false;
$wp_reset = isset( $enable_pass_strength['reset'] ) ? $enable_pass_strength['reset'] : false;
$password = '';
if ( current_filter() === 'registration_errors' ) {
$password = isset( $_POST['loginpress-reg-pass'] ) ? sanitize_text_field( wp_unslash( $_POST['loginpress-reg-pass'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Registration form validation.
} elseif ( current_filter() === 'validate_password_reset' ) {
$wc_password = isset( $_POST['password_1'] ) ? sanitize_text_field( wp_unslash( $_POST['password_1'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Password reset validation.
$wp_password = isset( $_POST['pass1'] ) ? sanitize_text_field( wp_unslash( $_POST['pass1'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Password reset validation.
if ( $wc_password ) {
$password = $wc_password;
} elseif ( $wp_password ) {
$password = $wp_password;
}
}
$validate_filter = current_filter() === 'validate_password_reset' ? true : false;
if ( isset( $_POST['password_1'] ) && false === $wc_reset && $validate_filter ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Password validation logic.
return $errors;
}
if ( ! isset( $_POST['password_1'] ) && $wc_reset && false === $wp_reset && $validate_filter ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Password validation logic.
return $errors;
}
if ( ! isset( $_POST['pass1'] ) && ! isset( $_POST['password_1'] ) && $validate_filter ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Password validation logic.
return $errors;
}
$min_length = isset( $this->loginpress_setting['minimum_pass_char'] ) ? $this->loginpress_setting['minimum_pass_char'] : '';
$require_upper_lower = isset( $this->loginpress_setting['pass_strength']['lower_upper_char_must'] ) ? $this->loginpress_setting['pass_strength']['lower_upper_char_must'] : 'off';
$require_special_char = isset( $this->loginpress_setting['pass_strength']['special_char_must'] ) ? $this->loginpress_setting['pass_strength']['special_char_must'] : 'off';
$integer_number_must = isset( $this->loginpress_setting['pass_strength']['integer_no_must'] ) ? $this->loginpress_setting['pass_strength']['integer_no_must'] : 'off';
if ( $min_length ) {
if ( strlen( $password ) < $min_length ) {
$errors->add(
'password_too_short',
sprintf(
// translators: Minimum password length.
esc_html__( 'Password must be at least %d characters long.', 'loginpress' ),
$min_length
)
);
}
}
if ( 'off' !== $require_upper_lower ) {
if ( ( ! preg_match( '/[A-Z]/', $password ) || ! preg_match( '/[a-z]/', $password ) ) ) {
$errors->add( 'password_upper_lower_case', esc_html__( 'Password must contain at least one both upper and lower case letters.', 'loginpress' ) );
}
}
if ( 'off' !== $require_special_char ) {
if ( ! preg_match( '/[^a-zA-Z0-9]/', $password ) ) {
$errors->add( 'password_special_character', esc_html__( 'Password must contain at least one special character.', 'loginpress' ) );
}
}
if ( 'off' !== $integer_number_must ) {
if ( ! preg_match( '/[0-9]/', $password ) ) {
$errors->add( 'password_integer_number', esc_html__( 'Password must contain at least one integer number.', 'loginpress' ) );
}
}
return $errors;
}
/**
* Enqueue password strength meter script.
*
* @since 4.0.0
* @access public
* @return void
*/
public function loginpress_password_strength_meter() {
wp_enqueue_script( 'loginpress-pasword-strength-meter', plugins_url( 'js/password-strength-meter.js', defined( 'LOGINPRESS_ROOT_FILE' ) ? LOGINPRESS_ROOT_FILE : '' ), array( 'jquery', 'password-strength-meter' ), defined( 'LOGINPRESS_VERSION' ) ? LOGINPRESS_VERSION : '1.0.0', true );
}
/**
* Show password hint message based on password strength settings.
*
* @since 4.0.0
* @access public
* @param string $hint the password hint message.
* @return string the modified hint message.
*/
public function loginpress_password_hint( $hint ) {
$hint = self::loginpress_hint_creator();
return $hint;
}
/**
* Modify WooCommerce password strength meter hint message with LoginPress password strength message.
*
* @since 4.0.0
* @access public
* @param array<string, mixed> $params the password strength meter parameters.
* @param string $handle the handle of the script.
* @return array<string, mixed> the modified password strength meter parameters.
*/
public function loginpress_wc_reset_password_hint( $params, $handle ) {
$hint = self::loginpress_hint_creator();
if ( 'wc-password-strength-meter' === $handle && isset( $params['i18n_password_hint'] ) ) {
$params['i18n_password_hint'] = $hint;
}
return $params;
}
/**
* Remove the password strength meter hint message on WooCommerce reset password page.
*
* @since 4.0.0
* @access public
* @param array<string, mixed> $params the password strength meter parameters.
* @param string $handle the handle of the script.
* @return array<string, mixed> the modified password strength meter parameters.
*/
public function loginpress_wc_reset_remove_hint( $params, $handle ) {
if ( 'wc-password-strength-meter' === $handle && isset( $params['i18n_password_hint'] ) ) {
$params['i18n_password_hint'] = '';
}
return $params;
}
/**
* Create a hint based on password strength settings.
*
* @since 4.0.0
* @access public
* @return string the hint message.
*/
public static function loginpress_hint_creator() {
$loginpress_setting = get_option( 'loginpress_setting' );
$min_length = isset( $loginpress_setting['minimum_pass_char'] ) ? $loginpress_setting['minimum_pass_char'] : '';
$require_upper_lower = isset( $loginpress_setting['pass_strength']['lower_upper_char_must'] ) ? $loginpress_setting['pass_strength']['lower_upper_char_must'] : 'off';
$require_special_char = isset( $loginpress_setting['pass_strength']['special_char_must'] ) ? $loginpress_setting['pass_strength']['special_char_must'] : 'off';
$integer_number_must = isset( $loginpress_setting['pass_strength']['integer_no_must'] ) ? $loginpress_setting['pass_strength']['integer_no_must'] : 'off';
$upper_lower_text = 'off' !== $require_upper_lower ? esc_html__( 'Require upper and lower case letters.', 'loginpress' ) : '';
$special_char_text = 'off' !== $require_special_char ? esc_html__( 'Require special characters like ! " ? $ % ^ & *', 'loginpress' ) : '';
$integer_number_text = 'off' !== $integer_number_must ? esc_html__( 'Require numbers.', 'loginpress' ) : '';
$hint = sprintf(
// translators: Minimum password length.
__( 'Hint: The password should be at least %1$d characters long. %2$s %3$s %4$s ', 'loginpress' ),
$min_length,
$upper_lower_text,
$integer_number_text,
$special_char_text
);
return $hint;
}
}
endif;