HEX
Server: LiteSpeed
System: Linux srv158.niagahoster.com 4.18.0-553.30.1.lve.el8.x86_64 #1 SMP Tue Dec 3 01:21:19 UTC 2024 x86_64
User: u1694298 (3732)
PHP: 7.4.33
Disabled: symlink,shell_exec,exec,popen,system,dl,passthru,escapeshellarg,escapeshellcmd,show_source,pcntl_exec
Upload Files
File: /home/u1694298/www/wp-content/plugins/hide-my-wp/controllers/Twofactor.php
<?php
/**
 * @package HMWPP/Twofactor
 * @since 1.0.0
 */

defined( 'ABSPATH' ) || die( 'Cheating uh?' );

class HMWP_Controllers_Twofactor extends HMWP_Classes_FrontController {

	/** @var WP_user Current logged in user */
	public $user;

	/** @var array Two-Factor Options */
	public $options = array();

	/** @var array Backup Codes */
	public $codes = array();

	public $downloadLinks;

	/**
	 * Constructor. Registers WP hooks for the two-factor authentication flow.
	 *
	 * Hooks into the authentication pipeline to collect credentials, intercept
	 * the login process, and validate the second factor. Skips 2FA hook
	 * registration when the safe URL is detected.
	 *
	 * @throws Exception
	 */
	public function __construct() {
		parent::__construct();

		//save the last login user
		add_filter( 'authenticate', array( $this->model, 'collectAuthLogin' ), PHP_INT_MAX, 1 );

		// If the safe URL was called, don't show the 2FA form
		if ( HMWP_Classes_Tools::calledSafeUrl() ) {
			return;
		}

		//Add login & validation hooks
		add_action( 'wp_login', array( $this, 'hookLogin' ), 10, 2 );
		add_action( 'set_auth_cookie', array( $this->model, 'collectAuthCookieTokens' ) );
		add_action( 'set_logged_in_cookie', array( $this->model, 'collectAuthCookieTokens' ) );
		add_action( 'init', array( $this->model, 'validateTwoFactor' ) );

		// AJAX endpoints for challenge (login) and (optionally) registration
		add_action( 'wp_ajax_hmwp_passkey_begin', array( $this->model, 'validatePasskeyLogin' ) );
		add_action( 'wp_ajax_nopriv_hmwp_passkey_begin', array( $this->model, 'validatePasskeyLogin' ) );

		//user list
		add_filter( 'manage_users_columns', array( $this->model, 'manageUsersColumnHeader' ) );
		add_filter( 'wpmu_users_columns', array( $this->model, 'manageUsersColumnHeader' ) );
		add_filter( 'manage_users_custom_column', array( $this->model, 'manageUsersColumn' ), 10, 3 );
		add_filter( 'users_list_table_query_args', array( $this->model, 'manageUsersColumnQuery' ) );
		add_filter( 'manage_users_sortable_columns', array( $this->model, 'manageUsersColumnSort' ) );

		if ( HMWP_Classes_Tools::isMultisites() ) {
			add_filter( 'manage_users-network_sortable_columns', array( $this->model, 'manageUsersColumnSort' ) );
		}

		//admin dashboard hooks
		add_action( 'admin_notices', array( $this->model, 'adminNotices' ) );

	}

	/**
	 * Load 2FA settings in the user profile
	 *
	 * @param $user
	 *
	 * @return void
	 * @throws Exception
	 */
	public function hookUserSettings( $user ) {

		HMWP_Classes_ObjController::getClass( 'HMWP_Classes_DisplayController' )->loadMedia( 'twofactor' );
		HMWP_Classes_ObjController::getClass( 'HMWP_Classes_DisplayController' )->loadMedia( 'qrcode' );

		//add 2FA with Code Scan in user settings View
		add_action( 'hmwp_two_factor_user_options', function () use ( $user ) {

			if ( ! $this->model->isActiveService( $user, 'hmwp_2fa_totp' )  ) {
				return;
			}

			/** @var HMWP_Models_Twofactor_Tftotp $twoFactorService */
			$twoFactorService = HMWP_Classes_ObjController::getClass( 'HMWP_Models_Twofactor_Tftotp' );

			$this->options = $twoFactorService->getTwoFactorOption( $user );

			//Show the two factor block
			$this->show( 'blocks/Totp' );
		} );

		//add 2FA with Email Code in user settings View
		add_action( 'hmwp_two_factor_user_options', function () use ( $user ) {

			if ( ! $this->model->isActiveService( $user, 'hmwp_2fa_email' )  ) {
					return;
			}

			/** @var HMWP_Models_Twofactor_Email $emailService */
			$emailService = HMWP_Classes_ObjController::getClass( 'HMWP_Models_Twofactor_Email' );

			$this->options = $emailService->getEmailOption( $user );

			//Show the two factor block
			$this->show( 'blocks/Email' );
		} );

		//add 2FA with Email Code in user settings View
		add_action( 'hmwp_two_factor_user_options', function () use ( $user ) {

			if ( ! $this->model->isActiveService( $user, 'hmwp_2fa_passkey' )  ) {
					return;
			}

			/** @var HMWP_Models_Twofactor_Passkey $passkeyService */
			$passkeyService = HMWP_Classes_ObjController::getClass( 'HMWP_Models_Twofactor_Passkey' );

			$this->options = $passkeyService->getPasskeyOption( $user );

			//Show the two factor block
			$this->show( 'blocks/Passkey' );
		} );

		$this->user = $user;

		//Show 2FA in user settings profile
		$this->show( 'TwofactorUser' );

		do_action( 'hmwp_user_security_settings_after', $user );
	}

	/**
	 * Handle the browser-based login.
	 *
	 * @param string $user_login Username.
	 * @param WP_User $user The WP_User instance representing the currently logged-in user.
	 *
	 * @throws Exception
	 */
	public function hookLogin( $user_login, $user ) {

		if ( isset( $_SERVER['REMOTE_ADDR'] ) ) { // phpcs:ignore WordPress.Security, check isset only
			$ip = $_SERVER['REMOTE_ADDR']; // phpcs:ignore WordPress.Security, filtered in isWhitelistedIP function

			if ( HMWP_Classes_ObjController::getClass( 'HMWP_Models_Firewall_Rules' )->isWhitelistedIP( $ip ) ) {
				return;
			}

			if ( $this->model->isRememberDevice( $user->ID ) ) {
				return;
			}

		}

		if ( ! $user ) {
			$user = wp_get_current_user();
		}
		/** @var HMWP_Models_Twofactor_Passkey $passkeyService */
		$passkeyService = HMWP_Classes_ObjController::getClass( 'HMWP_Models_Twofactor_Passkey' );

		/** @var HMWP_Models_Twofactor_Tftotp $twoFactorService */
		$twoFactorService = HMWP_Classes_ObjController::getClass( 'HMWP_Models_Twofactor_Tftotp' );

		/** @var HMWP_Models_Twofactor_Email $emailService */
		$emailService = HMWP_Classes_ObjController::getClass( 'HMWP_Models_Twofactor_Email' );

		// If none of the services are active
		if ( ! $passkeyService->isServiceActive( $user ) && ! $twoFactorService->isServiceActive( $user ) && ! $emailService->isServiceActive( $user ) ) {
			return;
		}

		// Invalidate the current login session to prevent from being re-used.
		$this->model->destroyCurrentSession( $user );

		$this->model->showTwoFactorLogin( $user );
		exit();
	}

	/**
	 * Get all 2FA logs
	 *
	 * @return array The array of 2FA logs
	 * @throws Exception
	 */
	public function getLogs() {

		$logs = array();

		if ( apply_filters( 'hmwp_showlogins', true ) ) {

			/** @var HMWP_Models_Twofactor $twoFactorModel */
			$twoFactorModel = HMWP_Classes_ObjController::getClass( 'HMWP_Models_Twofactor' );

			/** @var HMWP_Models_Twofactor_Tftotp $twoFactorService */
			$twoFactorService = HMWP_Classes_ObjController::getClass( 'HMWP_Models_Twofactor_Tftotp' );

			/** @var HMWP_Models_Twofactor_Email $emailService */
			$emailService = HMWP_Classes_ObjController::getClass( 'HMWP_Models_Twofactor_Email' );

			/** @var HMWP_Models_Twofactor_Passkey $passkeyService */
			$passkeyService = HMWP_Classes_ObjController::getClass( 'HMWP_Models_Twofactor_Passkey' );

			/** @var WP_User[] $users */
			$users = get_users();

			foreach ( $users as $user ) {

				if ( $last_totp_login = $twoFactorService->getLastLoginTimestamp( $user->ID ) ) {
					$logs[] = array(
						'user'       => $user,
						'email'      => $user->user_email,
						'last_login' => $twoFactorModel->timeElapsed( $last_totp_login ),
						'success'    => true,
						'mode'       => esc_html__( '2FA Code', 'hide-my-wp' ),
					);
				}


				if ( $last_totp_login = $emailService->getLastLoginTimestamp( $user->ID ) ) {
					$logs[] = array(
						'user'       => $user,
						'email'      => $user->user_email,
						'last_login' => $twoFactorModel->timeElapsed( $last_totp_login ),
						'success'    => true,
						'mode'       => esc_html__( "Email Code", 'hide-my-wp' ),
					);
				}

				if ( $last_failed = $twoFactorModel->getLastUserLoginFail( $user ) ) {
					$logs[] = array(
						'user'       => $user,
						'email'      => $user->user_email,
						'last_login' => wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $last_failed ),
						'success'    => false,
					);
				}

				if ( $last_passkey_login = $passkeyService->getLastLoginTimestamp( $user->ID ) ) {
					$logs[] = array(
						'user'       => $user,
						'email'      => $user->user_email,
						'last_login' => $twoFactorModel->timeElapsed( $last_passkey_login ),
						'success'    => true,
						'mode'       => esc_html__( 'Passkey', 'hide-my-wp' ),
					);
				}

			}

			return $logs;

		}

		return $logs;

	}

	/**
	 * Login form validation.
	 *
	 * @return void
	 * @throws Exception
	 */
	public function action() {
		parent::action();

		//if the current user can't manage the personal profile
		if ( ! HMWP_Classes_Tools::userCan( 'read' ) ) {
			return;
		}

		switch ( HMWP_Classes_Tools::getValue( 'action' ) ) {
			case 'hmwp_2fasettings':

				// Check if the current user has the 'hmwp_manage_settings' capability
				if ( ! HMWP_Classes_Tools::userCan( HMWP_CAPABILITY ) ) {
					return;
				}

				if ( isset( $_SERVER['REQUEST_METHOD'] ) && 'POST' === strtoupper( $_SERVER['REQUEST_METHOD'] ) ) { // phpcs:ignore WordPress.Security
					$this->saveValues( $_POST ); // phpcs:ignore WordPress.Security, nonce is checked in function
				}

				// Save the text every time to prevent from removing the white space from the text
				HMWP_Classes_Tools::saveOptions( 'hmwp_2falogin_message', HMWP_Classes_Tools::getValue( 'hmwp_2falogin_message' ) );
				HMWP_Classes_Tools::saveOptions( 'hmwp_2falogin_fail_message', HMWP_Classes_Tools::getValue( 'hmwp_2falogin_fail_message' ) );

				// Add action for later use
				do_action( 'hmwp_2fasettings_saved' );

				HMWP_Classes_Error::setNotification( esc_html__( 'Saved', 'hide-my-wp' ), 'success' );

				break;
			case 'hmwp_2fa_method':

				$user_id = HMWP_Classes_Tools::getValue( 'user_id' );
				$method     = HMWP_Classes_Tools::getValue( 'method' );

				HMWP_Classes_Tools::saveUserMeta('_hmwp_2fa_method', $method, $user_id);

				wp_send_json_success( esc_html__( 'Saved', 'hide-my-wp' ) );

				break;
			case 'hmwp_totp_submit':
				$user_id = HMWP_Classes_Tools::getValue( 'user_id' );
				$key     = HMWP_Classes_Tools::getValue( 'key' );
				$code    = HMWP_Classes_Tools::getValue( 'authcode' );

				/** @var HMWP_Models_Twofactor_Tftotp $twoFactorService */
				$twoFactorService = HMWP_Classes_ObjController::getClass( 'HMWP_Models_Twofactor_Tftotp' );
				$response         = $twoFactorService->setupTotp( $user_id, $key, $code );

				if ( ! is_wp_error( $response ) ) {
					$user = get_user_by( 'ID', $user_id );

					$this->options = $twoFactorService->getTwoFactorOption( $user );

					//Show the two factor block
					wp_send_json_success( $this->getView( 'blocks/Totp' ) );
				} else {
					/** @var WP_Error $response */
					wp_send_json_error( $response->get_error_message() );
				}
				break;
			case 'hmwp_totp_reset':
				$user_id = HMWP_Classes_Tools::getValue( 'user_id' );


				/** @var HMWP_Models_Twofactor_Tftotp $twoFactorService */
				$twoFactorService = HMWP_Classes_ObjController::getClass( 'HMWP_Models_Twofactor_Tftotp' );

				if ( $twoFactorService->deleteUserTotpKey( $user_id ) ) {

					// Remove the remember devices
					$this->model->deleteRememberDevices( $user_id );

					$user = get_user_by( 'ID', $user_id );

					$this->options = $twoFactorService->getTwoFactorOption( $user );

					//Show the two-factor block
					wp_send_json_success( $this->getView( 'blocks/Totp' ) );
				} else {
					wp_send_json_error( 'Error' );
				}
				break;
			case 'hmwp_codes_generate':
				$user_id = HMWP_Classes_Tools::getValue( 'user_id' );

				/** @var HMWP_Models_Twofactor_Codes $codesService */
				$codesService = HMWP_Classes_ObjController::getClass( 'HMWP_Models_Twofactor_Codes' );

				if ( $user = get_user_by( 'ID', (int) $user_id ) ) {
					if ( $this->codes = $codesService->generateCodes( $user ) ) {
						$this->downloadLinks = $codesService->getDownloadLink( $this->codes );

						//Show the two factor block
						wp_send_json_success( $this->getView( 'blocks/Codes' ) );
					} else {
						wp_send_json_error( 'Error' );
					}
				}

				break;

			case 'hmwp_email_submit':
				$user_id = HMWP_Classes_Tools::getValue( 'user_id' );
				$email   = HMWP_Classes_Tools::getValue( 'email' );

				/** @var HMWP_Models_Twofactor_Email $emailService */
				$emailService = HMWP_Classes_ObjController::getClass( 'HMWP_Models_Twofactor_Email' );

				if ( $user_id ) {
					if ( $emailService->setUserEmail( $user_id, $email ) ) {
						$user = get_user_by( 'ID', $user_id );

						$this->options = $emailService->getEmailOption( $user );

						wp_send_json_success( $this->getView( 'blocks/Email' ) );
					} else {
						wp_send_json_error( 'Error' );
					}
				}

				break;

			case 'hmwp_email_reset':
				$user_id = HMWP_Classes_Tools::getValue( 'user_id' );

				/** @var HMWP_Models_Twofactor_Email $emailService */
				$emailService = HMWP_Classes_ObjController::getClass( 'HMWP_Models_Twofactor_Email' );

				if ( $user_id ) {
					if ( $emailService->deleteUserEmail( $user_id ) ) {
						$user = get_user_by( 'ID', $user_id );

						$this->options = $emailService->getEmailOption( $user );

						wp_send_json_success( $this->getView( 'blocks/Email' ) );
					} else {
						wp_send_json_error( 'Error' );
					}
				}

				break;

			case 'hmwp_passkey_submit':
				$user_id = HMWP_Classes_Tools::getValue( 'user_id' );

				if ( ! $user_id ) {
					wp_send_json_error( esc_html__( 'Not authenticated.', 'hide-my-wp' ) );
				}

				/** @var HMWP_Models_Twofactor_Passkey $passkeyService */
				$passkeyService = HMWP_Classes_ObjController::getClass( 'HMWP_Models_Twofactor_Passkey' );

				if ( $user_id ) {
					if ($passkey = $passkeyService->passkeyRegister( $user_id )){
						wp_send_json_success( $passkey );
					}
				}

				wp_send_json_error( esc_html__( 'Passkey registered failed.', 'hide-my-wp' ) );
				break;

			case 'hmwp_passkey_register':

				$user_id = HMWP_Classes_Tools::getValue( 'user_id' );

				if ( ! $user_id || ! isset( $_POST['credential'] ) ) { //phpcs:ignore
					wp_send_json_error( esc_html__( 'Not authenticated.', 'hide-my-wp' ) );
				}

				$credential = json_decode( sanitize_text_field( wp_unslash( $_POST['credential'] ) ), true ); //phpcs:ignore

				/** @var HMWP_Models_Twofactor_Passkey $passkeyService */
				$passkeyService = HMWP_Classes_ObjController::getClass( 'HMWP_Models_Twofactor_Passkey' );

				if ( $user_id && $passkeyService->registerCredential( $user_id, $credential )) {
					wp_send_json_success( esc_html__( 'Passkey registered successfully.', 'hide-my-wp' ) );
				}

				wp_send_json_error( esc_html__( 'Passkey registered failed.', 'hide-my-wp' ) );
				break;

			case 'hmwp_passkey_remove':

				$user_id = HMWP_Classes_Tools::getValue( 'user_id' );
				$id = HMWP_Classes_Tools::getValue( 'id' );

				if ( ! $user_id ) {
					wp_send_json_error( esc_html__( 'Not authenticated.', 'hide-my-wp' ) );
				}

				/** @var HMWP_Models_Twofactor_Passkey $passkeyService */
				$passkeyService = HMWP_Classes_ObjController::getClass( 'HMWP_Models_Twofactor_Passkey' );

				if ( $user_id && $passkeyService->passkeyDelete( $user_id, $id )) {
					wp_send_json_success( esc_html__( 'Passkey deleted successfully.', 'hide-my-wp' ) );
				}

				wp_send_json_error( esc_html__( 'Passkey deleted failed.', 'hide-my-wp' ) );
				break;


		}
	}

	/**
	 * Persist a set of plugin option values.
	 *
	 * Iterates over the supplied key/value pairs, sanitizes each value that
	 * corresponds to a known plugin option, and saves them all in one call.
	 *
	 * @param array $params Associative array of option keys and their new values.
	 *
	 * @return void
	 */
	public function saveValues( $params ) {

		//Save the option values
		foreach ( $params as $key => $value ) {
			if ( in_array( $key, array_keys( HMWP_Classes_Tools::$options ) ) ) {

				//Sanitize each value from subarray
				HMWP_Classes_Tools::$options[ $key ] = HMWP_Classes_Tools::getValue( $key );
			}
		}

		//sanitize the value and save it
		HMWP_Classes_Tools::saveOptions();
	}

}