From 90d595785b0888f37b06f1224ddad35de4e9ad14 Mon Sep 17 00:00:00 2001 From: Kaspars Dambis Date: Thu, 19 Sep 2024 13:17:57 +0300 Subject: [PATCH 01/11] Prototype --- class-two-factor-core.php | 45 ++++++++++++++++++++++----------------- user-edit.css | 13 ----------- 2 files changed, 25 insertions(+), 33 deletions(-) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index eebce9c4..a1450cc6 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -1800,9 +1800,9 @@ public static function user_two_factor_options( $user ) { } // This is specific to the current session, not the displayed user. - $show_2fa_options = self::current_user_can_update_two_factor_options(); + $show_2fa_options = self::current_user_can_update_two_factor_options() || true; - if ( ! $show_2fa_options ) { + if ( ! $show_2fa_options && false ) { $url = self::get_user_two_factor_revalidate_url(); $url = add_query_arg( 'redirect_to', urlencode( self::get_user_settings_page_url( $user->ID ) . '#two-factor-options' ), $url ); @@ -1830,28 +1830,26 @@ public static function user_two_factor_options( $user ) { ?>

+ $notice ) : ?>

+ - - - - - - - - + +
$object ) : ?> - - + + + + + - - - - - - - Date: Tue, 3 Dec 2024 12:27:23 +0200 Subject: [PATCH 02/11] Remove test code --- class-two-factor-core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index 0b69ea04..236663fa 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -1802,7 +1802,7 @@ public static function user_two_factor_options( $user ) { } // This is specific to the current session, not the displayed user. - $show_2fa_options = self::current_user_can_update_two_factor_options() || true; + $show_2fa_options = self::current_user_can_update_two_factor_options(); if ( ! $show_2fa_options ) { $url = add_query_arg( From d369a3ac4e1db043f937e0100db7ed1356bd1bbf Mon Sep 17 00:00:00 2001 From: Kaspars Dambis Date: Tue, 3 Dec 2024 12:47:43 +0200 Subject: [PATCH 03/11] Primary is determined dynamically --- class-two-factor-core.php | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index 236663fa..a38da73e 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -1920,16 +1920,8 @@ public static function enable_provider_for_user( $user_id, $new_provider ) { } $enabled_providers[] = $new_provider; - $enabled = update_user_meta( $user_id, self::ENABLED_PROVIDERS_USER_META_KEY, $enabled_providers ); - // Primary provider must be enabled. - $has_primary = is_object( self::get_primary_provider_for_user( $user_id ) ); - - if ( ! $has_primary ) { - $has_primary = update_user_meta( $user_id, self::PROVIDER_USER_META_KEY, $new_provider ); - } - - return $enabled && $has_primary; + return update_user_meta( $user_id, self::ENABLED_PROVIDERS_USER_META_KEY, $enabled_providers ); } /** From cc830ce3c59263ae99689e03f11acf2c5be3bc4c Mon Sep 17 00:00:00 2001 From: Kaspars Dambis Date: Tue, 3 Dec 2024 12:48:07 +0200 Subject: [PATCH 04/11] Allow unsetting the primary provider for default behaviour --- class-two-factor-core.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index a38da73e..1a2a0334 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -1991,6 +1991,8 @@ public static function user_two_factor_options_update( $user_id ) { $new_provider = isset( $_POST[ self::PROVIDER_USER_META_KEY ] ) ? $_POST[ self::PROVIDER_USER_META_KEY ] : ''; if ( ! empty( $new_provider ) && in_array( $new_provider, $enabled_providers, true ) ) { update_user_meta( $user_id, self::PROVIDER_USER_META_KEY, $new_provider ); + } else { + delete_user_meta( $user_id, self::PROVIDER_USER_META_KEY ); } // Have we changed the two-factor settings for the current user? Alter their session metadata. From ab43eb3c6888466512313c6f08443619e36e3610 Mon Sep 17 00:00:00 2001 From: Kaspars Dambis Date: Tue, 3 Dec 2024 13:18:37 +0200 Subject: [PATCH 05/11] Introduce a dedicated helper to fetch the user selection Required for settings and to seperate from default pick by system --- class-two-factor-core.php | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index 1a2a0334..26cc9e55 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -576,6 +576,25 @@ public static function get_provider_for_user( $user = null, $preferred_provider return self::get_primary_provider_for_user( $user ); } + /** + * Get the name of the primary provider selected by the user + * and enabled for the user. + * + * @param WP_User|int $user User ID or instance. + * + * @return string|null + */ + private static function get_primary_provider_key_selected_for_user( $user ) { + $primary_provider = get_user_meta( $user->ID, self::PROVIDER_USER_META_KEY, true ); + $available_providers = self::get_available_providers_for_user( $user ); + + if ( ! empty( $primary_provider ) && ! empty( $available_providers[ $primary_provider ] ) ) { + return $primary_provider; + } + + return null; + } + /** * Gets the Two-Factor Auth provider for the specified|current user. * @@ -599,7 +618,7 @@ public static function get_primary_provider_for_user( $user = null ) { } elseif ( 1 === count( $available_providers ) ) { $provider = key( $available_providers ); } else { - $provider = get_user_meta( $user->ID, self::PROVIDER_USER_META_KEY, true ); + $provider = self::get_primary_provider_key_selected_for_user( $user ); // If the provider specified isn't enabled, just grab the first one that is. if ( ! isset( $available_providers[ $provider ] ) ) { @@ -1793,13 +1812,7 @@ public static function user_two_factor_options( $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 = self::get_primary_provider_for_user( $user->ID ); - - if ( ! empty( $primary_provider ) && is_object( $primary_provider ) ) { - $primary_provider_key = $primary_provider->get_key(); - } else { - $primary_provider_key = null; - } + $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(); From 26331d3ed60158b115c24d8daf31e1bcd1056745 Mon Sep 17 00:00:00 2001 From: Kaspars Dambis Date: Tue, 3 Dec 2024 13:32:26 +0200 Subject: [PATCH 06/11] Return a boolean per tests --- class-two-factor-core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index 26cc9e55..55fdfb2c 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -1934,7 +1934,7 @@ public static function enable_provider_for_user( $user_id, $new_provider ) { $enabled_providers[] = $new_provider; - return update_user_meta( $user_id, self::ENABLED_PROVIDERS_USER_META_KEY, $enabled_providers ); + return (bool) update_user_meta( $user_id, self::ENABLED_PROVIDERS_USER_META_KEY, $enabled_providers ); } /** From 1cf08896dd9bc899a2b0512b72d23ddb2f2d3d21 Mon Sep 17 00:00:00 2001 From: Kaspars Dambis Date: Thu, 9 Jan 2025 13:49:22 +0200 Subject: [PATCH 07/11] Per suggestion from @jeffpaul --- class-two-factor-core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index b75cec68..36900643 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -1885,7 +1885,7 @@ public static function user_two_factor_options( $user ) { -

+

From 116609869b80e6ace2c5b59c0bcd64ca8365ca54 Mon Sep 17 00:00:00 2001 From: Kaspars Dambis Date: Thu, 9 Jan 2025 13:59:33 +0200 Subject: [PATCH 08/11] Move to own section for visual seperation --- class-two-factor-core.php | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index 36900643..b396c60a 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -1874,20 +1874,25 @@ public static function user_two_factor_options( $user ) { - - - - -

- - + + +
+ + + + + + From 701a26058d09ad1bb2fc37432f39e18dd0af78ec Mon Sep 17 00:00:00 2001 From: Kaspars Dambis Date: Thu, 9 Jan 2025 14:13:11 +0200 Subject: [PATCH 09/11] Consistent casing with the other methods --- providers/class-two-factor-totp.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/class-two-factor-totp.php b/providers/class-two-factor-totp.php index e94163f4..d58ec6d3 100644 --- a/providers/class-two-factor-totp.php +++ b/providers/class-two-factor-totp.php @@ -110,7 +110,7 @@ public function register_rest_routes() { * Returns the name of the provider. */ public function get_label() { - return _x( 'Authenticator app', 'Provider Label', 'two-factor' ); + return _x( 'Authenticator App', 'Provider Label', 'two-factor' ); } /** From f1b53ef83364c3784c3a972729783d036cdcf288 Mon Sep 17 00:00:00 2001 From: Kaspars Dambis Date: Thu, 9 Jan 2025 14:13:21 +0200 Subject: [PATCH 10/11] Mention the TOTP at least somewhere --- providers/class-two-factor-totp.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/class-two-factor-totp.php b/providers/class-two-factor-totp.php index d58ec6d3..9b3dd084 100644 --- a/providers/class-two-factor-totp.php +++ b/providers/class-two-factor-totp.php @@ -119,7 +119,7 @@ public function get_label() { * @since 0.9.0 */ public function get_alternative_provider_label() { - return __( 'Use your authenticator app', 'two-factor' ); + return __( 'Use your authenticator app for time-based one-time passwords (TOTP)', 'two-factor' ); } /** From 54f34e5e7386c22bfc2c2b5c679ad48cb8a0d139 Mon Sep 17 00:00:00 2001 From: Kaspars Dambis Date: Thu, 9 Jan 2025 14:36:23 +0200 Subject: [PATCH 11/11] Match the updated title --- tests/providers/class-two-factor-totp.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/providers/class-two-factor-totp.php b/tests/providers/class-two-factor-totp.php index 52aa6090..62663323 100644 --- a/tests/providers/class-two-factor-totp.php +++ b/tests/providers/class-two-factor-totp.php @@ -58,7 +58,7 @@ public function test_get_instance() { * @covers Two_Factor_Totp::get_label */ public function test_get_label() { - $this->assertStringContainsString( 'Authenticator app', $this->provider->get_label() ); + $this->assertStringContainsString( 'Authenticator App', $this->provider->get_label() ); } /**