updated plugin Jetpack Protect
version 1.4.2
This commit is contained in:
@ -5,6 +5,105 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [1.58.2] - 2023-10-19
|
||||
### Changed
|
||||
- Updated package dependencies. [#33687]
|
||||
|
||||
## [1.58.1] - 2023-10-10
|
||||
### Changed
|
||||
- Updated package dependencies. [#33428]
|
||||
|
||||
## [1.58.0] - 2023-09-25
|
||||
### Added
|
||||
- Disallow private IP addresses for site connection. [#32898]
|
||||
|
||||
## [1.57.5] - 2023-09-19
|
||||
|
||||
- Minor internal updates.
|
||||
|
||||
## [1.57.4] - 2023-09-13
|
||||
### Fixed
|
||||
- Use JS to check if initial state is already rendered. [#32932]
|
||||
|
||||
## [1.57.3] - 2023-09-11
|
||||
### Changed
|
||||
- General: remove WP 6.1 backwards compatibility checks [#32772]
|
||||
|
||||
## [1.57.2] - 2023-09-04
|
||||
### Changed
|
||||
- Updated package dependencies. [#32803]
|
||||
|
||||
## [1.57.1] - 2023-08-23
|
||||
### Changed
|
||||
- Updated package dependencies. [#32605]
|
||||
|
||||
## [1.57.0] - 2023-08-21
|
||||
### Added
|
||||
- Better way to render initial state. [#32499]
|
||||
|
||||
## [1.56.1] - 2023-08-09
|
||||
### Changed
|
||||
- Updated package dependencies. [#32166]
|
||||
|
||||
### Removed
|
||||
- Tests: remove invalid tests for WP 6.3 [#32353]
|
||||
|
||||
## [1.56.0] - 2023-08-01
|
||||
### Added
|
||||
- Add a filter to modify response for the `jetpack.idcUrlValidation` endpoint, add unit test. [#32005]
|
||||
|
||||
## [1.55.0] - 2023-07-25
|
||||
### Added
|
||||
- Connection: lock tokens to prevent IDC during AIOWPM export. [#31883]
|
||||
|
||||
## [1.54.1] - 2023-07-18
|
||||
### Fixed
|
||||
- Pass Calypso environment during connection to redirect users to proper Calypso URL. [#31906]
|
||||
|
||||
## [1.54.0] - 2023-07-17
|
||||
### Added
|
||||
- Restore invalid connection owner ID. [#31618]
|
||||
|
||||
## [1.53.3] - 2023-07-11
|
||||
### Changed
|
||||
- Updated package dependencies. [#31785]
|
||||
|
||||
## [1.53.2] - 2023-07-05
|
||||
### Changed
|
||||
- Updated package dependencies. [#31659]
|
||||
|
||||
## [1.53.1] - 2023-06-23
|
||||
### Changed
|
||||
- Updated package dependencies. [#31468]
|
||||
|
||||
## [1.53.0] - 2023-06-19
|
||||
### Changed
|
||||
- Do not disconnect sites on WPCOM in Offline Mode. [#31305]
|
||||
|
||||
## [1.52.2] - 2023-06-06
|
||||
### Changed
|
||||
- Updated package dependencies. [#31129]
|
||||
|
||||
## [1.52.1] - 2023-05-29
|
||||
### Added
|
||||
- Include the user's email in data returned from WordPress.com Connected User data query [#30990]
|
||||
|
||||
## [1.52.0] - 2023-05-22
|
||||
### Added
|
||||
- Add Offline Mode flag into initial state. [#30570]
|
||||
|
||||
## [1.51.10] - 2023-05-18
|
||||
### Changed
|
||||
- PHP8 compatibility updates, mostly focusing on Jetpack. [#30714]
|
||||
|
||||
## [1.51.9] - 2023-05-15
|
||||
### Changed
|
||||
- Internal updates.
|
||||
|
||||
## [1.51.8] - 2023-05-02
|
||||
### Changed
|
||||
- Updated package dependencies. [#30375]
|
||||
|
||||
## [1.51.7] - 2023-04-10
|
||||
### Added
|
||||
- Add Jetpack Autoloader package suggestion. [#29988]
|
||||
@ -797,6 +896,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Separate the connection library into its own package.
|
||||
|
||||
[1.58.2]: https://github.com/Automattic/jetpack-connection/compare/v1.58.1...v1.58.2
|
||||
[1.58.1]: https://github.com/Automattic/jetpack-connection/compare/v1.58.0...v1.58.1
|
||||
[1.58.0]: https://github.com/Automattic/jetpack-connection/compare/v1.57.5...v1.58.0
|
||||
[1.57.5]: https://github.com/Automattic/jetpack-connection/compare/v1.57.4...v1.57.5
|
||||
[1.57.4]: https://github.com/Automattic/jetpack-connection/compare/v1.57.3...v1.57.4
|
||||
[1.57.3]: https://github.com/Automattic/jetpack-connection/compare/v1.57.2...v1.57.3
|
||||
[1.57.2]: https://github.com/Automattic/jetpack-connection/compare/v1.57.1...v1.57.2
|
||||
[1.57.1]: https://github.com/Automattic/jetpack-connection/compare/v1.57.0...v1.57.1
|
||||
[1.57.0]: https://github.com/Automattic/jetpack-connection/compare/v1.56.1...v1.57.0
|
||||
[1.56.1]: https://github.com/Automattic/jetpack-connection/compare/v1.56.0...v1.56.1
|
||||
[1.56.0]: https://github.com/Automattic/jetpack-connection/compare/v1.55.0...v1.56.0
|
||||
[1.55.0]: https://github.com/Automattic/jetpack-connection/compare/v1.54.1...v1.55.0
|
||||
[1.54.1]: https://github.com/Automattic/jetpack-connection/compare/v1.54.0...v1.54.1
|
||||
[1.54.0]: https://github.com/Automattic/jetpack-connection/compare/v1.53.3...v1.54.0
|
||||
[1.53.3]: https://github.com/Automattic/jetpack-connection/compare/v1.53.2...v1.53.3
|
||||
[1.53.2]: https://github.com/Automattic/jetpack-connection/compare/v1.53.1...v1.53.2
|
||||
[1.53.1]: https://github.com/Automattic/jetpack-connection/compare/v1.53.0...v1.53.1
|
||||
[1.53.0]: https://github.com/Automattic/jetpack-connection/compare/v1.52.2...v1.53.0
|
||||
[1.52.2]: https://github.com/Automattic/jetpack-connection/compare/v1.52.1...v1.52.2
|
||||
[1.52.1]: https://github.com/Automattic/jetpack-connection/compare/v1.52.0...v1.52.1
|
||||
[1.52.0]: https://github.com/Automattic/jetpack-connection/compare/v1.51.10...v1.52.0
|
||||
[1.51.10]: https://github.com/Automattic/jetpack-connection/compare/v1.51.9...v1.51.10
|
||||
[1.51.9]: https://github.com/Automattic/jetpack-connection/compare/v1.51.8...v1.51.9
|
||||
[1.51.8]: https://github.com/Automattic/jetpack-connection/compare/v1.51.7...v1.51.8
|
||||
[1.51.7]: https://github.com/Automattic/jetpack-connection/compare/v1.51.6...v1.51.7
|
||||
[1.51.6]: https://github.com/Automattic/jetpack-connection/compare/v1.51.5...v1.51.6
|
||||
[1.51.5]: https://github.com/Automattic/jetpack-connection/compare/v1.51.4...v1.51.5
|
||||
|
@ -4,11 +4,20 @@ Full details of the Automattic Security Policy can be found on [automattic.com](
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Generally, only the latest version of Jetpack has continued support. If a critical vulnerability is found in the current version of Jetpack, we may opt to backport any patches to previous versions.
|
||||
Generally, only the latest version of Jetpack and its associated plugins have continued support. If a critical vulnerability is found in the current version of a plugin, we may opt to backport any patches to previous versions.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
[Jetpack](https://jetpack.com/) is an open-source plugin for WordPress. Our HackerOne program covers the plugin software, as well as a variety of related projects and infrastructure.
|
||||
Our HackerOne program covers the below plugin software, as well as a variety of related projects and infrastructure:
|
||||
|
||||
* [Jetpack](https://jetpack.com/)
|
||||
* Jetpack Backup
|
||||
* Jetpack Boost
|
||||
* Jetpack CRM
|
||||
* Jetpack Protect
|
||||
* Jetpack Search
|
||||
* Jetpack Social
|
||||
* Jetpack VideoPress
|
||||
|
||||
**For responsible disclosure of security issues and to be eligible for our bug bounty program, please submit your report via the [HackerOne](https://hackerone.com/automattic) portal.**
|
||||
|
||||
|
@ -4,18 +4,18 @@
|
||||
"type": "jetpack-library",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"automattic/jetpack-a8c-mc-stats": "^1.4.20",
|
||||
"automattic/jetpack-admin-ui": "^0.2.19",
|
||||
"automattic/jetpack-constants": "^1.6.22",
|
||||
"automattic/jetpack-roles": "^1.4.23",
|
||||
"automattic/jetpack-status": "^1.16.4",
|
||||
"automattic/jetpack-redirect": "^1.7.25"
|
||||
"automattic/jetpack-a8c-mc-stats": "^1.4.22",
|
||||
"automattic/jetpack-admin-ui": "^0.2.23",
|
||||
"automattic/jetpack-constants": "^1.6.23",
|
||||
"automattic/jetpack-roles": "^1.4.25",
|
||||
"automattic/jetpack-status": "^1.18.5",
|
||||
"automattic/jetpack-redirect": "^1.7.27"
|
||||
},
|
||||
"require-dev": {
|
||||
"automattic/wordbless": "@dev",
|
||||
"yoast/phpunit-polyfills": "1.0.4",
|
||||
"yoast/phpunit-polyfills": "1.1.0",
|
||||
"brain/monkey": "2.6.1",
|
||||
"automattic/jetpack-changelogger": "^3.3.2"
|
||||
"automattic/jetpack-changelogger": "^3.3.11"
|
||||
},
|
||||
"suggest": {
|
||||
"automattic/jetpack-autoloader": "Allow for better interoperability with other plugins that use this package."
|
||||
@ -56,7 +56,7 @@
|
||||
"link-template": "https://github.com/Automattic/jetpack-connection/compare/v${old}...v${new}"
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-trunk": "1.51.x-dev"
|
||||
"dev-trunk": "1.58.x-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
|
@ -1 +1 @@
|
||||
<?php return array('dependencies' => array(), 'version' => 'd9dbf909a3d10fb26f39');
|
||||
<?php return array('dependencies' => array(), 'version' => 'a96178e4d62fb695caa0');
|
||||
|
@ -1 +1 @@
|
||||
(()=>{var e={775:e=>{let n;window._tkq=window._tkq||[];const t=console.error;const o={initialize:function(e,n){o.setUser(e,n),o.identifyUser()},mc:{bumpStat:function(e,n){const t=function(e,n){let t="";if("object"==typeof e)for(const n in e)t+="&x_"+encodeURIComponent(n)+"="+encodeURIComponent(e[n]);else t="&x_"+encodeURIComponent(e)+"="+encodeURIComponent(n);return t}(e,n);(new Image).src=document.location.protocol+"//pixel.wp.com/g.gif?v=wpcom-no-pv"+t+"&t="+Math.random()}},tracks:{recordEvent:function(e,n){n=n||{},0===e.indexOf("jetpack_")?window._tkq.push(["recordEvent",e,n]):t('- Event name must be prefixed by "jetpack_"')},recordPageView:function(e){o.tracks.recordEvent("jetpack_page_view",{path:e})}},setUser:function(e,t){n={ID:e,username:t}},identifyUser:function(){n&&window._tkq.push(["identifyUser",n.ID,n.username])},clearedIdentity:function(){window._tkq.push(["clearIdentity"])}};e.exports=o}},n={};var t=function t(o){var r=n[o];if(void 0!==r)return r.exports;var i=n[o]={exports:{}};return e[o](i,i.exports,t),i.exports}(775);window.analytics=t})();
|
||||
!function(){var e={775:function(e){let n;window._tkq=window._tkq||[];const t=console.error;const o={initialize:function(e,n){o.setUser(e,n),o.identifyUser()},mc:{bumpStat:function(e,n){const t=function(e,n){let t="";if("object"==typeof e)for(const n in e)t+="&x_"+encodeURIComponent(n)+"="+encodeURIComponent(e[n]);else t="&x_"+encodeURIComponent(e)+"="+encodeURIComponent(n);return t}(e,n);(new Image).src=document.location.protocol+"//pixel.wp.com/g.gif?v=wpcom-no-pv"+t+"&t="+Math.random()}},tracks:{recordEvent:function(e,n){n=n||{},0===e.indexOf("jetpack_")?window._tkq.push(["recordEvent",e,n]):t('- Event name must be prefixed by "jetpack_"')},recordPageView:function(e){o.tracks.recordEvent("jetpack_page_view",{path:e})}},setUser:function(e,t){n={ID:e,username:t}},identifyUser:function(){n&&window._tkq.push(["identifyUser",n.ID,n.username])},clearedIdentity:function(){window._tkq.push(["clearIdentity"])}};e.exports=o}},n={};var t=function t(o){var r=n[o];if(void 0!==r)return r.exports;var i=n[o]={exports:{}};return e[o](i,i.exports,t),i.exports}(775);window.analytics=t}();
|
@ -128,6 +128,7 @@ class Jetpack_Options {
|
||||
'partner_coupon_added', // (string) A date for when `partner_coupon` was added, so we can auto-purge after a certain time interval.
|
||||
'dismissed_backup_review_restore', // (bool) Determines if the component review request is dismissed for successful restore requests.
|
||||
'dismissed_backup_review_backups', // (bool) Determines if the component review request is dismissed for successful backup requests.
|
||||
'identity_crisis_url_secret', // (array) The IDC URL secret and its expiration date.
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ class Jetpack_Signature {
|
||||
// and encoded on the Jetpack side.
|
||||
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
if ( empty( $body ) && is_array( $_POST ) && count( $_POST ) > 0 ) {
|
||||
if ( empty( $body ) && is_array( $_POST ) && $_POST !== array() ) {
|
||||
$body = $_POST; // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
}
|
||||
}
|
||||
@ -105,7 +105,7 @@ class Jetpack_Signature {
|
||||
|
||||
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
|
||||
$put_data = json_decode( $raw_put_data, true );
|
||||
if ( is_array( $put_data ) && count( $put_data ) > 0 ) {
|
||||
if ( is_array( $put_data ) && $put_data !== array() ) {
|
||||
$body = $put_data;
|
||||
}
|
||||
}
|
||||
@ -166,7 +166,7 @@ class Jetpack_Signature {
|
||||
|
||||
// If we got an array at this point, let's encode it, so we can see what it looks like as a string.
|
||||
if ( is_array( $body ) ) {
|
||||
if ( count( $body ) > 0 ) {
|
||||
if ( $body !== array() ) {
|
||||
// phpcs:ignore WordPress.WP.AlternativeFunctions.json_encode_json_encode
|
||||
$body = json_encode( $body );
|
||||
|
||||
@ -257,7 +257,7 @@ class Jetpack_Signature {
|
||||
}
|
||||
$normalized_request_pieces = $flat_normalized_request_pieces;
|
||||
|
||||
$normalized_request_string = join( "\n", $normalized_request_pieces ) . "\n";
|
||||
$normalized_request_string = implode( "\n", $normalized_request_pieces ) . "\n";
|
||||
|
||||
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
|
||||
return base64_encode( hash_hmac( 'sha1', $normalized_request_string, $this->secret, true ) );
|
||||
|
@ -221,6 +221,7 @@ class Jetpack_Tracks_Client {
|
||||
|
||||
return array(
|
||||
'blogid' => Jetpack_Options::get_option( 'id', 0 ),
|
||||
'email' => $user_data['email'],
|
||||
'userid' => $user_data['ID'],
|
||||
'username' => $user_data['login'],
|
||||
'user_locale' => $user_data['user_locale'],
|
||||
|
@ -762,17 +762,28 @@ class Jetpack_XMLRPC_Server {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the home URL and site URL for the current site which can be used on the WPCOM side for
|
||||
* Returns the home URL, site URL, and URL secret for the current site which can be used on the WPCOM side for
|
||||
* IDC mitigation to decide whether sync should be allowed if the home and siteurl values differ between WPCOM
|
||||
* and the remote Jetpack site.
|
||||
*
|
||||
* @since 1.56.0 Additional data may be added via filter `jetpack_connection_validate_urls_for_idc_mitigation_response`.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function validate_urls_for_idc_mitigation() {
|
||||
return array(
|
||||
$response = array(
|
||||
'home' => Urls::home_url(),
|
||||
'siteurl' => Urls::site_url(),
|
||||
);
|
||||
|
||||
/**
|
||||
* Allows modifying the response.
|
||||
*
|
||||
* @since 1.56.0
|
||||
*
|
||||
* @param array $response
|
||||
*/
|
||||
return apply_filters( 'jetpack_connection_validate_urls_for_idc_mitigation_response', $response );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -863,5 +874,4 @@ class Jetpack_XMLRPC_Server {
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ class Client {
|
||||
if ( is_array( $body ) ) {
|
||||
// We cast this to a new variable, because the array form of $body needs to be
|
||||
// maintained so it can be passed into the request later on in the code.
|
||||
if ( count( $body ) > 0 ) {
|
||||
if ( array() !== $body ) {
|
||||
$body_to_hash = wp_json_encode( self::_stringify_data( $body ) );
|
||||
} else {
|
||||
$body_to_hash = '';
|
||||
@ -206,7 +206,7 @@ class Client {
|
||||
$request['headers'] = array_merge(
|
||||
$args['headers'],
|
||||
array(
|
||||
'Authorization' => 'X_JETPACK ' . join( ' ', $header_pieces ),
|
||||
'Authorization' => 'X_JETPACK ' . implode( ' ', $header_pieces ),
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -240,5 +240,4 @@ class Connection_Notice {
|
||||
echo '</p>';
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -114,6 +114,7 @@ class Error_Handler {
|
||||
'invalid_body_hash',
|
||||
'invalid_nonce',
|
||||
'signature_mismatch',
|
||||
'invalid_connection_owner',
|
||||
);
|
||||
|
||||
/**
|
||||
@ -139,7 +140,7 @@ class Error_Handler {
|
||||
|
||||
// If the site gets reconnected, clear errors.
|
||||
add_action( 'jetpack_site_registered', array( $this, 'delete_all_errors' ) );
|
||||
add_action( 'jetpack_get_site_data_success', array( $this, 'delete_all_errors' ) );
|
||||
add_action( 'jetpack_get_site_data_success', array( $this, 'delete_all_api_errors' ) );
|
||||
add_filter( 'jetpack_connection_disconnect_site_wpcom', array( $this, 'delete_all_errors_and_return_unfiltered_value' ) );
|
||||
add_filter( 'jetpack_connection_delete_all_tokens', array( $this, 'delete_all_errors_and_return_unfiltered_value' ) );
|
||||
add_action( 'jetpack_unlinked_user', array( $this, 'delete_all_errors' ) );
|
||||
@ -170,6 +171,7 @@ class Error_Handler {
|
||||
case 'signature_mismatch':
|
||||
case 'no_user_tokens':
|
||||
case 'no_token_for_user':
|
||||
case 'invalid_connection_owner':
|
||||
add_action( 'admin_notices', array( $this, 'generic_admin_notice_error' ) );
|
||||
add_action( 'react_connection_errors_initial_state', array( $this, 'jetpack_react_dashboard_error' ) );
|
||||
$this->error_code = $error_code;
|
||||
@ -277,7 +279,8 @@ class Error_Handler {
|
||||
$stored_errors[ $error_code ][ $user_id ] = $error_array;
|
||||
|
||||
// Let's store a maximum of 5 different user ids for each error code.
|
||||
if ( count( $stored_errors[ $error_code ] ) > 5 ) {
|
||||
$error_code_count = is_countable( $stored_errors[ $error_code ] ) ? count( $stored_errors[ $error_code ] ) : 0;
|
||||
if ( $error_code_count > 5 ) {
|
||||
// array_shift will destroy keys here because they are numeric, so manually remove first item.
|
||||
$keys = array_keys( $stored_errors[ $error_code ] );
|
||||
unset( $stored_errors[ $error_code ][ $keys[0] ] );
|
||||
@ -308,7 +311,7 @@ class Error_Handler {
|
||||
|
||||
$signature_details = $data['signature_details'];
|
||||
|
||||
if ( ! isset( $signature_details['token'] ) || empty( $signature_details['token'] ) ) {
|
||||
if ( ! isset( $signature_details['token'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -389,12 +392,14 @@ class Error_Handler {
|
||||
* @return string $the user id or `invalid` if user id not present.
|
||||
*/
|
||||
public function get_user_id_from_token( $token ) {
|
||||
$parsed_token = explode( ':', wp_unslash( $token ) );
|
||||
$user_id = 'invalid';
|
||||
|
||||
if ( isset( $parsed_token[2] ) && ctype_digit( $parsed_token[2] ) ) {
|
||||
$user_id = $parsed_token[2];
|
||||
} else {
|
||||
$user_id = 'invalid';
|
||||
if ( $token ) {
|
||||
$parsed_token = explode( ':', wp_unslash( $token ) );
|
||||
|
||||
if ( isset( $parsed_token[2] ) && ctype_digit( $parsed_token[2] ) ) {
|
||||
$user_id = $parsed_token[2];
|
||||
}
|
||||
}
|
||||
|
||||
return $user_id;
|
||||
@ -482,6 +487,47 @@ class Error_Handler {
|
||||
$this->delete_verified_errors();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all stored and verified API errors from the database, leave the non-API errors intact.
|
||||
*
|
||||
* @since 1.54.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete_all_api_errors() {
|
||||
$type_filter = function ( $errors ) {
|
||||
if ( is_array( $errors ) ) {
|
||||
foreach ( $errors as $key => $error ) {
|
||||
if ( ! empty( $error['error_type'] ) && in_array( $error['error_type'], array( 'xmlrpc', 'rest' ), true ) ) {
|
||||
unset( $errors[ $key ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count( $errors ) ? $errors : null;
|
||||
};
|
||||
|
||||
$stored_errors = $this->get_stored_errors();
|
||||
if ( is_array( $stored_errors ) && count( $stored_errors ) ) {
|
||||
$stored_errors = array_filter( array_map( $type_filter, $stored_errors ) );
|
||||
if ( count( $stored_errors ) ) {
|
||||
update_option( static::STORED_ERRORS_OPTION, $stored_errors );
|
||||
} else {
|
||||
delete_option( static::STORED_ERRORS_OPTION );
|
||||
}
|
||||
}
|
||||
|
||||
$verified_errors = $this->get_verified_errors();
|
||||
if ( is_array( $verified_errors ) && count( $verified_errors ) ) {
|
||||
$verified_errors = array_filter( array_map( $type_filter, $verified_errors ) );
|
||||
if ( count( $verified_errors ) ) {
|
||||
update_option( static::STORED_VERIFIED_ERRORS_OPTION, $verified_errors );
|
||||
} else {
|
||||
delete_option( static::STORED_VERIFIED_ERRORS_OPTION );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all stored and verified errors from the database and returns unfiltered value
|
||||
*
|
||||
@ -726,5 +772,4 @@ class Error_Handler {
|
||||
|
||||
$this->report_error( $error, false, true );
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -249,5 +249,4 @@ class Heartbeat {
|
||||
WP_CLI::line( sprintf( __( 'Last heartbeat sent at: %s', 'jetpack-connection' ), $last_date ) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -14,13 +14,6 @@ use Automattic\Jetpack\Status;
|
||||
*/
|
||||
class Initial_State {
|
||||
|
||||
/**
|
||||
* Whether the initial state was already rendered
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private static $rendered = false;
|
||||
|
||||
/**
|
||||
* Get the initial state data.
|
||||
*
|
||||
@ -29,6 +22,8 @@ class Initial_State {
|
||||
private static function get_data() {
|
||||
global $wp_version;
|
||||
|
||||
$status = new Status();
|
||||
|
||||
return array(
|
||||
'apiRoot' => esc_url_raw( rest_url() ),
|
||||
'apiNonce' => wp_create_nonce( 'wp_rest' ),
|
||||
@ -37,8 +32,10 @@ class Initial_State {
|
||||
'userConnectionData' => REST_Connector::get_user_connection_data( false ),
|
||||
'connectedPlugins' => REST_Connector::get_connection_plugins( false ),
|
||||
'wpVersion' => $wp_version,
|
||||
'siteSuffix' => ( new Status() )->get_site_suffix(),
|
||||
'siteSuffix' => $status->get_site_suffix(),
|
||||
'connectionErrors' => Error_Handler::get_instance()->get_verified_errors(),
|
||||
'isOfflineMode' => $status->is_offline_mode(),
|
||||
'calypsoEnv' => ( new Status\Host() )->get_calypso_env(),
|
||||
);
|
||||
}
|
||||
|
||||
@ -48,11 +45,17 @@ class Initial_State {
|
||||
* @return string
|
||||
*/
|
||||
public static function render() {
|
||||
if ( self::$rendered ) {
|
||||
return null;
|
||||
}
|
||||
self::$rendered = true;
|
||||
return 'var JP_CONNECTION_INITIAL_STATE=JSON.parse(decodeURIComponent("' . rawurlencode( wp_json_encode( self::get_data() ) ) . '"));';
|
||||
return 'var JP_CONNECTION_INITIAL_STATE; typeof JP_CONNECTION_INITIAL_STATE === "object" || (JP_CONNECTION_INITIAL_STATE = JSON.parse(decodeURIComponent("' . rawurlencode( wp_json_encode( self::get_data() ) ) . '")));';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the initial state using an inline script.
|
||||
*
|
||||
* @param string $handle The JS script handle.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function render_script( $handle ) {
|
||||
wp_add_inline_script( $handle, static::render(), 'before' );
|
||||
}
|
||||
}
|
||||
|
@ -7,11 +7,12 @@
|
||||
|
||||
namespace Automattic\Jetpack\Connection;
|
||||
|
||||
use Automattic\Jetpack\A8c_Mc_Stats as A8c_Mc_Stats;
|
||||
use Automattic\Jetpack\A8c_Mc_Stats;
|
||||
use Automattic\Jetpack\Constants;
|
||||
use Automattic\Jetpack\Heartbeat;
|
||||
use Automattic\Jetpack\Roles;
|
||||
use Automattic\Jetpack\Status;
|
||||
use Automattic\Jetpack\Status\Host;
|
||||
use Automattic\Jetpack\Terms_Of_Service;
|
||||
use Automattic\Jetpack\Tracking;
|
||||
use Jetpack_IXR_Client;
|
||||
@ -134,6 +135,9 @@ class Manager {
|
||||
|
||||
// Initialize connection notices.
|
||||
new Connection_Notice();
|
||||
|
||||
// Initialize token locks.
|
||||
new Tokens_Locks();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -203,7 +207,6 @@ class Manager {
|
||||
// The jetpack.authorize method should be available for unauthenticated users on a site with an
|
||||
// active Jetpack connection, so that additional users can link their account.
|
||||
$callback = array( $this->xmlrpc_server, 'authorize_xmlrpc_methods' );
|
||||
|
||||
} else {
|
||||
// Any other unsigned request should expose the bootstrap methods.
|
||||
$callback = array( $this->xmlrpc_server, 'bootstrap_xmlrpc_methods' );
|
||||
@ -785,6 +788,25 @@ class Manager {
|
||||
$connection_owner = get_userdata( $user_token->external_user_id );
|
||||
}
|
||||
|
||||
if ( $connection_owner === false ) {
|
||||
Error_Handler::get_instance()->report_error(
|
||||
new WP_Error(
|
||||
'invalid_connection_owner',
|
||||
'Invalid connection owner',
|
||||
array(
|
||||
'user_id' => $user_id,
|
||||
'has_user_token' => (bool) $user_token,
|
||||
'error_type' => 'connection',
|
||||
'signature_details' => array(
|
||||
'token' => '',
|
||||
),
|
||||
)
|
||||
),
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
return $connection_owner;
|
||||
}
|
||||
|
||||
@ -1046,6 +1068,11 @@ class Manager {
|
||||
* @return true|WP_Error The error object.
|
||||
*/
|
||||
public function register( $api_endpoint = 'register' ) {
|
||||
// Clean-up leftover tokens just in-case.
|
||||
// This fixes an edge case that was preventing users to register when the blog token was missing but
|
||||
// there were still leftover user tokens present.
|
||||
$this->delete_all_connection_tokens( true );
|
||||
|
||||
add_action( 'pre_update_jetpack_option_register', array( '\\Jetpack_Options', 'delete_option' ) );
|
||||
$secrets = ( new Secrets() )->generate( 'register', get_current_user_id(), 600 );
|
||||
|
||||
@ -1125,7 +1152,7 @@ class Manager {
|
||||
'timeout' => $timeout,
|
||||
);
|
||||
|
||||
$args['body'] = $this->apply_activation_source_to_args( $args['body'] );
|
||||
$args['body'] = static::apply_activation_source_to_args( $args['body'] );
|
||||
|
||||
// TODO: fix URLs for bad hosts.
|
||||
$response = Client::_wp_remote_request(
|
||||
@ -1643,6 +1670,11 @@ class Manager {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ( new Status() )->is_offline_mode() && ! apply_filters( 'jetpack_connection_disconnect_site_wpcom_offline_mode', false ) ) {
|
||||
// Prevent potential disconnect of the live site by removing WPCOM tokens.
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires upon the disconnect attempt.
|
||||
* Return `false` to prevent the disconnect.
|
||||
@ -1686,7 +1718,6 @@ class Manager {
|
||||
( new Tracking() )->record_user_event( 'restore_connection_reconnect' );
|
||||
|
||||
$this->disconnect_site_wpcom( true );
|
||||
$this->delete_all_connection_tokens( true );
|
||||
|
||||
return $this->register();
|
||||
}
|
||||
@ -1884,10 +1915,11 @@ class Manager {
|
||||
'site_lang' => get_locale(),
|
||||
'site_created' => $this->get_assumed_site_creation_date(),
|
||||
'allow_site_connection' => ! $this->has_connected_owner(),
|
||||
'calypso_env' => ( new Host() )->get_calypso_env(),
|
||||
)
|
||||
);
|
||||
|
||||
$body = $this->apply_activation_source_to_args( urlencode_deep( $body ) );
|
||||
$body = static::apply_activation_source_to_args( urlencode_deep( $body ) );
|
||||
|
||||
$api_url = $this->api_url( 'authorize' );
|
||||
|
||||
@ -2107,7 +2139,6 @@ class Manager {
|
||||
'wordpress.com',
|
||||
'localhost',
|
||||
'localhost.localdomain',
|
||||
'127.0.0.1',
|
||||
'local.wordpress.test', // VVV pattern.
|
||||
'local.wordpress-trunk.test', // VVV pattern.
|
||||
'src.wordpress-develop.test', // VVV pattern.
|
||||
@ -2163,6 +2194,24 @@ class Manager {
|
||||
return true;
|
||||
}
|
||||
|
||||
$domain = preg_replace( '#^https?://#', '', untrailingslashit( $domain ) );
|
||||
|
||||
if ( filter_var( $domain, FILTER_VALIDATE_IP )
|
||||
&& ! filter_var( $domain, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE )
|
||||
) {
|
||||
return new \WP_Error(
|
||||
'fail_ip_forbidden',
|
||||
sprintf(
|
||||
/* translators: %1$s is a domain name. */
|
||||
__(
|
||||
'IP address `%1$s` just failed is_usable_domain check as it is in the private network.',
|
||||
'jetpack-connection'
|
||||
),
|
||||
$domain
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ class Nonce_Handler {
|
||||
// Removing zeroes in case AUTO_INCREMENT of the options table is broken, and all ID's are zeroes.
|
||||
$ids = array_filter( $ids );
|
||||
|
||||
if ( ! count( $ids ) ) {
|
||||
if ( array() === $ids ) {
|
||||
// There's nothing to remove.
|
||||
return false;
|
||||
}
|
||||
@ -209,5 +209,4 @@ class Nonce_Handler {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -108,5 +108,4 @@ class Package_Version_Tracker {
|
||||
set_transient( self::CACHED_FAILED_REQUEST_KEY, time(), self::CACHED_FAILED_REQUEST_EXPIRATION );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ namespace Automattic\Jetpack\Connection;
|
||||
*/
|
||||
class Package_Version {
|
||||
|
||||
const PACKAGE_VERSION = '1.51.7';
|
||||
const PACKAGE_VERSION = '1.58.2';
|
||||
|
||||
const PACKAGE_SLUG = 'connection';
|
||||
|
||||
|
@ -521,7 +521,7 @@ class REST_Connector {
|
||||
*/
|
||||
public static function is_request_signed_by_jetpack_debugger( $pub_key = null ) {
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||
if ( ! isset( $_GET['signature'], $_GET['timestamp'], $_GET['url'], $_GET['rest_route'] ) ) {
|
||||
if ( ! isset( $_GET['signature'] ) || ! isset( $_GET['timestamp'] ) || ! isset( $_GET['url'] ) || ! isset( $_GET['rest_route'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ class Secrets {
|
||||
$user_id = get_current_user_id();
|
||||
}
|
||||
|
||||
$callable = apply_filters( 'jetpack_connection_secret_generator', array( get_called_class(), 'secret_callable_method' ) );
|
||||
$callable = apply_filters( 'jetpack_connection_secret_generator', array( static::class, 'secret_callable_method' ) );
|
||||
|
||||
$secrets = Jetpack_Options::get_raw_option(
|
||||
self::LEGACY_SECRETS_OPTION_NAME,
|
||||
|
@ -108,5 +108,4 @@ class Terms_Of_Service {
|
||||
protected function set_reject() {
|
||||
\Jetpack_Options::update_option( self::OPTION_NAME, false );
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* The Jetpack Connection Tokens Locks class file.
|
||||
*
|
||||
* @package automattic/jetpack-connection
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Connection;
|
||||
|
||||
/**
|
||||
*
|
||||
* Jetpack Connection tokens cleanup during migration.
|
||||
* This class encapsulates plugin or tool specific code that activates token lock upon migration.
|
||||
*
|
||||
* The connection tokens are locked to the current domain.
|
||||
* If the database is imported on another site (domain name doesn't match), the tokens get removed.
|
||||
*
|
||||
* @see https://github.com/Automattic/jetpack/pull/23597
|
||||
* @see \Automattic\Jetpack\Connection\Tokens::is_locked()
|
||||
*/
|
||||
class Tokens_Locks {
|
||||
|
||||
/**
|
||||
* Whether the class has been initialized.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private static $is_initialized = false;
|
||||
|
||||
/**
|
||||
* Run the initializers if they haven't been run already.
|
||||
*/
|
||||
public function __construct() {
|
||||
if ( static::$is_initialized ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->init_aiowpm();
|
||||
|
||||
static::$is_initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the token lock for AIOWPM plugin export.
|
||||
*
|
||||
* @param array $params The filter parameters.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function aiowpm_set_lock( $params ) {
|
||||
( new Tokens() )->set_lock();
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the token lock for AIOWPM plugin export.
|
||||
*
|
||||
* @param array $params The filter parameters.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function aiowpm_remove_lock( $params ) {
|
||||
( new Tokens() )->remove_lock();
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the All-in-One-WP-Migration plugin hooks.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function init_aiowpm() {
|
||||
add_filter( 'ai1wm_export', array( $this, 'aiowpm_set_lock' ), 180 );
|
||||
add_filter( 'ai1wm_export', array( $this, 'aiowpm_remove_lock' ), 250 );
|
||||
}
|
||||
}
|
@ -552,7 +552,7 @@ class Tokens {
|
||||
$nonce = substr( sha1( wp_rand( 0, 1000000 ) ), 0, 10 );
|
||||
}
|
||||
|
||||
$normalized_request_string = join(
|
||||
$normalized_request_string = implode(
|
||||
"\n",
|
||||
array(
|
||||
$token_key,
|
||||
@ -576,7 +576,7 @@ class Tokens {
|
||||
$header_pieces[] = sprintf( '%s="%s"', $key, $value );
|
||||
}
|
||||
|
||||
return join( ' ', $header_pieces );
|
||||
return implode( ' ', $header_pieces );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -183,5 +183,4 @@ class Urls {
|
||||
public static function main_network_site_url() {
|
||||
return self::get_protocol_normalized_url( 'main_network_site_url', network_site_url() );
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ class XMLRPC_Async_Call {
|
||||
public static function do_calls() {
|
||||
foreach ( self::$clients as $client_blog_id => $blog_clients ) {
|
||||
if ( $client_blog_id > 0 ) {
|
||||
$switch_success = switch_to_blog( $client_blog_id, true );
|
||||
$switch_success = switch_to_blog( $client_blog_id );
|
||||
|
||||
if ( ! $switch_success ) {
|
||||
continue;
|
||||
|
Reference in New Issue
Block a user