From 808cd6aed150d1d36ece1c1bd77ea5300fd1de95 Mon Sep 17 00:00:00 2001 From: Eric Michel Date: Thu, 18 Dec 2025 16:06:48 -0500 Subject: [PATCH 1/6] added filter to control whether authcode autosubmits --- class-two-factor-core.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index 8086c434..122626f2 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -958,6 +958,7 @@ public static function login_html( $user, $login_nonce, $redirect_to, $error_msg $interim_login = isset( $_REQUEST['interim-login'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended $rememberme = intval( self::rememberme() ); + $auto_submit_authcode = apply_filters( 'two_factor_auto_submit_authcode', true ); if ( ! function_exists( 'login_header' ) ) { // We really should migrate login_header() out of `wp-login.php` so it can be called from an includes file. @@ -1076,13 +1077,15 @@ function() { this.value = value; - // Auto-submit if it's the expected length. - if ( expectedLength && value.replace( / /g, '' ).length == expectedLength ) { - if ( undefined !== form.requestSubmit ) { - form.requestSubmit(); - form.submit.disabled = "disabled"; + + // Auto-submit if it's the expected length. + if ( expectedLength && value.replace( / /g, '' ).length == expectedLength ) { + if ( undefined !== form.requestSubmit ) { + form.requestSubmit(); + form.submit.disabled = "disabled"; + } } - } + } ); } From 00605f2ddfe89335ad25c4a86aa8616c58bc56bd Mon Sep 17 00:00:00 2001 From: Eric Michel Date: Tue, 23 Dec 2025 12:43:11 -0500 Subject: [PATCH 2/6] updated readme --- readme.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.txt b/readme.txt index befe8525..398b8b7c 100644 --- a/readme.txt +++ b/readme.txt @@ -33,6 +33,7 @@ Here is a list of action and filter hooks provided by the plugin: - `two_factor_email_token_length` filter overrides the default 8 character count for email tokens. - `two_factor_backup_code_length` filter overrides the default 8 character count for backup codes. Provides the `WP_User` of the associated user as the second argument. - `two_factor_rest_api_can_edit_user` filter overrides whether a user’s Two-Factor settings can be edited via the REST API. First argument is the current `$can_edit` boolean, the second argument is the user ID. +- `two_factor_auto_submit_authcode` filter overrides whether the authentication form auto-submits when a code is entered. == Frequently Asked Questions == From bd499ec0d6ef2c8a5dc44c4e317e65c7990f95d7 Mon Sep 17 00:00:00 2001 From: Eric Michel Date: Fri, 9 Jan 2026 16:06:50 -0500 Subject: [PATCH 3/6] swapped variable output to data attribute on form and check happens within JS --- class-two-factor-core.php | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index 122626f2..ff01b4ca 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -977,7 +977,7 @@ public static function login_html( $user, $login_nonce, $redirect_to, $error_msg } ?> -
+ data-auto-submit="true"> @@ -1077,15 +1077,13 @@ function() { this.value = value; - - // Auto-submit if it's the expected length. - if ( expectedLength && value.replace( / /g, '' ).length == expectedLength ) { - if ( undefined !== form.requestSubmit ) { - form.requestSubmit(); - form.submit.disabled = "disabled"; - } + // Auto-submit if auto-submit is enabled and entered value is the expected length. + if ( form.dataset.autoSubmit && expectedLength && value.replace( / /g, '' ).length == expectedLength ) { + if ( undefined !== form.requestSubmit ) { + form.requestSubmit(); + form.submit.disabled = "disabled"; } - + } } ); } From aac5403aac1fb95e9343249120a4fc8ee15c7f15 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 2 Mar 2026 20:32:42 +0100 Subject: [PATCH 4/6] add provider_key Co-authored-by: George Stephanis --- 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 0d7ab3f8..ba2b6094 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -1027,7 +1027,7 @@ public static function login_html( $user, $login_nonce, $redirect_to, $error_msg $interim_login = isset( $_REQUEST['interim-login'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended $rememberme = intval( self::rememberme() ); - $auto_submit_authcode = apply_filters( 'two_factor_auto_submit_authcode', true ); + $auto_submit_authcode = apply_filters( 'two_factor_auto_submit_authcode', true, $provider_key ); if ( is_wp_error( $available_providers ) ) { // If it returned an error, the configured methods don't exist, and it couldn't swap in a replacement. From 628a461c58587fe1388a0c586834875aa42e1659 Mon Sep 17 00:00:00 2001 From: Eric Michel <45110062+eric-michel@users.noreply.github.com> Date: Tue, 3 Mar 2026 09:35:09 -0500 Subject: [PATCH 5/6] filter documentation added Co-authored-by: Brian --- class-two-factor-core.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index ba2b6094..45b61396 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -1027,6 +1027,20 @@ public static function login_html( $user, $login_nonce, $redirect_to, $error_msg $interim_login = isset( $_REQUEST['interim-login'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended $rememberme = intval( self::rememberme() ); + + /** + * Filters whether the authentication code field should auto‑submit when the last digit is entered. + * + * This allows providers or site owners to disable (or enable) auto‑submission behavior + * of the TOTP/verification code input, e.g., for accessibility, UX, or device‑specific reasons. + * + * @since 0.16.0 + * + * @param bool $auto_submit Whether to auto‑submit the auth code. Default true. + * @param string $provider_key The current two‑factor provider key. + * @return bool Filtered value of $auto_submit. + */ + $auto_submit_authcode = apply_filters( 'two_factor_auto_submit_authcode', true, $provider_key ); if ( is_wp_error( $available_providers ) ) { From 749a8f03b2b76c1be54ebb9d283b5ba7d849b6c9 Mon Sep 17 00:00:00 2001 From: Eric Michel Date: Tue, 3 Mar 2026 10:47:18 -0500 Subject: [PATCH 6/6] shifted auto-submit check to data-digits attribute --- class-two-factor-core.php | 19 ++-------------- providers/class-two-factor-backup-codes.php | 3 ++- providers/class-two-factor-email.php | 3 ++- providers/class-two-factor-provider.php | 24 +++++++++++++++++++++ providers/class-two-factor-totp.php | 3 ++- 5 files changed, 32 insertions(+), 20 deletions(-) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index cb1050b6..0ec86973 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -1024,21 +1024,6 @@ public static function login_html( $user, $login_nonce, $redirect_to, $error_msg $interim_login = isset( $_REQUEST['interim-login'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended $rememberme = intval( self::rememberme() ); - - /** - * Filters whether the authentication code field should auto‑submit when the last digit is entered. - * - * This allows providers or site owners to disable (or enable) auto‑submission behavior - * of the TOTP/verification code input, e.g., for accessibility, UX, or device‑specific reasons. - * - * @since 0.16.0 - * - * @param bool $auto_submit Whether to auto‑submit the auth code. Default true. - * @param string $provider_key The current two‑factor provider key. - * @return bool Filtered value of $auto_submit. - */ - - $auto_submit_authcode = apply_filters( 'two_factor_auto_submit_authcode', true, $provider_key ); if ( is_wp_error( $available_providers ) ) { // If it returned an error, the configured methods don't exist, and it couldn't swap in a replacement. @@ -1064,7 +1049,7 @@ public static function login_html( $user, $login_nonce, $redirect_to, $error_msg } ?> - data-auto-submit="true"> + @@ -1158,7 +1143,7 @@ function() { this.value = value; // Auto-submit if auto-submit is enabled and entered value is the expected length. - if ( form.dataset.autoSubmit && expectedLength && value.replace( / /g, '' ).length == expectedLength ) { + if ( expectedLength && value.replace( / /g, '' ).length == expectedLength ) { if ( undefined !== form.requestSubmit ) { form.requestSubmit(); form.submit.disabled = "disabled"; diff --git a/providers/class-two-factor-backup-codes.php b/providers/class-two-factor-backup-codes.php index 6d6896bb..f0f0ba88 100644 --- a/providers/class-two-factor-backup-codes.php +++ b/providers/class-two-factor-backup-codes.php @@ -384,6 +384,7 @@ public static function codes_remaining_for_user( $user ) { public function authentication_page( $user ) { require_once ABSPATH . '/wp-admin/includes/template.php'; + $auto_submit_authcode = $this->is_authcode_auto_submit_enabled(); $code_length = $this->get_backup_code_length( $user ); $code_placeholder = str_repeat( 'X', $code_length ); @@ -411,7 +412,7 @@ public function authentication_page( $user ) { ?>

- +

generate_and_email_token( $user ); } + $auto_submit_authcode = $this->is_authcode_auto_submit_enabled(); $token_length = $this->get_token_length(); $token_placeholder = str_repeat( 'X', $token_length ); @@ -362,7 +363,7 @@ public function authentication_page( $user ) { ?>

- +

get_key() ); + } } diff --git a/providers/class-two-factor-totp.php b/providers/class-two-factor-totp.php index 9726fef3..e06efd7f 100644 --- a/providers/class-two-factor-totp.php +++ b/providers/class-two-factor-totp.php @@ -833,6 +833,7 @@ public function is_available_for_user( $user ) { */ public function authentication_page( $user ) { require_once ABSPATH . '/wp-admin/includes/template.php'; + $auto_submit_authcode = $this->is_authcode_auto_submit_enabled(); ?>

- +