diff --git a/class-two-factor-core.php b/class-two-factor-core.php index b396c60a..12ae6895 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -249,9 +249,12 @@ private static function get_providers_classes( $providers ) { } /** - * Get all enabled two-factor providers with keys as the original + * Get all registered two-factor providers with keys as the original * provider class names and the values as the provider class instances. * + * @see Two_Factor_Core::get_enabled_providers_for_user() + * @see Two_Factor_Core::get_supported_providers_for_user() + * * @since 0.1-dev * * @return array @@ -297,6 +300,28 @@ public static function get_providers() { return $providers; } + /** + * Get providers available for user which may not be enabled or configured. + * + * @see Two_Factor_Core::get_enabled_providers_for_user() + * @see Two_Factor_Core::get_available_providers_for_user() + * + * @param WP_User|int|null $user User ID. + * @return array List of provider instances indexed by provider key. + */ + public static function get_supported_providers_for_user( $user = null ) { + $user = self::fetch_user( $user ); + $providers = self::get_providers(); + + /** + * List of providers available to user which may not be enabled or configured. + * + * @param array $providers List of available provider instances indexed by provider key. + * @param int|WP_User $user User ID. + */ + return apply_filters( 'two_factor_providers_for_user', $providers, $user ); + } + /** * Enable the dummy method only during debugging. * @@ -483,7 +508,11 @@ public static function fetch_user( $user = null ) { } /** - * Get all Two-Factor Auth providers that are enabled for the specified|current user. + * Get two-factor providers that are enabled for the specified (or current) user + * but might not be configured, yet. + * + * @see Two_Factor_Core::get_supported_providers_for_user() + * @see Two_Factor_Core::get_available_providers_for_user() * * @param int|WP_User $user Optional. User ID, or WP_User object of the the user. Defaults to current user. * @return array @@ -494,7 +523,7 @@ public static function get_enabled_providers_for_user( $user = null ) { return array(); } - $providers = self::get_providers(); + $providers = self::get_supported_providers_for_user( $user ); $enabled_providers = get_user_meta( $user->ID, self::ENABLED_PROVIDERS_USER_META_KEY, true ); if ( empty( $enabled_providers ) ) { $enabled_providers = array(); @@ -511,10 +540,14 @@ public static function get_enabled_providers_for_user( $user = null ) { } /** - * Get all Two-Factor Auth providers that are both enabled and configured for the specified|current user. + * Get all two-factor providers that are both enabled and configured + * for the specified (or current) user. + * + * @see Two_Factor_Core::get_supported_providers_for_user() + * @see Two_Factor_Core::get_enabled_providers_for_user() * * @param int|WP_User $user Optional. User ID, or WP_User object of the the user. Defaults to current user. - * @return array + * @return array List of provider instances. */ public static function get_available_providers_for_user( $user = null ) { $user = self::fetch_user( $user ); @@ -522,8 +555,8 @@ public static function get_available_providers_for_user( $user = null ) { return array(); } - $providers = self::get_providers(); - $enabled_providers = self::get_enabled_providers_for_user( $user ); + $providers = self::get_supported_providers_for_user( $user ); // Returns full objects. + $enabled_providers = self::get_enabled_providers_for_user( $user ); // Returns just the keys. $configured_providers = array(); foreach ( $providers as $provider_key => $provider ) { @@ -538,7 +571,7 @@ public static function get_available_providers_for_user( $user = null ) { /** * Fetch the provider for the request based on the user preferences. * - * @param int|WP_User $user Optional. User ID, or WP_User object of the the user. Defaults to current user. + * @param int|WP_User $user Optional. User ID, or WP_User object of the the user. Defaults to current user. * @param null|string|object $preferred_provider Optional. The name of the provider, the provider, or empty. * @return null|object The provider */ @@ -556,7 +589,7 @@ public static function get_provider_for_user( $user = null, $preferred_provider // Default to the currently logged in provider. if ( ! $preferred_provider && get_current_user_id() === $user->ID ) { $session = self::get_current_user_session(); - if ( ! empty( $session['two-factor-provider'] ) ) { + if ( ! empty( $session['two-factor-provider'] ) ) { $preferred_provider = $session['two-factor-provider']; } } @@ -604,7 +637,7 @@ public static function get_primary_provider_for_user( $user = null ) { return null; } - $providers = self::get_providers(); + $providers = self::get_supported_providers_for_user( $user ); $available_providers = self::get_available_providers_for_user( $user ); // If there's only one available provider, force that to be the primary. @@ -1515,10 +1548,12 @@ public static function _login_form_revalidate_2fa( $nonce = '', $provider = '', } // Update the session metadata with the revalidation details. - self::update_current_user_session( array( - 'two-factor-provider' => $provider->get_key(), - 'two-factor-login' => time(), - ) ); + self::update_current_user_session( + array( + 'two-factor-provider' => $provider->get_key(), + 'two-factor-login' => time(), + ) + ); do_action( 'two_factor_user_revalidated', $user, $provider ); @@ -1754,7 +1789,7 @@ public static function show_password_reset_error() { ) ); - login_header( __( 'Password Reset', 'two-factor' ), '', $error ); + login_header( __( 'Password Reset', 'two-factor' ), '', $error ); login_footer(); } @@ -1804,10 +1839,11 @@ public static function manage_users_custom_column( $output, $column_name, $user_ public static function user_two_factor_options( $user ) { $notices = []; + $providers = self::get_supported_providers_for_user( $user ); + wp_enqueue_style( 'user-edit-2fa', plugins_url( 'user-edit.css', __FILE__ ), array(), TWO_FACTOR_VERSION ); $enabled_providers = array_keys( self::get_available_providers_for_user( $user ) ); - $primary_provider_key = self::get_primary_provider_key_selected_for_user( $user ); // This is specific to the current session, not the displayed user. $show_2fa_options = self::current_user_can_update_two_factor_options(); @@ -1820,18 +1856,18 @@ public static function user_two_factor_options( $user ) { ); $notices['warning two-factor-warning-revalidate-session'] = sprintf( - esc_html__( 'To update your Two-Factor options, you must first revalidate your session.', 'two-factor' ) . + esc_html__( 'To update your Two-Factor options, you must first revalidate your session.', 'two-factor' ) . ' ' . esc_html__( 'Revalidate now', 'two-factor' ) . '', - esc_url( $url ) + esc_url( $url ) ); } - printf( - '
', - $show_2fa_options ? '' : 'disabled="disabled"' - ); + if ( empty( $providers ) ) { + $notices['notice two-factor-notice-no-providers-supported'] = esc_html__( 'No providers are available for your account.', 'two-factor' ); + } - if ( 1 === count( $enabled_providers ) ) { + // Suggest enabling a backup method if only method is enabled and there are more available. + if ( count( $providers ) > 1 && 1 === count( $enabled_providers ) ) { $notices['warning two-factor-warning-suggest-backup'] = esc_html__( 'To prevent being locked out of your account, consider enabling a backup method like Recovery Codes in case you lose access to your primary authentication method.', 'two-factor' ); } ?> @@ -1842,15 +1878,44 @@ public static function user_two_factor_options( $user ) {

+ +
> + +
+ +

- +

+ - $object ) : ?> + $object ) : ?>