diff --git a/wp-content/plugins/two-factor/class-two-factor-compat.php b/wp-content/plugins/two-factor/class-two-factor-compat.php
index 47e6ebfba3670f0e9655e7d248474c126673b592..b578c84762c3ac721a9506e5d675afaba448c0df 100644
--- a/wp-content/plugins/two-factor/class-two-factor-compat.php
+++ b/wp-content/plugins/two-factor/class-two-factor-compat.php
@@ -1,4 +1,9 @@
 <?php
+/**
+ * A compatibility layer for some of the most popular plugins.
+ *
+ * @package Two_Factor
+ */
 
 /**
  * A compatibility layer for some of the most popular plugins.
@@ -30,7 +35,9 @@ class Two_Factor_Compat {
 	 * @return boolean
 	 */
 	public function jetpack_rememberme( $rememberme ) {
-		if ( isset( $_GET['action'] ) && 'jetpack-sso' === $_GET['action'] && $this->jetpack_is_sso_active() ) {
+		$action = filter_input( INPUT_GET, 'action', FILTER_SANITIZE_STRING );
+
+		if ( 'jetpack-sso' === $action && $this->jetpack_is_sso_active() ) {
 			return true;
 		}
 
diff --git a/wp-content/plugins/two-factor/class-two-factor-core.php b/wp-content/plugins/two-factor/class-two-factor-core.php
index 923cdfc830ce0568b3e6cf444b9d617cfa2f2801..e319cf6212cc9ff20f934d7dabe48c08614f1f47 100644
--- a/wp-content/plugins/two-factor/class-two-factor-core.php
+++ b/wp-content/plugins/two-factor/class-two-factor-core.php
@@ -1,4 +1,10 @@
 <?php
+/**
+ * Two Factore Core Class.
+ *
+ * @package Two_Factor
+ */
+
 /**
  * Class for creating two factor authorization.
  *
@@ -54,6 +60,8 @@ class Two_Factor_Core {
 	/**
 	 * Set up filters and actions.
 	 *
+	 * @param object $compat A compaitbility later for plugins.
+	 *
 	 * @since 0.1-dev
 	 */
 	public static function add_hooks( $compat ) {
@@ -106,11 +114,11 @@ class Two_Factor_Core {
 	 */
 	public static function get_providers() {
 		$providers = array(
-			'Two_Factor_Email'        => TWO_FACTOR_DIR . 'providers/class.two-factor-email.php',
-			'Two_Factor_Totp'         => TWO_FACTOR_DIR . 'providers/class.two-factor-totp.php',
-			'Two_Factor_FIDO_U2F'     => TWO_FACTOR_DIR . 'providers/class.two-factor-fido-u2f.php',
-			'Two_Factor_Backup_Codes' => TWO_FACTOR_DIR . 'providers/class.two-factor-backup-codes.php',
-			'Two_Factor_Dummy'        => TWO_FACTOR_DIR . 'providers/class.two-factor-dummy.php',
+			'Two_Factor_Email'        => TWO_FACTOR_DIR . 'providers/class-two-factor-email.php',
+			'Two_Factor_Totp'         => TWO_FACTOR_DIR . 'providers/class-two-factor-totp.php',
+			'Two_Factor_FIDO_U2F'     => TWO_FACTOR_DIR . 'providers/class-two-factor-fido-u2f.php',
+			'Two_Factor_Backup_Codes' => TWO_FACTOR_DIR . 'providers/class-two-factor-backup-codes.php',
+			'Two_Factor_Dummy'        => TWO_FACTOR_DIR . 'providers/class-two-factor-dummy.php',
 		);
 
 		/**
@@ -127,18 +135,20 @@ class Two_Factor_Core {
 		// FIDO U2F is PHP 5.3+ only.
 		if ( isset( $providers['Two_Factor_FIDO_U2F'] ) && version_compare( PHP_VERSION, '5.3.0', '<' ) ) {
 			unset( $providers['Two_Factor_FIDO_U2F'] );
-			trigger_error( sprintf( // WPCS: XSS OK.
+			trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
+				sprintf(
 				/* translators: %s: version number */
-				__( 'FIDO U2F is not available because you are using PHP %s. (Requires 5.3 or greater)', 'two-factor' ),
-				PHP_VERSION
-			) );
+					__( 'FIDO U2F is not available because you are using PHP %s. (Requires 5.3 or greater)', 'two-factor' ), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+					PHP_VERSION
+				)
+			);
 		}
 
 		/**
 		 * For each filtered provider,
 		 */
 		foreach ( $providers as $class => $path ) {
-			include_once( $path );
+			include_once $path;
 
 			/**
 			 * Confirm that it's been successfully included before instantiating.
@@ -267,7 +277,7 @@ class Two_Factor_Core {
 	 * @return void
 	 */
 	public static function trigger_user_settings_action() {
-		$action = filter_input( INPUT_GET, self::USER_SETTINGS_ACTION_QUERY_VAR, FILTER_SANITIZE_STRING );
+		$action  = filter_input( INPUT_GET, self::USER_SETTINGS_ACTION_QUERY_VAR, FILTER_SANITIZE_STRING );
 		$user_id = self::current_user_being_edited();
 
 		if ( ! empty( $action ) && self::is_valid_user_action( $user_id, $action ) ) {
@@ -341,7 +351,7 @@ class Two_Factor_Core {
 		$configured_providers = array();
 
 		foreach ( $providers as $classname => $provider ) {
-			if ( in_array( $classname, $enabled_providers ) && $provider->is_available_for_user( $user ) ) {
+			if ( in_array( $classname, $enabled_providers, true ) && $provider->is_available_for_user( $user ) ) {
 				$configured_providers[ $classname ] = $provider;
 			}
 		}
@@ -526,29 +536,33 @@ class Two_Factor_Core {
 	 * @since 0.1-dev
 	 */
 	public static function backup_2fa() {
-		if ( ! isset( $_GET['wp-auth-id'], $_GET['wp-auth-nonce'], $_GET['provider'] ) ) {
+		$wp_auth_id = filter_input( INPUT_GET, 'wp-auth-id', FILTER_SANITIZE_NUMBER_INT );
+		$nonce      = filter_input( INPUT_GET, 'wp-auth-nonce', FILTER_SANITIZE_STRING );
+		$provider   = filter_input( INPUT_GET, 'provider', FILTER_SANITIZE_STRING );
+
+		if ( ! $wp_auth_id || ! $nonce || ! $provider ) {
 			return;
 		}
 
-		$user = get_userdata( $_GET['wp-auth-id'] );
+		$user = get_userdata( $wp_auth_id );
 		if ( ! $user ) {
 			return;
 		}
 
-		$nonce = $_GET['wp-auth-nonce'];
 		if ( true !== self::verify_login_nonce( $user->ID, $nonce ) ) {
 			wp_safe_redirect( get_bloginfo( 'url' ) );
 			exit;
 		}
 
 		$providers = self::get_available_providers_for_user( $user );
-		if ( isset( $providers[ $_GET['provider'] ] ) ) {
-			$provider = $providers[ $_GET['provider'] ];
+		if ( isset( $providers[ $provider ] ) ) {
+			$provider = $providers[ $provider ];
 		} else {
 			wp_die( esc_html__( 'Cheatin&#8217; uh?', 'two-factor' ), 403 );
 		}
 
-		self::login_html( $user, $_GET['wp-auth-nonce'], $_GET['redirect_to'], '', $provider );
+		$redirect_to = filter_input( INPUT_GET, 'redirect_to', FILTER_SANITIZE_URL );
+		self::login_html( $user, $nonce, $redirect_to, '', $provider );
 
 		exit;
 	}
@@ -574,14 +588,14 @@ class Two_Factor_Core {
 		$provider_class = get_class( $provider );
 
 		$available_providers = self::get_available_providers_for_user( $user );
-		$backup_providers = array_diff_key( $available_providers, array( $provider_class => null ) );
-		$interim_login = isset( $_REQUEST['interim-login'] ); // WPCS: CSRF ok.
+		$backup_providers    = array_diff_key( $available_providers, array( $provider_class => null ) );
+		$interim_login       = isset( $_REQUEST['interim-login'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
 
 		$rememberme = intval( self::rememberme() );
 
 		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.
-			include_once( TWO_FACTOR_DIR . 'includes/function.login-header.php' );
+			include_once TWO_FACTOR_DIR . 'includes/function.login-header.php';
 		}
 
 		login_header();
@@ -595,11 +609,11 @@ class Two_Factor_Core {
 				<input type="hidden" name="provider"      id="provider"      value="<?php echo esc_attr( $provider_class ); ?>" />
 				<input type="hidden" name="wp-auth-id"    id="wp-auth-id"    value="<?php echo esc_attr( $user->ID ); ?>" />
 				<input type="hidden" name="wp-auth-nonce" id="wp-auth-nonce" value="<?php echo esc_attr( $login_nonce ); ?>" />
-				<?php   if ( $interim_login ) { ?>
+				<?php if ( $interim_login ) { ?>
 					<input type="hidden" name="interim-login" value="1" />
-				<?php   } else { ?>
+				<?php } else { ?>
 					<input type="hidden" name="redirect_to" value="<?php echo esc_attr( $redirect_to ); ?>" />
-				<?php   } ?>
+				<?php } ?>
 				<input type="hidden" name="rememberme"    id="rememberme"    value="<?php echo esc_attr( $rememberme ); ?>" />
 
 				<?php $provider->authentication_page( $user ); ?>
@@ -608,8 +622,8 @@ class Two_Factor_Core {
 		<?php
 		if ( 1 === count( $backup_providers ) ) :
 			$backup_classname = key( $backup_providers );
-			$backup_provider = $backup_providers[ $backup_classname ];
-			$login_url = self::login_url(
+			$backup_provider  = $backup_providers[ $backup_classname ];
+			$login_url        = self::login_url(
 				array(
 					'action'        => 'backup_2fa',
 					'provider'      => $backup_classname,
@@ -703,7 +717,8 @@ class Two_Factor_Core {
 
 		<?php
 		/** This action is documented in wp-login.php */
-		do_action( 'login_footer' ); ?>
+		do_action( 'login_footer' );
+		?>
 		<div class="clear"></div>
 		</body>
 		</html>
@@ -737,11 +752,11 @@ class Two_Factor_Core {
 	 * @return array
 	 */
 	public static function create_login_nonce( $user_id ) {
-		$login_nonce               = array();
+		$login_nonce = array();
 		try {
 			$login_nonce['key'] = bin2hex( random_bytes( 32 ) );
-		} catch (Exception $ex) {
-			$login_nonce['key'] = wp_hash( $user_id . mt_rand() . microtime(), 'nonce' );
+		} catch ( Exception $ex ) {
+			$login_nonce['key'] = wp_hash( $user_id . wp_rand() . microtime(), 'nonce' );
 		}
 		$login_nonce['expiration'] = time() + HOUR_IN_SECONDS;
 
@@ -793,25 +808,28 @@ class Two_Factor_Core {
 	 * @since 0.1-dev
 	 */
 	public static function login_form_validate_2fa() {
-		if ( ! isset( $_POST['wp-auth-id'], $_POST['wp-auth-nonce'] ) ) {
+		$wp_auth_id = filter_input( INPUT_POST, 'wp-auth-id', FILTER_SANITIZE_NUMBER_INT );
+		$nonce      = filter_input( INPUT_POST, 'wp-auth-nonce', FILTER_SANITIZE_STRING );
+
+		if ( ! $wp_auth_id || ! $nonce ) {
 			return;
 		}
 
-		$user = get_userdata( $_POST['wp-auth-id'] );
+		$user = get_userdata( $wp_auth_id );
 		if ( ! $user ) {
 			return;
 		}
 
-		$nonce = $_POST['wp-auth-nonce'];
 		if ( true !== self::verify_login_nonce( $user->ID, $nonce ) ) {
 			wp_safe_redirect( get_bloginfo( 'url' ) );
 			exit;
 		}
 
-		if ( isset( $_POST['provider'] ) ) {
+		$provider = filter_input( INPUT_POST, 'provider', FILTER_SANITIZE_STRING );
+		if ( $provider ) {
 			$providers = self::get_available_providers_for_user( $user );
-			if ( isset( $providers[ $_POST['provider'] ] ) ) {
-				$provider = $providers[ $_POST['provider'] ];
+			if ( isset( $providers[ $provider ] ) ) {
+				$provider = $providers[ $provider ];
 			} else {
 				wp_die( esc_html__( 'Cheatin&#8217; uh?', 'two-factor' ), 403 );
 			}
@@ -856,7 +874,7 @@ class Two_Factor_Core {
 
 		// Must be global because that's how login_header() uses it.
 		global $interim_login;
-		$interim_login = isset( $_REQUEST['interim-login'] ); // WPCS: override ok.
+		$interim_login = isset( $_REQUEST['interim-login'] ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited,WordPress.Security.NonceVerification.Recommended
 
 		if ( $interim_login ) {
 			$customize_login = isset( $_REQUEST['customize-login'] );
@@ -864,14 +882,16 @@ class Two_Factor_Core {
 				wp_enqueue_script( 'customize-base' );
 			}
 			$message       = '<p class="message">' . __( 'You have logged in successfully.', 'two-factor' ) . '</p>';
-			$interim_login = 'success'; // WPCS: override ok.
-			login_header( '', $message ); ?>
+			$interim_login = 'success'; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
+			login_header( '', $message );
+			?>
 			</div>
 			<?php
 			/** This action is documented in wp-login.php */
-			do_action( 'login_footer' ); ?>
+			do_action( 'login_footer' );
+			?>
 			<?php if ( $customize_login ) : ?>
-				<script type="text/javascript">setTimeout( function(){ new wp.customize.Messenger({ url: '<?php echo wp_customize_url(); /* WPCS: XSS OK. */ ?>', channel: 'login' }).send('login') }, 1000 );</script>
+				<script type="text/javascript">setTimeout( function(){ new wp.customize.Messenger({ url: '<?php echo esc_url( wp_customize_url() ); ?>', channel: 'login' }).send('login') }, 1000 );</script>
 			<?php endif; ?>
 			</body></html>
 			<?php
@@ -927,10 +947,10 @@ class Two_Factor_Core {
 	 * @param WP_User $user WP_User object of the logged-in user.
 	 */
 	public static function user_two_factor_options( $user ) {
-		wp_enqueue_style( 'user-edit-2fa', plugins_url( 'user-edit.css', __FILE__ ) );
+		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 );
+		$primary_provider  = self::get_primary_provider_for_user( $user->ID );
 
 		if ( ! empty( $primary_provider ) && is_object( $primary_provider ) ) {
 			$primary_provider_key = get_class( $primary_provider );
@@ -959,11 +979,24 @@ class Two_Factor_Core {
 						<tbody>
 						<?php foreach ( self::get_providers() as $class => $object ) : ?>
 							<tr>
-								<th scope="row"><input type="checkbox" name="<?php echo esc_attr( self::ENABLED_PROVIDERS_USER_META_KEY ); ?>[]" value="<?php echo esc_attr( $class ); ?>" <?php checked( in_array( $class, $enabled_providers ) ); ?> /></th>
+								<th scope="row"><input type="checkbox" name="<?php echo esc_attr( self::ENABLED_PROVIDERS_USER_META_KEY ); ?>[]" value="<?php echo esc_attr( $class ); ?>" <?php checked( in_array( $class, $enabled_providers, true ) ); ?> /></th>
 								<th scope="row"><input type="radio" name="<?php echo esc_attr( self::PROVIDER_USER_META_KEY ); ?>" value="<?php echo esc_attr( $class ); ?>" <?php checked( $class, $primary_provider_key ); ?> /></th>
 								<td>
-									<?php $object->print_label(); ?>
-									<?php do_action( 'two-factor-user-options-' . $class, $user ); ?>
+									<?php
+										$object->print_label();
+
+										/**
+										 * Fires after user options are shown.
+										 *
+										 * Use the {@see 'two_factor_user_options_' . $class } hook instead.
+										 *
+										 * @deprecated 0.7.0
+										 *
+										 * @param WP_User $user The user.
+										 */
+										do_action_deprecated(  'two-factor-user-options-' . $class, array( $user ), '0.7.0', 'two_factor_user_options_' . $class );
+										do_action( 'two_factor_user_options_' . $class, $user );
+									?>
 								</td>
 							</tr>
 						<?php endforeach; ?>
diff --git a/wp-content/plugins/two-factor/docker-compose.yml b/wp-content/plugins/two-factor/docker-compose.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9a92e6cecc3d5016dfc079eaffda14fee13dab52
--- /dev/null
+++ b/wp-content/plugins/two-factor/docker-compose.yml
@@ -0,0 +1,11 @@
+version: '3.6'
+
+services:
+
+  wpdevlib:
+    build: ./tests/docker/wp-dev-lib
+    working_dir: /var/www/html
+    volumes:
+      - .:/var/www/html
+    environment:
+      CHECK_SCOPE: all
diff --git a/wp-content/plugins/two-factor/providers/class-two-factor-backup-codes.php b/wp-content/plugins/two-factor/providers/class-two-factor-backup-codes.php
new file mode 100644
index 0000000000000000000000000000000000000000..f22675383910ddb88ed4a65a3f3c2058d7c68a4e
--- /dev/null
+++ b/wp-content/plugins/two-factor/providers/class-two-factor-backup-codes.php
@@ -0,0 +1,355 @@
+<?php
+/**
+ * Class for creating a backup codes provider.
+ *
+ * @package Two_Factor
+ */
+
+/**
+ * Class for creating a backup codes provider.
+ *
+ * @since 0.1-dev
+ *
+ * @package Two_Factor
+ */
+class Two_Factor_Backup_Codes extends Two_Factor_Provider {
+
+	/**
+	 * The user meta backup codes key.
+	 *
+	 * @type string
+	 */
+	const BACKUP_CODES_META_KEY = '_two_factor_backup_codes';
+
+	/**
+	 * The number backup codes.
+	 *
+	 * @type int
+	 */
+	const NUMBER_OF_CODES = 10;
+
+	/**
+	 * Ensures only one instance of this class exists in memory at any one time.
+	 *
+	 * @since 0.1-dev
+	 */
+	public static function get_instance() {
+		static $instance;
+		$class = __CLASS__;
+		if ( ! is_a( $instance, $class ) ) {
+			$instance = new $class();
+		}
+		return $instance;
+	}
+
+	/**
+	 * Class constructor.
+	 *
+	 * @since 0.1-dev
+	 */
+	protected function __construct() {
+		add_action( 'two_factor_user_options_' . __CLASS__, array( $this, 'user_options' ) );
+		add_action( 'admin_notices', array( $this, 'admin_notices' ) );
+		add_action( 'wp_ajax_two_factor_backup_codes_generate', array( $this, 'ajax_generate_json' ) );
+
+		return parent::__construct();
+	}
+
+	/**
+	 * Displays an admin notice when backup codes have run out.
+	 *
+	 * @since 0.1-dev
+	 */
+	public function admin_notices() {
+		$user = wp_get_current_user();
+
+		// Return if the provider is not enabled.
+		if ( ! in_array( __CLASS__, Two_Factor_Core::get_enabled_providers_for_user( $user->ID ), true ) ) {
+			return;
+		}
+
+		// Return if we are not out of codes.
+		if ( $this->is_available_for_user( $user ) ) {
+			return;
+		}
+		?>
+		<div class="error">
+			<p>
+				<span>
+					<?php
+					wp_kses(
+						sprintf(
+						/* translators: %s: URL for code regeneration */
+							__( 'Two-Factor: You are out of backup codes and need to <a href="%s">regenerate!</a>', 'two-factor' ),
+							esc_url( get_edit_user_link( $user->ID ) . '#two-factor-backup-codes' )
+						),
+						array( 'a' => array( 'href' => true ) )
+					);
+					?>
+				<span>
+			</p>
+		</div>
+		<?php
+	}
+
+	/**
+	 * Returns the name of the provider.
+	 *
+	 * @since 0.1-dev
+	 */
+	public function get_label() {
+		return _x( 'Backup Verification Codes (Single Use)', 'Provider Label', 'two-factor' );
+	}
+
+	/**
+	 * Whether this Two Factor provider is configured and codes are available for the user specified.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 * @return boolean
+	 */
+	public function is_available_for_user( $user ) {
+		// Does this user have available codes?
+		if ( 0 < self::codes_remaining_for_user( $user ) ) {
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Inserts markup at the end of the user profile field for this provider.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 */
+	public function user_options( $user ) {
+		$ajax_nonce = wp_create_nonce( 'two-factor-backup-codes-generate-json-' . $user->ID );
+		$count      = self::codes_remaining_for_user( $user );
+		?>
+		<p id="two-factor-backup-codes">
+			<button type="button" class="button button-two-factor-backup-codes-generate button-secondary hide-if-no-js">
+				<?php esc_html_e( 'Generate Verification Codes', 'two-factor' ); ?>
+			</button>
+			<span class="two-factor-backup-codes-count">
+			<?php
+				echo esc_html(
+					sprintf(
+					/* translators: %s: count */
+						_n( '%s unused code remaining.', '%s unused codes remaining.', $count, 'two-factor' ),
+						$count
+					)
+				);
+			?>
+				</span>
+		</p>
+		<div class="two-factor-backup-codes-wrapper" style="display:none;">
+			<ol class="two-factor-backup-codes-unused-codes"></ol>
+			<p class="description"><?php esc_html_e( 'Write these down!  Once you navigate away from this page, you will not be able to view these codes again.', 'two-factor' ); ?></p>
+			<p>
+				<a class="button button-two-factor-backup-codes-download button-secondary hide-if-no-js" href="javascript:void(0);" id="two-factor-backup-codes-download-link" download="two-factor-backup-codes.txt"><?php esc_html_e( 'Download Codes', 'two-factor' ); ?></a>
+			<p>
+		</div>
+		<script type="text/javascript">
+			( function( $ ) {
+				$( '.button-two-factor-backup-codes-generate' ).click( function() {
+					$.ajax( {
+						method: 'POST',
+						url: ajaxurl,
+						data: {
+							action: 'two_factor_backup_codes_generate',
+							user_id: '<?php echo esc_js( $user->ID ); ?>',
+							nonce: '<?php echo esc_js( $ajax_nonce ); ?>'
+						},
+						dataType: 'JSON',
+						success: function( response ) {
+							var $codesList = $( '.two-factor-backup-codes-unused-codes' );
+
+							$( '.two-factor-backup-codes-wrapper' ).show();
+							$codesList.html( '' );
+
+							// Append the codes.
+							for ( i = 0; i < response.data.codes.length; i++ ) {
+								$codesList.append( '<li>' + response.data.codes[ i ] + '</li>' );
+							}
+
+							// Update counter.
+							$( '.two-factor-backup-codes-count' ).html( response.data.i18n.count );
+
+							// Build the download link.
+							var txt_data = 'data:application/text;charset=utf-8,' + '\n';
+							txt_data += response.data.i18n.title.replace( /%s/g, document.domain ) + '\n\n';
+
+							for ( i = 0; i < response.data.codes.length; i++ ) {
+								txt_data += i + 1 + '. ' + response.data.codes[ i ] + '\n';
+							}
+
+							$( '#two-factor-backup-codes-download-link' ).attr( 'href', encodeURI( txt_data ) );
+						}
+					} );
+				} );
+			} )( jQuery );
+		</script>
+		<?php
+	}
+
+	/**
+	 * Generates backup codes & updates the user meta.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 * @param array   $args Optional arguments for assigning new codes.
+	 * @return array
+	 */
+	public function generate_codes( $user, $args = '' ) {
+		$codes        = array();
+		$codes_hashed = array();
+
+		// Check for arguments.
+		if ( isset( $args['number'] ) ) {
+			$num_codes = (int) $args['number'];
+		} else {
+			$num_codes = self::NUMBER_OF_CODES;
+		}
+
+		// Append or replace (default).
+		if ( isset( $args['method'] ) && 'append' === $args['method'] ) {
+			$codes_hashed = (array) get_user_meta( $user->ID, self::BACKUP_CODES_META_KEY, true );
+		}
+
+		for ( $i = 0; $i < $num_codes; $i++ ) {
+			$code           = $this->get_code();
+			$codes_hashed[] = wp_hash_password( $code );
+			$codes[]        = $code;
+			unset( $code );
+		}
+
+		update_user_meta( $user->ID, self::BACKUP_CODES_META_KEY, $codes_hashed );
+
+		// Unhashed.
+		return $codes;
+	}
+
+	/**
+	 * Generates a JSON object of backup codes.
+	 *
+	 * @since 0.1-dev
+	 */
+	public function ajax_generate_json() {
+		$user = get_user_by( 'id', filter_input( INPUT_POST, 'user_id', FILTER_SANITIZE_NUMBER_INT ) );
+		check_ajax_referer( 'two-factor-backup-codes-generate-json-' . $user->ID, 'nonce' );
+
+		// Setup the return data.
+		$codes = $this->generate_codes( $user );
+		$count = self::codes_remaining_for_user( $user );
+		$i18n  = array(
+			/* translators: %s: count */
+			'count' => esc_html( sprintf( _n( '%s unused code remaining.', '%s unused codes remaining.', $count, 'two-factor' ), $count ) ),
+			/* translators: %s: the site's domain */
+			'title' => esc_html__( 'Two-Factor Backup Codes for %s', 'two-factor' ),
+		);
+
+		// Send the response.
+		wp_send_json_success(
+			array(
+				'codes' => $codes,
+				'i18n'  => $i18n,
+			)
+		);
+	}
+
+	/**
+	 * Returns the number of unused codes for the specified user
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 * @return int $int  The number of unused codes remaining
+	 */
+	public static function codes_remaining_for_user( $user ) {
+		$backup_codes = get_user_meta( $user->ID, self::BACKUP_CODES_META_KEY, true );
+		if ( is_array( $backup_codes ) && ! empty( $backup_codes ) ) {
+			return count( $backup_codes );
+		}
+		return 0;
+	}
+
+	/**
+	 * Prints the form that prompts the user to authenticate.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 */
+	public function authentication_page( $user ) {
+		require_once ABSPATH . '/wp-admin/includes/template.php';
+		?>
+		<p><?php esc_html_e( 'Enter a backup verification code.', 'two-factor' ); ?></p><br/>
+		<p>
+			<label for="authcode"><?php esc_html_e( 'Verification Code:', 'two-factor' ); ?></label>
+			<input type="tel" name="two-factor-backup-code" id="authcode" class="input" value="" size="20" pattern="[0-9]*" />
+		</p>
+		<?php
+		submit_button( __( 'Submit', 'two-factor' ) );
+	}
+
+	/**
+	 * Validates the users input token.
+	 *
+	 * In this class we just return true.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 * @return boolean
+	 */
+	public function validate_authentication( $user ) {
+		$backup_code = isset( $_POST['two-factor-backup-code'] ) ? sanitize_text_field( wp_unslash( $_POST['two-factor-backup-code'] ) ) : false;
+		return $this->validate_code( $user, filter_var( $backup_code, FILTER_SANITIZE_STRING ) );
+	}
+
+	/**
+	 * Validates a backup code.
+	 *
+	 * Backup Codes are single use and are deleted upon a successful validation.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 * @param int     $code The backup code.
+	 * @return boolean
+	 */
+	public function validate_code( $user, $code ) {
+		$backup_codes = get_user_meta( $user->ID, self::BACKUP_CODES_META_KEY, true );
+
+		if ( is_array( $backup_codes ) && ! empty( $backup_codes ) ) {
+			foreach ( $backup_codes as $code_index => $code_hashed ) {
+				if ( wp_check_password( $code, $code_hashed, $user->ID ) ) {
+					$this->delete_code( $user, $code_hashed );
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Deletes a backup code.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 * @param string  $code_hashed The hashed the backup code.
+	 */
+	public function delete_code( $user, $code_hashed ) {
+		$backup_codes = get_user_meta( $user->ID, self::BACKUP_CODES_META_KEY, true );
+
+		// Delete the current code from the list since it's been used.
+		$backup_codes = array_flip( $backup_codes );
+		unset( $backup_codes[ $code_hashed ] );
+		$backup_codes = array_values( array_flip( $backup_codes ) );
+
+		// Update the backup code master list.
+		update_user_meta( $user->ID, self::BACKUP_CODES_META_KEY, $backup_codes );
+	}
+}
diff --git a/wp-content/plugins/two-factor/providers/class-two-factor-dummy.php b/wp-content/plugins/two-factor/providers/class-two-factor-dummy.php
new file mode 100644
index 0000000000000000000000000000000000000000..f1625dcea09e0d0e746243a9bb047157b52c89bb
--- /dev/null
+++ b/wp-content/plugins/two-factor/providers/class-two-factor-dummy.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Class for creating a dummy provider.
+ *
+ * @package Two_Factor
+ */
+
+/**
+ * Class for creating a dummy provider.
+ *
+ * @since 0.1-dev
+ *
+ * @package Two_Factor
+ */
+class Two_Factor_Dummy extends Two_Factor_Provider {
+
+	/**
+	 * Ensures only one instance of this class exists in memory at any one time.
+	 *
+	 * @since 0.1-dev
+	 */
+	public static function get_instance() {
+		static $instance;
+		$class = __CLASS__;
+		if ( ! is_a( $instance, $class ) ) {
+			$instance = new $class();
+		}
+		return $instance;
+	}
+
+	/**
+	 * Class constructor.
+	 *
+	 * @since 0.1-dev
+	 */
+	protected function __construct() {
+		add_action( 'two_factor_user_options_' . __CLASS__, array( $this, 'user_options' ) );
+		return parent::__construct();
+	}
+
+	/**
+	 * Returns the name of the provider.
+	 *
+	 * @since 0.1-dev
+	 */
+	public function get_label() {
+		return _x( 'Dummy Method', 'Provider Label', 'two-factor' );
+	}
+
+	/**
+	 * Prints the form that prompts the user to authenticate.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 */
+	public function authentication_page( $user ) {
+		require_once ABSPATH . '/wp-admin/includes/template.php';
+		?>
+		<p><?php esc_html_e( 'Are you really you?', 'two-factor' ); ?></p>
+		<?php
+		submit_button( __( 'Yup.', 'two-factor' ) );
+	}
+
+	/**
+	 * Validates the users input token.
+	 *
+	 * In this class we just return true.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 * @return boolean
+	 */
+	public function validate_authentication( $user ) {
+		return true;
+	}
+
+	/**
+	 * Whether this Two Factor provider is configured and available for the user specified.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 * @return boolean
+	 */
+	public function is_available_for_user( $user ) {
+		return true;
+	}
+
+	/**
+	 * Inserts markup at the end of the user profile field for this provider.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 */
+	public function user_options( $user ) {}
+}
diff --git a/wp-content/plugins/two-factor/providers/class-two-factor-email.php b/wp-content/plugins/two-factor/providers/class-two-factor-email.php
new file mode 100644
index 0000000000000000000000000000000000000000..94fd8448272b007db2b66ea856304aaad7ec620b
--- /dev/null
+++ b/wp-content/plugins/two-factor/providers/class-two-factor-email.php
@@ -0,0 +1,361 @@
+<?php
+/**
+ * Class for creating an email provider.
+ *
+ * @package Two_Factor
+ */
+
+/**
+ * Class for creating an email provider.
+ *
+ * @since 0.1-dev
+ *
+ * @package Two_Factor
+ */
+class Two_Factor_Email extends Two_Factor_Provider {
+
+	/**
+	 * The user meta token key.
+	 *
+	 * @var string
+	 */
+	const TOKEN_META_KEY = '_two_factor_email_token';
+
+	/**
+	 * Store the timestamp when the token was generated.
+	 *
+	 * @var string
+	 */
+	const TOKEN_META_KEY_TIMESTAMP = '_two_factor_email_token_timestamp';
+
+	/**
+	 * Name of the input field used for code resend.
+	 *
+	 * @var string
+	 */
+	const INPUT_NAME_RESEND_CODE = 'two-factor-email-code-resend';
+
+	/**
+	 * Ensures only one instance of this class exists in memory at any one time.
+	 *
+	 * @since 0.1-dev
+	 */
+	public static function get_instance() {
+		static $instance;
+		$class = __CLASS__;
+		if ( ! is_a( $instance, $class ) ) {
+			$instance = new $class();
+		}
+		return $instance;
+	}
+
+	/**
+	 * Class constructor.
+	 *
+	 * @since 0.1-dev
+	 */
+	protected function __construct() {
+		add_action( 'two_factor_user_options_' . __CLASS__, array( $this, 'user_options' ) );
+		return parent::__construct();
+	}
+
+	/**
+	 * Returns the name of the provider.
+	 *
+	 * @since 0.1-dev
+	 */
+	public function get_label() {
+		return _x( 'Email', 'Provider Label', 'two-factor' );
+	}
+
+	/**
+	 * Generate the user token.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param int $user_id User ID.
+	 * @return string
+	 */
+	public function generate_token( $user_id ) {
+		$token = $this->get_code();
+
+		update_user_meta( $user_id, self::TOKEN_META_KEY_TIMESTAMP, time() );
+		update_user_meta( $user_id, self::TOKEN_META_KEY, wp_hash( $token ) );
+
+		return $token;
+	}
+
+	/**
+	 * Check if user has a valid token already.
+	 *
+	 * @param  int $user_id User ID.
+	 * @return boolean      If user has a valid email token.
+	 */
+	public function user_has_token( $user_id ) {
+		$hashed_token = $this->get_user_token( $user_id );
+
+		if ( ! empty( $hashed_token ) ) {
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * Has the user token validity timestamp expired.
+	 *
+	 * @param integer $user_id User ID.
+	 *
+	 * @return boolean
+	 */
+	public function user_token_has_expired( $user_id ) {
+		$token_lifetime = $this->user_token_lifetime( $user_id );
+		$token_ttl      = $this->user_token_ttl( $user_id );
+
+		// Invalid token lifetime is considered an expired token.
+		if ( is_int( $token_lifetime ) && $token_lifetime <= $token_ttl ) {
+			return false;
+		}
+
+		return true;
+	}
+
+	/**
+	 * Get the lifetime of a user token in seconds.
+	 *
+	 * @param integer $user_id User ID.
+	 *
+	 * @return integer|null Return `null` if the lifetime can't be measured.
+	 */
+	public function user_token_lifetime( $user_id ) {
+		$timestamp = intval( get_user_meta( $user_id, self::TOKEN_META_KEY_TIMESTAMP, true ) );
+
+		if ( ! empty( $timestamp ) ) {
+			return time() - $timestamp;
+		}
+
+		return null;
+	}
+
+	/**
+	 * Return the token time-to-live for a user.
+	 *
+	 * @param integer $user_id User ID.
+	 *
+	 * @return integer
+	 */
+	public function user_token_ttl( $user_id ) {
+		$token_ttl = 15 * MINUTE_IN_SECONDS;
+
+		/**
+		 * Number of seconds the token is considered valid
+		 * after the generation.
+		 *
+		 * @param integer $token_ttl Token time-to-live in seconds.
+		 * @param integer $user_id User ID.
+		 */
+		return (int) apply_filters( 'two_factor_token_ttl', $token_ttl, $user_id );
+	}
+
+	/**
+	 * Get the authentication token for the user.
+	 *
+	 * @param  int $user_id    User ID.
+	 *
+	 * @return string|boolean  User token or `false` if no token found.
+	 */
+	public function get_user_token( $user_id ) {
+		$hashed_token = get_user_meta( $user_id, self::TOKEN_META_KEY, true );
+
+		if ( ! empty( $hashed_token ) && is_string( $hashed_token ) ) {
+			return $hashed_token;
+		}
+
+		return false;
+	}
+
+	/**
+	 * Validate the user token.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param int    $user_id User ID.
+	 * @param string $token User token.
+	 * @return boolean
+	 */
+	public function validate_token( $user_id, $token ) {
+		$hashed_token = $this->get_user_token( $user_id );
+
+		// Bail if token is empty or it doesn't match.
+		if ( empty( $hashed_token ) || ( wp_hash( $token ) !== $hashed_token ) ) {
+			return false;
+		}
+
+		if ( $this->user_token_has_expired( $user_id ) ) {
+			return false;
+		}
+
+		// Ensure the token can be used only once.
+		$this->delete_token( $user_id );
+
+		return true;
+	}
+
+	/**
+	 * Delete the user token.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param int $user_id User ID.
+	 */
+	public function delete_token( $user_id ) {
+		delete_user_meta( $user_id, self::TOKEN_META_KEY );
+	}
+
+	/**
+	 * Generate and email the user token.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 * @return bool Whether the email contents were sent successfully.
+	 */
+	public function generate_and_email_token( $user ) {
+		$token = $this->generate_token( $user->ID );
+
+		/* translators: %s: site name */
+		$subject = wp_strip_all_tags( sprintf( __( 'Your login confirmation code for %s', 'two-factor' ), get_bloginfo( 'name' ) ) );
+		/* translators: %s: token */
+		$message = wp_strip_all_tags( sprintf( __( 'Enter %s to log in.', 'two-factor' ), $token ) );
+
+		/**
+		 * Filter the token email subject.
+		 *
+		 * @param string $subject The email subject line.
+		 * @param int    $user_id The ID of the user.
+		 */
+		$subject = apply_filters( 'two_factor_token_email_subject', $subject, $user->ID );
+
+		/**
+		 * Filter the token email message.
+		 *
+		 * @param string $message The email message.
+		 * @param string $token   The token.
+		 * @param int    $user_id The ID of the user.
+		 */
+		$message = apply_filters( 'two_factor_token_email_message', $message, $token, $user->ID );
+
+		return wp_mail( $user->user_email, $subject, $message );
+	}
+
+	/**
+	 * Prints the form that prompts the user to authenticate.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 */
+	public function authentication_page( $user ) {
+		if ( ! $user ) {
+			return;
+		}
+
+		if ( ! $this->user_has_token( $user->ID ) || $this->user_token_has_expired( $user->ID ) ) {
+			$this->generate_and_email_token( $user );
+		}
+
+		require_once ABSPATH . '/wp-admin/includes/template.php';
+		?>
+		<p><?php esc_html_e( 'A verification code has been sent to the email address associated with your account.', 'two-factor' ); ?></p>
+		<p>
+			<label for="authcode"><?php esc_html_e( 'Verification Code:', 'two-factor' ); ?></label>
+			<input type="tel" name="two-factor-email-code" id="authcode" class="input" value="" size="20" />
+			<?php submit_button( __( 'Log In', 'two-factor' ) ); ?>
+		</p>
+		<p class="two-factor-email-resend">
+			<input type="submit" class="button" name="<?php echo esc_attr( self::INPUT_NAME_RESEND_CODE ); ?>" value="<?php esc_attr_e( 'Resend Code', 'two-factor' ); ?>" />
+		</p>
+		<script type="text/javascript">
+			setTimeout( function(){
+				var d;
+				try{
+					d = document.getElementById('authcode');
+					d.value = '';
+					d.focus();
+				} catch(e){}
+			}, 200);
+		</script>
+		<?php
+	}
+
+	/**
+	 * Send the email code if missing or requested. Stop the authentication
+	 * validation if a new token has been generated and sent.
+	 *
+	 * @param  WP_USer $user WP_User object of the logged-in user.
+	 * @return boolean
+	 */
+	public function pre_process_authentication( $user ) {
+		if ( isset( $user->ID ) && isset( $_REQUEST[ self::INPUT_NAME_RESEND_CODE ] ) ) {
+			$this->generate_and_email_token( $user );
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * Validates the users input token.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 * @return boolean
+	 */
+	public function validate_authentication( $user ) {
+		if ( ! isset( $user->ID ) || ! isset( $_REQUEST['two-factor-email-code'] ) ) {
+			return false;
+		}
+
+		// Ensure there are no spaces or line breaks around the code.
+		$code = trim( sanitize_text_field( $_REQUEST['two-factor-email-code'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, handled by the core method already.
+
+		return $this->validate_token( $user->ID, $code );
+	}
+
+	/**
+	 * Whether this Two Factor provider is configured and available for the user specified.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 * @return boolean
+	 */
+	public function is_available_for_user( $user ) {
+		return true;
+	}
+
+	/**
+	 * Inserts markup at the end of the user profile field for this provider.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 */
+	public function user_options( $user ) {
+		$email = $user->user_email;
+		?>
+		<div>
+			<?php
+			echo esc_html(
+				sprintf(
+				/* translators: %s: email address */
+					__( 'Authentication codes will be sent to %s.', 'two-factor' ),
+					$email
+				)
+			);
+			?>
+		</div>
+		<?php
+	}
+}
diff --git a/wp-content/plugins/two-factor/providers/class-two-factor-fido-u2f-admin-list-table.php b/wp-content/plugins/two-factor/providers/class-two-factor-fido-u2f-admin-list-table.php
new file mode 100644
index 0000000000000000000000000000000000000000..deb220cf9729023bd5231fdeaf959dd4d0cb1105
--- /dev/null
+++ b/wp-content/plugins/two-factor/providers/class-two-factor-fido-u2f-admin-list-table.php
@@ -0,0 +1,160 @@
+<?php
+/**
+ * Class for displaying the list of security key items.
+ *
+ * @package Two_Factor
+ */
+
+// Load the parent class if it doesn't exist.
+if ( ! class_exists( 'WP_List_Table' ) ) {
+	require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
+}
+
+/**
+ * Class for displaying the list of security key items.
+ *
+ * @since 0.1-dev
+ * @access private
+ *
+ * @package Two_Factor
+ */
+class Two_Factor_FIDO_U2F_Admin_List_Table extends WP_List_Table {
+
+	/**
+	 * Get a list of columns.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @return array
+	 */
+	public function get_columns() {
+		return array(
+			'name'      => wp_strip_all_tags( __( 'Name', 'two-factor' ) ),
+			'added'     => wp_strip_all_tags( __( 'Added', 'two-factor' ) ),
+			'last_used' => wp_strip_all_tags( __( 'Last Used', 'two-factor' ) ),
+		);
+	}
+
+	/**
+	 * Prepares the list of items for displaying.
+	 *
+	 * @since 0.1-dev
+	 */
+	public function prepare_items() {
+		$columns               = $this->get_columns();
+		$hidden                = array();
+		$sortable              = array();
+		$primary               = 'name';
+		$this->_column_headers = array( $columns, $hidden, $sortable, $primary );
+	}
+
+	/**
+	 * Generates content for a single row of the table
+	 *
+	 * @since 0.1-dev
+	 * @access protected
+	 *
+	 * @param object $item The current item.
+	 * @param string $column_name The current column name.
+	 * @return string
+	 */
+	protected function column_default( $item, $column_name ) {
+		switch ( $column_name ) {
+			case 'name':
+				$out  = '<div class="hidden" id="inline_' . esc_attr( $item->keyHandle ) . '">'; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+				$out .= '<div class="name">' . esc_html( $item->name ) . '</div>';
+				$out .= '</div>';
+
+				$actions = array(
+					'rename hide-if-no-js' => Two_Factor_FIDO_U2F_Admin::rename_link( $item ),
+					'delete'               => Two_Factor_FIDO_U2F_Admin::delete_link( $item ),
+				);
+
+				return esc_html( $item->name ) . $out . self::row_actions( $actions );
+			case 'added':
+				return gmdate( get_option( 'date_format', 'r' ), $item->added );
+			case 'last_used':
+				return gmdate( get_option( 'date_format', 'r' ), $item->last_used );
+			default:
+				return 'WTF^^?';
+		}
+	}
+
+	/**
+	 * Generates custom table navigation to prevent conflicting nonces.
+	 *
+	 * @since 0.1-dev
+	 * @access protected
+	 *
+	 * @param string $which The location of the bulk actions: 'top' or 'bottom'.
+	 */
+	protected function display_tablenav( $which ) {
+		// Not used for the Security key list.
+	}
+
+	/**
+	 * Generates content for a single row of the table
+	 *
+	 * @since 0.1-dev
+	 * @access public
+	 *
+	 * @param object $item The current item.
+	 */
+	public function single_row( $item ) {
+		?>
+		<tr id="key-<?php echo esc_attr( $item->keyHandle ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase ?>">
+		<?php $this->single_row_columns( $item ); ?>
+		</tr>
+		<?php
+	}
+
+	/**
+	 * Outputs the hidden row displayed when inline editing
+	 *
+	 * @since 0.1-dev
+	 */
+	public function inline_edit() {
+		?>
+		<table style="display: none">
+			<tbody id="inlineedit">
+				<tr id="inline-edit" class="inline-edit-row" style="display: none">
+					<td colspan="<?php echo esc_attr( $this->get_column_count() ); ?>" class="colspanchange">
+						<fieldset>
+							<div class="inline-edit-col">
+								<label>
+									<span class="title"><?php esc_html_e( 'Name', 'two-factor' ); ?></span>
+									<span class="input-text-wrap"><input type="text" name="name" class="ptitle" value="" /></span>
+								</label>
+							</div>
+						</fieldset>
+						<?php
+						$core_columns    = array(
+							'name'      => true,
+							'added'     => true,
+							'last_used' => true,
+						);
+						list( $columns ) = $this->get_column_info();
+						foreach ( $columns as $column_name => $column_display_name ) {
+							if ( isset( $core_columns[ $column_name ] ) ) {
+								continue;
+							}
+
+							/** This action is documented in wp-admin/includes/class-wp-posts-list-table.php */
+							do_action( 'quick_edit_custom_box', $column_name, 'edit-security-keys' );
+						}
+						?>
+						<p class="inline-edit-save submit">
+							<a href="#inline-edit" class="cancel button-secondary alignleft"><?php esc_html_e( 'Cancel', 'two-factor' ); ?></a>
+							<a href="#inline-edit" class="save button-primary alignright"><?php esc_html_e( 'Update', 'two-factor' ); ?></a>
+							<span class="spinner"></span>
+							<span class="error" style="display:none;"></span>
+							<?php wp_nonce_field( 'keyinlineeditnonce', '_inline_edit', false ); ?>
+							<br class="clear" />
+						</p>
+					</td>
+				</tr>
+			</tbody>
+		</table>
+		<?php
+	}
+}
diff --git a/wp-content/plugins/two-factor/providers/class-two-factor-fido-u2f-admin.php b/wp-content/plugins/two-factor/providers/class-two-factor-fido-u2f-admin.php
new file mode 100644
index 0000000000000000000000000000000000000000..7fc297f7165a2dbe4849ab0ec63717732d9a7807
--- /dev/null
+++ b/wp-content/plugins/two-factor/providers/class-two-factor-fido-u2f-admin.php
@@ -0,0 +1,358 @@
+<?php
+/**
+ * Class for registering & modifying FIDO U2F security keys.
+ *
+ * @package Two_Factor
+ */
+
+/**
+ * Class for registering & modifying FIDO U2F security keys.
+ *
+ * @since 0.1-dev
+ *
+ * @package Two_Factor
+ */
+class Two_Factor_FIDO_U2F_Admin {
+
+	/**
+	 * The user meta register data.
+	 *
+	 * @type string
+	 */
+	const REGISTER_DATA_USER_META_KEY = '_two_factor_fido_u2f_register_request';
+
+	/**
+	 * Add various hooks.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @access public
+	 * @static
+	 */
+	public static function add_hooks() {
+		add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_assets' ) );
+		add_action( 'show_user_security_settings', array( __CLASS__, 'show_user_profile' ) );
+		add_action( 'personal_options_update', array( __CLASS__, 'catch_submission' ), 0 );
+		add_action( 'edit_user_profile_update', array( __CLASS__, 'catch_submission' ), 0 );
+		add_action( 'load-profile.php', array( __CLASS__, 'catch_delete_security_key' ) );
+		add_action( 'load-user-edit.php', array( __CLASS__, 'catch_delete_security_key' ) );
+		add_action( 'wp_ajax_inline-save-key', array( __CLASS__, 'wp_ajax_inline_save' ) );
+	}
+
+	/**
+	 * Enqueue assets.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @access public
+	 * @static
+	 *
+	 * @param string $hook Current page.
+	 */
+	public static function enqueue_assets( $hook ) {
+		if ( ! in_array( $hook, array( 'user-edit.php', 'profile.php' ), true ) ) {
+			return;
+		}
+
+		$user_id = Two_Factor_Core::current_user_being_edited();
+		if ( ! $user_id ) {
+			return;
+		}
+
+		$security_keys = Two_Factor_FIDO_U2F::get_security_keys( $user_id );
+
+		// @todo Ensure that scripts don't fail because of missing u2fL10n.
+		try {
+			$data              = Two_Factor_FIDO_U2F::$u2f->getRegisterData( $security_keys );
+			list( $req,$sigs ) = $data;
+
+			update_user_meta( $user_id, self::REGISTER_DATA_USER_META_KEY, $req );
+		} catch ( Exception $e ) {
+			return false;
+		}
+
+		wp_enqueue_style(
+			'fido-u2f-admin',
+			plugins_url( 'css/fido-u2f-admin.css', __FILE__ ),
+			null,
+			self::asset_version()
+		);
+
+		wp_enqueue_script(
+			'fido-u2f-admin',
+			plugins_url( 'js/fido-u2f-admin.js', __FILE__ ),
+			array( 'jquery', 'fido-u2f-api' ),
+			self::asset_version(),
+			true
+		);
+
+		/**
+		 * Pass a U2F challenge and user data to our scripts
+		 */
+
+		$translation_array = array(
+			'user_id'  => $user_id,
+			'register' => array(
+				'request' => $req,
+				'sigs'    => $sigs,
+			),
+			'text'     => array(
+				'insert'            => esc_html__( 'Now insert (and tap) your Security Key.', 'two-factor' ),
+				'error'             => esc_html__( 'U2F request failed.', 'two-factor' ),
+				'error_codes'       => array(
+					// Map u2f.ErrorCodes to error messages.
+					0 => esc_html__( 'Request OK.', 'two-factor' ),
+					1 => esc_html__( 'Other U2F error.', 'two-factor' ),
+					2 => esc_html__( 'Bad U2F request.', 'two-factor' ),
+					3 => esc_html__( 'Unsupported U2F configuration.', 'two-factor' ),
+					4 => esc_html__( 'U2F device ineligible.', 'two-factor' ),
+					5 => esc_html__( 'U2F request timeout reached.', 'two-factor' ),
+				),
+				'u2f_not_supported' => esc_html__( 'FIDO U2F appears to be not supported by your web browser. Try using Google Chrome or Firefox.', 'two-factor' ),
+			),
+		);
+
+		wp_localize_script(
+			'fido-u2f-admin',
+			'u2fL10n',
+			$translation_array
+		);
+
+		/**
+		 * Script for admin UI
+		 */
+
+		wp_enqueue_script(
+			'inline-edit-key',
+			plugins_url( 'js/fido-u2f-admin-inline-edit.js', __FILE__ ),
+			array( 'jquery' ),
+			self::asset_version(),
+			true
+		);
+
+		wp_localize_script(
+			'inline-edit-key',
+			'inlineEditL10n',
+			array(
+				'error' => esc_html__( 'Error while saving the changes.', 'two-factor' ),
+			)
+		);
+	}
+
+	/**
+	 * Return the current asset version number.
+	 *
+	 * Added as own helper to allow swapping the implementation once we inject
+	 * it as a dependency.
+	 *
+	 * @return string
+	 */
+	protected static function asset_version() {
+		return Two_Factor_FIDO_U2F::asset_version();
+	}
+
+	/**
+	 * Display the security key section in a users profile.
+	 *
+	 * This executes during the `show_user_security_settings` action.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @access public
+	 * @static
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 */
+	public static function show_user_profile( $user ) {
+		wp_nonce_field( "user_security_keys-{$user->ID}", '_nonce_user_security_keys' );
+		$new_key = false;
+
+		$security_keys = Two_Factor_FIDO_U2F::get_security_keys( $user->ID );
+		if ( $security_keys ) {
+			foreach ( $security_keys as &$security_key ) {
+				if ( property_exists( $security_key, 'new' ) ) {
+					$new_key = true;
+					unset( $security_key->new );
+
+					// If we've got a new one, update the db record to not save it there any longer.
+					Two_Factor_FIDO_U2F::update_security_key( $user->ID, $security_key );
+				}
+			}
+			unset( $security_key );
+		}
+
+		?>
+		<div class="security-keys" id="security-keys-section">
+			<h3><?php esc_html_e( 'Security Keys', 'two-factor' ); ?></h3>
+
+			<?php if ( ! is_ssl() ) : ?>
+			<p class="u2f-error-https">
+				<em><?php esc_html_e( 'U2F requires an HTTPS connection. You won\'t be able to add new security keys over HTTP.', 'two-factor' ); ?></em>
+			</p>
+			<?php endif; ?>
+
+			<div class="register-security-key">
+				<input type="hidden" name="do_new_security_key" id="do_new_security_key" />
+				<input type="hidden" name="u2f_response" id="u2f_response" />
+				<button type="button" class="button button-secondary" id="register_security_key"><?php echo esc_html( _x( 'Register New Key', 'security key', 'two-factor' ) ); ?></button>
+				<span class="spinner"></span>
+				<span class="security-key-status"></span>
+			</div>
+
+			<?php if ( $new_key ) : ?>
+			<div class="notice notice-success is-dismissible">
+				<p class="new-security-key"><?php esc_html_e( 'Your new security key registered.', 'two-factor' ); ?></p>
+			</div>
+			<?php endif; ?>
+
+			<p><a href="https://support.google.com/accounts/answer/6103523"><?php esc_html_e( 'You can find FIDO U2F Security Key devices for sale from here.', 'two-factor' ); ?></a></p>
+
+			<?php
+				require TWO_FACTOR_DIR . 'providers/class-two-factor-fido-u2f-admin-list-table.php';
+				$u2f_list_table        = new Two_Factor_FIDO_U2F_Admin_List_Table();
+				$u2f_list_table->items = $security_keys;
+				$u2f_list_table->prepare_items();
+				$u2f_list_table->display();
+				$u2f_list_table->inline_edit();
+			?>
+		</div>
+		<?php
+	}
+
+	/**
+	 * Catch the non-ajax submission from the new form.
+	 *
+	 * This executes during the `personal_options_update` & `edit_user_profile_update` actions.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @access public
+	 * @static
+	 *
+	 * @param int $user_id User ID.
+	 * @return false
+	 */
+	public static function catch_submission( $user_id ) {
+		if ( ! empty( $_REQUEST['do_new_security_key'] ) ) {
+			check_admin_referer( "user_security_keys-{$user_id}", '_nonce_user_security_keys' );
+
+			try {
+				$response = json_decode( stripslashes( $_POST['u2f_response'] ) );
+				$reg      = Two_Factor_FIDO_U2F::$u2f->doRegister( get_user_meta( $user_id, self::REGISTER_DATA_USER_META_KEY, true ), $response );
+				$reg->new = true;
+
+				Two_Factor_FIDO_U2F::add_security_key( $user_id, $reg );
+			} catch ( Exception $e ) {
+				return false;
+			}
+
+			delete_user_meta( $user_id, self::REGISTER_DATA_USER_META_KEY );
+
+			wp_safe_redirect(
+				add_query_arg(
+					array(
+						'new_app_pass' => 1,
+					),
+					wp_get_referer()
+				) . '#security-keys-section'
+			);
+			exit;
+		}
+	}
+
+	/**
+	 * Catch the delete security key request.
+	 *
+	 * This executes during the `load-profile.php` & `load-user-edit.php` actions.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @access public
+	 * @static
+	 */
+	public static function catch_delete_security_key() {
+		$user_id = Two_Factor_Core::current_user_being_edited();
+
+		if ( ! empty( $user_id ) && ! empty( $_REQUEST['delete_security_key'] ) ) {
+			$slug = $_REQUEST['delete_security_key'];
+
+			check_admin_referer( "delete_security_key-{$slug}", '_nonce_delete_security_key' );
+
+			Two_Factor_FIDO_U2F::delete_security_key( $user_id, $slug );
+
+			wp_safe_redirect( remove_query_arg( 'new_app_pass', wp_get_referer() ) . '#security-keys-section' );
+		}
+	}
+
+	/**
+	 * Generate a link to rename a specified security key.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @access public
+	 * @static
+	 *
+	 * @param array $item The current item.
+	 * @return string
+	 */
+	public static function rename_link( $item ) {
+		return sprintf( '<a href="#" class="editinline">%s</a>', esc_html__( 'Rename', 'two-factor' ) );
+	}
+
+	/**
+	 * Generate a link to delete a specified security key.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @access public
+	 * @static
+	 *
+	 * @param array $item The current item.
+	 * @return string
+	 */
+	public static function delete_link( $item ) {
+		$delete_link = add_query_arg( 'delete_security_key', $item->keyHandle ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+		$delete_link = wp_nonce_url( $delete_link, "delete_security_key-{$item->keyHandle}", '_nonce_delete_security_key' );
+		return sprintf( '<a href="%1$s">%2$s</a>', esc_url( $delete_link ), esc_html__( 'Delete', 'two-factor' ) );
+	}
+
+	/**
+	 * Ajax handler for quick edit saving for a security key.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @access public
+	 * @static
+	 */
+	public static function wp_ajax_inline_save() {
+		check_ajax_referer( 'keyinlineeditnonce', '_inline_edit' );
+
+		require TWO_FACTOR_DIR . 'providers/class-two-factor-fido-u2f-admin-list-table.php';
+		$wp_list_table = new Two_Factor_FIDO_U2F_Admin_List_Table();
+
+		if ( ! isset( $_POST['keyHandle'] ) ) {
+			wp_die();
+		}
+
+		$user_id       = Two_Factor_Core::current_user_being_edited();
+		$security_keys = Two_Factor_FIDO_U2F::get_security_keys( $user_id );
+		if ( ! $security_keys ) {
+			wp_die();
+		}
+
+		foreach ( $security_keys as &$key ) {
+			if ( $key->keyHandle === $_POST['keyHandle'] ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+				break;
+			}
+		}
+
+		$key->name = $_POST['name'];
+
+		$updated = Two_Factor_FIDO_U2F::update_security_key( $user_id, $key );
+		if ( ! $updated ) {
+			wp_die( esc_html__( 'Item not updated.', 'two-factor' ) );
+		}
+		$wp_list_table->single_row( $key );
+		wp_die();
+	}
+}
diff --git a/wp-content/plugins/two-factor/providers/class-two-factor-fido-u2f.php b/wp-content/plugins/two-factor/providers/class-two-factor-fido-u2f.php
new file mode 100644
index 0000000000000000000000000000000000000000..330451c2f9c4c107e0ded1196c079bca3903e2f9
--- /dev/null
+++ b/wp-content/plugins/two-factor/providers/class-two-factor-fido-u2f.php
@@ -0,0 +1,397 @@
+<?php
+/**
+ * Class for creating a FIDO Universal 2nd Factor provider.
+ *
+ * @package Two_Factor
+ */
+
+/**
+ * Class for creating a FIDO Universal 2nd Factor provider.
+ *
+ * @since 0.1-dev
+ *
+ * @package Two_Factor
+ */
+class Two_Factor_FIDO_U2F extends Two_Factor_Provider {
+
+	/**
+	 * U2F Library
+	 *
+	 * @var u2flib_server\U2F
+	 */
+	public static $u2f;
+
+	/**
+	 * The user meta registered key.
+	 *
+	 * @type string
+	 */
+	const REGISTERED_KEY_USER_META_KEY = '_two_factor_fido_u2f_registered_key';
+
+	/**
+	 * The user meta authenticate data.
+	 *
+	 * @type string
+	 */
+	const AUTH_DATA_USER_META_KEY = '_two_factor_fido_u2f_login_request';
+
+	/**
+	 * Version number for the bundled assets.
+	 *
+	 * @var string
+	 */
+	const U2F_ASSET_VERSION = '0.2.1';
+
+	/**
+	 * Ensures only one instance of this class exists in memory at any one time.
+	 *
+	 * @return \Two_Factor_FIDO_U2F
+	 */
+	public static function get_instance() {
+		static $instance;
+
+		if ( ! isset( $instance ) ) {
+			$instance = new self();
+		}
+
+		return $instance;
+	}
+
+	/**
+	 * Class constructor.
+	 *
+	 * @since 0.1-dev
+	 */
+	protected function __construct() {
+		if ( version_compare( PHP_VERSION, '5.3.0', '<' ) ) {
+			return;
+		}
+
+		require_once TWO_FACTOR_DIR . 'includes/Yubico/U2F.php';
+		self::$u2f = new u2flib_server\U2F( self::get_u2f_app_id() );
+
+		require_once TWO_FACTOR_DIR . 'providers/class-two-factor-fido-u2f-admin.php';
+		Two_Factor_FIDO_U2F_Admin::add_hooks();
+
+		// Ensure the script dependencies have been registered before they're enqueued at a later priority.
+		add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ), 5 );
+		add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ), 5 );
+		add_action( 'login_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ), 5 );
+
+		add_action( 'two_factor_user_options_' . __CLASS__, array( $this, 'user_options' ) );
+
+		return parent::__construct();
+	}
+
+	/**
+	 * Get the asset version number.
+	 *
+	 * TODO: There should be a plugin-level helper for getting the current plugin version.
+	 *
+	 * @return string
+	 */
+	public static function asset_version() {
+		return self::U2F_ASSET_VERSION;
+	}
+
+	/**
+	 * Return the U2F AppId. U2F requires the AppID to use HTTPS
+	 * and a top-level domain.
+	 *
+	 * @return string AppID URI
+	 */
+	public static function get_u2f_app_id() {
+		$url_parts = wp_parse_url( home_url() );
+
+		if ( ! empty( $url_parts['port'] ) ) {
+			return sprintf( 'https://%s:%d', $url_parts['host'], $url_parts['port'] );
+		} else {
+			return sprintf( 'https://%s', $url_parts['host'] );
+		}
+	}
+
+	/**
+	 * Returns the name of the provider.
+	 *
+	 * @since 0.1-dev
+	 */
+	public function get_label() {
+		return _x( 'FIDO U2F Security Keys', 'Provider Label', 'two-factor' );
+	}
+
+	/**
+	 * Register script dependencies used during login and when
+	 * registering keys in the WP admin.
+	 *
+	 * @return void
+	 */
+	public static function enqueue_scripts() {
+		wp_register_script(
+			'fido-u2f-api',
+			plugins_url( 'includes/Google/u2f-api.js', dirname( __FILE__ ) ),
+			null,
+			self::asset_version(),
+			true
+		);
+
+		wp_register_script(
+			'fido-u2f-login',
+			plugins_url( 'js/fido-u2f-login.js', __FILE__ ),
+			array( 'jquery', 'fido-u2f-api' ),
+			self::asset_version(),
+			true
+		);
+	}
+
+	/**
+	 * Prints the form that prompts the user to authenticate.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 * @return null
+	 */
+	public function authentication_page( $user ) {
+		require_once ABSPATH . '/wp-admin/includes/template.php';
+
+		// U2F doesn't work without HTTPS.
+		if ( ! is_ssl() ) {
+			?>
+			<p><?php esc_html_e( 'U2F requires an HTTPS connection. Please use an alternative 2nd factor method.', 'two-factor' ); ?></p>
+			<?php
+
+			return;
+		}
+
+		try {
+			$keys = self::get_security_keys( $user->ID );
+			$data = self::$u2f->getAuthenticateData( $keys );
+			update_user_meta( $user->ID, self::AUTH_DATA_USER_META_KEY, $data );
+		} catch ( Exception $e ) {
+			?>
+			<p><?php esc_html_e( 'An error occurred while creating authentication data.', 'two-factor' ); ?></p>
+			<?php
+			return null;
+		}
+
+		wp_localize_script(
+			'fido-u2f-login',
+			'u2fL10n',
+			array(
+				'request' => $data,
+			)
+		);
+
+		wp_enqueue_script( 'fido-u2f-login' );
+
+		?>
+		<p><?php esc_html_e( 'Now insert (and tap) your Security Key.', 'two-factor' ); ?></p>
+		<input type="hidden" name="u2f_response" id="u2f_response" />
+		<?php
+	}
+
+	/**
+	 * Validates the users input token.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 * @return boolean
+	 */
+	public function validate_authentication( $user ) {
+		$requests = get_user_meta( $user->ID, self::AUTH_DATA_USER_META_KEY, true );
+
+		$response = json_decode( stripslashes( $_REQUEST['u2f_response'] ) );
+
+		$keys = self::get_security_keys( $user->ID );
+
+		try {
+			$reg = self::$u2f->doAuthenticate( $requests, $keys, $response );
+
+			$reg->last_used = time();
+
+			self::update_security_key( $user->ID, $reg );
+
+			return true;
+		} catch ( Exception $e ) {
+			return false;
+		}
+	}
+
+	/**
+	 * Whether this Two Factor provider is configured and available for the user specified.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 * @return boolean
+	 */
+	public function is_available_for_user( $user ) {
+		return (bool) self::get_security_keys( $user->ID );
+	}
+
+	/**
+	 * Inserts markup at the end of the user profile field for this provider.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 */
+	public function user_options( $user ) {
+		?>
+		<p>
+			<?php esc_html_e( 'Requires an HTTPS connection. Configure your security keys in the "Security Keys" section below.', 'two-factor' ); ?>
+		</p>
+		<?php
+	}
+
+	/**
+	 * Add registered security key to a user.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param int    $user_id  User ID.
+	 * @param object $register The data of registered security key.
+	 * @return int|bool Meta ID on success, false on failure.
+	 */
+	public static function add_security_key( $user_id, $register ) {
+		if ( ! is_numeric( $user_id ) ) {
+			return false;
+		}
+
+		if (
+			! is_object( $register )
+				|| ! property_exists( $register, 'keyHandle' ) || empty( $register->keyHandle ) // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+				|| ! property_exists( $register, 'publicKey' ) || empty( $register->publicKey ) // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+				|| ! property_exists( $register, 'certificate' ) || empty( $register->certificate )
+				|| ! property_exists( $register, 'counter' ) || ( -1 > $register->counter )
+		) {
+			return false;
+		}
+
+		$register = array(
+			'keyHandle'   => $register->keyHandle, // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+			'publicKey'   => $register->publicKey, // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+			'certificate' => $register->certificate,
+			'counter'     => $register->counter,
+		);
+
+		$register['name']      = __( 'New Security Key', 'two-factor' );
+		$register['added']     = time();
+		$register['last_used'] = $register['added'];
+
+		return add_user_meta( $user_id, self::REGISTERED_KEY_USER_META_KEY, $register );
+	}
+
+	/**
+	 * Retrieve registered security keys for a user.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param int $user_id User ID.
+	 * @return array|bool Array of keys on success, false on failure.
+	 */
+	public static function get_security_keys( $user_id ) {
+		if ( ! is_numeric( $user_id ) ) {
+			return false;
+		}
+
+		$keys = get_user_meta( $user_id, self::REGISTERED_KEY_USER_META_KEY );
+		if ( $keys ) {
+			foreach ( $keys as &$key ) {
+				$key = (object) $key;
+			}
+			unset( $key );
+		}
+
+		return $keys;
+	}
+
+	/**
+	 * Update registered security key.
+	 *
+	 * Use the $prev_value parameter to differentiate between meta fields with the
+	 * same key and user ID.
+	 *
+	 * If the meta field for the user does not exist, it will be added.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param int    $user_id  User ID.
+	 * @param object $data The data of registered security key.
+	 * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure.
+	 */
+	public static function update_security_key( $user_id, $data ) {
+		if ( ! is_numeric( $user_id ) ) {
+			return false;
+		}
+
+		if (
+			! is_object( $data )
+				|| ! property_exists( $data, 'keyHandle' ) || empty( $data->keyHandle ) // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+				|| ! property_exists( $data, 'publicKey' ) || empty( $data->publicKey ) // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+				|| ! property_exists( $data, 'certificate' ) || empty( $data->certificate )
+				|| ! property_exists( $data, 'counter' ) || ( -1 > $data->counter )
+		) {
+			return false;
+		}
+
+		$keys = self::get_security_keys( $user_id );
+		if ( $keys ) {
+			foreach ( $keys as $key ) {
+				if ( $key->keyHandle === $data->keyHandle ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+					return update_user_meta( $user_id, self::REGISTERED_KEY_USER_META_KEY, (array) $data, (array) $key );
+				}
+			}
+		}
+
+		return self::add_security_key( $user_id, $data );
+	}
+
+	/**
+	 * Remove registered security key matching criteria from a user.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param int    $user_id   User ID.
+	 * @param string $keyHandle Optional. Key handle.
+	 * @return bool True on success, false on failure.
+	 */
+	public static function delete_security_key( $user_id, $keyHandle = null ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
+		global $wpdb;
+
+		if ( ! is_numeric( $user_id ) ) {
+			return false;
+		}
+
+		$user_id = absint( $user_id );
+		if ( ! $user_id ) {
+			return false;
+		}
+
+		$keyHandle = wp_unslash( $keyHandle ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
+		$keyHandle = maybe_serialize( $keyHandle ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
+
+		$query = $wpdb->prepare( "SELECT umeta_id FROM {$wpdb->usermeta} WHERE meta_key = %s AND user_id = %d", self::REGISTERED_KEY_USER_META_KEY, $user_id );
+
+		if ( $keyHandle ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
+			$key_handle_lookup = sprintf( ':"%s";s:', $keyHandle ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
+
+			$query .= $wpdb->prepare(
+				' AND meta_value LIKE %s',
+				'%' . $wpdb->esc_like( $key_handle_lookup ) . '%'
+			);
+		}
+
+		$meta_ids = $wpdb->get_col( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+		if ( ! count( $meta_ids ) ) {
+			return false;
+		}
+
+		foreach ( $meta_ids as $meta_id ) {
+			delete_metadata_by_mid( 'user', $meta_id );
+		}
+
+		return true;
+	}
+}
diff --git a/wp-content/plugins/two-factor/providers/class-two-factor-provider.php b/wp-content/plugins/two-factor/providers/class-two-factor-provider.php
new file mode 100644
index 0000000000000000000000000000000000000000..a2f9be062eb2cab7513833293f71dc4baa78ca59
--- /dev/null
+++ b/wp-content/plugins/two-factor/providers/class-two-factor-provider.php
@@ -0,0 +1,102 @@
+<?php
+/**
+ * Abstract class for creating two factor authentication providers.
+ *
+ * @package Two_Factor
+ */
+
+/**
+ * Abstract class for creating two factor authentication providers.
+ *
+ * @since 0.1-dev
+ *
+ * @package Two_Factor
+ */
+abstract class Two_Factor_Provider {
+
+	/**
+	 * Class constructor.
+	 *
+	 * @since 0.1-dev
+	 */
+	protected function __construct() {
+		return $this;
+	}
+
+	/**
+	 * Returns the name of the provider.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @return string
+	 */
+	abstract public function get_label();
+
+	/**
+	 * Prints the name of the provider.
+	 *
+	 * @since 0.1-dev
+	 */
+	public function print_label() {
+		echo esc_html( $this->get_label() );
+	}
+
+	/**
+	 * Prints the form that prompts the user to authenticate.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 */
+	abstract public function authentication_page( $user );
+
+	/**
+	 * Allow providers to do extra processing before the authentication.
+	 * Return `true` to prevent the authentication and render the
+	 * authentication page.
+	 *
+	 * @param  WP_User $user WP_User object of the logged-in user.
+	 * @return boolean
+	 */
+	public function pre_process_authentication( $user ) {
+		return false;
+	}
+
+	/**
+	 * Validates the users input token.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 * @return boolean
+	 */
+	abstract public function validate_authentication( $user );
+
+	/**
+	 * Whether this Two Factor provider is configured and available for the user specified.
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 * @return boolean
+	 */
+	abstract public function is_available_for_user( $user );
+
+	/**
+	 * Generate a random eight-digit string to send out as an auth code.
+	 *
+	 * @since 0.1-dev
+	 *
+	 * @param int          $length The code length.
+	 * @param string|array $chars Valid auth code characters.
+	 * @return string
+	 */
+	public function get_code( $length = 8, $chars = '1234567890' ) {
+		$code = '';
+		if ( is_array( $chars ) ) {
+			$chars = implode( '', $chars );
+		}
+		for ( $i = 0; $i < $length; $i++ ) {
+			$code .= substr( $chars, wp_rand( 0, strlen( $chars ) - 1 ), 1 );
+		}
+		return $code;
+	}
+}
diff --git a/wp-content/plugins/two-factor/providers/class-two-factor-totp.php b/wp-content/plugins/two-factor/providers/class-two-factor-totp.php
new file mode 100644
index 0000000000000000000000000000000000000000..11f71f6e1779e939259273c80fc263a4b637f310
--- /dev/null
+++ b/wp-content/plugins/two-factor/providers/class-two-factor-totp.php
@@ -0,0 +1,558 @@
+<?php
+/**
+ * Class for creating a Time Based One-Time Password provider.
+ *
+ * @package Two_Factor
+ */
+
+/**
+ * Class Two_Factor_Totp
+ */
+class Two_Factor_Totp extends Two_Factor_Provider {
+
+	/**
+	 * The user meta token key.
+	 *
+	 * @var string
+	 */
+	const SECRET_META_KEY = '_two_factor_totp_key';
+
+	/**
+	 * The user meta token key.
+	 *
+	 * @var string
+	 */
+	const NOTICES_META_KEY = '_two_factor_totp_notices';
+
+	/**
+	 * Action name for resetting the secret token.
+	 *
+	 * @var string
+	 */
+	const ACTION_SECRET_DELETE = 'totp-delete';
+
+	const DEFAULT_KEY_BIT_SIZE        = 160;
+	const DEFAULT_CRYPTO              = 'sha1';
+	const DEFAULT_DIGIT_COUNT         = 6;
+	const DEFAULT_TIME_STEP_SEC       = 30;
+	const DEFAULT_TIME_STEP_ALLOWANCE = 4;
+
+	/**
+	 * Chracters used in base32 encoding.
+	 *
+	 * @var string
+	 */
+	private static $base_32_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
+
+	/**
+	 * Class constructor. Sets up hooks, etc.
+	 */
+	protected function __construct() {
+		add_action( 'two_factor_user_options_' . __CLASS__, array( $this, 'user_two_factor_options' ) );
+		add_action( 'personal_options_update', array( $this, 'user_two_factor_options_update' ) );
+		add_action( 'edit_user_profile_update', array( $this, 'user_two_factor_options_update' ) );
+		add_action( 'two_factor_user_settings_action', array( $this, 'user_settings_action' ), 10, 2 );
+
+		return parent::__construct();
+	}
+
+	/**
+	 * Ensures only one instance of this class exists in memory at any one time.
+	 */
+	public static function get_instance() {
+		static $instance;
+		if ( ! isset( $instance ) ) {
+			$instance = new self();
+		}
+		return $instance;
+	}
+
+	/**
+	 * Returns the name of the provider.
+	 */
+	public function get_label() {
+		return _x( 'Time Based One-Time Password (TOTP)', 'Provider Label', 'two-factor' );
+	}
+
+	/**
+	 * Trigger our custom user settings actions.
+	 *
+	 * @param integer $user_id User ID.
+	 * @param string  $action Action ID.
+	 *
+	 * @return void
+	 */
+	public function user_settings_action( $user_id, $action ) {
+		if ( self::ACTION_SECRET_DELETE === $action ) {
+			$this->delete_user_totp_key( $user_id );
+		}
+	}
+
+	/**
+	 * Get the URL for deleting the secret token.
+	 *
+	 * @param integer $user_id User ID.
+	 *
+	 * @return string
+	 */
+	protected function get_token_delete_url_for_user( $user_id ) {
+		return Two_Factor_Core::get_user_update_action_url( $user_id, self::ACTION_SECRET_DELETE );
+	}
+
+	/**
+	 * Display TOTP options on the user settings page.
+	 *
+	 * @param WP_User $user The current user being edited.
+	 * @return false
+	 */
+	public function user_two_factor_options( $user ) {
+		if ( ! isset( $user->ID ) ) {
+			return false;
+		}
+
+		wp_nonce_field( 'user_two_factor_totp_options', '_nonce_user_two_factor_totp_options', false );
+
+		$key = $this->get_user_totp_key( $user->ID );
+		$this->admin_notices( $user->ID );
+
+		?>
+		<div id="two-factor-totp-options">
+		<?php
+		if ( empty( $key ) ) :
+			$key        = $this->generate_key();
+			$site_name  = get_bloginfo( 'name', 'display' );
+			$totp_title = apply_filters( 'two_factor_totp_title', $site_name . ':' . $user->user_login, $user );
+			?>
+			<p>
+				<?php esc_html_e( 'Please scan the QR code or manually enter the key, then enter an authentication code from your app in order to complete setup.', 'two-factor' ); ?>
+			</p>
+			<p>
+				<img src="<?php echo esc_url( $this->get_google_qr_code( $totp_title, $key, $site_name ) ); ?>" id="two-factor-totp-qrcode" />
+			</p>
+			<p>
+				<code><?php echo esc_html( $key ); ?></code>
+			</p>
+			<p>
+				<input type="hidden" name="two-factor-totp-key" value="<?php echo esc_attr( $key ); ?>" />
+				<label for="two-factor-totp-authcode">
+					<?php esc_html_e( 'Authentication Code:', 'two-factor' ); ?>
+					<input type="tel" name="two-factor-totp-authcode" id="two-factor-totp-authcode" class="input" value="" size="20" pattern="[0-9]*" />
+				</label>
+				<input type="submit" class="button" name="two-factor-totp-submit" value="<?php esc_attr_e( 'Submit', 'two-factor' ); ?>" />
+			</p>
+		<?php else : ?>
+			<p class="success">
+				<?php esc_html_e( 'Secret key is configured and registered. It is not possible to view it again for security reasons.', 'two-factor' ); ?>
+			</p>
+			<p>
+				<a class="button" href="<?php echo esc_url( self::get_token_delete_url_for_user( $user->ID ) ); ?>"><?php esc_html_e( 'Reset Key', 'two-factor' ); ?></a>
+				<em class="description">
+					<?php esc_html_e( 'You will have to re-scan the QR code on all devices as the previous codes will stop working.', 'two-factor' ); ?>
+				</em>
+			</p>
+		<?php endif; ?>
+		</div>
+		<?php
+	}
+
+	/**
+	 * Save the options specified in `::user_two_factor_options()`
+	 *
+	 * @param integer $user_id The user ID whose options are being updated.
+	 *
+	 * @return void
+	 */
+	public function user_two_factor_options_update( $user_id ) {
+		$notices = array();
+		$errors  = array();
+
+		if ( isset( $_POST['_nonce_user_two_factor_totp_options'] ) ) {
+			check_admin_referer( 'user_two_factor_totp_options', '_nonce_user_two_factor_totp_options' );
+
+			// Validate and store a new secret key.
+			if ( ! empty( $_POST['two-factor-totp-authcode'] ) && ! empty( $_POST['two-factor-totp-key'] ) ) {
+				// Don't use filter_input() because we can't mock it during tests for now.
+				$authcode = filter_var( sanitize_text_field( $_POST['two-factor-totp-authcode'] ), FILTER_SANITIZE_NUMBER_INT );
+				$key      = sanitize_text_field( $_POST['two-factor-totp-key'] );
+
+				if ( $this->is_valid_key( $key ) ) {
+					if ( $this->is_valid_authcode( $key, $authcode ) ) {
+						if ( ! $this->set_user_totp_key( $user_id, $key ) ) {
+							$errors[] = __( 'Unable to save Two Factor Authentication code. Please re-scan the QR code and enter the code provided by your application.', 'two-factor' );
+						}
+					} else {
+						$errors[] = __( 'Invalid Two Factor Authentication code.', 'two-factor' );
+					}
+				} else {
+					$errors[] = __( 'Invalid Two Factor Authentication secret key.', 'two-factor' );
+				}
+			}
+
+			if ( ! empty( $errors ) ) {
+				$notices['error'] = $errors;
+			}
+
+			if ( ! empty( $notices ) ) {
+				update_user_meta( $user_id, self::NOTICES_META_KEY, $notices );
+			}
+		}
+	}
+
+	/**
+	 * Get the TOTP secret key for a user.
+	 *
+	 * @param  int $user_id User ID.
+	 *
+	 * @return string
+	 */
+	public function get_user_totp_key( $user_id ) {
+		return (string) get_user_meta( $user_id, self::SECRET_META_KEY, true );
+	}
+
+	/**
+	 * Set the TOTP secret key for a user.
+	 *
+	 * @param int    $user_id User ID.
+	 * @param string $key TOTP secret key.
+	 *
+	 * @return boolean If the key was stored successfully.
+	 */
+	public function set_user_totp_key( $user_id, $key ) {
+		return update_user_meta( $user_id, self::SECRET_META_KEY, $key );
+	}
+
+	/**
+	 * Delete the TOTP secret key for a user.
+	 *
+	 * @param  int $user_id User ID.
+	 *
+	 * @return boolean If the key was deleted successfully.
+	 */
+	public function delete_user_totp_key( $user_id ) {
+		return delete_user_meta( $user_id, self::SECRET_META_KEY );
+	}
+
+	/**
+	 * Check if the TOTP secret key has a proper format.
+	 *
+	 * @param  string $key TOTP secret key.
+	 *
+	 * @return boolean
+	 */
+	public function is_valid_key( $key ) {
+		$check = sprintf( '/^[%s]+$/', self::$base_32_chars );
+
+		if ( 1 === preg_match( $check, $key ) ) {
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * Display any available admin notices.
+	 *
+	 * @param integer $user_id User ID.
+	 *
+	 * @return void
+	 */
+	public function admin_notices( $user_id ) {
+		$notices = get_user_meta( $user_id, self::NOTICES_META_KEY, true );
+
+		if ( ! empty( $notices ) ) {
+			delete_user_meta( $user_id, self::NOTICES_META_KEY );
+
+			foreach ( $notices as $class => $messages ) {
+				?>
+				<div class="<?php echo esc_attr( $class ); ?>">
+					<?php
+					foreach ( $messages as $msg ) {
+						?>
+						<p>
+							<span><?php echo esc_html( $msg ); ?><span>
+						</p>
+						<?php
+					}
+					?>
+				</div>
+				<?php
+			}
+		}
+	}
+
+	/**
+	 * Validates authentication.
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 *
+	 * @return bool Whether the user gave a valid code
+	 */
+	public function validate_authentication( $user ) {
+		if ( ! empty( $_REQUEST['authcode'] ) ) {
+			return $this->is_valid_authcode(
+				$this->get_user_totp_key( $user->ID ),
+				sanitize_text_field( $_REQUEST['authcode'] )
+			);
+		}
+
+		return false;
+	}
+
+	/**
+	 * Checks if a given code is valid for a given key, allowing for a certain amount of time drift
+	 *
+	 * @param string $key      The share secret key to use.
+	 * @param string $authcode The code to test.
+	 *
+	 * @return bool Whether the code is valid within the time frame
+	 */
+	public static function is_valid_authcode( $key, $authcode ) {
+		/**
+		 * Filter the maximum ticks to allow when checking valid codes.
+		 *
+		 * Ticks are the allowed offset from the correct time in 30 second increments,
+		 * so the default of 4 allows codes that are two minutes to either side of server time
+		 *
+		 * @deprecated 0.7.0 Use {@see 'two_factor_totp_time_step_allowance'} instead.
+		 * @param int $max_ticks Max ticks of time correction to allow. Default 4.
+		 */
+		$max_ticks = apply_filters_deprecated( 'two-factor-totp-time-step-allowance', array( self::DEFAULT_TIME_STEP_ALLOWANCE ), '0.7.0', 'two_factor_totp_time_step_allowance' );
+
+		$max_ticks = apply_filters( 'two_factor_totp_time_step_allowance', self::DEFAULT_TIME_STEP_ALLOWANCE );
+
+		// Array of all ticks to allow, sorted using absolute value to test closest match first.
+		$ticks = range( - $max_ticks, $max_ticks );
+		usort( $ticks, array( __CLASS__, 'abssort' ) );
+
+		$time = time() / self::DEFAULT_TIME_STEP_SEC;
+
+		foreach ( $ticks as $offset ) {
+			$log_time = $time + $offset;
+			if ( self::calc_totp( $key, $log_time ) === $authcode ) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Generates key
+	 *
+	 * @param int $bitsize Nume of bits to use for key.
+	 *
+	 * @return string $bitsize long string composed of available base32 chars.
+	 */
+	public static function generate_key( $bitsize = self::DEFAULT_KEY_BIT_SIZE ) {
+		$bytes  = ceil( $bitsize / 8 );
+		$secret = wp_generate_password( $bytes, true, true );
+
+		return self::base32_encode( $secret );
+	}
+
+	/**
+	 * Pack stuff
+	 *
+	 * @param string $value The value to be packed.
+	 *
+	 * @return string Binary packed string.
+	 */
+	public static function pack64( $value ) {
+		// 64bit mode (PHP_INT_SIZE == 8).
+		if ( PHP_INT_SIZE >= 8 ) {
+			// If we're on PHP 5.6.3+ we can use the new 64bit pack functionality.
+			if ( version_compare( PHP_VERSION, '5.6.3', '>=' ) && PHP_INT_SIZE >= 8 ) {
+				return pack( 'J', $value );
+			}
+			$highmap = 0xffffffff << 32;
+			$higher  = ( $value & $highmap ) >> 32;
+		} else {
+			/*
+			 * 32bit PHP can't shift 32 bits like that, so we have to assume 0 for the higher
+			 * and not pack anything beyond it's limits.
+			 */
+			$higher = 0;
+		}
+
+		$lowmap = 0xffffffff;
+		$lower  = $value & $lowmap;
+
+		return pack( 'NN', $higher, $lower );
+	}
+
+	/**
+	 * Calculate a valid code given the shared secret key
+	 *
+	 * @param string $key        The shared secret key to use for calculating code.
+	 * @param mixed  $step_count The time step used to calculate the code, which is the floor of time() divided by step size.
+	 * @param int    $digits     The number of digits in the returned code.
+	 * @param string $hash       The hash used to calculate the code.
+	 * @param int    $time_step  The size of the time step.
+	 *
+	 * @return string The totp code
+	 */
+	public static function calc_totp( $key, $step_count = false, $digits = self::DEFAULT_DIGIT_COUNT, $hash = self::DEFAULT_CRYPTO, $time_step = self::DEFAULT_TIME_STEP_SEC ) {
+		$secret = self::base32_decode( $key );
+
+		if ( false === $step_count ) {
+			$step_count = floor( time() / $time_step );
+		}
+
+		$timestamp = self::pack64( $step_count );
+
+		$hash = hash_hmac( $hash, $timestamp, $secret, true );
+
+		$offset = ord( $hash[19] ) & 0xf;
+
+		$code = (
+				( ( ord( $hash[ $offset + 0 ] ) & 0x7f ) << 24 ) |
+				( ( ord( $hash[ $offset + 1 ] ) & 0xff ) << 16 ) |
+				( ( ord( $hash[ $offset + 2 ] ) & 0xff ) << 8 ) |
+				( ord( $hash[ $offset + 3 ] ) & 0xff )
+			) % pow( 10, $digits );
+
+		return str_pad( $code, $digits, '0', STR_PAD_LEFT );
+	}
+
+	/**
+	 * Uses the Google Charts API to build a QR Code for use with an otpauth url
+	 *
+	 * @param string $name  The name to display in the Authentication app.
+	 * @param string $key   The secret key to share with the Authentication app.
+	 * @param string $title The title to display in the Authentication app.
+	 *
+	 * @return string A URL to use as an img src to display the QR code
+	 */
+	public static function get_google_qr_code( $name, $key, $title = null ) {
+		// Encode to support spaces, question marks and other characters.
+		$name       = rawurlencode( $name );
+		$google_url = urlencode( 'otpauth://totp/' . $name . '?secret=' . $key );
+		if ( isset( $title ) ) {
+			$google_url .= urlencode( '&issuer=' . rawurlencode( $title ) );
+		}
+		return 'https://chart.googleapis.com/chart?chs=200x200&chld=M|0&cht=qr&chl=' . $google_url;
+	}
+
+	/**
+	 * Whether this Two Factor provider is configured and available for the user specified.
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 *
+	 * @return boolean
+	 */
+	public function is_available_for_user( $user ) {
+		// Only available if the secret key has been saved for the user.
+		$key = $this->get_user_totp_key( $user->ID );
+
+		return ! empty( $key );
+	}
+
+	/**
+	 * Prints the form that prompts the user to authenticate.
+	 *
+	 * @param WP_User $user WP_User object of the logged-in user.
+	 */
+	public function authentication_page( $user ) {
+		require_once ABSPATH . '/wp-admin/includes/template.php';
+		?>
+		<p>
+			<?php esc_html_e( 'Please enter the code generated by your authenticator app.', 'two-factor' ); ?>
+		</p>
+		<p>
+			<label for="authcode"><?php esc_html_e( 'Authentication Code:', 'two-factor' ); ?></label>
+			<input type="tel" autocomplete="off" name="authcode" id="authcode" class="input" value="" size="20" pattern="[0-9]*" />
+		</p>
+		<script type="text/javascript">
+			setTimeout( function(){
+				var d;
+				try{
+					d = document.getElementById('authcode');
+					d.focus();
+				} catch(e){}
+			}, 200);
+		</script>
+		<?php
+		submit_button( __( 'Authenticate', 'two-factor' ) );
+	}
+
+	/**
+	 * Returns a base32 encoded string.
+	 *
+	 * @param string $string String to be encoded using base32.
+	 *
+	 * @return string base32 encoded string without padding.
+	 */
+	public static function base32_encode( $string ) {
+		if ( empty( $string ) ) {
+			return '';
+		}
+
+		$binary_string = '';
+
+		foreach ( str_split( $string ) as $character ) {
+			$binary_string .= str_pad( base_convert( ord( $character ), 10, 2 ), 8, '0', STR_PAD_LEFT );
+		}
+
+		$five_bit_sections = str_split( $binary_string, 5 );
+		$base32_string     = '';
+
+		foreach ( $five_bit_sections as $five_bit_section ) {
+			$base32_string .= self::$base_32_chars[ base_convert( str_pad( $five_bit_section, 5, '0' ), 2, 10 ) ];
+		}
+
+		return $base32_string;
+	}
+
+	/**
+	 * Decode a base32 string and return a binary representation
+	 *
+	 * @param string $base32_string The base 32 string to decode.
+	 *
+	 * @throws Exception If string contains non-base32 characters.
+	 *
+	 * @return string Binary representation of decoded string
+	 */
+	public static function base32_decode( $base32_string ) {
+
+		$base32_string = strtoupper( $base32_string );
+
+		if ( ! preg_match( '/^[' . self::$base_32_chars . ']+$/', $base32_string, $match ) ) {
+			throw new Exception( 'Invalid characters in the base32 string.' );
+		}
+
+		$l      = strlen( $base32_string );
+		$n      = 0;
+		$j      = 0;
+		$binary = '';
+
+		for ( $i = 0; $i < $l; $i++ ) {
+
+			$n  = $n << 5; // Move buffer left by 5 to make room.
+			$n  = $n + strpos( self::$base_32_chars, $base32_string[ $i ] );    // Add value into buffer.
+			$j += 5; // Keep track of number of bits in buffer.
+
+			if ( $j >= 8 ) {
+				$j      -= 8;
+				$binary .= chr( ( $n & ( 0xFF << $j ) ) >> $j );
+			}
+		}
+
+		return $binary;
+	}
+
+	/**
+	 * Used with usort to sort an array by distance from 0
+	 *
+	 * @param int $a First array element.
+	 * @param int $b Second array element.
+	 *
+	 * @return int -1, 0, or 1 as needed by usort
+	 */
+	private static function abssort( $a, $b ) {
+		$a = abs( $a );
+		$b = abs( $b );
+		if ( $a === $b ) {
+			return 0;
+		}
+		return ( $a < $b ) ? -1 : 1;
+	}
+}
diff --git a/wp-content/plugins/two-factor/readme.md b/wp-content/plugins/two-factor/readme.md
index ba7bf6312fb2a6b2295b8d763db592287fc7bf45..fd83f1e69f3eba6b01a4fd47c0e42c0e5695c19b 100644
--- a/wp-content/plugins/two-factor/readme.md
+++ b/wp-content/plugins/two-factor/readme.md
@@ -7,11 +7,11 @@ Enable Two-Factor Authentication using time-based one-time passwords (OTP, Googl
 **Contributors:** [georgestephanis](https://profiles.wordpress.org/georgestephanis), [valendesigns](https://profiles.wordpress.org/valendesigns), [stevenkword](https://profiles.wordpress.org/stevenkword), [extendwings](https://profiles.wordpress.org/extendwings), [sgrant](https://profiles.wordpress.org/sgrant), [aaroncampbell](https://profiles.wordpress.org/aaroncampbell), [johnbillion](https://profiles.wordpress.org/johnbillion), [stevegrunwell](https://profiles.wordpress.org/stevegrunwell), [netweb](https://profiles.wordpress.org/netweb), [kasparsd](https://profiles.wordpress.org/kasparsd), [alihusnainarshad](https://profiles.wordpress.org/alihusnainarshad), [passoniate](https://profiles.wordpress.org/passoniate)  
 **Tags:** [two factor](https://wordpress.org/plugins/tags/two-factor), [two step](https://wordpress.org/plugins/tags/two-step), [authentication](https://wordpress.org/plugins/tags/authentication), [login](https://wordpress.org/plugins/tags/login), [totp](https://wordpress.org/plugins/tags/totp), [fido u2f](https://wordpress.org/plugins/tags/fido-u2f), [u2f](https://wordpress.org/plugins/tags/u2f), [email](https://wordpress.org/plugins/tags/email), [backup codes](https://wordpress.org/plugins/tags/backup-codes), [2fa](https://wordpress.org/plugins/tags/2fa), [yubikey](https://wordpress.org/plugins/tags/yubikey)  
 **Requires at least:** 4.3  
-**Tested up to:** 5.4  
+**Tested up to:** 5.5  
 **Stable tag:** trunk (master)  
 **Requires PHP:** 5.6  
 
-[![Build Status](https://travis-ci.org/WordPress/two-factor.svg?branch=master)](https://travis-ci.org/WordPress/two-factor) [![Coverage Status](https://coveralls.io/repos/WordPress/two-factor/badge.svg?branch=master)](https://coveralls.io/github/WordPress/two-factor) [![Built with Grunt](https://gruntjs.com/cdn/builtwith.svg)](http://gruntjs.com) 
+[![Build Status](https://travis-ci.org/wordpress/two-factor.svg?branch=master)](https://travis-ci.org/wordpress/two-factor) [![Coverage Status](https://coveralls.io/repos/wordpress/two-factor/badge.svg?branch=master)](https://coveralls.io/github/wordpress/two-factor) [![Built with Grunt](https://gruntjs.com/cdn/builtwith.svg)](http://gruntjs.com) 
 
 ## Description ##
 
diff --git a/wp-content/plugins/two-factor/readme.txt b/wp-content/plugins/two-factor/readme.txt
index b355343a971ac2f2a38c811f39529fb7d208e3b2..59aaee4a0659565009f1b671d34f6b3f5b578687 100644
--- a/wp-content/plugins/two-factor/readme.txt
+++ b/wp-content/plugins/two-factor/readme.txt
@@ -2,7 +2,7 @@
 Contributors: georgestephanis, valendesigns, stevenkword, extendwings, sgrant, aaroncampbell, johnbillion, stevegrunwell, netweb, kasparsd, alihusnainarshad, passoniate
 Tags: two factor, two step, authentication, login, totp, fido u2f, u2f, email, backup codes, 2fa, yubikey
 Requires at least: 4.3
-Tested up to: 5.4
+Tested up to: 5.5
 Requires PHP: 5.6
 Stable tag: trunk
 
diff --git a/wp-content/plugins/two-factor/two-factor.php b/wp-content/plugins/two-factor/two-factor.php
index a607d0bfc6697e8dfa014f010a48ce6298a838e0..d94f9924b8e2ca9bbefbe9e4678de68c185a5512 100644
--- a/wp-content/plugins/two-factor/two-factor.php
+++ b/wp-content/plugins/two-factor/two-factor.php
@@ -1,10 +1,18 @@
 <?php
 /**
+ * Two Factor
+ *
+ * @package     Two_Factor
+ * @author      Plugin Contributors
+ * @copyright   2020 Plugin Contributors
+ * @license     GPL-2.0-or-later
+ *
+ * @wordpress-plugin
  * Plugin Name: Two Factor
  * Plugin URI: https://wordpress.org/plugins/two-factor/
  * Description: Two-Factor Authentication using time-based one-time passwords, Universal 2nd Factor (FIDO U2F), email and backup verification codes.
  * Author: Plugin Contributors
- * Version: 0.6.0
+ * Version: 0.7.0
  * Author URI: https://github.com/wordpress/two-factor/graphs/contributors
  * Network: True
  * Text Domain: two-factor
@@ -15,20 +23,25 @@
  */
 define( 'TWO_FACTOR_DIR', plugin_dir_path( __FILE__ ) );
 
+/**
+ * Version of the plugin.
+ */
+define( 'TWO_FACTOR_VERSION', '0.7.0' );
+
 /**
  * Include the base class here, so that other plugins can also extend it.
  */
-require_once( TWO_FACTOR_DIR . 'providers/class.two-factor-provider.php' );
+require_once TWO_FACTOR_DIR . 'providers/class-two-factor-provider.php';
 
 /**
  * Include the core that handles the common bits.
  */
-require_once( TWO_FACTOR_DIR . 'class-two-factor-core.php' );
+require_once TWO_FACTOR_DIR . 'class-two-factor-core.php';
 
 /**
  * A compatability layer for some of the most-used plugins out there.
  */
-require_once( TWO_FACTOR_DIR . 'class-two-factor-compat.php' );
+require_once TWO_FACTOR_DIR . 'class-two-factor-compat.php';
 
 $two_factor_compat = new Two_Factor_Compat();