File manager - Edit - /home/xfekoga/grenier/wp-content/plugins/defender-security/src/component/two-factor/providers/class-webauthn.php
Back
<?php /** * Handles Web Authentication (WebAuthn) for Two-Factor Authentication. * * @package WP_Defender\Component\Two_Factor\Providers */ namespace WP_Defender\Component\Two_Factor\Providers; use WP_User; use WP_Error; use WP_Defender\Component\Two_Fa; use WP_Defender\Behavior\WPMUDEV; use WP_Defender\Traits\Webauthn as Webauthn_Trait; use WP_Defender\Component\Webauthn as Webauthn_Component; use WP_Defender\Component\Two_Factor\Two_Factor_Provider; use WP_Defender\Controller\Webauthn as Webauthn_Controller; /** * Handle Web Authentication (WebAuthn) for Two-Factor Authentication. * * @since 3.0.0 */ class Webauthn extends Two_Factor_Provider { use Webauthn_Trait; /** * 2fa provider slug. * * @var string */ public static $slug = 'webauthn'; /** * Constructor for the Biometric provider. */ public function __construct() { add_action( 'wd_2fa_user_options_' . self::$slug, array( $this, 'user_options' ) ); } /** * Get the name of the provider. * * @return string */ public function get_label(): string { return $this->get_user_label(); } /** * Get login label. * * @return string */ public function get_login_label(): string { return $this->get_label(); } /** * Get user label. * * @return string */ public function get_user_label(): string { return esc_html__( 'Web Authentication', 'defender-security' ); } /** * Get the desc of the provider. * * @return string */ public function get_description(): string { return esc_html__( "Authenticate login using your device's built-in fingerprint, facial recognition, or an external hardware security key.", 'defender-security' ); } /** * Display auth method. * * @param WP_User $user WP_User object of the logged-in user. */ public function user_options( WP_User $user ): void { $notices = array( array( 'type' => 'info', 'extra_class' => 'additional-2fa-method', 'style' => 'display: none', 'message' => esc_html__( 'Access from unregistered devices will be denied. To avoid this, consider setting up an additional authentication method.', 'defender-security' ), ), ); $missed_requirement_message = $this->missed_requirement_message(); $user_has_admin_capability = current_user_can( 'manage_options' ); if ( $user_has_admin_capability ) { $notice_message = $missed_requirement_message['warning']; } else { $notice_message = esc_html__( 'Your site doesn\'t meet the web authentication requirement. Please contact your site\'s administrator to fix this issue.', 'defender-security' ); } $all_server_requirement_passed = $missed_requirement_message['all_server_requirement_passed']; if ( $all_server_requirement_passed ) { $message = $missed_requirement_message['browser_message']; $extra_class = ' browser-notice '; } else { $message = $notice_message; $extra_class = ' has-server-error '; } $notices[] = array( 'type' => 'warning', 'extra_class' => $extra_class, 'style' => '', 'message' => $message, ); $translations = wd_di()->get( Webauthn_Controller::class )->get_translations(); $notices[] = array( 'type' => 'warning', 'extra_class' => ' user-handle-mismatch ', 'style' => 'display: none', 'is_dismissible' => true, 'message' => $translations['user_handle_mismatch_main_notice'], ); $this->get_controller()->render_partial( 'two-fa/providers/biometric', array( 'notices' => $notices, ) ); } /** * Whether this 2FA provider is configured and available for the user specified. * * @param WP_User $user WP_User object of the logged-in user. * * @return bool */ public function is_available_for_user( WP_User $user ): bool { return true; } /** * Authentication form markup. * * @return void */ public function authentication_form() { ?> <div class="welcome-screen"> <p class="wpdef-2fa-label"><?php echo $this->get_login_label(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></p> <p><?php esc_html_e( 'Select an authentication method to continue.', 'defender-security' ); ?></p> <div class="option-row" data-authType="platform"> <span class="icon biometric"></span> <span> <strong class="option-hd"><?php esc_html_e( 'Biometric Authentication', 'defender-security' ); ?></strong> <?php esc_html_e( 'Use fingerprint or facial recognition', 'defender-security' ); ?> </span> </div> <div class="option-row" data-authType="cross-platform"> <span class="icon hardware"></span> <span> <strong class="option-hd"><?php esc_html_e( 'Hardware Key Authentication', 'defender-security' ); ?></strong> <?php esc_html_e( 'Use USB security keys to login', 'defender-security' ); ?> </span> </div> </div> <div class="webauthn-content-wrap"> <div class="webauthn-platform" style="display:none;"> <p class="wpdef-2fa-label"><?php esc_html_e( 'Biometric Authentication', 'defender-security' ); ?></p> <p class="wpdef-2fa-text"> <?php esc_html_e( 'Please verify your identity using fingerprint or facial recognition.', 'defender-security' ); ?> </p> </div> <div class="webauthn-cross-platform" style="display:none;"> <p class="wpdef-2fa-label"><?php esc_html_e( 'Hardware Key Authentication', 'defender-security' ); ?></p> <p class="wpdef-2fa-text"> <?php esc_html_e( 'Insert and tap on your USB security key to login.', 'defender-security' ); ?> </p> </div> <p class="wpdef-2fa-text wpdef-2fa-biometric-process-desc" style="display: none;"> <img class="def-loader" src="<?php defender_asset_url( '/assets/img/spinner.svg', true ); ?>" alt="loading"> <?php esc_html_e( 'Verification in process...', 'defender-security' ); ?> </p> <div class="wpdef-2fa-webauthn-control" style="display:none;"> <button type="button" class="button" id="wpdef-2fa-webauthn-back-btn"><?php esc_html_e( 'Back', 'defender-security' ); ?></button> <button type="button" class="button button-primary float-r" id="wpdef-2fa-biometric-retry-btn"> <span class="dashicons dashicons-update"></span> <?php esc_html_e( 'Retry', 'defender-security' ); ?> </button> </div> <input type="hidden" id="wpdef-2fa-biometric-data" name="data"/> <input type="hidden" id="wpdef-2fa-biometric-username" name="username"/> <input type="hidden" id="wpdef-2fa-biometric-client-id" name="client_id"/> <input type="hidden" id="wpdef-2fa-biometric-nonce" name="_def_nonce"/> <button id="wpdef-2fa-biometric-submit-btn" type="submit" style="display:none;"></button> </div> <?php } /** * Whether this 2FA provider is configured and available for the user specified. * * @param WP_User $user The user to authenticate. * * @return bool|WP_Error */ public function validate_authentication( WP_User $user ) { $webauthn_controller = wd_di()->get( Webauthn_Controller::class ); $response = $webauthn_controller->verify_response( true ); if ( isset( $response['success'] ) && true === $response['success'] ) { return true; } else { // No attempt-checks. $translations = $webauthn_controller->get_translations(); if ( 'Invalid user handle' === $response['data']['message'] ) { $message = $translations['login_user_handle_match_failed']; } else { $message = $translations['login_failed']; } return new WP_Error( 'opt_fail', $message ); } } /** * Create missed requirement message. * Create dynamic message with boolean flag for all server requirement passed. * * @return array Dynamic message with boolean flag for all server requirement passed. */ private function missed_requirement_message(): array { $warning_count = 0; $all_server_requirement_passed = true; $warning_core_message = ''; if ( ! $this->is_ssl() ) { ++$warning_count; $all_server_requirement_passed = false; $warning_core_message .= esc_html__( 'SSL certificate or HTTPS is not forced. ', 'defender-security' ); } $extension_warning_message = $this->get_extension_warning_message(); if ( '' !== $extension_warning_message ) { $warning_count += count( $this->get_failed_extension() ); $all_server_requirement_passed = false; $warning_core_message .= $extension_warning_message; } $browser_extension_message = '<span class="browser-incompatible-msg">'; $browser_extension_message .= sprintf( /* translators: %s: Browser version */ esc_html__( 'The current browser version %s is not compatible with this feature, please update your browser version, or try a different one. ', 'defender-security' ), '<span class="browser-version">' . $this->get_browser_name() . '</span>' ); $browser_extension_message .= '</span>'; $warning_prefix = _n( 'Your site doesn\'t meet the web authentication requirement. ', 'Your site doesn\'t meet the web authentication requirements. ', $warning_count, 'defender-security' ); $warning_suffix = $this->get_warning_suffix(); $warning = $warning_prefix . $warning_core_message . $browser_extension_message . $warning_suffix; $browser_message = $warning_prefix . $browser_extension_message . $warning_suffix; return array( 'warning' => $warning, 'all_server_requirement_passed' => $all_server_requirement_passed, 'browser_message' => $browser_message, ); } /** * Get list of failed extensions. * * @return array Array of failed extensions or empty array if all extensions exists. */ private function get_failed_extension(): array { $failed_extensions = array(); if ( ! $this->is_enabled_gmp() ) { $failed_extensions[] = 'GMP'; } if ( ! $this->is_enabled_mbstring() ) { $failed_extensions[] = 'MBSTRING'; } if ( ! $this->is_enabled_sodium() ) { $failed_extensions[] = 'SODIUM'; } return $failed_extensions; } /** * Concatenate multiple failed extensions. * Form a comma separated with and before last element string from array of elements, if elements is more than two. * * @param array $extensions list of failed extensions. * * @return string Return concatenated string on success else empty string. */ private function concatenate_failed_extensions( array $extensions ): string { if ( count( $extensions ) === 1 ) { return $extensions[0]; } if ( count( $extensions ) > 1 ) { $last_extension = esc_html__( ' and ', 'defender-security' ) . array_pop( $extensions ); return implode( ', ', $extensions ) . $last_extension; } return ''; } /** * Create extension warning message * * @return string Warning message if extension not met the requirement or empty string for met requirement. */ private function get_extension_warning_message(): string { $message = ''; $failed_extensions = $this->get_failed_extension(); $failed_extensions_count = count( $failed_extensions ); if ( $failed_extensions_count > 0 ) { $extension_string = $this->concatenate_failed_extensions( $failed_extensions ); $message .= sprintf( /* translators: %s: Missing PHP extension(s) */ _n( 'The <strong>%s extension</strong> is not active on your server. ', 'The <strong>%s extensions</strong> are not active on your server. ', $failed_extensions_count, 'defender-security' ), $extension_string ); } return $message; } /** * Retrieves the browser name and optionally the version. * * @param bool $with_version Whether to include the version number. * * @return string Browser name, optionally including the version. */ private function get_browser_name( $with_version = true ): string { if ( ! function_exists( 'wp_check_browser_version' ) ) { include_once ABSPATH . 'wp-admin/includes/dashboard.php'; } $browser = wp_check_browser_version(); $browser_string = $browser['name'] . ( $with_version ? ' ' . $browser['version'] : '' ); return $browser_string; } /** * Determine the warning suffix. * * @return string Warning suffix sentence. */ private function get_warning_suffix(): string { $warning_suffix = ''; if ( ( new WPMUDEV() )->show_support_links() ) { $warning_suffix = defender_support_ticket_text(); } return $warning_suffix; } /** * Check if OTP screen should be shown to user. * * @param WP_User $user The user to check. * * @return bool * @since 3.3.0 */ public function is_otp_screen_available( WP_User $user ): bool { $is_available = false; $service_two_fa = wd_di()->get( Two_Fa::class ); $enabled_providers = $service_two_fa->get_enabled_providers_for_user( $user ); if ( ! empty( $user->ID ) && true === in_array( self::$slug, $enabled_providers, true ) ) { $controller = wd_di()->get( Webauthn_Controller::class ); $service_webauthn = wd_di()->get( Webauthn_Component::class ); $user_entity = $controller->get_user_entity( $user->ID ); if ( false !== $user_entity ) { $credential_sources = $service_webauthn->findAllForUserEntity( $user_entity ); if ( is_array( $credential_sources ) && 0 < count( $credential_sources ) ) { $is_available = true; } } } return $is_available; } }
| ver. 1.4 |
Github
|
.
| PHP 8.0.30 | Generation time: 0 |
proxy
|
phpinfo
|
Settings