From 100df25004f692c016a37f00b5848e830352671b Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 7 Feb 2026 23:14:42 +0100 Subject: [PATCH 1/2] Update class-two-factor-compat.php --- class-two-factor-compat.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/class-two-factor-compat.php b/class-two-factor-compat.php index d7b4f46a..94e47f4d 100644 --- a/class-two-factor-compat.php +++ b/class-two-factor-compat.php @@ -11,11 +11,15 @@ * Should be used with care because ideally we wouldn't need * any integration specific code for this plugin. Everything should * be handled through clever use of hooks and best practices. + * + * @since 0.5.0 */ class Two_Factor_Compat { /** * Initialize all the custom hooks as necessary. * + * @since 0.5.0 + * * @return void */ public function init() { @@ -30,6 +34,8 @@ public function init() { /** * Jetpack single sign-on wants long-lived sessions for users. * + * @since 0.5.0 + * * @param boolean $rememberme Current state of the "remember me" toggle. * * @return boolean @@ -47,6 +53,8 @@ public function jetpack_rememberme( $rememberme ) { /** * Helper to detect the presence of the active SSO module. * + * @since 0.5.0 + * * @return boolean */ public function jetpack_is_sso_active() { From 0304f319b4751d29ce4f0784bfb7cf2b14e4cc46 Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 7 Feb 2026 23:51:21 +0100 Subject: [PATCH 2/2] Update class-two-factor-core.php --- class-two-factor-core.php | 120 +++++++++++++++++++++++++++++++++----- 1 file changed, 105 insertions(+), 15 deletions(-) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index ecca5595..0f864334 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -8,7 +8,7 @@ /** * Class for creating two factor authorization. * - * @since 0.1-dev + * @since 0.2.0 * * @package Two_Factor */ @@ -90,7 +90,7 @@ class Two_Factor_Core { * * @param object $compat A compatibility layer for plugins. * - * @since 0.1-dev + * @since 0.2.0 */ public static function add_hooks( $compat ) { add_action( 'init', array( __CLASS__, 'get_providers' ) ); // @phpstan-ignore return.void @@ -137,6 +137,8 @@ public static function add_hooks( $compat ) { /** * Delete all plugin data on uninstall. + * + * @since 0.10.0 * * @return void */ @@ -203,6 +205,8 @@ public static function uninstall() { /** * Get the registered providers of which some might not be enabled. + * + * @since 0.11.0 * * @return array List of provider keys and paths to class files. */ @@ -218,6 +222,8 @@ private static function get_default_providers() { /** * Get the classnames for specific providers. + * + * @since 0.10.0 * * @param array $providers List of paths to provider class files indexed by class names. * @@ -259,7 +265,7 @@ private static function get_providers_classes( $providers ) { * @see Two_Factor_Core::get_enabled_providers_for_user() * @see Two_Factor_Core::get_supported_providers_for_user() * - * @since 0.1-dev + * @since 0.2.0 * * @return array */ @@ -306,6 +312,8 @@ public static function get_providers() { /** * Get providers available for user which may not be enabled or configured. + * + * @since 0.13.0 * * @see Two_Factor_Core::get_enabled_providers_for_user() * @see Two_Factor_Core::get_available_providers_for_user() @@ -328,6 +336,8 @@ public static function get_supported_providers_for_user( $user = null ) { /** * Enable the dummy method only during debugging. + * + * @since 0.5.2 * * @param array $methods List of enabled methods. * @@ -364,6 +374,8 @@ public static function add_settings_action_link( $links ) { /** * Check if the debug mode is enabled. + * + * @since 0.5.2 * * @return boolean */ @@ -376,6 +388,8 @@ protected static function is_wp_debug() { * * Fetch this from the plugin core after we introduce proper dependency injection * and get away from the singletons at the provider level (should be handled by core). + * + * @since 0.5.2 * * @param integer $user_id User ID. * @@ -396,6 +410,8 @@ protected static function get_user_settings_page_url( $user_id ) { /** * Get the URL for resetting the secret token. + * + * @since 0.5.2 * * @param integer $user_id User ID. * @param string $action Custom two factor action key. @@ -417,6 +433,8 @@ public static function get_user_update_action_url( $user_id, $action ) { /** * Get the two-factor revalidate URL. + * + * @since 0.9.0 * * @param bool $interim If the URL should load the interim login iframe modal. * @return string @@ -434,6 +452,8 @@ public static function get_user_two_factor_revalidate_url( $interim = false ) { /** * Check if a user action is valid. + * + * @since 0.5.2 * * @param integer $user_id User ID. * @param string $action User action ID. @@ -455,6 +475,8 @@ public static function is_valid_user_action( $user_id, $action ) { /** * Get the ID of the user being edited. + * + * @since 0.5.2 * * @return integer */ @@ -474,6 +496,8 @@ public static function current_user_being_edited() { /** * Trigger our custom update action if a valid * action request is detected and passes the nonce check. + * + * @since 0.5.2 * * @return void */ @@ -496,6 +520,8 @@ public static function trigger_user_settings_action() { /** * Keep track of all the authentication cookies that need to be * invalidated before the second factor authentication. + * + * @since 0.5.1 * * @param string $cookie Cookie string. * @@ -535,6 +561,8 @@ public static function fetch_user( $user = null ) { /** * Get two-factor providers that are enabled for the specified (or current) user * but might not be configured, yet. + * + * @since 0.2.0 * * @see Two_Factor_Core::get_supported_providers_for_user() * @see Two_Factor_Core::get_available_providers_for_user() @@ -567,6 +595,8 @@ public static function get_enabled_providers_for_user( $user = null ) { /** * Get all two-factor providers that are both enabled and configured * for the specified (or current) user. + * + * @since 0.2.0 * * @see Two_Factor_Core::get_supported_providers_for_user() * @see Two_Factor_Core::get_enabled_providers_for_user() @@ -595,6 +625,8 @@ public static function get_available_providers_for_user( $user = null ) { /** * Fetch the provider for the request based on the user preferences. + * + * @since 0.9.0 * * @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. @@ -632,6 +664,8 @@ public static function get_provider_for_user( $user = null, $preferred_provider /** * Get the name of the primary provider selected by the user * and enabled for the user. + * + * @since 0.12.0 * * @param WP_User|int $user User ID or instance. * @@ -651,7 +685,7 @@ private static function get_primary_provider_key_selected_for_user( $user ) { /** * Gets the Two-Factor Auth provider for the specified|current user. * - * @since 0.1-dev + * @since 0.2.0 * * @param int|WP_User $user Optional. User ID, or WP_User object of the the user. Defaults to current user. * @return object|null @@ -697,7 +731,7 @@ public static function get_primary_provider_for_user( $user = null ) { /** * Quick boolean check for whether a given user is using two-step. * - * @since 0.1-dev + * @since 0.2.0 * * @param int|WP_User $user Optional. User ID, or WP_User object of the the user. Defaults to current user. * @return bool @@ -710,7 +744,7 @@ public static function is_user_using_two_factor( $user = null ) { /** * Handle the browser-based login. * - * @since 0.1-dev + * @since 0.2.0 * * @param string $user_login Username. * @param WP_User $user WP_User object of the logged-in user. @@ -736,6 +770,8 @@ public static function wp_login( $user_login, $user ) { * Is there a better way of finding the current session token without * having access to the authentication cookies which are just being set * on the first password-based authentication request. + * + * @since 0.5.1 * * @param \WP_User $user User object. * @@ -753,6 +789,8 @@ public static function destroy_current_session_for_user( $user ) { * Trigget the two-factor workflow only for valid login attempts * with username present. Prevent authentication during API requests * unless explicitly enabled for the user (disabled by default). + * + * @since 0.4.0 * * @param WP_User|WP_Error $user Valid WP_User only if the previous filters * have verified and confirmed the @@ -786,6 +824,8 @@ public static function filter_authenticate( $user, $username, $password ) { * If the user can login via API requests such as XML-RPC and REST. * * Only logins with application passwords are permitted by default. + * + * @since 0.4.0 * * @param integer $user_id User ID. * @@ -808,6 +848,8 @@ public static function is_user_api_login_enabled( $user_id ) { /** * Is the current request an XML-RPC or REST request. + * + * @since 0.4.0 * * @return boolean */ @@ -826,7 +868,7 @@ public static function is_api_request() { /** * Display the login form. * - * @since 0.1-dev + * @since 0.2.0 * * @param WP_User $user WP_User object of the logged-in user. */ @@ -847,6 +889,8 @@ public static function show_two_factor_login( $user ) { /** * Displays a message informing the user that their account has had failed login attempts. + * + * @since 0.8.0 * * @param WP_User $user WP_User object of the logged-in user. */ @@ -876,6 +920,8 @@ public static function maybe_show_last_login_failure_notice( $user ) { * * They were also sent an email notification in `send_password_reset_email()`, but email sent from a typical * web server is not reliable enough to trust completely. + * + * @since 0.8.0 * * @param WP_Error $errors Error object. */ @@ -919,6 +965,8 @@ public static function maybe_show_reset_password_notice( $errors ) { /** * Clear the password reset notice after the user resets their password. + * + * @since 0.8.0 * * @param WP_User $user User object. */ @@ -929,7 +977,7 @@ public static function clear_password_reset_notice( $user ) { /** * Generates the html form for the second step of the authentication process. * - * @since 0.1-dev + * @since 0.9.0 * * @param WP_User $user WP_User object of the logged-in user. * @param string $login_nonce A string nonce stored in usermeta. @@ -1092,6 +1140,8 @@ function() { /** * Generate the two-factor login form URL. + * + * @since 0.3.0 * * @param array $params List of query argument pairs to add to the URL. * @param string $scheme URL scheme context. @@ -1121,6 +1171,8 @@ public static function login_url( $params = array(), $scheme = 'login' ) { /** * Get the hash of a nonce for storage and comparison. + * + * @since 0.7.2 * * @param array $nonce Nonce array to be hashed. ⚠️ This must contain user ID and expiration, * to guarantee the nonce only works for the intended user during the @@ -1141,7 +1193,7 @@ protected static function hash_login_nonce( $nonce ) { /** * Create the login nonce. * - * @since 0.1-dev + * @since 0.2.0 * * @param int $user_id User ID. * @return array|false @@ -1178,7 +1230,7 @@ public static function create_login_nonce( $user_id ) { /** * Delete the login nonce. * - * @since 0.1-dev + * @since 0.2.0 * * @param int $user_id User ID. * @return bool @@ -1190,7 +1242,7 @@ public static function delete_login_nonce( $user_id ) { /** * Verify the login nonce. * - * @since 0.1-dev + * @since 0.2.0 * * @param int $user_id User ID. * @param string $nonce Login nonce. @@ -1227,6 +1279,8 @@ public static function verify_login_nonce( $user_id, $nonce ) { * * This implements an increasing backoff, requiring an attacker to wait longer * each time to attempt to brute-force the login. + * + * @since 0.8.0 * * @param WP_User $user The user being operated upon. * @return int Time delay in seconds between login attempts. @@ -1311,6 +1365,7 @@ public static function is_current_user_session_two_factor() { /** * Determine if the current user session can update Two-Factor settings. * + * @since 0.9.0 * @param string $context The context in use, 'display' or 'save'. Save has twice the grace time. * * @return bool @@ -1367,6 +1422,7 @@ public static function current_user_can_update_two_factor_options( $context = 'd /** * Validate that the current user can edit the specified user. If two-factor is required by the account, also verify that it's within the revalidation grace period. * + * @since 0.9.0 * @param int $user_id The user ID being updated. * * @return bool|\WP_Error @@ -1386,7 +1442,7 @@ public static function rest_api_can_edit_user_and_update_two_factor_options( $us /** * Login form validation handler. * - * @since 0.1-dev + * @since 0.2.0 */ public static function login_form_validate_2fa() { $wp_auth_id = ! empty( $_REQUEST['wp-auth-id'] ) ? absint( $_REQUEST['wp-auth-id'] ) : 0; @@ -1614,6 +1670,8 @@ public static function _login_form_revalidate_2fa( $nonce = '', $provider = '', /** * Process the 2FA provider authentication. + * + * @since 0.9.0 * * @param object $provider The Two Factor Provider. * @param WP_User $user The user being authenticated. @@ -1681,6 +1739,7 @@ public static function process_provider( $provider, $user, $is_post_request ) { * Determine if the user's password should be reset. * * @param int $user_id User ID. + * @since 0.8.0 * * @return bool */ @@ -1713,6 +1772,8 @@ public static function should_reset_password( $user_id ) { * which guarantees that attackers can't brute force it (unless they compromise the new password). * * @param WP_User $user The user who failed to login. + * + * @since 0.8.0 */ public static function reset_compromised_password( $user ) { // Unhook because `wp_password_change_notification()` wouldn't notify the site admin when @@ -1729,6 +1790,8 @@ public static function reset_compromised_password( $user ) { /** * Notify the user and admin that a password was reset for being compromised. + * + * @since 0.8.0 * * @param WP_User $user The user whose password should be reset. */ @@ -1751,6 +1814,8 @@ public static function send_password_reset_emails( $user ) { /** * Notify the user that their password has been compromised and reset. + * + * @since 0.8.0 * * @param WP_User $user The user to notify. * @@ -1779,6 +1844,8 @@ public static function notify_user_password_reset( $user ) { /** * Notify the admin that a user's password was compromised and reset. + * + * @since 0.8.0 * * @param WP_User $user The user whose password was reset. * @@ -1809,6 +1876,8 @@ public static function notify_admin_user_password_reset( $user ) { /** * Show the password reset error when on the login screen. + * + * @since 0.8.0 */ public static function show_password_reset_error() { $error = new WP_Error( @@ -1827,6 +1896,8 @@ public static function show_password_reset_error() { /** * Filter the columns on the Users admin screen. + * + * @since 0.2.0 * * @param array $columns Available columns. * @return array Updated array of columns. @@ -1838,6 +1909,8 @@ public static function filter_manage_users_columns( array $columns ) { /** * Output the 2FA column data on the Users screen. + * + * @since 0.2.0 * * @param string $output The column output. * @param string $column_name The column ID. @@ -1863,7 +1936,7 @@ public static function manage_users_custom_column( $output, $column_name, $user_ * * This executes during the `show_user_profile` & `edit_user_profile` actions. * - * @since 0.1-dev + * @since 0.2.0 * * @param WP_User $user WP_User object of the logged-in user. */ @@ -1927,13 +2000,15 @@ public static function user_two_factor_options( $user ) { * @param WP_User $user The user. * @param array $providers List of providers available to the user. * - * @since 0.1-dev + * @since 0.2.0 */ do_action( 'show_user_security_settings', $user, $providers ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Legacy unprefixed hook. } /** * Get the recommended providers for a user. + * + * @since 0.14.0 * * @param WP_User $user User instance. * @@ -1956,6 +2031,8 @@ private static function get_recommended_providers( $user ) { /** * Render the user settings. + * + * @since 0.13.0 * * @param WP_User $user User instance. * @param array $providers List of available providers. @@ -2041,6 +2118,8 @@ private static function render_user_providers_form( $user, $providers ) { * Enable a provider for a user. * * The caller is responsible for checking the user has permission to do this. + * + * @since 0.8.0 * * @param int $user_id The ID of the user. * @param string $new_provider The name of the provider class. @@ -2072,6 +2151,8 @@ public static function enable_provider_for_user( $user_id, $new_provider ) { * `get_primary_provider_for_user()` will pick a new one automatically. * * The caller is responsible for checking the user has permission to do this. + * + * @since 0.9.0 * * @param int $user_id The ID of the user. * @param string $provider_to_delete The name of the provider class. @@ -2107,7 +2188,7 @@ public static function disable_provider_for_user( $user_id, $provider_to_delete * * This executes during the `personal_options_update` & `edit_user_profile_update` actions. * - * @since 0.1-dev + * @since 0.2.0 * * @param int $user_id User ID. */ @@ -2184,6 +2265,8 @@ public static function user_two_factor_options_update( $user_id ) { * Update the current user session metadata. * * Any values set in $data that are null will be removed from the user session metadata. + * + * @since 0.9.0 * * @param array $data The data to append/remove from the current session. * @return bool @@ -2211,6 +2294,8 @@ public static function update_current_user_session( $data = array() ) { /** * Fetch the current user session metadata. + * + * @since 0.9.0 * * @return false|array The session array, false on error. */ @@ -2228,6 +2313,8 @@ public static function get_current_user_session() { /** * Should the login session persist between sessions. + * + * @since 0.5.0 * * @return boolean */ @@ -2247,6 +2334,8 @@ public static function rememberme() { * This is required as WordPress creates a new session when the user password is changed. * * @see https://core.trac.wordpress.org/ticket/58427 + * + * @since 0.9.0 * * @param array $session The Session information. * @param int $user_id The User ID for the session. @@ -2269,3 +2358,4 @@ public static function filter_session_information( $session, $user_id ) { return $session; } } +