[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Error Protection API: WP_Recovery_Mode_Key_Service class 4 * 5 * @package WordPress 6 * @since 5.2.0 7 */ 8 9 /** 10 * Core class used to generate and validate keys used to enter Recovery Mode. 11 * 12 * @since 5.2.0 13 */ 14 #[AllowDynamicProperties] 15 final class WP_Recovery_Mode_Key_Service { 16 17 /** 18 * The option name used to store the keys. 19 * 20 * @since 5.2.0 21 * @var string 22 */ 23 private $option_name = 'recovery_keys'; 24 25 /** 26 * Creates a recovery mode token. 27 * 28 * @since 5.2.0 29 * 30 * @return string A random string to identify its associated key in storage. 31 */ 32 public function generate_recovery_mode_token() { 33 return wp_generate_password( 22, false ); 34 } 35 36 /** 37 * Creates a recovery mode key. 38 * 39 * @since 5.2.0 40 * @since 6.8.0 The stored key is now hashed using wp_fast_hash() instead of phpass. 41 * 42 * @param string $token A token generated by {@see generate_recovery_mode_token()}. 43 * @return string Recovery mode key. 44 */ 45 public function generate_and_store_recovery_mode_key( $token ) { 46 $key = wp_generate_password( 22, false ); 47 48 $records = $this->get_keys(); 49 50 $records[ $token ] = array( 51 'hashed_key' => wp_fast_hash( $key ), 52 'created_at' => time(), 53 ); 54 55 $this->update_keys( $records ); 56 57 /** 58 * Fires when a recovery mode key is generated. 59 * 60 * @since 5.2.0 61 * 62 * @param string $token The recovery data token. 63 * @param string $key The recovery mode key. 64 */ 65 do_action( 'generate_recovery_mode_key', $token, $key ); 66 67 return $key; 68 } 69 70 /** 71 * Verifies if the recovery mode key is correct. 72 * 73 * Recovery mode keys can only be used once; the key will be consumed in the process. 74 * 75 * @since 5.2.0 76 * 77 * @param string $token The token used when generating the given key. 78 * @param string $key The plain text key. 79 * @param int $ttl Time in seconds for the key to be valid for. 80 * @return true|WP_Error True on success, error object on failure. 81 */ 82 public function validate_recovery_mode_key( $token, $key, $ttl ) { 83 $records = $this->get_keys(); 84 85 if ( ! isset( $records[ $token ] ) ) { 86 return new WP_Error( 'token_not_found', __( 'Recovery Mode not initialized.' ) ); 87 } 88 89 $record = $records[ $token ]; 90 91 $this->remove_key( $token ); 92 93 if ( ! is_array( $record ) || ! isset( $record['hashed_key'], $record['created_at'] ) ) { 94 return new WP_Error( 'invalid_recovery_key_format', __( 'Invalid recovery key format.' ) ); 95 } 96 97 if ( ! wp_verify_fast_hash( $key, $record['hashed_key'] ) ) { 98 return new WP_Error( 'hash_mismatch', __( 'Invalid recovery key.' ) ); 99 } 100 101 if ( time() > $record['created_at'] + $ttl ) { 102 return new WP_Error( 'key_expired', __( 'Recovery key expired.' ) ); 103 } 104 105 return true; 106 } 107 108 /** 109 * Removes expired recovery mode keys. 110 * 111 * @since 5.2.0 112 * 113 * @param int $ttl Time in seconds for the keys to be valid for. 114 */ 115 public function clean_expired_keys( $ttl ) { 116 117 $records = $this->get_keys(); 118 119 foreach ( $records as $key => $record ) { 120 if ( ! isset( $record['created_at'] ) || time() > $record['created_at'] + $ttl ) { 121 unset( $records[ $key ] ); 122 } 123 } 124 125 $this->update_keys( $records ); 126 } 127 128 /** 129 * Removes a used recovery key. 130 * 131 * @since 5.2.0 132 * 133 * @param string $token The token used when generating a recovery mode key. 134 */ 135 private function remove_key( $token ) { 136 137 $records = $this->get_keys(); 138 139 if ( ! isset( $records[ $token ] ) ) { 140 return; 141 } 142 143 unset( $records[ $token ] ); 144 145 $this->update_keys( $records ); 146 } 147 148 /** 149 * Gets the recovery key records. 150 * 151 * @since 5.2.0 152 * @since 6.8.0 Each key is now hashed using wp_fast_hash() instead of phpass. 153 * Existing keys may still be hashed using phpass. 154 * 155 * @return array { 156 * Associative array of token => data pairs, where the data is an associative 157 * array of information about the key. 158 * 159 * @type array ...$0 { 160 * Information about the key. 161 * 162 * @type string $hashed_key The hashed value of the key. 163 * @type int $created_at The timestamp when the key was created. 164 * } 165 * } 166 */ 167 private function get_keys() { 168 return (array) get_option( $this->option_name, array() ); 169 } 170 171 /** 172 * Updates the recovery key records. 173 * 174 * @since 5.2.0 175 * @since 6.8.0 Each key should now be hashed using wp_fast_hash() instead of phpass. 176 * 177 * @param array $keys { 178 * Associative array of token => data pairs, where the data is an associative 179 * array of information about the key. 180 * 181 * @type array ...$0 { 182 * Information about the key. 183 * 184 * @type string $hashed_key The hashed value of the key. 185 * @type int $created_at The timestamp when the key was created. 186 * } 187 * } 188 * @return bool True on success, false on failure. 189 */ 190 private function update_keys( array $keys ) { 191 return update_option( $this->option_name, $keys, false ); 192 } 193 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Sat Feb 22 08:20:01 2025 | Cross-referenced by PHPXref |