* * @param \WP_REST_Request $request * @return string|null */ public static function extractKey($request) { // Check X-API-Key header first $apiKey = $request->get_header('X-API-Key'); if (!empty($apiKey)) { return sanitize_text_field($apiKey); } // Check Authorization: Bearer $auth = $request->get_header('Authorization'); if (!empty($auth) && stripos($auth, 'Bearer ') === 0) { return sanitize_text_field(substr($auth, 7)); } return null; } /** * Authenticate a REST request using a bot API key * * @param \WP_REST_Request $request * @return ApiKeyBot|\WP_Error */ public static function authenticate($request) { $key = self::extractKey($request); if (empty($key)) { return new \WP_Error( 'rest_missing_api_key', 'API key is required. Send it via X-API-Key header or Authorization: Bearer .', ['status' => 401, 'code' => 'MISSING_API_KEY'] ); } $apiKey = ApiKeyBot::authenticate($key); if (!$apiKey) { return new \WP_Error( 'rest_invalid_api_key', 'Invalid or inactive API key.', ['status' => 401, 'code' => 'INVALID_API_KEY'] ); } return $apiKey; } }