From 6a438ba2beae8398bf1199179dde1644d492a241 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 26 Mar 2026 21:54:20 +0100 Subject: [PATCH 01/12] fix WordPress.Files.FileName.InvalidClassFileName --- .../{class-secure-dummy.php => class-two-factor-secure-dummy.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/{class-secure-dummy.php => class-two-factor-secure-dummy.php} (100%) diff --git a/tests/class-secure-dummy.php b/tests/class-two-factor-secure-dummy.php similarity index 100% rename from tests/class-secure-dummy.php rename to tests/class-two-factor-secure-dummy.php From 1050fab62b17ad45c53f03d19f99c5a1b2acd53e Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 26 Mar 2026 21:54:26 +0100 Subject: [PATCH 02/12] fix WordPress.Files.FileName.InvalidClassFileName --- TESTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TESTS.md b/TESTS.md index d0460f50..1b92bb10 100644 --- a/TESTS.md +++ b/TESTS.md @@ -157,4 +157,4 @@ Tests `Two_Factor_Dummy_Secure` (a fixture that always _fails_ authentication, u ## Test Helpers - **`tests/bootstrap.php`** — Locates the WordPress test library (via `WP_TESTS_DIR` env var, relative path, or `/tmp/wordpress-tests-lib`), loads the plugin via `muplugins_loaded`, then boots the WP test environment. -- **`tests/class-secure-dummy.php`** — Defines `Two_Factor_Dummy_Secure`, a test-only provider class that spoofs the key of `Two_Factor_Dummy` but always fails `validate_authentication`. Used by `Tests_Two_Factor_Dummy_Secure` and some core tests. +- **`tests/class-two-factor-secure-dummy.php`** — Defines `Two_Factor_Dummy_Secure`, a test-only provider class that spoofs the key of `Two_Factor_Dummy` but always fails `validate_authentication`. Used by `Tests_Two_Factor_Dummy_Secure` and some core tests. From 3a407e388ef4d4e943a33db88e8b3393bdf9f011 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 26 Mar 2026 21:57:04 +0100 Subject: [PATCH 03/12] fix Equals sign not aligned & CloseBraceAfterBody --- settings/class-two-factor-settings.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/settings/class-two-factor-settings.php b/settings/class-two-factor-settings.php index cb7b7132..48018835 100644 --- a/settings/class-two-factor-settings.php +++ b/settings/class-two-factor-settings.php @@ -55,7 +55,7 @@ public static function render_settings_page() { // Default to all providers enabled when the option has never been saved. $all_provider_keys = array_keys( $provider_instances ); - $saved_enabled = get_option( 'two_factor_enabled_providers', $all_provider_keys ); + $saved_enabled = get_option( 'two_factor_enabled_providers', $all_provider_keys ); echo '
'; echo '

' . esc_html__( 'Two-Factor Settings', 'two-factor' ) . '

'; @@ -94,5 +94,4 @@ public static function render_settings_page() { echo '
'; } - } From 18ece23c476c79fd3fbfd1f81359ee07cd6cd7a1 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 26 Mar 2026 22:00:51 +0100 Subject: [PATCH 04/12] fix Doc comment --- two-factor.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/two-factor.php b/two-factor.php index 6be20e19..7fd77ac6 100644 --- a/two-factor.php +++ b/two-factor.php @@ -142,6 +142,9 @@ function two_factor_get_enabled_providers_option() { * This filter receives providers in core format: classname => path. * * @since 0.16 + * + * @param array $providers Registered providers in classname => path format. + * @return array Filtered list of enabled providers. */ function two_factor_filter_enabled_providers( $providers ) { $site_enabled = two_factor_get_enabled_providers_option(); @@ -170,6 +173,10 @@ function two_factor_filter_enabled_providers( $providers ) { * Filter enabled providers for a user (classnames array) to enforce the site-enabled list. * * @since 0.16 + * + * @param array $enabled Enabled provider classnames for the user. + * @param int $user_id ID of the user being filtered. + * @return array Filtered list of provider classnames allowed by the site. */ function two_factor_filter_enabled_providers_for_user( $enabled, $user_id ) { $site_enabled = two_factor_get_enabled_providers_option(); From 95e7133b08568fea5632488cf2cf015810199d42 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 26 Mar 2026 22:05:00 +0100 Subject: [PATCH 05/12] fix DocComment.LongNotCapital --- tests/providers/class-two-factor-provider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/providers/class-two-factor-provider.php b/tests/providers/class-two-factor-provider.php index 149fd022..86a4bee3 100644 --- a/tests/providers/class-two-factor-provider.php +++ b/tests/providers/class-two-factor-provider.php @@ -101,7 +101,7 @@ public function test_get_key_returns_class_name() { /** * Verify is_supported_for_user() returns true when the provider is globally registered. * - * is_supported_for_user() checks Two_Factor_Core::get_supported_providers_for_user(), + * The method checks Two_Factor_Core::get_supported_providers_for_user(), * which reflects global registration (the two_factor_providers filter), not per-user * enabled state. Two_Factor_Dummy is registered globally when WP_DEBUG is true. * From 659f1bb915b7d3587a62319b76738318d4454c01 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 26 Mar 2026 22:16:49 +0100 Subject: [PATCH 06/12] resolve PHPCS violations in class-two-factor-totp --- providers/class-two-factor-totp.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/providers/class-two-factor-totp.php b/providers/class-two-factor-totp.php index e34dee6c..8c47d74a 100644 --- a/providers/class-two-factor-totp.php +++ b/providers/class-two-factor-totp.php @@ -70,7 +70,7 @@ protected function __construct() { * @return int */ private static function time() { - return self::$now ?: time(); + return self::$now ? self::$now : time(); } /** @@ -428,7 +428,7 @@ public function user_two_factor_options( $user ) { 'two-factor-totp-qrcode', 'twoFactorTotpQrcode', array( - 'totpUrl' => $totp_url, + 'totpUrl' => $totp_url, 'qrCodeLabel' => __( 'Authenticator App QR Code', 'two-factor' ), ) ); @@ -806,18 +806,18 @@ public function authentication_page( $user ) { * * @since 0.2.0 * - * @param string $string String to be encoded using base32. + * @param string $input String to be encoded using base32. * * @return string base32 encoded string without padding. */ - public static function base32_encode( $string ) { - if ( empty( $string ) ) { + public static function base32_encode( $input ) { + if ( empty( $input ) ) { return ''; } $binary_string = ''; - foreach ( str_split( $string ) as $character ) { + foreach ( str_split( $input ) as $character ) { $binary_string .= str_pad( base_convert( ord( $character ), 10, 2 ), 8, '0', STR_PAD_LEFT ); } From d2cd74e21483fc11c7c397e36f3cf8fab36d76de Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 26 Mar 2026 22:23:20 +0100 Subject: [PATCH 07/12] fix Generic.CodeAnalysis.EmptyStatement.DetectedCatch --- class-two-factor-core.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index 7b57b868..ae170842 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -210,7 +210,7 @@ public static function uninstall() { call_user_func( array( $provider_class, 'uninstall_user_meta_keys' ) ) ); } catch ( Exception $e ) { - // Do nothing. + error_log( sprintf( 'Two Factor: failed to retrieve uninstall user meta keys for %s: %s', $provider_class, $e->getMessage() ) ); } } @@ -222,7 +222,7 @@ public static function uninstall() { call_user_func( array( $provider_class, 'uninstall_options' ) ) ); } catch ( Exception $e ) { - // Do nothing. + error_log( sprintf( 'Two Factor: failed to retrieve uninstall options for %s: %s', $provider_class, $e->getMessage() ) ); } } } From 02a70a43ebf378351841a7c39c40ac9a692edd62 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 26 Mar 2026 22:31:04 +0100 Subject: [PATCH 08/12] fix Generic.WhiteSpace.ScopeIndent.IncorrectExact --- class-two-factor-core.php | 52 +++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index ae170842..8b41feaf 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -1144,32 +1144,32 @@ public static function login_html( $user, $login_nonce, $redirect_to, $error_msg $action, - 'wp-auth-id' => $user->ID, - 'wp-auth-nonce' => $login_nonce, - ); - if ( $rememberme ) { - $backup_link_args['rememberme'] = $rememberme; - } - if ( $redirect_to ) { - $backup_link_args['redirect_to'] = $redirect_to; - } - if ( $interim_login ) { - $backup_link_args['interim-login'] = 1; - } + if ( $backup_providers ) { + $backup_link_args = array( + 'action' => $action, + 'wp-auth-id' => $user->ID, + 'wp-auth-nonce' => $login_nonce, + ); + if ( $rememberme ) { + $backup_link_args['rememberme'] = $rememberme; + } + if ( $redirect_to ) { + $backup_link_args['redirect_to'] = $redirect_to; + } + if ( $interim_login ) { + $backup_link_args['interim-login'] = 1; + } - foreach ( $backup_providers as $backup_provider_key => $backup_provider ) { - $backup_link_args['provider'] = $backup_provider_key; - $links[] = array( - 'url' => self::login_url( $backup_link_args ), - 'label' => $backup_provider->get_alternative_provider_label(), - ); - } + foreach ( $backup_providers as $backup_provider_key => $backup_provider ) { + $backup_link_args['provider'] = $backup_provider_key; + $links[] = array( + 'url' => self::login_url( $backup_link_args ), + 'label' => $backup_provider->get_alternative_provider_label(), + ); } + } /** * Filters the links displayed on the two-factor login form. @@ -1191,9 +1191,9 @@ public static function login_html( $user, $login_nonce, $redirect_to, $error_msg

From a3b39c501fba6d7f418c13fbd8acc5d8b217e71a Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 26 Mar 2026 22:36:26 +0100 Subject: [PATCH 09/12] ignore --- class-two-factor-core.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index 8b41feaf..f9f987ce 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -209,8 +209,7 @@ public static function uninstall() { $user_meta_keys, call_user_func( array( $provider_class, 'uninstall_user_meta_keys' ) ) ); - } catch ( Exception $e ) { - error_log( sprintf( 'Two Factor: failed to retrieve uninstall user meta keys for %s: %s', $provider_class, $e->getMessage() ) ); + } catch ( Exception $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch -- Intentionally empty, provider may not implement this method. } } @@ -221,8 +220,7 @@ public static function uninstall() { $option_keys, call_user_func( array( $provider_class, 'uninstall_options' ) ) ); - } catch ( Exception $e ) { - error_log( sprintf( 'Two Factor: failed to retrieve uninstall options for %s: %s', $provider_class, $e->getMessage() ) ); + } catch ( Exception $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch -- Intentionally empty, provider may not implement this method. } } } From 562264c46c81c278f297fea6024b8fe683031319 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 26 Mar 2026 22:37:44 +0100 Subject: [PATCH 10/12] filechange --- ...-factor-secure-dummy.php => class-two-factor-dummy-secure.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/{class-two-factor-secure-dummy.php => class-two-factor-dummy-secure.php} (100%) diff --git a/tests/class-two-factor-secure-dummy.php b/tests/class-two-factor-dummy-secure.php similarity index 100% rename from tests/class-two-factor-secure-dummy.php rename to tests/class-two-factor-dummy-secure.php From a7dab37c67d7bf4f932d4f39178a1320e48bdb5b Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 26 Mar 2026 22:51:26 +0100 Subject: [PATCH 11/12] fix WordPress.PHP.YodaConditions.NotYoda, Inline comments must end in full-stops & PEAR.Functions.FunctionCallSignature.MultipleArguments --- class-two-factor-core.php | 46 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index f9f987ce..2e01014a 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -1505,7 +1505,7 @@ public static function current_user_can_update_two_factor_options( $context = 'd */ $two_factor_revalidate_time = apply_filters( 'two_factor_revalidate_time', 10 * MINUTE_IN_SECONDS, $user_id, $context ); - if ( $context === 'save' ) { + if ( 'save' === $context ) { $two_factor_revalidate_time *= 2; } @@ -1959,15 +1959,14 @@ public static function send_password_reset_emails( $user ) { public static function notify_user_password_reset( $user ) { $user_message = sprintf( /* translators: 1: username, 2: site URL, 3: URL to password best-practices article, 4: URL to reset password */ - __( 'Hello %1$s, an unusually high number of failed login attempts have been detected on your account at %2$s. - - These attempts successfully entered your password, and were only blocked because they failed to enter your second authentication factor. Despite not being able to access your account, this behavior indicates that the attackers have compromised your password. The most common reasons for this are that your password was easy to guess, or was reused on another site which has been compromised. - - To protect your account, your password has been reset, and you will need to create a new one. For advice on setting a strong password, please read %3$s - - To pick a new password, please visit %4$s - - This is an automated notification. If you would like to speak to a site administrator, please contact them directly.', 'two-factor' ), + __( + 'Hello %1$s, an unusually high number of failed login attempts have been detected on your account at %2$s. + These attempts successfully entered your password, and were only blocked because they failed to enter your second authentication factor. Despite not being able to access your account, this behavior indicates that the attackers have compromised your password. The most common reasons for this are that your password was easy to guess, or was reused on another site which has been compromised. + To protect your account, your password has been reset, and you will need to create a new one. For advice on setting a strong password, please read %3$s + To pick a new password, please visit %4$s + This is an automated notification. If you would like to speak to a site administrator, please contact them directly.', + 'two-factor' + ), esc_html( $user->user_login ), home_url(), 'https://wordpress.org/documentation/article/password-best-practices/', @@ -1997,15 +1996,14 @@ public static function notify_admin_user_password_reset( $user ) { $message = sprintf( /* translators: 1: username, 2: user ID, 3: URL to developer docs */ - __( 'Hello, this is a notice from the Two Factor plugin to inform you that an unusually high number of failed login attempts have been detected on the %1$s account (ID %2$d). - - Those attempts successfully entered the user\'s password, and were only blocked because they entered invalid second authentication factors. - - To protect their account, the password has automatically been reset, and they have been notified that they will need to create a new one. - - If you do not wish to receive these notifications, you can disable them with the `two_factor_notify_admin_user_password_reset` filter. See %3$s for more information. - - Thank you', 'two-factor' ), + __( + 'Hello, this is a notice from the Two Factor plugin to inform you that an unusually high number of failed login attempts have been detected on the %1$s account (ID %2$d). + Those attempts successfully entered the user\'s password, and were only blocked because they entered invalid second authentication factors. + To protect their account, the password has automatically been reset, and they have been notified that they will need to create a new one. + If you do not wish to receive these notifications, you can disable them with the `two_factor_notify_admin_user_password_reset` filter. See %3$s for more information. + Thank you', + 'two-factor' + ), esc_html( $user->user_login ), $user->ID, 'https://developer.wordpress.org/plugins/hooks/' @@ -2456,7 +2454,7 @@ public static function user_two_factor_options_update( $user_id ) { } // Have we changed the two-factor settings for the current user? Alter their session metadata. - if ( $user_id === get_current_user_id() ) { + if ( get_current_user_id() === $user_id ) { if ( $enabled_providers && ! $existing_providers && ! self::is_current_user_session_two_factor() ) { // We've enabled two-factor from a non-two-factor session, set the key but not the provider, as no provider has been used yet. @@ -2477,14 +2475,14 @@ public static function user_two_factor_options_update( $user_id ) { } } - // Destroy other sessions if setup 2FA for the first time, or deactivated a provider + // Destroy other sessions if setup 2FA for the first time, or deactivated a provider. if ( - // No providers, enabling one (or more) + // No providers, enabling one (or more). ( ! $existing_providers && $enabled_providers ) || // Has providers, and is disabling one (or more), but remaining with 2FA. ( $existing_providers && $enabled_providers && array_diff( $existing_providers, array_keys( $enabled_providers ) ) ) ) { - if ( $user_id === get_current_user_id() ) { + if ( get_current_user_id() === $user_id ) { // Keep the current session, destroy others sessions for this user. wp_destroy_other_sessions(); } else { @@ -2583,7 +2581,7 @@ public static function rememberme() { * @return array */ public static function filter_session_information( $session, $user_id ) { - if ( $user_id !== get_current_user_id() ) { + if ( get_current_user_id() !== $user_id ) { return $session; } From 1b27702161d55090752e124481396131d1737a2c Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 26 Mar 2026 22:56:28 +0100 Subject: [PATCH 12/12] fix Generic.WhiteSpace.DisallowSpaceIndent.SpacesUsed --- class-two-factor-core.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index 2e01014a..d98cbfe6 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -1960,12 +1960,12 @@ public static function notify_user_password_reset( $user ) { $user_message = sprintf( /* translators: 1: username, 2: site URL, 3: URL to password best-practices article, 4: URL to reset password */ __( - 'Hello %1$s, an unusually high number of failed login attempts have been detected on your account at %2$s. - These attempts successfully entered your password, and were only blocked because they failed to enter your second authentication factor. Despite not being able to access your account, this behavior indicates that the attackers have compromised your password. The most common reasons for this are that your password was easy to guess, or was reused on another site which has been compromised. - To protect your account, your password has been reset, and you will need to create a new one. For advice on setting a strong password, please read %3$s - To pick a new password, please visit %4$s - This is an automated notification. If you would like to speak to a site administrator, please contact them directly.', - 'two-factor' + 'Hello %1$s, an unusually high number of failed login attempts have been detected on your account at %2$s. + These attempts successfully entered your password, and were only blocked because they failed to enter your second authentication factor. Despite not being able to access your account, this behavior indicates that the attackers have compromised your password. The most common reasons for this are that your password was easy to guess, or was reused on another site which has been compromised. + To protect your account, your password has been reset, and you will need to create a new one. For advice on setting a strong password, please read %3$s + To pick a new password, please visit %4$s + This is an automated notification. If you would like to speak to a site administrator, please contact them directly.', + 'two-factor' ), esc_html( $user->user_login ), home_url(), @@ -1997,13 +1997,13 @@ public static function notify_admin_user_password_reset( $user ) { $message = sprintf( /* translators: 1: username, 2: user ID, 3: URL to developer docs */ __( - 'Hello, this is a notice from the Two Factor plugin to inform you that an unusually high number of failed login attempts have been detected on the %1$s account (ID %2$d). + 'Hello, this is a notice from the Two Factor plugin to inform you that an unusually high number of failed login attempts have been detected on the %1$s account (ID %2$d). Those attempts successfully entered the user\'s password, and were only blocked because they entered invalid second authentication factors. To protect their account, the password has automatically been reset, and they have been notified that they will need to create a new one. If you do not wish to receive these notifications, you can disable them with the `two_factor_notify_admin_user_password_reset` filter. See %3$s for more information. - Thank you', - 'two-factor' - ), + Thank you', + 'two-factor' + ), esc_html( $user->user_login ), $user->ID, 'https://developer.wordpress.org/plugins/hooks/'