updated plugin Jetpack Protect
version 1.0.4
This commit is contained in:
@ -41,6 +41,14 @@ class Client {
|
||||
|
||||
$response = self::_wp_remote_request( $result['url'], $result['request'] );
|
||||
|
||||
Error_Handler::get_instance()->check_api_response_for_errors(
|
||||
$response,
|
||||
$result['auth'],
|
||||
empty( $args['url'] ) ? '' : $args['url'],
|
||||
empty( $args['method'] ) ? 'POST' : $args['method'],
|
||||
'rest'
|
||||
);
|
||||
|
||||
/**
|
||||
* Fired when the remote request response has been received.
|
||||
*
|
||||
@ -63,6 +71,7 @@ class Client {
|
||||
*
|
||||
* @type String $url The request URL.
|
||||
* @type array $request Request arguments.
|
||||
* @type array $auth Authorization data.
|
||||
* }
|
||||
*/
|
||||
public static function build_signed_request( $args, $body = null ) {
|
||||
@ -205,7 +214,7 @@ class Client {
|
||||
$url = add_query_arg( 'signature', rawurlencode( $signature ), $url );
|
||||
}
|
||||
|
||||
return compact( 'url', 'request' );
|
||||
return compact( 'url', 'request', 'auth' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -197,17 +197,18 @@ class Error_Handler {
|
||||
/**
|
||||
* Keep track of a connection error that was encountered
|
||||
*
|
||||
* @since 1.14.2
|
||||
* @param \WP_Error $error The error object.
|
||||
* @param boolean $force Force the report, even if should_report_error is false.
|
||||
* @param boolean $skip_wpcom_verification Set to 'true' to verify the error locally and skip the WP.com verification.
|
||||
*
|
||||
* @param \WP_Error $error the error object.
|
||||
* @param boolean $force Force the report, even if should_report_error is false.
|
||||
* @return void
|
||||
* @since 1.14.2
|
||||
*/
|
||||
public function report_error( \WP_Error $error, $force = false ) {
|
||||
public function report_error( \WP_Error $error, $force = false, $skip_wpcom_verification = false ) {
|
||||
if ( in_array( $error->get_error_code(), $this->known_errors, true ) && $this->should_report_error( $error ) || $force ) {
|
||||
$stored_error = $this->store_error( $error );
|
||||
if ( $stored_error ) {
|
||||
$this->send_error_to_wpcom( $stored_error );
|
||||
$skip_wpcom_verification ? $this->verify_error( $stored_error ) : $this->send_error_to_wpcom( $stored_error );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -223,15 +224,14 @@ class Error_Handler {
|
||||
* @return boolean $should_report True if gate is open and the error should be reported.
|
||||
*/
|
||||
public function should_report_error( \WP_Error $error ) {
|
||||
|
||||
if ( defined( 'JETPACK_DEV_DEBUG' ) && JETPACK_DEV_DEBUG ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to bypass the gate for XML-RPC error handling
|
||||
* Whether to bypass the gate for the error handling
|
||||
*
|
||||
* By default, we only process XML-RPC errors once an hour for each error code.
|
||||
* By default, we only process errors once an hour for each error code.
|
||||
* This is done to avoid overflows. If you need to disable this gate, you can set this variable to true.
|
||||
*
|
||||
* This filter is useful for unit testing
|
||||
@ -307,21 +307,22 @@ class Error_Handler {
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = $data['signature_details'];
|
||||
$signature_details = $data['signature_details'];
|
||||
|
||||
if ( ! isset( $data['token'] ) || empty( $data['token'] ) ) {
|
||||
if ( ! isset( $signature_details['token'] ) || empty( $signature_details['token'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$user_id = $this->get_user_id_from_token( $data['token'] );
|
||||
$user_id = $this->get_user_id_from_token( $signature_details['token'] );
|
||||
|
||||
$error_array = array(
|
||||
'error_code' => $error->get_error_code(),
|
||||
'user_id' => $user_id,
|
||||
'error_message' => $error->get_error_message(),
|
||||
'error_data' => $data,
|
||||
'error_data' => $signature_details,
|
||||
'timestamp' => time(),
|
||||
'nonce' => wp_generate_password( 10, false ),
|
||||
'error_type' => empty( $data['error_type'] ) ? '' : $data['error_type'],
|
||||
);
|
||||
|
||||
return $error_array;
|
||||
@ -387,7 +388,7 @@ class Error_Handler {
|
||||
*
|
||||
* @since 1.14.2
|
||||
*
|
||||
* @param string $token the token used to make the xml-rpc request.
|
||||
* @param string $token the token used to make the request.
|
||||
* @return string $the user id or `invalid` if user id not present.
|
||||
*/
|
||||
public function get_user_id_from_token( $token ) {
|
||||
@ -603,7 +604,6 @@ class Error_Handler {
|
||||
* @return boolean
|
||||
*/
|
||||
public function verify_xml_rpc_error( \WP_REST_Request $request ) {
|
||||
|
||||
$error = $this->get_error_by_nonce( $request['nonce'] );
|
||||
|
||||
if ( $error ) {
|
||||
@ -634,7 +634,7 @@ class Error_Handler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the message to be displayed in the admin notices area when there's a xmlrpc error.
|
||||
* Filters the message to be displayed in the admin notices area when there's a connection error.
|
||||
*
|
||||
* By default we don't display any errors.
|
||||
*
|
||||
@ -679,7 +679,7 @@ class Error_Handler {
|
||||
*/
|
||||
public function jetpack_react_dashboard_error( $errors ) {
|
||||
$errors[] = array(
|
||||
'code' => 'xmlrpc_error',
|
||||
'code' => 'connection_error',
|
||||
'message' => __( 'Your connection with WordPress.com seems to be broken. If you\'re experiencing issues, please try reconnecting.', 'jetpack-connection' ),
|
||||
'action' => 'reconnect',
|
||||
'data' => array( 'api_error_code' => $this->error_code ),
|
||||
@ -687,4 +687,50 @@ class Error_Handler {
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check REST API response for errors, and report them to WP.com if needed.
|
||||
*
|
||||
* @see wp_remote_request() For more information on the $http_response array format.
|
||||
* @param array|\WP_Error $http_response The response or WP_Error on failure.
|
||||
* @param array $auth_data Auth data, allowed keys: `token`, `timestamp`, `nonce`, `body-hash`.
|
||||
* @param string $url Request URL.
|
||||
* @param string $method Request method.
|
||||
* @param string $error_type The source of an error: 'xmlrpc' or 'rest'.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function check_api_response_for_errors( $http_response, $auth_data, $url, $method, $error_type ) {
|
||||
if ( 200 === wp_remote_retrieve_response_code( $http_response ) || ! is_array( $auth_data ) || ! $url || ! $method ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$body_raw = wp_remote_retrieve_body( $http_response );
|
||||
if ( ! $body_raw ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$body = json_decode( $body_raw, true );
|
||||
if ( empty( $body['error'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$error = new \WP_Error(
|
||||
$body['error'],
|
||||
empty( $body['message'] ) ? '' : $body['message'],
|
||||
array(
|
||||
'signature_details' => array(
|
||||
'token' => empty( $auth_data['token'] ) ? '' : $auth_data['token'],
|
||||
'timestamp' => empty( $auth_data['timestamp'] ) ? '' : $auth_data['timestamp'],
|
||||
'nonce' => empty( $auth_data['nonce'] ) ? '' : $auth_data['nonce'],
|
||||
'body_hash' => empty( $auth_data['body_hash'] ) ? '' : $auth_data['body_hash'],
|
||||
'method' => $method,
|
||||
'url' => $url,
|
||||
),
|
||||
'error_type' => in_array( $error_type, array( 'xmlrpc', 'rest' ), true ) ? $error_type : '',
|
||||
)
|
||||
);
|
||||
|
||||
$this->report_error( $error, false, true );
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -30,14 +30,15 @@ class Initial_State {
|
||||
global $wp_version;
|
||||
|
||||
return array(
|
||||
'apiRoot' => esc_url_raw( rest_url() ),
|
||||
'apiNonce' => wp_create_nonce( 'wp_rest' ),
|
||||
'registrationNonce' => wp_create_nonce( 'jetpack-registration-nonce' ),
|
||||
'connectionStatus' => REST_Connector::connection_status( false ),
|
||||
'userConnectionData' => REST_Connector::get_user_connection_data( false ),
|
||||
'connectedPlugins' => REST_Connector::get_connection_plugins( false ),
|
||||
'wpVersion' => $wp_version,
|
||||
'siteSuffix' => ( new Status() )->get_site_suffix(),
|
||||
'apiRoot' => esc_url_raw( rest_url() ),
|
||||
'apiNonce' => wp_create_nonce( 'wp_rest' ),
|
||||
'registrationNonce' => wp_create_nonce( 'jetpack-registration-nonce' ),
|
||||
'connectionStatus' => REST_Connector::connection_status( false ),
|
||||
'userConnectionData' => REST_Connector::get_user_connection_data( false ),
|
||||
'connectedPlugins' => REST_Connector::get_connection_plugins( false ),
|
||||
'wpVersion' => $wp_version,
|
||||
'siteSuffix' => ( new Status() )->get_site_suffix(),
|
||||
'connectionVerifiedErrors' => Error_Handler::get_instance()->get_verified_errors(),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -363,6 +363,8 @@ class Manager {
|
||||
'signature' => isset( $_GET['signature'] ) ? wp_unslash( $_GET['signature'] ) : '',
|
||||
);
|
||||
|
||||
$error_type = 'xmlrpc';
|
||||
|
||||
// phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
|
||||
@list( $token_key, $version, $user_id ) = explode( ':', wp_unslash( $_GET['token'] ) );
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
@ -373,7 +375,7 @@ class Manager {
|
||||
empty( $token_key )
|
||||
||
|
||||
empty( $version ) || (string) $jetpack_api_version !== $version ) {
|
||||
return new \WP_Error( 'malformed_token', 'Malformed token in request', compact( 'signature_details' ) );
|
||||
return new \WP_Error( 'malformed_token', 'Malformed token in request', compact( 'signature_details', 'error_type' ) );
|
||||
}
|
||||
|
||||
if ( '0' === $user_id ) {
|
||||
@ -385,7 +387,7 @@ class Manager {
|
||||
return new \WP_Error(
|
||||
'malformed_user_id',
|
||||
'Malformed user_id in request',
|
||||
compact( 'signature_details' )
|
||||
compact( 'signature_details', 'error_type' )
|
||||
);
|
||||
}
|
||||
$user_id = (int) $user_id;
|
||||
@ -395,20 +397,20 @@ class Manager {
|
||||
return new \WP_Error(
|
||||
'unknown_user',
|
||||
sprintf( 'User %d does not exist', $user_id ),
|
||||
compact( 'signature_details' )
|
||||
compact( 'signature_details', 'error_type' )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$token = $this->get_tokens()->get_access_token( $user_id, $token_key, false );
|
||||
if ( is_wp_error( $token ) ) {
|
||||
$token->add_data( compact( 'signature_details' ) );
|
||||
$token->add_data( compact( 'signature_details', 'error_type' ) );
|
||||
return $token;
|
||||
} elseif ( ! $token ) {
|
||||
return new \WP_Error(
|
||||
'unknown_token',
|
||||
sprintf( 'Token %s:%s:%d does not exist', $token_key, $version, $user_id ),
|
||||
compact( 'signature_details' )
|
||||
compact( 'signature_details', 'error_type' )
|
||||
);
|
||||
}
|
||||
|
||||
@ -450,7 +452,7 @@ class Manager {
|
||||
return new \WP_Error(
|
||||
'could_not_sign',
|
||||
'Unknown signature error',
|
||||
compact( 'signature_details' )
|
||||
compact( 'signature_details', 'error_type' )
|
||||
);
|
||||
} elseif ( is_wp_error( $signature ) ) {
|
||||
return $signature;
|
||||
@ -466,7 +468,7 @@ class Manager {
|
||||
return new \WP_Error(
|
||||
'invalid_nonce',
|
||||
'Could not add nonce',
|
||||
compact( 'signature_details' )
|
||||
compact( 'signature_details', 'error_type' )
|
||||
);
|
||||
}
|
||||
|
||||
@ -480,7 +482,7 @@ class Manager {
|
||||
return new \WP_Error(
|
||||
'signature_mismatch',
|
||||
'Signature mismatch',
|
||||
compact( 'signature_details' )
|
||||
compact( 'signature_details', 'error_type' )
|
||||
);
|
||||
}
|
||||
|
||||
@ -1846,7 +1848,7 @@ class Manager {
|
||||
'scope' => $signed_role,
|
||||
'user_email' => $user->user_email,
|
||||
'user_login' => $user->user_login,
|
||||
'is_active' => $this->is_active(), // TODO Deprecate this.
|
||||
'is_active' => $this->has_connected_owner(), // TODO Deprecate this.
|
||||
'jp_version' => Constants::get_constant( 'JETPACK__VERSION' ),
|
||||
'auth_type' => $auth_type,
|
||||
'secret' => $secrets['secret_1'],
|
||||
@ -2315,7 +2317,7 @@ class Manager {
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
public function get_connected_plugins() {
|
||||
$maybe_plugins = Plugin_Storage::get_all( true );
|
||||
$maybe_plugins = Plugin_Storage::get_all();
|
||||
|
||||
if ( $maybe_plugins instanceof WP_Error ) {
|
||||
return $maybe_plugins;
|
||||
@ -2351,14 +2353,12 @@ class Manager {
|
||||
* Whether the plugin is allowed to use the connection, or it's been disconnected by user.
|
||||
* If no plugin slug was passed into the constructor, always returns true.
|
||||
*
|
||||
* @deprecated 1.42.0 This method no longer has a purpose after the removal of the soft disconnect feature.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_plugin_enabled() {
|
||||
if ( ! $this->plugin ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->plugin->is_enabled();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -12,7 +12,7 @@ namespace Automattic\Jetpack\Connection;
|
||||
*/
|
||||
class Package_Version {
|
||||
|
||||
const PACKAGE_VERSION = '1.41.7';
|
||||
const PACKAGE_VERSION = '1.44.0';
|
||||
|
||||
const PACKAGE_SLUG = 'connection';
|
||||
|
||||
|
@ -83,7 +83,7 @@ class Plugin {
|
||||
* @return bool
|
||||
*/
|
||||
public function is_only() {
|
||||
$plugins = Plugin_Storage::get_all( true );
|
||||
$plugins = Plugin_Storage::get_all();
|
||||
|
||||
return ! $plugins || ( array_key_exists( $this->slug, $plugins ) && 1 === count( $plugins ) );
|
||||
}
|
||||
@ -113,7 +113,7 @@ class Plugin {
|
||||
/**
|
||||
* Whether this plugin is allowed to use the connection.
|
||||
*
|
||||
* @deprecated since $next-version$$
|
||||
* @deprecated since 11.0
|
||||
* @return bool
|
||||
*/
|
||||
public function is_enabled() {
|
||||
|
@ -302,7 +302,7 @@ class REST_Connector {
|
||||
$connection = new Manager();
|
||||
|
||||
$connection_status = array(
|
||||
'isActive' => $connection->is_active(), // TODO deprecate this.
|
||||
'isActive' => $connection->has_connected_owner(), // TODO deprecate this.
|
||||
'isStaging' => $status->is_staging_site(),
|
||||
'isRegistered' => $connection->is_connected(),
|
||||
'isUserConnected' => $connection->is_user_connected(),
|
||||
|
Reference in New Issue
Block a user