updated plugin Jetpack Protect
version 1.4.2
This commit is contained in:
@ -5,6 +5,13 @@ 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.4.22] - 2023-09-19
|
||||
- Minor internal updates.
|
||||
|
||||
## [1.4.21] - 2023-08-23
|
||||
### Changed
|
||||
- Updated package dependencies. [#32605]
|
||||
|
||||
## [1.4.20] - 2023-04-10
|
||||
### Added
|
||||
- Add Jetpack Autoloader package suggestion. [#29988]
|
||||
@ -119,6 +126,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Creates the MC Stats package
|
||||
|
||||
[1.4.22]: https://github.com/Automattic/jetpack-a8c-mc-stats/compare/v1.4.21...v1.4.22
|
||||
[1.4.21]: https://github.com/Automattic/jetpack-a8c-mc-stats/compare/v1.4.20...v1.4.21
|
||||
[1.4.20]: https://github.com/Automattic/jetpack-a8c-mc-stats/compare/v1.4.19...v1.4.20
|
||||
[1.4.19]: https://github.com/Automattic/jetpack-a8c-mc-stats/compare/v1.4.18...v1.4.19
|
||||
[1.4.18]: https://github.com/Automattic/jetpack-a8c-mc-stats/compare/v1.4.17...v1.4.18
|
||||
|
@ -5,8 +5,8 @@
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {},
|
||||
"require-dev": {
|
||||
"yoast/phpunit-polyfills": "1.0.4",
|
||||
"automattic/jetpack-changelogger": "^3.3.2"
|
||||
"yoast/phpunit-polyfills": "1.1.0",
|
||||
"automattic/jetpack-changelogger": "^3.3.9"
|
||||
},
|
||||
"suggest": {
|
||||
"automattic/jetpack-autoloader": "Allow for better interoperability with other plugins that use this package."
|
||||
|
@ -178,5 +178,4 @@ class A8c_Mc_Stats {
|
||||
$url = add_query_arg( $args, $base_url );
|
||||
return $url;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,22 @@ 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).
|
||||
|
||||
## [0.2.23] - 2023-09-19
|
||||
### Changed
|
||||
- Updated Jetpack submenu sort order so individual features are alpha-sorted. [#32958]
|
||||
|
||||
## [0.2.22] - 2023-09-11
|
||||
### Fixed
|
||||
- Akismet: update naming to common form [#32908]
|
||||
|
||||
## [0.2.21] - 2023-08-23
|
||||
### Changed
|
||||
- Updated package dependencies. [#32605]
|
||||
|
||||
## [0.2.20] - 2023-04-25
|
||||
### Fixed
|
||||
- Avoid errors when used in combination with an older version of the Logo package. [#30136]
|
||||
|
||||
## [0.2.19] - 2023-04-10
|
||||
### Added
|
||||
- Add Jetpack Autoloader package suggestion. [#29988]
|
||||
@ -104,6 +120,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Fixed
|
||||
- Fixing menu visibility issues.
|
||||
|
||||
[0.2.23]: https://github.com/Automattic/jetpack-admin-ui/compare/0.2.22...0.2.23
|
||||
[0.2.22]: https://github.com/Automattic/jetpack-admin-ui/compare/0.2.21...0.2.22
|
||||
[0.2.21]: https://github.com/Automattic/jetpack-admin-ui/compare/0.2.20...0.2.21
|
||||
[0.2.20]: https://github.com/Automattic/jetpack-admin-ui/compare/0.2.19...0.2.20
|
||||
[0.2.19]: https://github.com/Automattic/jetpack-admin-ui/compare/0.2.18...0.2.19
|
||||
[0.2.18]: https://github.com/Automattic/jetpack-admin-ui/compare/0.2.17...0.2.18
|
||||
[0.2.17]: https://github.com/Automattic/jetpack-admin-ui/compare/0.2.16...0.2.17
|
||||
|
@ -5,9 +5,9 @@
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {},
|
||||
"require-dev": {
|
||||
"yoast/phpunit-polyfills": "1.0.4",
|
||||
"automattic/jetpack-changelogger": "^3.3.2",
|
||||
"automattic/jetpack-logo": "^1.6.1",
|
||||
"yoast/phpunit-polyfills": "1.1.0",
|
||||
"automattic/jetpack-changelogger": "^3.3.9",
|
||||
"automattic/jetpack-logo": "^1.6.3",
|
||||
"automattic/wordbless": "dev-master"
|
||||
},
|
||||
"suggest": {
|
||||
|
@ -13,7 +13,7 @@ namespace Automattic\Jetpack\Admin_UI;
|
||||
*/
|
||||
class Admin_Menu {
|
||||
|
||||
const PACKAGE_VERSION = '0.2.19';
|
||||
const PACKAGE_VERSION = '0.2.23';
|
||||
|
||||
/**
|
||||
* Whether this class has been initialized
|
||||
@ -60,7 +60,7 @@ class Admin_Menu {
|
||||
);
|
||||
|
||||
// Add an Anti-spam menu item for Jetpack.
|
||||
self::add_menu( __( 'Anti-Spam', 'jetpack-admin-ui' ), __( 'Anti-Spam', 'jetpack-admin-ui' ), 'manage_options', 'akismet-key-config', array( 'Akismet_Admin', 'display_page' ) );
|
||||
self::add_menu( __( 'Akismet Anti-spam', 'jetpack-admin-ui' ), __( 'Akismet Anti-spam', 'jetpack-admin-ui' ), 'manage_options', 'akismet-key-config', array( 'Akismet_Admin', 'display_page' ) );
|
||||
|
||||
}
|
||||
}
|
||||
@ -73,7 +73,7 @@ class Admin_Menu {
|
||||
public static function admin_menu_hook_callback() {
|
||||
$can_see_toplevel_menu = true;
|
||||
$jetpack_plugin_present = class_exists( 'Jetpack_React_Page' );
|
||||
$icon = class_exists( '\Automattic\Jetpack\Assets\Logo' )
|
||||
$icon = method_exists( '\Automattic\Jetpack\Assets\Logo', 'get_base64_logo' )
|
||||
? ( new \Automattic\Jetpack\Assets\Logo() )->get_base64_logo()
|
||||
: 'dashicons-admin-plugins';
|
||||
|
||||
@ -104,7 +104,13 @@ class Admin_Menu {
|
||||
function ( $a, $b ) {
|
||||
$position_a = empty( $a['position'] ) ? 0 : $a['position'];
|
||||
$position_b = empty( $b['position'] ) ? 0 : $b['position'];
|
||||
return $position_a - $position_b;
|
||||
$result = $position_a - $position_b;
|
||||
|
||||
if ( 0 === $result ) {
|
||||
$result = strcmp( $a['menu_title'], $b['menu_title'] );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
);
|
||||
|
||||
@ -150,7 +156,7 @@ class Admin_Menu {
|
||||
* and only include lowercase alphanumeric, dashes, and underscores characters
|
||||
* to be compatible with sanitize_key().
|
||||
* @param callable $function The function to be called to output the content for this page.
|
||||
* @param int $position The position in the menu order this item should appear.
|
||||
* @param int $position The position in the menu order this item should appear. Leave empty typically.
|
||||
*
|
||||
* @return string The resulting page's hook_suffix
|
||||
*/
|
||||
@ -198,5 +204,4 @@ class Admin_Menu {
|
||||
$url = $fallback ? $fallback : admin_url();
|
||||
return $url;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,66 @@ 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.18.13] - 2023-10-19
|
||||
### Changed
|
||||
- Updated package dependencies. [#33687]
|
||||
|
||||
## [1.18.12] - 2023-10-10
|
||||
### Changed
|
||||
- Updated package dependencies. [#33428]
|
||||
|
||||
### Fixed
|
||||
- Pass `false`, not `null`, to `WP_Scripts->add()`. [#33513]
|
||||
|
||||
## [1.18.11] - 2023-09-19
|
||||
|
||||
- Minor internal updates.
|
||||
|
||||
## [1.18.10] - 2023-09-04
|
||||
### Changed
|
||||
- Updated package dependencies. [#32803]
|
||||
|
||||
## [1.18.9] - 2023-08-23
|
||||
### Changed
|
||||
- Updated package dependencies. [#32605]
|
||||
|
||||
## [1.18.8] - 2023-08-09
|
||||
### Changed
|
||||
- Updated package dependencies. [#32166]
|
||||
|
||||
## [1.18.7] - 2023-07-11
|
||||
### Changed
|
||||
- Updated package dependencies. [#31785]
|
||||
|
||||
## [1.18.6] - 2023-07-05
|
||||
### Changed
|
||||
- Updated package dependencies. [#31659]
|
||||
|
||||
## [1.18.5] - 2023-06-21
|
||||
### Changed
|
||||
- Updated package dependencies. [#31468]
|
||||
|
||||
## [1.18.4] - 2023-06-06
|
||||
### Changed
|
||||
- Updated package dependencies. [#31129]
|
||||
|
||||
## [1.18.3] - 2023-05-15
|
||||
### Changed
|
||||
- Internal updates.
|
||||
|
||||
## [1.18.2] - 2023-05-02
|
||||
### Changed
|
||||
- Updated package dependencies. [#30375]
|
||||
|
||||
## [1.18.1] - 2023-04-10
|
||||
### Added
|
||||
- Add Jetpack Autoloader package suggestion. [#29988]
|
||||
|
||||
## [1.18.0] - 2023-04-04
|
||||
### Changed
|
||||
- Async script enqueuing: switch to static method. [#29780]
|
||||
- Updated package dependencies. [#29854]
|
||||
|
||||
## [1.17.34] - 2023-03-20
|
||||
### Changed
|
||||
- Updated package dependencies. [#29471]
|
||||
@ -312,6 +372,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Statically access asset tools
|
||||
|
||||
[1.18.13]: https://github.com/Automattic/jetpack-assets/compare/v1.18.12...v1.18.13
|
||||
[1.18.12]: https://github.com/Automattic/jetpack-assets/compare/v1.18.11...v1.18.12
|
||||
[1.18.11]: https://github.com/Automattic/jetpack-assets/compare/v1.18.10...v1.18.11
|
||||
[1.18.10]: https://github.com/Automattic/jetpack-assets/compare/v1.18.9...v1.18.10
|
||||
[1.18.9]: https://github.com/Automattic/jetpack-assets/compare/v1.18.8...v1.18.9
|
||||
[1.18.8]: https://github.com/Automattic/jetpack-assets/compare/v1.18.7...v1.18.8
|
||||
[1.18.7]: https://github.com/Automattic/jetpack-assets/compare/v1.18.6...v1.18.7
|
||||
[1.18.6]: https://github.com/Automattic/jetpack-assets/compare/v1.18.5...v1.18.6
|
||||
[1.18.5]: https://github.com/Automattic/jetpack-assets/compare/v1.18.4...v1.18.5
|
||||
[1.18.4]: https://github.com/Automattic/jetpack-assets/compare/v1.18.3...v1.18.4
|
||||
[1.18.3]: https://github.com/Automattic/jetpack-assets/compare/v1.18.2...v1.18.3
|
||||
[1.18.2]: https://github.com/Automattic/jetpack-assets/compare/v1.18.1...v1.18.2
|
||||
[1.18.1]: https://github.com/Automattic/jetpack-assets/compare/v1.18.0...v1.18.1
|
||||
[1.18.0]: https://github.com/Automattic/jetpack-assets/compare/v1.17.34...v1.18.0
|
||||
[1.17.34]: https://github.com/Automattic/jetpack-assets/compare/v1.17.33...v1.17.34
|
||||
[1.17.33]: https://github.com/Automattic/jetpack-assets/compare/v1.17.32...v1.17.33
|
||||
[1.17.32]: https://github.com/Automattic/jetpack-assets/compare/v1.17.31...v1.17.32
|
||||
|
@ -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,14 +4,17 @@
|
||||
"type": "jetpack-library",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"automattic/jetpack-constants": "^1.6.21"
|
||||
"automattic/jetpack-constants": "^1.6.23"
|
||||
},
|
||||
"require-dev": {
|
||||
"brain/monkey": "2.6.1",
|
||||
"yoast/phpunit-polyfills": "1.0.4",
|
||||
"automattic/jetpack-changelogger": "^3.3.2",
|
||||
"yoast/phpunit-polyfills": "1.1.0",
|
||||
"automattic/jetpack-changelogger": "^3.3.11",
|
||||
"wikimedia/testing-access-wrapper": "^1.0 || ^2.0"
|
||||
},
|
||||
"suggest": {
|
||||
"automattic/jetpack-autoloader": "Allow for better interoperability with other plugins that use this package."
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"actions.php"
|
||||
@ -47,7 +50,7 @@
|
||||
"link-template": "https://github.com/Automattic/jetpack-assets/compare/v${old}...v${new}"
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-trunk": "1.17.x-dev"
|
||||
"dev-trunk": "1.18.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,8 +75,9 @@ class Assets {
|
||||
*
|
||||
* @param string $script_handle Script handle.
|
||||
*/
|
||||
public function add_async_script( $script_handle ) {
|
||||
$this->defer_script_handles[] = $script_handle;
|
||||
public static function add_async_script( $script_handle ) {
|
||||
$assets_instance = self::instance();
|
||||
$assets_instance->defer_script_handles[] = $script_handle;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -281,7 +282,7 @@ class Assets {
|
||||
++$i;
|
||||
}
|
||||
}
|
||||
$ret .= join( '/', $pp );
|
||||
$ret .= implode( '/', $pp );
|
||||
|
||||
$ret .= isset( $parts['query'] ) ? '?' . $parts['query'] : '';
|
||||
$ret .= isset( $parts['fragment'] ) ? '#' . $parts['fragment'] : '';
|
||||
@ -508,7 +509,7 @@ class Assets {
|
||||
}
|
||||
|
||||
// Deprecated state module: Depend on wp-i18n to ensure global `wp` exists and because anything needing this will need that too.
|
||||
$wp_scripts->add( 'wp-jp-i18n-state', null, array( 'wp-deprecated', 'wp-jp-i18n-loader' ) );
|
||||
$wp_scripts->add( 'wp-jp-i18n-state', false, array( 'wp-deprecated', 'wp-jp-i18n-loader' ) );
|
||||
$wp_scripts->add_inline_script( 'wp-jp-i18n-state', 'wp.deprecated( "wp-jp-i18n-state", { alternative: "wp-jp-i18n-loader" } );' );
|
||||
$wp_scripts->add_inline_script( 'wp-jp-i18n-state', 'wp.jpI18nState = wp.jpI18nLoader.state;' );
|
||||
}
|
||||
@ -730,7 +731,6 @@ class Assets {
|
||||
}
|
||||
|
||||
// endregion .
|
||||
|
||||
}
|
||||
|
||||
// Enable section folding in vim:
|
||||
|
@ -118,5 +118,4 @@ class Semver {
|
||||
}
|
||||
return $al - $bl;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,17 @@ 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.15.4] - 2023-09-19
|
||||
- Minor internal updates.
|
||||
|
||||
## [1.15.3] - 2023-06-26
|
||||
### Changed
|
||||
- Blaze can now be loaded as a module, instead of relying on the Config package. [#31479]
|
||||
|
||||
## [1.15.2] - 2023-04-10
|
||||
### Added
|
||||
- Add Jetpack Autoloader package suggestion. [#29988]
|
||||
|
||||
## [1.15.1] - 2023-03-28
|
||||
### Changed
|
||||
- Minor internal updates.
|
||||
@ -176,6 +187,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Trying to add deterministic initialization.
|
||||
|
||||
[1.15.4]: https://github.com/Automattic/jetpack-config/compare/v1.15.3...v1.15.4
|
||||
[1.15.3]: https://github.com/Automattic/jetpack-config/compare/v1.15.2...v1.15.3
|
||||
[1.15.2]: https://github.com/Automattic/jetpack-config/compare/v1.15.1...v1.15.2
|
||||
[1.15.1]: https://github.com/Automattic/jetpack-config/compare/v1.15.0...v1.15.1
|
||||
[1.15.0]: https://github.com/Automattic/jetpack-config/compare/v1.14.0...v1.15.0
|
||||
[1.14.0]: https://github.com/Automattic/jetpack-config/compare/v1.13.0...v1.14.0
|
||||
[1.13.0]: https://github.com/Automattic/jetpack-config/compare/v1.12.0...v1.13.0
|
||||
|
@ -5,7 +5,10 @@
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {},
|
||||
"require-dev": {
|
||||
"automattic/jetpack-changelogger": "^3.3.2"
|
||||
"automattic/jetpack-changelogger": "^3.3.9"
|
||||
},
|
||||
"suggest": {
|
||||
"automattic/jetpack-autoloader": "Allow for better interoperability with other plugins that use this package."
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
|
@ -12,14 +12,12 @@ namespace Automattic\Jetpack;
|
||||
* contain the package classes shown below. The consumer plugin
|
||||
* must require the corresponding packages to use these features.
|
||||
*/
|
||||
use Automattic\Jetpack\Blaze as Blaze;
|
||||
use Automattic\Jetpack\Connection\Manager;
|
||||
use Automattic\Jetpack\Connection\Plugin;
|
||||
use Automattic\Jetpack\Import\Main as Import_Main;
|
||||
use Automattic\Jetpack\JITM as JITM;
|
||||
use Automattic\Jetpack\JITMS\JITM as JITMS_JITM;
|
||||
use Automattic\Jetpack\Post_List\Post_List as Post_List;
|
||||
use Automattic\Jetpack\Publicize\Publicize_Setup as Publicize_Setup;
|
||||
use Automattic\Jetpack\Post_List\Post_List;
|
||||
use Automattic\Jetpack\Publicize\Publicize_Setup;
|
||||
use Automattic\Jetpack\Search\Initializer as Jetpack_Search_Main;
|
||||
use Automattic\Jetpack\Stats\Main as Stats_Main;
|
||||
use Automattic\Jetpack\Stats_Admin\Main as Stats_Admin_Main;
|
||||
@ -27,7 +25,6 @@ use Automattic\Jetpack\Sync\Main as Sync_Main;
|
||||
use Automattic\Jetpack\VideoPress\Initializer as VideoPress_Pkg_Initializer;
|
||||
use Automattic\Jetpack\Waf\Waf_Initializer as Jetpack_Waf_Main;
|
||||
use Automattic\Jetpack\WordAds\Initializer as Jetpack_WordAds_Main;
|
||||
use Automattic\Jetpack\Yoast_Promo as Yoast_Promo;
|
||||
|
||||
/**
|
||||
* The configuration class.
|
||||
@ -56,7 +53,6 @@ class Config {
|
||||
'videopress' => false,
|
||||
'stats' => false,
|
||||
'stats_admin' => false,
|
||||
'blaze' => false,
|
||||
'yoast_promo' => false,
|
||||
'import' => false,
|
||||
);
|
||||
@ -163,10 +159,6 @@ class Config {
|
||||
$this->ensure_class( 'Automattic\Jetpack\Stats_Admin\Main' ) && $this->ensure_feature( 'stats_admin' );
|
||||
}
|
||||
|
||||
if ( $this->config['blaze'] ) {
|
||||
$this->ensure_class( 'Automattic\Jetpack\Blaze' ) && $this->ensure_feature( 'blaze' );
|
||||
}
|
||||
|
||||
if ( $this->config['yoast_promo'] ) {
|
||||
$this->ensure_class( 'Automattic\Jetpack\Yoast_Promo' ) && $this->ensure_feature( 'yoast_promo' );
|
||||
}
|
||||
@ -360,14 +352,6 @@ class Config {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables Blaze.
|
||||
*/
|
||||
protected function enable_blaze() {
|
||||
Blaze::init();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables Yoast Promo.
|
||||
*/
|
||||
@ -467,5 +451,4 @@ class Config {
|
||||
protected function get_feature_options( $feature ) {
|
||||
return empty( $this->feature_options[ $feature ] ) ? array() : $this->feature_options[ $feature ];
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -5,6 +5,10 @@ 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.6.23] - 2023-08-23
|
||||
### Changed
|
||||
- Updated package dependencies. [#32605]
|
||||
|
||||
## [1.6.22] - 2023-04-10
|
||||
### Added
|
||||
- Add Jetpack Autoloader package suggestion. [#29988]
|
||||
@ -150,6 +154,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Packages: Finish the constants package
|
||||
|
||||
[1.6.23]: https://github.com/Automattic/jetpack-constants/compare/v1.6.22...v1.6.23
|
||||
[1.6.22]: https://github.com/Automattic/jetpack-constants/compare/v1.6.21...v1.6.22
|
||||
[1.6.21]: https://github.com/Automattic/jetpack-constants/compare/v1.6.20...v1.6.21
|
||||
[1.6.20]: https://github.com/Automattic/jetpack-constants/compare/v1.6.19...v1.6.20
|
||||
|
@ -6,8 +6,8 @@
|
||||
"require": {},
|
||||
"require-dev": {
|
||||
"brain/monkey": "2.6.1",
|
||||
"yoast/phpunit-polyfills": "1.0.4",
|
||||
"automattic/jetpack-changelogger": "^3.3.2"
|
||||
"yoast/phpunit-polyfills": "1.1.0",
|
||||
"automattic/jetpack-changelogger": "^3.3.8"
|
||||
},
|
||||
"suggest": {
|
||||
"automattic/jetpack-autoloader": "Allow for better interoperability with other plugins that use this package."
|
||||
|
@ -5,6 +5,14 @@ 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.4.27] - 2023-08-23
|
||||
### Changed
|
||||
- Updated package dependencies. [#32605]
|
||||
|
||||
## [1.4.26] - 2023-06-12
|
||||
### Fixed
|
||||
- Catch PHP notice if User Agent is not available [#31279]
|
||||
|
||||
## [1.4.25] - 2023-04-10
|
||||
### Added
|
||||
- Add Jetpack Autoloader package suggestion. [#29988]
|
||||
@ -155,6 +163,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Moving jetpack_is_mobile into a package
|
||||
|
||||
[1.4.27]: https://github.com/Automattic/jetpack-device-detection/compare/v1.4.26...v1.4.27
|
||||
[1.4.26]: https://github.com/Automattic/jetpack-device-detection/compare/v1.4.25...v1.4.26
|
||||
[1.4.25]: https://github.com/Automattic/jetpack-device-detection/compare/v1.4.24...v1.4.25
|
||||
[1.4.24]: https://github.com/Automattic/jetpack-device-detection/compare/v1.4.23...v1.4.24
|
||||
[1.4.23]: https://github.com/Automattic/jetpack-device-detection/compare/v1.4.22...v1.4.23
|
||||
|
@ -5,8 +5,8 @@
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {},
|
||||
"require-dev": {
|
||||
"yoast/phpunit-polyfills": "1.0.4",
|
||||
"automattic/jetpack-changelogger": "^3.3.2"
|
||||
"yoast/phpunit-polyfills": "1.1.0",
|
||||
"automattic/jetpack-changelogger": "^3.3.8"
|
||||
},
|
||||
"suggest": {
|
||||
"automattic/jetpack-autoloader": "Allow for better interoperability with other plugins that use this package."
|
||||
|
@ -223,13 +223,17 @@ class User_Agent_Info {
|
||||
* Note that this function returns the platform name, not the UA name/type. You should use a different function
|
||||
* if you need to test the UA capabilites.
|
||||
*
|
||||
* @return string Name of the platform, false otherwise.
|
||||
* @return string|bool Name of the platform, false otherwise.
|
||||
*/
|
||||
public function get_platform() {
|
||||
if ( isset( $this->platform ) ) {
|
||||
return $this->platform;
|
||||
}
|
||||
|
||||
if ( empty( $this->useragent ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( strpos( $this->useragent, 'windows phone' ) !== false ) {
|
||||
$this->platform = self::PLATFORM_WINDOWS;
|
||||
} elseif ( strpos( $this->useragent, 'windows ce' ) !== false ) {
|
||||
|
@ -5,10 +5,108 @@ 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).
|
||||
|
||||
## [0.11.1] - 2023-10-19
|
||||
### Changed
|
||||
- Updated package dependencies. [#33687]
|
||||
|
||||
### Fixed
|
||||
- Fix possible use of an undefined variable. [#33668]
|
||||
|
||||
## [0.11.0] - 2023-10-17
|
||||
### Changed
|
||||
- Updated package dependencies. [#33646]
|
||||
|
||||
### Fixed
|
||||
- Added search and replace protection for wpcom urls stored in the database. [#33412]
|
||||
|
||||
## [0.10.7] - 2023-10-16
|
||||
### Changed
|
||||
- Updated package dependencies. [#33429]
|
||||
|
||||
## [0.10.6] - 2023-10-10
|
||||
### Changed
|
||||
- Updated package dependencies. [#33428]
|
||||
|
||||
## [0.10.5] - 2023-09-19
|
||||
### Changed
|
||||
- Updated package dependencies. [#33001]
|
||||
|
||||
## [0.10.4] - 2023-09-11
|
||||
### Changed
|
||||
- General: remove WP 6.1 backwards compatibility checks [#32772]
|
||||
|
||||
## [0.10.3] - 2023-09-04
|
||||
### Changed
|
||||
- Updated package dependencies. [#32803]
|
||||
- Updated package dependencies. [#32804]
|
||||
|
||||
## [0.10.2] - 2023-08-23
|
||||
### Changed
|
||||
- Updated package dependencies. [#32605]
|
||||
|
||||
## [0.10.1] - 2023-08-09
|
||||
### Changed
|
||||
- Updated package dependencies. [#32166]
|
||||
|
||||
## [0.10.0] - 2023-08-07
|
||||
### Changed
|
||||
- Make IDC container ID adjustable.
|
||||
|
||||
## [0.9.0] - 2023-08-01
|
||||
### Added
|
||||
- URL secret to detect multi-domain sites. [#32005]
|
||||
|
||||
## [0.8.52] - 2023-07-25
|
||||
### Changed
|
||||
- Updated package dependencies. [#32040]
|
||||
|
||||
## [0.8.51] - 2023-07-17
|
||||
### Changed
|
||||
- Updated package dependencies. [#31785]
|
||||
|
||||
## [0.8.50] - 2023-07-05
|
||||
### Changed
|
||||
- Updated package dependencies. [#31659]
|
||||
|
||||
## [0.8.49] - 2023-06-26
|
||||
### Changed
|
||||
- Updated package dependencies. [#31468]
|
||||
|
||||
## [0.8.48] - 2023-06-06
|
||||
### Changed
|
||||
- Updated package dependencies. [#31129]
|
||||
|
||||
## [0.8.47] - 2023-05-15
|
||||
### Changed
|
||||
- Internal updates.
|
||||
|
||||
## [0.8.46] - 2023-05-02
|
||||
### Changed
|
||||
- Updated package dependencies.
|
||||
|
||||
## [0.8.45] - 2023-05-01
|
||||
### Changed
|
||||
- Internal updates.
|
||||
|
||||
## [0.8.44] - 2023-04-17
|
||||
### Changed
|
||||
- Updated package dependencies. [#30019]
|
||||
|
||||
## [0.8.43] - 2023-04-10
|
||||
### Added
|
||||
- Add Jetpack Autoloader package suggestion. [#29988]
|
||||
|
||||
## [0.8.42] - 2023-04-04
|
||||
### Changed
|
||||
- Updated package dependencies. [#29854]
|
||||
|
||||
## [0.8.41] - 2023-04-03
|
||||
### Changed
|
||||
- Internal updates.
|
||||
|
||||
## [0.8.40] - 2023-03-20
|
||||
### Changed
|
||||
- Updated package dependencies. [#29471]
|
||||
- Updated package dependencies. [#29480]
|
||||
|
||||
## [0.8.39] - 2023-03-08
|
||||
### Changed
|
||||
@ -337,6 +435,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Updated package dependencies.
|
||||
- Use Connection/Urls for home_url and site_url functions migrated from Sync.
|
||||
|
||||
[0.11.1]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.11.0...v0.11.1
|
||||
[0.11.0]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.10.7...v0.11.0
|
||||
[0.10.7]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.10.6...v0.10.7
|
||||
[0.10.6]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.10.5...v0.10.6
|
||||
[0.10.5]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.10.4...v0.10.5
|
||||
[0.10.4]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.10.3...v0.10.4
|
||||
[0.10.3]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.10.2...v0.10.3
|
||||
[0.10.2]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.10.1...v0.10.2
|
||||
[0.10.1]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.10.0...v0.10.1
|
||||
[0.10.0]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.9.0...v0.10.0
|
||||
[0.9.0]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.8.52...v0.9.0
|
||||
[0.8.52]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.8.51...v0.8.52
|
||||
[0.8.51]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.8.50...v0.8.51
|
||||
[0.8.50]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.8.49...v0.8.50
|
||||
[0.8.49]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.8.48...v0.8.49
|
||||
[0.8.48]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.8.47...v0.8.48
|
||||
[0.8.47]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.8.46...v0.8.47
|
||||
[0.8.46]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.8.45...v0.8.46
|
||||
[0.8.45]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.8.44...v0.8.45
|
||||
[0.8.44]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.8.43...v0.8.44
|
||||
[0.8.43]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.8.42...v0.8.43
|
||||
[0.8.42]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.8.41...v0.8.42
|
||||
[0.8.41]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.8.40...v0.8.41
|
||||
[0.8.40]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.8.39...v0.8.40
|
||||
[0.8.39]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.8.38...v0.8.39
|
||||
[0.8.38]: https://github.com/Automattic/jetpack-identity-crisis/compare/v0.8.37...v0.8.38
|
||||
|
@ -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.**
|
||||
|
||||
|
@ -1 +1 @@
|
||||
<?php return array('dependencies' => array('react', 'wp-components', 'wp-compose', 'wp-data', 'wp-element', 'wp-i18n', 'wp-polyfill', 'wp-url'), 'version' => 'fb59dccf666add58f6fb');
|
||||
<?php return array('dependencies' => array('react', 'wp-components', 'wp-compose', 'wp-data', 'wp-element', 'wp-i18n', 'wp-polyfill', 'wp-url'), 'version' => '40e79e96702db6f6da6d');
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,5 +1,5 @@
|
||||
/*!
|
||||
Copyright (c) 2018 Jed Watson.
|
||||
Licensed under the MIT License (MIT), see
|
||||
http://jedwatson.github.io/classnames
|
||||
Copyright (c) 2018 Jed Watson.
|
||||
Licensed under the MIT License (MIT), see
|
||||
http://jedwatson.github.io/classnames
|
||||
*/
|
||||
|
File diff suppressed because one or more lines are too long
@ -4,17 +4,20 @@
|
||||
"type": "jetpack-library",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"automattic/jetpack-connection": "^1.51.2",
|
||||
"automattic/jetpack-constants": "^1.6.21",
|
||||
"automattic/jetpack-status": "^1.16.2",
|
||||
"automattic/jetpack-logo": "^1.5.22",
|
||||
"automattic/jetpack-assets": "^1.17.34"
|
||||
"automattic/jetpack-connection": "^1.58.2",
|
||||
"automattic/jetpack-constants": "^1.6.23",
|
||||
"automattic/jetpack-status": "^1.18.5",
|
||||
"automattic/jetpack-logo": "^1.6.3",
|
||||
"automattic/jetpack-assets": "^1.18.13"
|
||||
},
|
||||
"require-dev": {
|
||||
"automattic/jetpack-changelogger": "^3.3.2",
|
||||
"yoast/phpunit-polyfills": "1.0.4",
|
||||
"automattic/jetpack-changelogger": "^3.3.11",
|
||||
"yoast/phpunit-polyfills": "1.1.0",
|
||||
"automattic/wordbless": "@dev"
|
||||
},
|
||||
"suggest": {
|
||||
"automattic/jetpack-autoloader": "Allow for better interoperability with other plugins that use this package."
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"src/"
|
||||
@ -53,7 +56,7 @@
|
||||
"link-template": "https://github.com/Automattic/jetpack-identity-crisis/compare/v${old}...v${new}"
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-trunk": "0.8.x-dev"
|
||||
"dev-trunk": "0.11.x-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
|
@ -9,9 +9,15 @@ import './style.scss';
|
||||
* The initial renderer function.
|
||||
*/
|
||||
function render() {
|
||||
const container = document.getElementById( 'jp-identity-crisis-container' );
|
||||
if ( ! window.hasOwnProperty( 'JP_IDENTITY_CRISIS__INITIAL_STATE' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( null === container || ! window.hasOwnProperty( 'JP_IDENTITY_CRISIS__INITIAL_STATE' ) ) {
|
||||
const container = document.getElementById(
|
||||
window.JP_IDENTITY_CRISIS__INITIAL_STATE.containerID || 'jp-identity-crisis-container'
|
||||
);
|
||||
|
||||
if ( null === container ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -30,7 +36,6 @@ function render() {
|
||||
} = window.JP_IDENTITY_CRISIS__INITIAL_STATE;
|
||||
|
||||
if ( ! isSafeModeConfirmed ) {
|
||||
// @todo: Remove fallback when we drop support for WP 6.1
|
||||
const component = (
|
||||
<IDCScreen
|
||||
wpcomHomeUrl={ wpcomHomeUrl }
|
||||
@ -48,12 +53,8 @@ function render() {
|
||||
possibleDynamicSiteUrlDetected={ possibleDynamicSiteUrlDetected }
|
||||
/>
|
||||
);
|
||||
if ( WPElement.createRoot ) {
|
||||
WPElement.createRoot( container ).render( component );
|
||||
} else {
|
||||
WPElement.render( component, container );
|
||||
}
|
||||
WPElement.createRoot( container ).render( component );
|
||||
}
|
||||
}
|
||||
|
||||
render();
|
||||
window.addEventListener( 'load', () => render() );
|
||||
|
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception class for the Identity Crisis package.
|
||||
*
|
||||
* @package automattic/jetpack-identity-crisis
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\IdentityCrisis;
|
||||
|
||||
/**
|
||||
* Exception class for the Identity Crisis package.
|
||||
*/
|
||||
class Exception extends \Exception {}
|
@ -10,10 +10,9 @@ namespace Automattic\Jetpack;
|
||||
use Automattic\Jetpack\Assets\Logo as Jetpack_Logo;
|
||||
use Automattic\Jetpack\Connection\Manager as Connection_Manager;
|
||||
use Automattic\Jetpack\Connection\Urls;
|
||||
use Automattic\Jetpack\Constants as Constants;
|
||||
use Automattic\Jetpack\IdentityCrisis\Exception;
|
||||
use Automattic\Jetpack\IdentityCrisis\UI;
|
||||
use Automattic\Jetpack\Status as Status;
|
||||
use Automattic\Jetpack\Tracking as Tracking;
|
||||
use Automattic\Jetpack\IdentityCrisis\URL_Secret;
|
||||
use Jetpack_Options;
|
||||
use WP_Error;
|
||||
|
||||
@ -28,7 +27,7 @@ class Identity_Crisis {
|
||||
/**
|
||||
* Package Version
|
||||
*/
|
||||
const PACKAGE_VERSION = '0.8.40';
|
||||
const PACKAGE_VERSION = '0.11.1';
|
||||
|
||||
/**
|
||||
* Instance of the object.
|
||||
@ -87,6 +86,10 @@ class Identity_Crisis {
|
||||
|
||||
add_filter( 'jetpack_remote_request_url', array( $this, 'add_idc_query_args_to_url' ) );
|
||||
|
||||
add_filter( 'jetpack_connection_validate_urls_for_idc_mitigation_response', array( static::class, 'add_secret_to_url_validation_response' ) );
|
||||
|
||||
add_filter( 'jetpack_options', array( static::class, 'reverse_wpcom_urls_for_idc' ) );
|
||||
|
||||
$urls_in_crisis = self::check_identity_crisis();
|
||||
if ( false === $urls_in_crisis ) {
|
||||
return;
|
||||
@ -144,14 +147,14 @@ class Identity_Crisis {
|
||||
foreach ( (array) $processed_items as $item ) {
|
||||
|
||||
// First, is this item a jetpack_sync_callable action? If so, then proceed.
|
||||
$callable_args = ( is_array( $item ) && isset( $item[0], $item[1] ) && 'jetpack_sync_callable' === $item[0] )
|
||||
$callable_args = ( is_array( $item ) && isset( $item[0] ) && isset( $item[1] ) && 'jetpack_sync_callable' === $item[0] )
|
||||
? $item[1]
|
||||
: null;
|
||||
|
||||
// Second, if $callable_args is set, check if the callable was home_url or site_url. If so,
|
||||
// clear the migrate option.
|
||||
if (
|
||||
isset( $callable_args, $callable_args[0] )
|
||||
isset( $callable_args[0] )
|
||||
&& ( 'home_url' === $callable_args[0] || 'site_url' === $callable_args[1] )
|
||||
) {
|
||||
Jetpack_Options::delete_option( 'migrate_for_idc' );
|
||||
@ -168,7 +171,7 @@ class Identity_Crisis {
|
||||
public function wordpress_init() {
|
||||
if ( current_user_can( 'jetpack_disconnect' ) ) {
|
||||
if (
|
||||
isset( $_GET['jetpack_idc_clear_confirmation'], $_GET['_wpnonce'] ) &&
|
||||
isset( $_GET['jetpack_idc_clear_confirmation'] ) && isset( $_GET['_wpnonce'] ) &&
|
||||
wp_verify_nonce( $_GET['_wpnonce'], 'jetpack_idc_clear_confirmation' ) // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- WordPress core doesn't unslash or verify nonces either.
|
||||
) {
|
||||
Jetpack_Options::delete_option( 'safe_mode_confirmed' );
|
||||
@ -284,7 +287,6 @@ class Identity_Crisis {
|
||||
if ( ! $connection->is_connected() || ( new Status() )->is_offline_mode() || ! self::validate_sync_error_idc_option() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Jetpack_Options::get_option( 'sync_error_idc' );
|
||||
}
|
||||
|
||||
@ -335,7 +337,7 @@ class Identity_Crisis {
|
||||
);
|
||||
|
||||
if ( in_array( $error_code, $allowed_idc_error_codes, true ) ) {
|
||||
\Jetpack_Options::update_option(
|
||||
Jetpack_Options::update_option(
|
||||
'sync_error_idc',
|
||||
self::get_sync_error_idc_option( $response )
|
||||
);
|
||||
@ -436,6 +438,24 @@ class Identity_Crisis {
|
||||
return $is_valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverses WP.com URLs stored in sync_error_idc option.
|
||||
*
|
||||
* @param array $sync_error error option containing reversed URLs.
|
||||
* @return array
|
||||
*/
|
||||
public static function reverse_wpcom_urls_for_idc( $sync_error ) {
|
||||
if ( isset( $sync_error['reversed_url'] ) ) {
|
||||
if ( array_key_exists( 'wpcom_siteurl', $sync_error ) ) {
|
||||
$sync_error['wpcom_siteurl'] = strrev( $sync_error['wpcom_siteurl'] );
|
||||
}
|
||||
if ( array_key_exists( 'wpcom_home', $sync_error ) ) {
|
||||
$sync_error['wpcom_home'] = strrev( $sync_error['wpcom_home'] );
|
||||
}
|
||||
}
|
||||
return $sync_error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes a url by doing three things:
|
||||
* - Strips protocol
|
||||
@ -505,6 +525,12 @@ class Identity_Crisis {
|
||||
|
||||
$returned_values[ $key ] = $normalized_url;
|
||||
}
|
||||
// We need to protect WPCOM URLs from search & replace by reversing them. See https://wp.me/pf5801-3R
|
||||
// Add 'reversed_url' key for backward compatibility
|
||||
if ( array_key_exists( 'wpcom_home', $returned_values ) && array_key_exists( 'wpcom_siteurl', $returned_values ) ) {
|
||||
$returned_values['reversed_url'] = true;
|
||||
$returned_values = self::reverse_wpcom_urls_for_idc( $returned_values );
|
||||
}
|
||||
|
||||
return $returned_values;
|
||||
}
|
||||
@ -1286,4 +1312,29 @@ class Identity_Crisis {
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds `url_secret` to the `jetpack.idcUrlValidation` URL validation endpoint.
|
||||
* Adds `url_secret_error` in case of an error.
|
||||
*
|
||||
* @param array $response The endpoint response that we're modifying.
|
||||
*
|
||||
* @return array
|
||||
* phpcs:ignore Squiz.Commenting.FunctionCommentThrowTag -- The exception is being caught, false positive.
|
||||
*/
|
||||
public static function add_secret_to_url_validation_response( array $response ) {
|
||||
try {
|
||||
$secret = new URL_Secret();
|
||||
|
||||
$secret->create();
|
||||
|
||||
if ( $secret->exists() ) {
|
||||
$response['url_secret'] = $secret->get_secret();
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
$response['url_secret_error'] = new WP_Error( 'unable_to_create_url_secret', $e->getMessage() );
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
namespace Automattic\Jetpack\IdentityCrisis;
|
||||
|
||||
use Automattic\Jetpack\Connection\Manager as Connection_Manager;
|
||||
use Automattic\Jetpack\Connection\Rest_Authentication;
|
||||
use Jetpack_Options;
|
||||
use WP_Error;
|
||||
use WP_REST_Server;
|
||||
@ -62,6 +63,17 @@ class REST_Endpoints {
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
// Fetch URL verification secret.
|
||||
register_rest_route(
|
||||
'jetpack/v4',
|
||||
'/identity-crisis/url-secret',
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( static::class, 'fetch_url_secret' ),
|
||||
'permission_callback' => array( static::class, 'url_secret_permission_check' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -184,4 +196,41 @@ class REST_Endpoints {
|
||||
return new WP_Error( 'invalid_user_permission_identity_crisis', $error_msg, array( 'status' => rest_authorization_required_code() ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Endpoint for fetching the existing secret.
|
||||
*
|
||||
* @return WP_Error|\WP_REST_Response
|
||||
*/
|
||||
public static function fetch_url_secret() {
|
||||
$secret = new URL_Secret();
|
||||
|
||||
if ( ! $secret->exists() ) {
|
||||
return new WP_Error( 'missing_url_secret', esc_html__( 'URL secret does not exist.', 'jetpack-idc' ) );
|
||||
}
|
||||
|
||||
return rest_ensure_response(
|
||||
array(
|
||||
'code' => 'success',
|
||||
'data' => array(
|
||||
'secret' => $secret->get_secret(),
|
||||
'expires_at' => $secret->get_expires_at(),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify url_secret create/fetch permissions (valid blog token authentication).
|
||||
*
|
||||
* @return true|WP_Error
|
||||
*/
|
||||
public static function url_secret_permission_check() {
|
||||
return Rest_Authentication::is_signed_with_blog_token()
|
||||
? true
|
||||
: new WP_Error(
|
||||
'invalid_user_permission_identity_crisis',
|
||||
esc_html__( 'You do not have the correct user permissions to perform this action.', 'jetpack-idc' ),
|
||||
array( 'status' => rest_authorization_required_code() )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ namespace Automattic\Jetpack\IdentityCrisis;
|
||||
use Automattic\Jetpack\Assets;
|
||||
use Automattic\Jetpack\Identity_Crisis;
|
||||
use Automattic\Jetpack\Status\Host;
|
||||
use Automattic\Jetpack\Tracking as Tracking;
|
||||
use Automattic\Jetpack\Tracking;
|
||||
use Jetpack_Options;
|
||||
use Jetpack_Tracks_Client;
|
||||
|
||||
@ -119,6 +119,15 @@ class UI {
|
||||
'consumerData' => static::get_consumer_data(),
|
||||
'isAdmin' => $is_admin,
|
||||
'possibleDynamicSiteUrlDetected' => $possible_dynamic_site_url_detected,
|
||||
|
||||
/**
|
||||
* Use the filter to provide custom HTML elecontainer ID.
|
||||
*
|
||||
* @since 0.10.0
|
||||
*
|
||||
* @param string|null $containerID The container ID.
|
||||
*/
|
||||
'containerID' => apply_filters( 'identity_crisis_container_id', null ),
|
||||
);
|
||||
}
|
||||
|
||||
@ -189,5 +198,4 @@ class UI {
|
||||
|
||||
return 'self-hosted';
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,134 @@
|
||||
<?php
|
||||
/**
|
||||
* IDC URL secret functionality.
|
||||
*
|
||||
* @package automattic/jetpack-identity-crisis
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\IdentityCrisis;
|
||||
|
||||
use Jetpack_Options;
|
||||
|
||||
/**
|
||||
* IDC URL secret functionality.
|
||||
* A short-lived secret used to verify whether an IDC is coming from the same vs a different Jetpack site.
|
||||
*/
|
||||
class URL_Secret {
|
||||
|
||||
/**
|
||||
* The options key used to store the secret.
|
||||
*/
|
||||
const OPTION_KEY = 'identity_crisis_url_secret';
|
||||
|
||||
/**
|
||||
* Secret lifespan (5 minutes)
|
||||
*/
|
||||
const LIFESPAN = 300;
|
||||
|
||||
/**
|
||||
* The URL secret string.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
private $secret = null;
|
||||
|
||||
/**
|
||||
* The URL secret expiration date in unix timestamp.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
private $expires_at = null;
|
||||
|
||||
/**
|
||||
* Initialize the class.
|
||||
*/
|
||||
public function __construct() {
|
||||
$secret_data = $this->fetch();
|
||||
|
||||
if ( $secret_data !== null ) {
|
||||
$this->secret = $secret_data['secret'];
|
||||
$this->expires_at = $secret_data['expires_at'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the URL secret from the database.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
private function fetch() {
|
||||
$data = Jetpack_Options::get_option( static::OPTION_KEY );
|
||||
|
||||
if ( $data === false || empty( $data['secret'] ) || empty( $data['expires_at'] ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( time() > $data['expires_at'] ) {
|
||||
Jetpack_Options::delete_option( static::OPTION_KEY );
|
||||
return null;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new secret and save it in the options.
|
||||
*
|
||||
* @throws Exception Thrown if unable to save the new secret.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function create() {
|
||||
$secret_data = array(
|
||||
'secret' => $this->generate_secret(),
|
||||
'expires_at' => time() + static::LIFESPAN,
|
||||
);
|
||||
|
||||
$result = Jetpack_Options::update_option( static::OPTION_KEY, $secret_data );
|
||||
|
||||
if ( ! $result ) {
|
||||
throw new Exception( esc_html__( 'Unable to save new URL secret', 'jetpack-idc' ) );
|
||||
}
|
||||
|
||||
$this->secret = $secret_data['secret'];
|
||||
$this->expires_at = $secret_data['expires_at'];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL secret.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_secret() {
|
||||
return $this->secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL secret expiration date.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_expires_at() {
|
||||
return $this->expires_at;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the secret exists.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function exists() {
|
||||
return $this->secret && $this->expires_at;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the secret string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generate_secret() {
|
||||
return wp_generate_password( 12, false );
|
||||
}
|
||||
}
|
@ -5,6 +5,21 @@ 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).
|
||||
|
||||
## [0.1.6] - 2023-09-19
|
||||
- Minor internal updates.
|
||||
|
||||
## [0.1.5] - 2023-08-23
|
||||
### Changed
|
||||
- Updated package dependencies. [#32605]
|
||||
|
||||
## [0.1.4] - 2023-05-29
|
||||
### Changed
|
||||
- Internal updates.
|
||||
|
||||
## [0.1.3] - 2023-05-11
|
||||
|
||||
- Updated package dependencies
|
||||
|
||||
## [0.1.2] - 2023-04-10
|
||||
### Added
|
||||
- Add Jetpack Autoloader package suggestion. [#29988]
|
||||
@ -19,5 +34,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Add jetpack-ip package functionality [#28846]
|
||||
- Initialized the package. [#28765]
|
||||
|
||||
[0.1.6]: https://github.com/automattic/jetpack-ip/compare/v0.1.5...v0.1.6
|
||||
[0.1.5]: https://github.com/automattic/jetpack-ip/compare/v0.1.4...v0.1.5
|
||||
[0.1.4]: https://github.com/automattic/jetpack-ip/compare/v0.1.3...v0.1.4
|
||||
[0.1.3]: https://github.com/automattic/jetpack-ip/compare/v0.1.2...v0.1.3
|
||||
[0.1.2]: https://github.com/automattic/jetpack-ip/compare/v0.1.1...v0.1.2
|
||||
[0.1.1]: https://github.com/automattic/jetpack-ip/compare/v0.1.0...v0.1.1
|
||||
|
@ -6,8 +6,8 @@
|
||||
"require": {},
|
||||
"require-dev": {
|
||||
"brain/monkey": "2.6.1",
|
||||
"yoast/phpunit-polyfills": "1.0.4",
|
||||
"automattic/jetpack-changelogger": "^3.3.2"
|
||||
"yoast/phpunit-polyfills": "1.1.0",
|
||||
"automattic/jetpack-changelogger": "^3.3.9"
|
||||
},
|
||||
"suggest": {
|
||||
"automattic/jetpack-autoloader": "Allow for better interoperability with other plugins that use this package."
|
||||
|
@ -12,7 +12,7 @@ namespace Automattic\Jetpack\IP;
|
||||
*/
|
||||
class Utils {
|
||||
|
||||
const PACKAGE_VERSION = '0.1.2';
|
||||
const PACKAGE_VERSION = '0.1.6';
|
||||
|
||||
/**
|
||||
* Get the current user's IP address.
|
||||
@ -242,5 +242,4 @@ class Utils {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,85 @@ 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).
|
||||
|
||||
## [2.5.1] - 2023-10-19
|
||||
### Changed
|
||||
- Updated package dependencies. [#33687]
|
||||
|
||||
## [2.5.0] - 2023-10-10
|
||||
### Added
|
||||
- JITMs can now redirect to a specific Jetpack settings page. [#32826]
|
||||
|
||||
### Changed
|
||||
- Update color of WooCommerce logo. [#33491]
|
||||
- Updated package dependencies. [#33428]
|
||||
|
||||
## [2.4.0] - 2023-09-28
|
||||
### Changed
|
||||
- Moved tracking for JITM buttons into JITM script, added message_path property [#33252]
|
||||
|
||||
## [2.3.19] - 2023-09-19
|
||||
|
||||
- Minor internal updates.
|
||||
|
||||
## [2.3.18] - 2023-09-04
|
||||
### Changed
|
||||
- Updated package dependencies. [#32803]
|
||||
|
||||
## [2.3.17] - 2023-08-23
|
||||
### Changed
|
||||
- Updated package dependencies. [#32605]
|
||||
|
||||
## [2.3.16] - 2023-08-21
|
||||
### Fixed
|
||||
- Update secondary button styling [#32503]
|
||||
|
||||
## [2.3.15] - 2023-08-09
|
||||
### Changed
|
||||
- Updated package dependencies. [#32166]
|
||||
|
||||
## [2.3.14] - 2023-07-25
|
||||
### Changed
|
||||
- Updated package dependencies. [#32040]
|
||||
|
||||
## [2.3.13] - 2023-07-17
|
||||
### Changed
|
||||
- Generate query string when using the WPCOM API to fetch JITMs [#31809]
|
||||
|
||||
## [2.3.12] - 2023-07-11
|
||||
### Changed
|
||||
- Updated package dependencies. [#31785]
|
||||
|
||||
## [2.3.11] - 2023-07-05
|
||||
### Changed
|
||||
- Updated package dependencies. [#31659]
|
||||
|
||||
## [2.3.10] - 2023-06-23
|
||||
### Changed
|
||||
- Updated package dependencies. [#31468]
|
||||
|
||||
## [2.3.9] - 2023-06-06
|
||||
### Changed
|
||||
- Updated package dependencies. [#31129]
|
||||
|
||||
## [2.3.8] - 2023-05-08
|
||||
### Added
|
||||
- JITM: Add jetpack-videopress to JITM refetch on hashchange list [#30465]
|
||||
|
||||
## [2.3.7] - 2023-05-02
|
||||
### Changed
|
||||
- Updated package dependencies. [#30375]
|
||||
|
||||
## [2.3.6] - 2023-04-10
|
||||
### Added
|
||||
- Add Jetpack Autoloader package suggestion. [#29988]
|
||||
|
||||
## [2.3.5] - 2023-04-04
|
||||
### Added
|
||||
- Add external link icons in JITM [#29654]
|
||||
|
||||
### Changed
|
||||
- Updated package dependencies. [#29854]
|
||||
|
||||
## [2.3.4] - 2023-03-28
|
||||
### Fixed
|
||||
- JITM: Fix button overflow when text length is too big [#29749]
|
||||
@ -562,6 +641,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Update Jetpack to use new JITM package
|
||||
|
||||
[2.5.1]: https://github.com/Automattic/jetpack-jitm/compare/v2.5.0...v2.5.1
|
||||
[2.5.0]: https://github.com/Automattic/jetpack-jitm/compare/v2.4.0...v2.5.0
|
||||
[2.4.0]: https://github.com/Automattic/jetpack-jitm/compare/v2.3.19...v2.4.0
|
||||
[2.3.19]: https://github.com/Automattic/jetpack-jitm/compare/v2.3.18...v2.3.19
|
||||
[2.3.18]: https://github.com/Automattic/jetpack-jitm/compare/v2.3.17...v2.3.18
|
||||
[2.3.17]: https://github.com/Automattic/jetpack-jitm/compare/v2.3.16...v2.3.17
|
||||
[2.3.16]: https://github.com/Automattic/jetpack-jitm/compare/v2.3.15...v2.3.16
|
||||
[2.3.15]: https://github.com/Automattic/jetpack-jitm/compare/v2.3.14...v2.3.15
|
||||
[2.3.14]: https://github.com/Automattic/jetpack-jitm/compare/v2.3.13...v2.3.14
|
||||
[2.3.13]: https://github.com/Automattic/jetpack-jitm/compare/v2.3.12...v2.3.13
|
||||
[2.3.12]: https://github.com/Automattic/jetpack-jitm/compare/v2.3.11...v2.3.12
|
||||
[2.3.11]: https://github.com/Automattic/jetpack-jitm/compare/v2.3.10...v2.3.11
|
||||
[2.3.10]: https://github.com/Automattic/jetpack-jitm/compare/v2.3.9...v2.3.10
|
||||
[2.3.9]: https://github.com/Automattic/jetpack-jitm/compare/v2.3.8...v2.3.9
|
||||
[2.3.8]: https://github.com/Automattic/jetpack-jitm/compare/v2.3.7...v2.3.8
|
||||
[2.3.7]: https://github.com/Automattic/jetpack-jitm/compare/v2.3.6...v2.3.7
|
||||
[2.3.6]: https://github.com/Automattic/jetpack-jitm/compare/v2.3.5...v2.3.6
|
||||
[2.3.5]: https://github.com/Automattic/jetpack-jitm/compare/v2.3.4...v2.3.5
|
||||
[2.3.4]: https://github.com/Automattic/jetpack-jitm/compare/v2.3.3...v2.3.4
|
||||
[2.3.3]: https://github.com/Automattic/jetpack-jitm/compare/v2.3.2...v2.3.3
|
||||
[2.3.2]: https://github.com/Automattic/jetpack-jitm/compare/v2.3.1...v2.3.2
|
||||
[2.3.1]: https://github.com/Automattic/jetpack-jitm/compare/v2.3.0...v2.3.1
|
||||
|
@ -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.**
|
||||
|
||||
|
@ -1 +1 @@
|
||||
<?php return array('dependencies' => array('jquery', 'wp-polyfill'), 'version' => 'ef911dd8f37f702652eb');
|
||||
<?php return array('dependencies' => array('jquery', 'wp-polyfill'), 'version' => '76ec3c26b0b3d8144645');
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -4,19 +4,22 @@
|
||||
"type": "jetpack-library",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"automattic/jetpack-a8c-mc-stats": "^1.4.19",
|
||||
"automattic/jetpack-assets": "^1.17.34",
|
||||
"automattic/jetpack-connection": "^1.51.4",
|
||||
"automattic/jetpack-device-detection": "^1.4.24",
|
||||
"automattic/jetpack-logo": "^1.5.22",
|
||||
"automattic/jetpack-partner": "^1.7.22",
|
||||
"automattic/jetpack-redirect": "^1.7.24",
|
||||
"automattic/jetpack-status": "^1.16.3"
|
||||
"automattic/jetpack-a8c-mc-stats": "^1.4.22",
|
||||
"automattic/jetpack-assets": "^1.18.13",
|
||||
"automattic/jetpack-connection": "^1.58.2",
|
||||
"automattic/jetpack-device-detection": "^1.4.27",
|
||||
"automattic/jetpack-logo": "^1.6.3",
|
||||
"automattic/jetpack-partner": "^1.7.25",
|
||||
"automattic/jetpack-redirect": "^1.7.27",
|
||||
"automattic/jetpack-status": "^1.18.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"brain/monkey": "2.6.1",
|
||||
"yoast/phpunit-polyfills": "1.0.4",
|
||||
"automattic/jetpack-changelogger": "^3.3.2"
|
||||
"yoast/phpunit-polyfills": "1.1.0",
|
||||
"automattic/jetpack-changelogger": "^3.3.11"
|
||||
},
|
||||
"suggest": {
|
||||
"automattic/jetpack-autoloader": "Allow for better interoperability with other plugins that use this package."
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
@ -54,7 +57,7 @@
|
||||
"link-template": "https://github.com/Automattic/jetpack-jitm/compare/v${old}...v${new}"
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-trunk": "2.3.x-dev"
|
||||
"dev-trunk": "2.5.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ use Automattic\Jetpack\Status;
|
||||
*/
|
||||
class JITM {
|
||||
|
||||
const PACKAGE_VERSION = '2.3.4';
|
||||
const PACKAGE_VERSION = '2.5.1';
|
||||
|
||||
/**
|
||||
* The configuration method that is called from the jetpack-config package.
|
||||
@ -156,6 +156,7 @@ class JITM {
|
||||
'activate_module_text' => esc_html__( 'Activate', 'jetpack-jitm' ),
|
||||
'activated_module_text' => esc_html__( 'Activated', 'jetpack-jitm' ),
|
||||
'activating_module_text' => esc_html__( 'Activating', 'jetpack-jitm' ),
|
||||
'settings_module_text' => esc_html__( 'Settings', 'jetpack-jitm' ),
|
||||
'nonce' => wp_create_nonce( 'wp_rest' ),
|
||||
)
|
||||
);
|
||||
@ -230,7 +231,7 @@ class JITM {
|
||||
.st0{clip-path:url(#SVGID_2_);enable-background:new ;}
|
||||
.st1{clip-path:url(#SVGID_4_);}
|
||||
.st2{clip-path:url(#SVGID_6_);}
|
||||
.st3{clip-path:url(#SVGID_8_);fill:#8F567F;}
|
||||
.st3{clip-path:url(#SVGID_8_);fill:#7F54B3;}
|
||||
.st4{clip-path:url(#SVGID_10_);fill:#FFFFFE;}
|
||||
.st5{clip-path:url(#SVGID_12_);fill:#FFFFFE;}
|
||||
.st6{clip-path:url(#SVGID_14_);fill:#FFFFFE;}
|
||||
|
@ -266,7 +266,7 @@ class Post_Connection_JITM extends JITM {
|
||||
array(
|
||||
'external_user_id' => urlencode_deep( $user->ID ),
|
||||
'user_roles' => urlencode_deep( $user_roles ),
|
||||
'query_string' => urlencode_deep( $query ),
|
||||
'query_string' => urlencode_deep( build_query( $query ) ),
|
||||
'mobile_browser' => Device_Detection::is_smartphone() ? 1 : 0,
|
||||
'_locale' => get_user_locale(),
|
||||
),
|
||||
@ -360,7 +360,8 @@ class Post_Connection_JITM extends JITM {
|
||||
$this->tracking->record_user_event(
|
||||
'jitm_view_client',
|
||||
array(
|
||||
'jitm_id' => $envelope->id,
|
||||
'jitm_id' => $envelope->id,
|
||||
'jitm_message_path' => $message_path,
|
||||
)
|
||||
);
|
||||
|
||||
@ -405,6 +406,7 @@ class Post_Connection_JITM extends JITM {
|
||||
}
|
||||
|
||||
$envelope->content->icon = $this->generate_icon( $envelope->content->icon, $full_jp_logo_exists );
|
||||
$envelope->message_path = esc_attr( $message_path );
|
||||
|
||||
$stats->add( 'jitm', $envelope->id . '-viewed' );
|
||||
$stats->do_server_side_stats();
|
||||
@ -412,5 +414,4 @@ class Post_Connection_JITM extends JITM {
|
||||
|
||||
return $envelopes;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -55,7 +55,13 @@ class Rest_Api_Endpoints {
|
||||
return array();
|
||||
}
|
||||
|
||||
return $jitm->get_messages( $request['message_path'], urldecode_deep( $request['query'] ), 'true' === $request['full_jp_logo_exists'] ? true : false );
|
||||
// add the search term to the query params if it exists
|
||||
$query = $request['query'];
|
||||
if ( ! empty( $request['s'] ) ) {
|
||||
$query['s'] = $request['s'];
|
||||
}
|
||||
|
||||
return $jitm->get_messages( $request['message_path'], urldecode_deep( $query ), 'true' === $request['full_jp_logo_exists'] ? true : false );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -87,5 +93,4 @@ class Rest_Api_Endpoints {
|
||||
|
||||
return new \WP_Error( 'invalid_user_permission_jetpack_delete_jitm_message', REST_Connector::get_user_permissions_error_msg(), array( 'status' => rest_authorization_required_code() ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -33,6 +33,7 @@
|
||||
// New JITMS - modified calypso banner styles
|
||||
$blue-medium-dark: #2271b1;
|
||||
$jp-gray: #dcdcde;
|
||||
$jp-gray-0: #f6f7f7;
|
||||
$jp-gray-20: #a7aaad;
|
||||
|
||||
.jitm-button {
|
||||
@ -64,6 +65,23 @@ $jp-gray-20: #a7aaad;
|
||||
&.is-primary {
|
||||
background: black;
|
||||
color: $white;
|
||||
.gridicons-external-link {
|
||||
fill: $white;
|
||||
}
|
||||
}
|
||||
|
||||
// Secondary buttons
|
||||
&.is-secondary {
|
||||
.gridicons-external-link {
|
||||
fill: black;
|
||||
}
|
||||
&:hover{
|
||||
color: black;
|
||||
background: $jp-gray-0;
|
||||
.gridicons-external-link {
|
||||
fill: black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover,
|
||||
@ -107,6 +125,11 @@ $jp-gray-20: #a7aaad;
|
||||
.gridicons-plus-small + .gridicon {
|
||||
margin-left: -4px;
|
||||
}
|
||||
|
||||
// Properly align icon with the button text
|
||||
.gridicons-external-link {
|
||||
margin: -3px 0 -3px 2px;
|
||||
}
|
||||
}
|
||||
&.hidden {
|
||||
display: none;
|
||||
|
@ -5,6 +5,13 @@ 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.8.4] - 2023-09-19
|
||||
- Minor internal updates.
|
||||
|
||||
## [1.8.3] - 2023-08-23
|
||||
### Changed
|
||||
- Updated package dependencies. [#32605]
|
||||
|
||||
## [1.8.2] - 2023-04-10
|
||||
### Added
|
||||
- Add Jetpack Autoloader package suggestion. [#29988]
|
||||
@ -242,6 +249,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Licensing: Add support for Jetpack licenses
|
||||
|
||||
[1.8.4]: https://github.com/Automattic/jetpack-licensing/compare/v1.8.3...v1.8.4
|
||||
[1.8.3]: https://github.com/Automattic/jetpack-licensing/compare/v1.8.2...v1.8.3
|
||||
[1.8.2]: https://github.com/Automattic/jetpack-licensing/compare/v1.8.1...v1.8.2
|
||||
[1.8.1]: https://github.com/Automattic/jetpack-licensing/compare/v1.8.0...v1.8.1
|
||||
[1.8.0]: https://github.com/Automattic/jetpack-licensing/compare/v1.7.14...v1.8.0
|
||||
|
@ -4,12 +4,12 @@
|
||||
"type": "jetpack-library",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"automattic/jetpack-connection": "^1.51.7"
|
||||
"automattic/jetpack-connection": "^1.57.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"automattic/wordbless": "@dev",
|
||||
"yoast/phpunit-polyfills": "1.0.4",
|
||||
"automattic/jetpack-changelogger": "^3.3.2"
|
||||
"yoast/phpunit-polyfills": "1.1.0",
|
||||
"automattic/jetpack-changelogger": "^3.3.9"
|
||||
},
|
||||
"suggest": {
|
||||
"automattic/jetpack-autoloader": "Allow for better interoperability with other plugins that use this package."
|
||||
|
@ -5,6 +5,13 @@ 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.6.3] - 2023-09-19
|
||||
- Minor internal updates.
|
||||
|
||||
## [1.6.2] - 2023-08-23
|
||||
### Changed
|
||||
- Updated package dependencies. [#32605]
|
||||
|
||||
## [1.6.1] - 2023-04-10
|
||||
### Added
|
||||
- Add Jetpack Autoloader package suggestion. [#29988]
|
||||
@ -154,6 +161,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Packages: Add a basic Jetpack Logo package
|
||||
|
||||
[1.6.3]: https://github.com/Automattic/jetpack-logo/compare/v1.6.2...v1.6.3
|
||||
[1.6.2]: https://github.com/Automattic/jetpack-logo/compare/v1.6.1...v1.6.2
|
||||
[1.6.1]: https://github.com/Automattic/jetpack-logo/compare/v1.6.0...v1.6.1
|
||||
[1.6.0]: https://github.com/Automattic/jetpack-logo/compare/v1.5.22...v1.6.0
|
||||
[1.5.22]: https://github.com/Automattic/jetpack-logo/compare/v1.5.21...v1.5.22
|
||||
|
@ -5,8 +5,8 @@
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {},
|
||||
"require-dev": {
|
||||
"yoast/phpunit-polyfills": "1.0.4",
|
||||
"automattic/jetpack-changelogger": "^3.3.2"
|
||||
"yoast/phpunit-polyfills": "1.1.0",
|
||||
"automattic/jetpack-changelogger": "^3.3.9"
|
||||
},
|
||||
"suggest": {
|
||||
"automattic/jetpack-autoloader": "Allow for better interoperability with other plugins that use this package."
|
||||
|
@ -5,6 +5,294 @@ 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).
|
||||
|
||||
## [3.9.1] - 2023-10-19
|
||||
### Changed
|
||||
- Make has_required_plan return true (as it was before #33410) as a way to revert the change. [#33697]
|
||||
- Updated package dependencies. [#33687]
|
||||
|
||||
## [3.9.0] - 2023-10-17
|
||||
### Added
|
||||
- Add has_required_plan method for VideoPress product class, check plan purchase exists for site [#33410]
|
||||
|
||||
### Changed
|
||||
- Updated package dependencies. [#33646]
|
||||
|
||||
## [3.8.2] - 2023-10-16
|
||||
### Changed
|
||||
- Updated package dependencies. [#33429, #33584]
|
||||
|
||||
## [3.8.1] - 2023-10-10
|
||||
### Changed
|
||||
- Changes title of the my-jetpack page to "My Jetpack" [#33486]
|
||||
- Updated package dependencies. [#33428]
|
||||
|
||||
### Fixed
|
||||
- My Jetpack: fix fatal error [#33523]
|
||||
- My Jetpack: fix Stats card status when not connected [#33521]
|
||||
|
||||
## [3.8.0] - 2023-10-03
|
||||
### Added
|
||||
- Display a new section on My Jetpack to display the stats of the site. [#33283]
|
||||
|
||||
## [3.7.0] - 2023-09-28
|
||||
### Added
|
||||
- Add a section to display stats from Jetpack Stats in My Jetpack [#33160]
|
||||
|
||||
### Changed
|
||||
- Redirect to a proper upgrade page for free license owners [#33297]
|
||||
|
||||
## [3.6.0] - 2023-09-25
|
||||
### Added
|
||||
- Add barebones infrastructure for querying jetpack product data. [#33095]
|
||||
|
||||
### Changed
|
||||
- Stats: link to purchase page within WP Admin. [#33227]
|
||||
|
||||
## [3.5.0] - 2023-09-19
|
||||
### Changed
|
||||
- Added support for upgradable products. Updated the Stats card to handle upgradeable products. [#33058]
|
||||
- Updated Jetpack submenu sort order so individual features are alpha-sorted. [#32958]
|
||||
|
||||
### Fixed
|
||||
- My Jetpack: Add AI Assistant Monthly to required plan check [#33078]
|
||||
|
||||
## [3.4.5] - 2023-09-13
|
||||
### Changed
|
||||
- Updated package dependencies. [#33001]
|
||||
|
||||
## [3.4.4] - 2023-09-11
|
||||
### Changed
|
||||
- General: remove WP 6.1 backwards compatibility checks [#32772]
|
||||
|
||||
### Fixed
|
||||
- Stats: stop showing upgrade button for sites with Complete plan [#32870]
|
||||
|
||||
## [3.4.3] - 2023-09-04
|
||||
### Changed
|
||||
- Updated package dependencies. [#32803]
|
||||
- Updated package dependencies. [#32804]
|
||||
|
||||
## [3.4.2] - 2023-08-23
|
||||
### Changed
|
||||
- Updated package dependencies. [#32605]
|
||||
|
||||
## [3.4.1] - 2023-08-22
|
||||
### Changed
|
||||
- Connection: allow dismissing the IDC modal. [#32594]
|
||||
|
||||
## [3.4.0] - 2023-08-21
|
||||
### Added
|
||||
- Support Jetpack AI Yearly offering [#32130]
|
||||
|
||||
### Changed
|
||||
- Use the new method to render Connection initial state. [#32499]
|
||||
|
||||
## [3.3.3] - 2023-08-14
|
||||
### Added
|
||||
- Make My Jetpack the default WP-Admin page for Jetpack. [#32385]
|
||||
|
||||
### Changed
|
||||
- Start showing My Jetpack for authors, editors, and contributors [#32420]
|
||||
|
||||
## [3.3.2] - 2023-08-09
|
||||
### Fixed
|
||||
- Revert My Jetpack as first menu item. [#32384]
|
||||
|
||||
## [3.3.1] - 2023-08-09
|
||||
### Changed
|
||||
- Updated package dependencies. [#32166]
|
||||
|
||||
## [3.3.0] - 2023-08-07
|
||||
### Added
|
||||
- Add Identity Crisis screen modal. [#32249]
|
||||
|
||||
### Changed
|
||||
- Move 'My Jetpack' sub-menu item to first position. [#32240]
|
||||
|
||||
### Fixed
|
||||
- Fix IDC modal height issue. [#32316]
|
||||
|
||||
## [3.2.1] - 2023-08-01
|
||||
### Added
|
||||
- Add transient caching for zendesk jwt auth token. [#32140]
|
||||
|
||||
### Changed
|
||||
- My Jetpack: Rename the namespace of the JWT endpoint, and register it only when it isn't already registered [#32081]
|
||||
|
||||
## [3.2.0] - 2023-07-25
|
||||
### Added
|
||||
- My Jetpack: register jetpack-ai-jwt endpoint [#31965]
|
||||
- My Jetpack: release Paid Stats to the public [#32020]
|
||||
|
||||
### Changed
|
||||
- My Jetpack: changed Stats features wording [#32046]
|
||||
- Updated package dependencies. [#31999]
|
||||
- Updated package dependencies. [#32040]
|
||||
|
||||
### Fixed
|
||||
- Make Jetpack logo in footer smaller [#31627]
|
||||
- My Jetpack: enabled Stats purchase flow returning to Stats Dashboard [#31959]
|
||||
|
||||
## [3.1.3] - 2023-07-17
|
||||
### Changed
|
||||
- Updated package dependencies. [#31872]
|
||||
|
||||
### Fixed
|
||||
- Hide connection owner information if the data is invalid
|
||||
- Don't suggest user connection if user is already connected, but connection owner is invalid [#31618]
|
||||
|
||||
## [3.1.2] - 2023-07-11
|
||||
### Changed
|
||||
- Updated package dependencies. [#31785]
|
||||
|
||||
## [3.1.1] - 2023-07-10
|
||||
### Fixed
|
||||
- Make product card primary buttons links when applicable [#31611]
|
||||
|
||||
## [3.1.0] - 2023-07-05
|
||||
### Added
|
||||
- Added Jetpack Stats card to My Jetpack [#31589]
|
||||
|
||||
### Changed
|
||||
- Jetpack Stats: Enable skipping interstitial page [#31629]
|
||||
- Updated package dependencies. [#31659]
|
||||
|
||||
### Fixed
|
||||
- My Jetpack: hide Stats card for standalone plugins [#31689]
|
||||
- Organize product cards in list [#31606]
|
||||
|
||||
## [3.0.0] - 2023-06-26
|
||||
### Added
|
||||
- Add authentication to Zendesk chat. [#31339]
|
||||
- Stats: add stats card to my Jetpack. [#31531]
|
||||
|
||||
## [2.15.0] - 2023-06-23
|
||||
### Added
|
||||
- My Jetpack: add Stats product [#31368]
|
||||
|
||||
### Changed
|
||||
- Updated package dependencies. [#31468]
|
||||
|
||||
## [2.14.3] - 2023-06-12
|
||||
### Added
|
||||
- My Jetpack: populate the Jetpack AI product with feature data [#31238]
|
||||
|
||||
## [2.14.2] - 2023-06-06
|
||||
### Changed
|
||||
- Filter out revoked licenses from the license activation options. [#31088]
|
||||
- Updated package dependencies. [#31129]
|
||||
|
||||
## [2.14.1] - 2023-05-29
|
||||
### Added
|
||||
- My Jetpack: Add new Jetpack AI card [#30904]
|
||||
|
||||
### Changed
|
||||
- My Jetpack: Enable Jetpack AI card [#30988]
|
||||
- My Jetpack: Update AI class to be product and not module [#30905]
|
||||
- My Jetpack: Update AI interstitial background [#30992]
|
||||
|
||||
## [2.14.0] - 2023-05-22
|
||||
### Added
|
||||
- Added ability to purchase Jetpack AI monthly product [#30793]
|
||||
- Added tier data to the Boost product to support a pricing table interstitial page. [#29931]
|
||||
|
||||
## [2.13.0] - 2023-05-15
|
||||
### Added
|
||||
- Added My Jetpack interstitial for Jetpack AI [#30543]
|
||||
|
||||
## [2.12.2] - 2023-05-11
|
||||
### Changed
|
||||
- PHP 8.1 compatibility updates [#30517]
|
||||
|
||||
## [2.12.1] - 2023-05-08
|
||||
### Added
|
||||
- My Jetpack: Add deactivate plugin menu action on product card [#30489]
|
||||
|
||||
### Changed
|
||||
- My Jetpack: Remove icon from plugin activation action in product card [#30458]
|
||||
- My Jetpack: Remove manage option from menu [#30440]
|
||||
- My Jetpack: Remove product card icon [#30441]
|
||||
- My Jetpack: Set a post-checkout redirect destination on the "Purchase a plan" link. [#27693]
|
||||
|
||||
### Fixed
|
||||
- My Jetpack: Add check for product status before requesting stats [#30430]
|
||||
- My Jetpack: Reload page after successful license activation [#30364]
|
||||
- My Jetpack: Use a single column for the page title section [#30406]
|
||||
|
||||
## [2.12.0] - 2023-05-02
|
||||
### Added
|
||||
- Add API to query Zendesk chat availability and use it to conditionally display zendesk chat. [#29942]
|
||||
- Add pricing table interstitial view for Jetpack Protect. [#29930]
|
||||
- My Jetpack: Add product detail table component for comparing product tiers. [#29759]
|
||||
|
||||
### Changed
|
||||
- My Jetpack: Move logic out of Product Card component. [#30274]
|
||||
- Updated package dependencies.
|
||||
|
||||
### Fixed
|
||||
- Fix activation and layout on Protect interstatial page. [#29525]
|
||||
- My Jetpack: Keep product card action button disabled while installing standalone plugin. [#30346]
|
||||
|
||||
## [2.11.0] - 2023-05-01
|
||||
### Added
|
||||
- Added Jetpack Starter bundle post-activation screen and plan header [#30368]
|
||||
|
||||
## [2.10.3] - 2023-04-25
|
||||
### Added
|
||||
- My Jetpack: Add flags field in initial state [#30241]
|
||||
- My Jetpack: Add Install/Activate menu actions based on the standalone plugin status. [#30153]
|
||||
- My Jetpack: Add neutral color in contextual card [#30250]
|
||||
- My Jetpack: Add side-effect action to request the standalone plugin installation on the backend. [#30143]
|
||||
- My Jetpack: Add stats to VideoPress card [#30197]
|
||||
- My Jetpack: Enable menu for all hybrid products [#30247]
|
||||
- My Jetpack: Reload page after standalone action [#30221]
|
||||
|
||||
### Changed
|
||||
- My Jetpack: Connect the standalone plugin menu options so they trigger the installation and activation when clicked. [#30168]
|
||||
- MyJetpack: set the Social standalone page as the default admin one [#30193]
|
||||
- MyJetpack: Try to activate the product module after installing the standalone plugin [#30215]
|
||||
- Updated package dependencies. [#30015]
|
||||
|
||||
## [2.10.2] - 2023-04-17
|
||||
### Added
|
||||
- Ad missing TOS in Jetpack interstitial. [#29683]
|
||||
- My Jetpack: Add endpoint to install the standalone plugin for hybrid products. [#30045]
|
||||
- My Jetpack: Expose information about standalone plugin status on My Jetpack product initial state. [#29977]
|
||||
|
||||
### Changed
|
||||
- Backup and Scan: redirect after checkout to Jetpack recommendations page if Jetpack plugin is active. Otherwise, redirect back to plugin admin page. [#29708]
|
||||
- My Jetpack: Adjustments in Product Card [#30014]
|
||||
- Updated package dependencies. [#30019]
|
||||
|
||||
## [2.10.1] - 2023-04-10
|
||||
### Added
|
||||
- Add Jetpack Autoloader package suggestion. [#29988]
|
||||
- My Jetpack: Introduce absent_with_plan status [#29920]
|
||||
|
||||
### Changed
|
||||
- My Jetpack: Turn Search into a hybrid product to handle it as module and as standalone plugin. [#29946]
|
||||
- My Jetpack: Turn Social into a hybrid product to handle it as module and as standalone plugin. [#29935]
|
||||
- My Jetpack: Turn VaultPress Backup into a Hybrid product to handle it as module and as standalone plugin. [#29928]
|
||||
- My Jetpack: Turn VideoPress into a Hybrid product to handle it as module and as standalone plugin. [#29918]
|
||||
|
||||
## [2.10.0] - 2023-04-04
|
||||
### Added
|
||||
- My Jetpack: Adds a selector, reducer and resolver machinery to fetch product stats. [#29764]
|
||||
- My Jetpack: Enhance Product Card [#29787]
|
||||
- My Jetpack: Introduce menu in Product Card [#29815]
|
||||
|
||||
### Changed
|
||||
- * Updated add-anti-spam path to add-akismet to match the product key
|
||||
* Updated product interstitial component to accept an existingLicenseKeyUrl
|
||||
* Updated product interstitial component to display a product name instead of a title where preferProductName is set
|
||||
* Make is_plugin_active available from the API [#29598]
|
||||
- My Jetpack: Change the bottom of My Jetpack screen to use single-column rows on small viewports. [#29844]
|
||||
- Updated package dependencies. [#29854]
|
||||
|
||||
## [2.9.2] - 2023-04-03
|
||||
### Changed
|
||||
- Internal updates.
|
||||
|
||||
## [2.9.1] - 2023-03-28
|
||||
### Changed
|
||||
- Move GoldenTokenModal component to licensing package. [#29748]
|
||||
@ -781,6 +1069,47 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Added
|
||||
- Created package
|
||||
|
||||
[3.9.1]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.9.0...3.9.1
|
||||
[3.9.0]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.8.2...3.9.0
|
||||
[3.8.2]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.8.1...3.8.2
|
||||
[3.8.1]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.8.0...3.8.1
|
||||
[3.8.0]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.7.0...3.8.0
|
||||
[3.7.0]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.6.0...3.7.0
|
||||
[3.6.0]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.5.0...3.6.0
|
||||
[3.5.0]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.4.5...3.5.0
|
||||
[3.4.5]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.4.4...3.4.5
|
||||
[3.4.4]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.4.3...3.4.4
|
||||
[3.4.3]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.4.2...3.4.3
|
||||
[3.4.2]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.4.1...3.4.2
|
||||
[3.4.1]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.4.0...3.4.1
|
||||
[3.4.0]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.3.3...3.4.0
|
||||
[3.3.3]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.3.2...3.3.3
|
||||
[3.3.2]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.3.1...3.3.2
|
||||
[3.3.1]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.3.0...3.3.1
|
||||
[3.3.0]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.2.1...3.3.0
|
||||
[3.2.1]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.2.0...3.2.1
|
||||
[3.2.0]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.1.3...3.2.0
|
||||
[3.1.3]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.1.2...3.1.3
|
||||
[3.1.2]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.1.1...3.1.2
|
||||
[3.1.1]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.1.0...3.1.1
|
||||
[3.1.0]: https://github.com/Automattic/jetpack-my-jetpack/compare/3.0.0...3.1.0
|
||||
[3.0.0]: https://github.com/Automattic/jetpack-my-jetpack/compare/2.15.0...3.0.0
|
||||
[2.15.0]: https://github.com/Automattic/jetpack-my-jetpack/compare/2.14.3...2.15.0
|
||||
[2.14.3]: https://github.com/Automattic/jetpack-my-jetpack/compare/2.14.2...2.14.3
|
||||
[2.14.2]: https://github.com/Automattic/jetpack-my-jetpack/compare/2.14.1...2.14.2
|
||||
[2.14.1]: https://github.com/Automattic/jetpack-my-jetpack/compare/2.14.0...2.14.1
|
||||
[2.14.0]: https://github.com/Automattic/jetpack-my-jetpack/compare/2.13.0...2.14.0
|
||||
[2.13.0]: https://github.com/Automattic/jetpack-my-jetpack/compare/2.12.2...2.13.0
|
||||
[2.12.2]: https://github.com/Automattic/jetpack-my-jetpack/compare/2.12.1...2.12.2
|
||||
[2.12.1]: https://github.com/Automattic/jetpack-my-jetpack/compare/2.12.0...2.12.1
|
||||
[2.12.0]: https://github.com/Automattic/jetpack-my-jetpack/compare/2.11.0...2.12.0
|
||||
[2.11.0]: https://github.com/Automattic/jetpack-my-jetpack/compare/2.10.3...2.11.0
|
||||
[2.10.3]: https://github.com/Automattic/jetpack-my-jetpack/compare/2.10.2...2.10.3
|
||||
[2.10.2]: https://github.com/Automattic/jetpack-my-jetpack/compare/2.10.1...2.10.2
|
||||
[2.10.1]: https://github.com/Automattic/jetpack-my-jetpack/compare/2.10.0...2.10.1
|
||||
[2.10.0]: https://github.com/Automattic/jetpack-my-jetpack/compare/2.9.2...2.10.0
|
||||
[2.9.2]: https://github.com/Automattic/jetpack-my-jetpack/compare/2.9.1...2.9.2
|
||||
[2.9.1]: https://github.com/Automattic/jetpack-my-jetpack/compare/2.9.0...2.9.1
|
||||
[2.9.0]: https://github.com/Automattic/jetpack-my-jetpack/compare/2.8.1...2.9.0
|
||||
[2.8.1]: https://github.com/Automattic/jetpack-my-jetpack/compare/2.8.0...2.8.1
|
||||
[2.8.0]: https://github.com/Automattic/jetpack-my-jetpack/compare/2.7.13...2.8.0
|
||||
|
@ -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.**
|
||||
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 55 KiB |
@ -1 +1 @@
|
||||
<?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-data', 'wp-date', 'wp-element', 'wp-i18n', 'wp-polyfill', 'wp-primitives', 'wp-url'), 'version' => '9fc14b80f5a467303947');
|
||||
<?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-data', 'wp-date', 'wp-element', 'wp-i18n', 'wp-polyfill', 'wp-primitives', 'wp-url'), 'version' => '86d713f826cd96de9db1');
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -7,9 +7,9 @@
|
||||
*/
|
||||
|
||||
/*!
|
||||
Copyright (c) 2018 Jed Watson.
|
||||
Licensed under the MIT License (MIT), see
|
||||
http://jedwatson.github.io/classnames
|
||||
Copyright (c) 2018 Jed Watson.
|
||||
Licensed under the MIT License (MIT), see
|
||||
http://jedwatson.github.io/classnames
|
||||
*/
|
||||
|
||||
/**
|
||||
|
File diff suppressed because one or more lines are too long
@ -4,20 +4,23 @@
|
||||
"type": "jetpack-library",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"automattic/jetpack-admin-ui": "^0.2.17",
|
||||
"automattic/jetpack-assets": "^1.17.34",
|
||||
"automattic/jetpack-connection": "^1.51.4",
|
||||
"automattic/jetpack-jitm": "^2.3.4",
|
||||
"automattic/jetpack-licensing": "^1.8.1",
|
||||
"automattic/jetpack-plugins-installer": "^0.2.3",
|
||||
"automattic/jetpack-redirect": "^1.7.24",
|
||||
"automattic/jetpack-constants": "^1.6.21"
|
||||
"automattic/jetpack-admin-ui": "^0.2.23",
|
||||
"automattic/jetpack-assets": "^1.18.13",
|
||||
"automattic/jetpack-connection": "^1.58.2",
|
||||
"automattic/jetpack-jitm": "^2.5.1",
|
||||
"automattic/jetpack-licensing": "^1.8.4",
|
||||
"automattic/jetpack-plugins-installer": "^0.2.5",
|
||||
"automattic/jetpack-redirect": "^1.7.27",
|
||||
"automattic/jetpack-constants": "^1.6.23"
|
||||
},
|
||||
"require-dev": {
|
||||
"yoast/phpunit-polyfills": "1.0.4",
|
||||
"automattic/jetpack-changelogger": "^3.3.2",
|
||||
"yoast/phpunit-polyfills": "1.1.0",
|
||||
"automattic/jetpack-changelogger": "^3.3.11",
|
||||
"automattic/wordbless": "@dev",
|
||||
"automattic/jetpack-videopress": "^0.13.4-alpha"
|
||||
"automattic/jetpack-videopress": "^0.18.0"
|
||||
},
|
||||
"suggest": {
|
||||
"automattic/jetpack-autoloader": "Allow for better interoperability with other plugins that use this package."
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
@ -62,7 +65,7 @@
|
||||
"link-template": "https://github.com/Automattic/jetpack-my-jetpack/compare/${old}...${new}"
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-trunk": "2.9.x-dev"
|
||||
"dev-trunk": "3.9.x-dev"
|
||||
},
|
||||
"version-constants": {
|
||||
"::PACKAGE_VERSION": "src/class-initializer.php"
|
||||
|
@ -9,14 +9,16 @@ namespace Automattic\Jetpack\My_Jetpack;
|
||||
|
||||
use Automattic\Jetpack\Admin_UI\Admin_Menu;
|
||||
use Automattic\Jetpack\Assets;
|
||||
use Automattic\Jetpack\Connection\Client as Client;
|
||||
use Automattic\Jetpack\Connection\Client;
|
||||
use Automattic\Jetpack\Connection\Initial_State as Connection_Initial_State;
|
||||
use Automattic\Jetpack\Connection\Manager as Connection_Manager;
|
||||
use Automattic\Jetpack\Connection\Rest_Authentication as Connection_Rest_Authentication;
|
||||
use Automattic\Jetpack\JITMS\JITM as JITM;
|
||||
use Automattic\Jetpack\Constants as Jetpack_Constants;
|
||||
use Automattic\Jetpack\JITMS\JITM;
|
||||
use Automattic\Jetpack\Licensing;
|
||||
use Automattic\Jetpack\Modules;
|
||||
use Automattic\Jetpack\Plugins_Installer;
|
||||
use Automattic\Jetpack\Status as Status;
|
||||
use Automattic\Jetpack\Status;
|
||||
use Automattic\Jetpack\Terms_Of_Service;
|
||||
use Automattic\Jetpack\Tracking;
|
||||
|
||||
@ -30,7 +32,12 @@ class Initializer {
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const PACKAGE_VERSION = '2.9.1';
|
||||
const PACKAGE_VERSION = '3.9.1';
|
||||
|
||||
/**
|
||||
* HTML container ID for the IDC screen on My Jetpack page.
|
||||
*/
|
||||
const IDC_CONTAINER_ID = 'my-jetpack-identity-crisis-container';
|
||||
|
||||
/**
|
||||
* Initialize My Jetpack
|
||||
@ -58,10 +65,10 @@ class Initializer {
|
||||
$page_suffix = Admin_Menu::add_menu(
|
||||
__( 'My Jetpack', 'jetpack-my-jetpack' ),
|
||||
__( 'My Jetpack', 'jetpack-my-jetpack' ),
|
||||
'manage_options',
|
||||
'edit_posts',
|
||||
'my-jetpack',
|
||||
array( __CLASS__, 'admin_page' ),
|
||||
999
|
||||
-1
|
||||
);
|
||||
|
||||
add_action( 'load-' . $page_suffix, array( __CLASS__, 'admin_init' ) );
|
||||
@ -116,6 +123,7 @@ class Initializer {
|
||||
* @return void
|
||||
*/
|
||||
public static function admin_init() {
|
||||
add_filter( 'identity_crisis_container_id', array( static::class, 'get_idc_container_id' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) );
|
||||
// Product statuses are constantly changing, so we never want to cache the page.
|
||||
header( 'Cache-Control: no-cache, no-store, must-revalidate' );
|
||||
@ -150,6 +158,7 @@ class Initializer {
|
||||
'textdomain' => 'jetpack-my-jetpack',
|
||||
)
|
||||
);
|
||||
$modules = new Modules();
|
||||
wp_localize_script(
|
||||
'my_jetpack_main_app',
|
||||
'myJetpackInitialState',
|
||||
@ -165,9 +174,13 @@ class Initializer {
|
||||
'topJetpackMenuItemUrl' => Admin_Menu::get_top_level_menu_item_url(),
|
||||
'siteSuffix' => ( new Status() )->get_site_suffix(),
|
||||
'myJetpackVersion' => self::PACKAGE_VERSION,
|
||||
'myJetpackFlags' => self::get_my_jetpack_flags(),
|
||||
'fileSystemWriteAccess' => self::has_file_system_write_access(),
|
||||
'loadAddLicenseScreen' => self::is_licensing_ui_enabled(),
|
||||
'adminUrl' => esc_url( admin_url() ),
|
||||
'IDCContainerID' => static::get_idc_container_id(),
|
||||
'userIsAdmin' => current_user_can( 'manage_options' ),
|
||||
'isStatsModuleActive' => $modules->is_active( 'stats' ),
|
||||
)
|
||||
);
|
||||
|
||||
@ -181,7 +194,7 @@ class Initializer {
|
||||
);
|
||||
|
||||
// Connection Initial State.
|
||||
wp_add_inline_script( 'my_jetpack_main_app', Connection_Initial_State::render(), 'before' );
|
||||
Connection_Initial_State::render_script( 'my_jetpack_main_app' );
|
||||
|
||||
// Required for Analytics.
|
||||
if ( self::can_use_analytics() ) {
|
||||
@ -189,6 +202,20 @@ class Initializer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build flags for My Jetpack UI
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_my_jetpack_flags() {
|
||||
$flags = array(
|
||||
'videoPressStats' => Jetpack_Constants::is_true( 'JETPACK_MY_JETPACK_VIDEOPRESS_STATS_ENABLED' ),
|
||||
'showJetpackStatsCard' => class_exists( 'Jetpack' ),
|
||||
);
|
||||
|
||||
return $flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Echoes the admin page content.
|
||||
*
|
||||
@ -206,6 +233,9 @@ class Initializer {
|
||||
public static function register_rest_endpoints() {
|
||||
new REST_Products();
|
||||
new REST_Purchases();
|
||||
new REST_Zendesk_Chat();
|
||||
new REST_Product_Data();
|
||||
new REST_AI();
|
||||
|
||||
register_rest_route(
|
||||
'my-jetpack/v1',
|
||||
@ -311,4 +341,12 @@ class Initializer {
|
||||
return $write_access;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get container IDC for the IDC screen.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_idc_container_id() {
|
||||
return static::IDC_CONTAINER_ID;
|
||||
}
|
||||
}
|
||||
|
@ -27,12 +27,14 @@ class Products {
|
||||
'boost' => Products\Boost::class,
|
||||
'crm' => Products\Crm::class,
|
||||
'extras' => Products\Extras::class,
|
||||
'jetpack-ai' => Products\Jetpack_Ai::class,
|
||||
'scan' => Products\Scan::class,
|
||||
'search' => Products\Search::class,
|
||||
'social' => Products\Social::class,
|
||||
'security' => Products\Security::class,
|
||||
'protect' => Products\Protect::class,
|
||||
'videopress' => Products\Videopress::class,
|
||||
'stats' => Products\Stats::class,
|
||||
);
|
||||
|
||||
/**
|
||||
@ -178,5 +180,4 @@ class Products {
|
||||
$class_name::extend_plugin_action_links();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/**
|
||||
* Sets up the AI REST API endpoints.
|
||||
*
|
||||
* @package automattic/my-jetpack
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\My_Jetpack;
|
||||
|
||||
use Automattic\Jetpack\Connection\Client;
|
||||
use Automattic\Jetpack\Connection\Manager as Connection_Manager;
|
||||
use Jetpack_Options;
|
||||
use WP_Error;
|
||||
|
||||
/**
|
||||
* Registers the REST routes for AI.
|
||||
*/
|
||||
class REST_AI {
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
/*
|
||||
* Check if the `jetpack/v4/jetpack-ai-jwt` endpoint is registered
|
||||
* by the Jetpack plugin to avoid registering it again.
|
||||
* In case it's not registered, register it
|
||||
* to make it available for Jetpack products that depend on it.
|
||||
*/
|
||||
if ( ! self::is_rest_endpoint_registered( 'jetpack/v4', '/jetpack-ai-jwt' ) ) {
|
||||
register_rest_route(
|
||||
'jetpack/v4',
|
||||
'jetpack-ai-jwt',
|
||||
array(
|
||||
'methods' => \WP_REST_Server::EDITABLE,
|
||||
'callback' => __CLASS__ . '::get_openai_jwt',
|
||||
'permission_callback' => function () {
|
||||
return ( new Connection_Manager( 'jetpack' ) )->is_user_connected() && current_user_can( 'edit_posts' );
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a specific REST endpoint is registered.
|
||||
*
|
||||
* @param string $namespace - The namespace of the endpoint.
|
||||
* @param string $route - The route of the endpoint.
|
||||
* @return bool True if the endpoint is registered, false otherwise.
|
||||
*/
|
||||
public static function is_rest_endpoint_registered( $namespace, $route ) {
|
||||
$server = rest_get_server();
|
||||
$routes = $server->get_routes();
|
||||
$full_endpoint = '/' . trim( $namespace, '/' ) . $route;
|
||||
return isset( $routes[ $full_endpoint ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask WPCOM for a JWT token to use for OpenAI completion.
|
||||
*/
|
||||
public static function get_openai_jwt() {
|
||||
$blog_id = Jetpack_Options::get_option( 'id' );
|
||||
|
||||
$response = Client::wpcom_json_api_request_as_user(
|
||||
"/sites/$blog_id/jetpack-openai-query/jwt",
|
||||
'2',
|
||||
array(
|
||||
'method' => 'POST',
|
||||
'headers' => array( 'Content-Type' => 'application/json; charset=utf-8' ),
|
||||
),
|
||||
wp_json_encode( array() ),
|
||||
'wpcom'
|
||||
);
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$json = json_decode( wp_remote_retrieve_body( $response ) );
|
||||
|
||||
if ( ! isset( $json->token ) ) {
|
||||
return new WP_Error( 'no-token', 'No token returned from WPCOM' );
|
||||
}
|
||||
|
||||
return array(
|
||||
'token' => $json->token,
|
||||
'blog_id' => $blog_id,
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**
|
||||
* Sets up the Product Data REST API endpoints.
|
||||
*
|
||||
* @package automattic/my-jetpack
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\My_Jetpack;
|
||||
|
||||
use Automattic\Jetpack\Connection\Client;
|
||||
use WP_Error;
|
||||
|
||||
/**
|
||||
* Registers the REST routes for Product Data
|
||||
*/
|
||||
class REST_Product_Data {
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
register_rest_route(
|
||||
'my-jetpack/v1',
|
||||
'site/product-data',
|
||||
array(
|
||||
'methods' => \WP_REST_Server::READABLE,
|
||||
'callback' => __CLASS__ . '::get_all_product_data',
|
||||
'permission_callback' => __CLASS__ . '::permissions_callback',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the user has the correct permissions
|
||||
*/
|
||||
public static function permissions_callback() {
|
||||
return current_user_can( 'manage_options' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the product data for all products
|
||||
*
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
public static function get_all_product_data() {
|
||||
$site_id = \Jetpack_Options::get_option( 'id' );
|
||||
$wpcom_endpoint = sprintf( 'sites/%d/jetpack-product-data?locale=%2$s&force=wpcom', $site_id, get_user_locale() );
|
||||
$api_version = '2';
|
||||
$response = Client::wpcom_json_api_request_as_blog( $wpcom_endpoint, $api_version, array(), null, 'wpcom' );
|
||||
$response_code = wp_remote_retrieve_response_code( $response );
|
||||
$body = json_decode( wp_remote_retrieve_body( $response ) );
|
||||
|
||||
if ( is_wp_error( $response ) || empty( $response['body'] ) || 200 !== $response_code ) {
|
||||
return new WP_Error( 'site_products_data_fetch_failed', 'Site products data fetch failed', array( 'status' => $response_code ? $response_code : 400 ) );
|
||||
}
|
||||
|
||||
return rest_ensure_response( $body, 200 );
|
||||
}
|
||||
}
|
@ -68,6 +68,21 @@ class REST_Products {
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
register_rest_route(
|
||||
'my-jetpack/v1',
|
||||
'site/products/(?P<product>[a-z\-]+)/install-standalone',
|
||||
array(
|
||||
array(
|
||||
'methods' => \WP_REST_Server::EDITABLE,
|
||||
'callback' => __CLASS__ . '::install_standalone',
|
||||
'permission_callback' => __CLASS__ . '::edit_permissions_callback',
|
||||
'args' => array(
|
||||
'product' => $product_arg,
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -205,4 +220,40 @@ class REST_Products {
|
||||
return rest_ensure_response( Products::get_product( $product_slug ), 200 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for installing the standalone plugin on a Hybrid Product.
|
||||
*
|
||||
* @param \WP_REST_Request $request The request object.
|
||||
* @return \WP_REST_Response
|
||||
*/
|
||||
public static function install_standalone( $request ) {
|
||||
$product_slug = $request->get_param( 'product' );
|
||||
$product = Products::get_product( $product_slug );
|
||||
if ( ! isset( $product['class'] ) ) {
|
||||
return new \WP_Error(
|
||||
'not_implemented',
|
||||
__( 'The product class handler is not implemented', 'jetpack-my-jetpack' ),
|
||||
array( 'status' => 501 )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the product is not hybrid, there is no need to deal with a standalone plugin.
|
||||
*/
|
||||
if ( ! is_subclass_of( $product['class'], Hybrid_Product::class ) ) {
|
||||
return new \WP_Error(
|
||||
'not_hybrid',
|
||||
__( 'This product does not have a standalone plugin to install', 'jetpack-my-jetpack' ),
|
||||
array( 'status' => 400 )
|
||||
);
|
||||
}
|
||||
|
||||
$install_product_result = call_user_func( array( $product['class'], 'install_and_activate_standalone' ) );
|
||||
if ( is_wp_error( $install_product_result ) ) {
|
||||
$install_product_result->add_data( array( 'status' => 400 ) );
|
||||
return $install_product_result;
|
||||
}
|
||||
|
||||
return rest_ensure_response( Products::get_product( $product_slug ), 200 );
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
namespace Automattic\Jetpack\My_Jetpack;
|
||||
|
||||
use Automattic\Jetpack\Connection\Client as Client;
|
||||
use Automattic\Jetpack\Connection\Client;
|
||||
use Automattic\Jetpack\Connection\Manager as Connection_Manager;
|
||||
|
||||
/**
|
||||
@ -51,7 +51,7 @@ class REST_Purchases {
|
||||
);
|
||||
}
|
||||
|
||||
return current_user_can( 'manage_options' );
|
||||
return current_user_can( 'edit_posts' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,120 @@
|
||||
<?php
|
||||
/**
|
||||
* Sets up the Zendesk Chat REST API endpoints.
|
||||
*
|
||||
* @package automattic/my-jetpack
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\My_Jetpack;
|
||||
|
||||
use Automattic\Jetpack\Connection\Client;
|
||||
|
||||
/**
|
||||
* Registers the REST routes for Zendesk Chat.
|
||||
*/
|
||||
class REST_Zendesk_Chat {
|
||||
const TRANSIENT_EXPIRY = 1 * MINUTE_IN_SECONDS * 60 * 24 * 7; // 1 week (JWT is actually 2 weeks, but lets be on the safe side)
|
||||
const ZENDESK_AUTH_TOKEN = 'zendesk_auth_token';
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
register_rest_route(
|
||||
'my-jetpack/v1',
|
||||
'chat/availability',
|
||||
array(
|
||||
'methods' => \WP_REST_Server::READABLE,
|
||||
'callback' => __CLASS__ . '::get_chat_availability',
|
||||
'permission_callback' => __CLASS__ . '::chat_authentication_permissions_callback',
|
||||
)
|
||||
);
|
||||
|
||||
register_rest_route(
|
||||
'my-jetpack/v1',
|
||||
'chat/authentication',
|
||||
array(
|
||||
'methods' => \WP_REST_Server::READABLE,
|
||||
'callback' => __CLASS__ . '::get_chat_authentication',
|
||||
'args' => array(
|
||||
'type' => array(
|
||||
'required' => false,
|
||||
'type' => 'string',
|
||||
),
|
||||
'test_mode' => array(
|
||||
'required' => false,
|
||||
'type' => 'boolean',
|
||||
),
|
||||
),
|
||||
'permission_callback' => __CLASS__ . '::chat_authentication_permissions_callback',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure user is logged in if making an authentication request
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return \WP_Error|true
|
||||
*/
|
||||
public static function chat_authentication_permissions_callback() {
|
||||
if ( ! get_current_user_id() ) {
|
||||
return new \WP_Error( 'unauthorized', 'You must be logged in to access this resource.', array( 'status' => 401 ) );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the chat authentication token.
|
||||
*
|
||||
* @return \WP_Error|object Object: { token: string }
|
||||
*/
|
||||
public static function get_chat_authentication() {
|
||||
$authentication = get_transient( self::ZENDESK_AUTH_TOKEN );
|
||||
if ( $authentication ) {
|
||||
return rest_ensure_response( $authentication, 200 );
|
||||
}
|
||||
|
||||
$proxied = function_exists( 'wpcom_is_proxied_request' ) ? wpcom_is_proxied_request() : false;
|
||||
$wpcom_endpoint = 'help/authenticate/chat';
|
||||
$wpcom_api_version = '2';
|
||||
|
||||
$body = array(
|
||||
'type' => 'zendesk',
|
||||
'test_mode' => $proxied ? true : false,
|
||||
);
|
||||
|
||||
$response = Client::wpcom_json_api_request_as_user( $wpcom_endpoint, $wpcom_api_version, array( 'method' => 'POST' ), $body );
|
||||
$response_code = wp_remote_retrieve_response_code( $response );
|
||||
$body = json_decode( wp_remote_retrieve_body( $response ) );
|
||||
|
||||
if ( is_wp_error( $response ) || empty( $response['body'] ) ) {
|
||||
return new \WP_Error( 'chat_authentication_failed', 'Chat authentication failed', array( 'status' => $response_code ) );
|
||||
}
|
||||
|
||||
set_transient( self::ZENDESK_AUTH_TOKEN, $body, self::TRANSIENT_EXPIRY );
|
||||
return rest_ensure_response( $body, 200 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls `wpcom/v2/presales/chat?group=jp_presales` endpoint.
|
||||
* This endpoint returns whether or not the Jetpack presales chat group is available
|
||||
*
|
||||
* @return \WP_Error/object Object: { is_available: bool }
|
||||
*/
|
||||
public static function get_chat_availability() {
|
||||
$wpcom_endpoint = '/presales/chat?group=jp_presales';
|
||||
$wpcom_api_version = '2';
|
||||
$response = Client::wpcom_json_api_request_as_user( $wpcom_endpoint, $wpcom_api_version );
|
||||
$response_code = wp_remote_retrieve_response_code( $response );
|
||||
$body = json_decode( wp_remote_retrieve_body( $response ) );
|
||||
|
||||
if ( is_wp_error( $response ) || empty( $response['body'] ) ) {
|
||||
return new \WP_Error( 'chat_config_data_fetch_failed', 'Chat config data fetch failed', array( 'status' => $response_code ) );
|
||||
}
|
||||
|
||||
return rest_ensure_response( $body, 200 );
|
||||
}
|
||||
}
|
@ -7,8 +7,9 @@
|
||||
|
||||
namespace Automattic\Jetpack\My_Jetpack;
|
||||
|
||||
use Automattic\Jetpack\Connection\Client as Client;
|
||||
use Automattic\Jetpack\Connection\Client;
|
||||
use Automattic\Jetpack\Status\Visitor;
|
||||
use Jetpack_Options;
|
||||
use WP_Error;
|
||||
/**
|
||||
* Stores the list of products available for purchase in WPCOM
|
||||
@ -189,6 +190,7 @@ class Wpcom_Products {
|
||||
'discount_price' => $discount_price,
|
||||
'is_introductory_offer' => $is_introductory_offer,
|
||||
'introductory_offer' => $introductory_offer,
|
||||
'product_term' => $product->product_term,
|
||||
);
|
||||
|
||||
return self::populate_with_discount( $product, $pricing, $discount_price );
|
||||
@ -226,4 +228,37 @@ class Wpcom_Products {
|
||||
|
||||
return $pricing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the site purchases from WPCOM.
|
||||
*
|
||||
* @todo Maybe add caching.
|
||||
*
|
||||
* @return Object|WP_Error
|
||||
*/
|
||||
public static function get_site_current_purchases() {
|
||||
// TODO: Add a short-lived cache (less than a minute) to accommodate repeated invocation of this function.
|
||||
static $purchases = null;
|
||||
|
||||
if ( $purchases !== null ) {
|
||||
return $purchases;
|
||||
}
|
||||
|
||||
$site_id = Jetpack_Options::get_option( 'id' );
|
||||
|
||||
$response = Client::wpcom_json_api_request_as_blog(
|
||||
sprintf( '/sites/%d/purchases', $site_id ),
|
||||
'1.1',
|
||||
array(
|
||||
'method' => 'GET',
|
||||
)
|
||||
);
|
||||
if ( 200 !== wp_remote_retrieve_response_code( $response ) ) {
|
||||
return new WP_Error( 'purchases_state_fetch_failed' );
|
||||
}
|
||||
|
||||
$body = wp_remote_retrieve_body( $response );
|
||||
$purchases = json_decode( $body );
|
||||
return $purchases;
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +87,6 @@ class Anti_Spam extends Product {
|
||||
public static function get_features() {
|
||||
return array(
|
||||
_x( 'Comment and form spam protection', 'Anti-Spam Product Feature', 'jetpack-my-jetpack' ),
|
||||
_x( 'Powered by Akismet', 'Anti-Spam Product Feature', 'jetpack-my-jetpack' ),
|
||||
_x( 'Block spam without CAPTCHAs', 'Anti-Spam Product Feature', 'jetpack-my-jetpack' ),
|
||||
_x( 'Advanced stats', 'Anti-Spam Product Feature', 'jetpack-my-jetpack' ),
|
||||
);
|
||||
|
@ -8,7 +8,7 @@
|
||||
namespace Automattic\Jetpack\My_Jetpack\Products;
|
||||
|
||||
use Automattic\Jetpack\Connection\Client;
|
||||
use Automattic\Jetpack\My_Jetpack\Product;
|
||||
use Automattic\Jetpack\My_Jetpack\Hybrid_Product;
|
||||
use Automattic\Jetpack\My_Jetpack\Wpcom_Products;
|
||||
use Automattic\Jetpack\Redirect;
|
||||
use Jetpack_Options;
|
||||
@ -17,7 +17,7 @@ use WP_Error;
|
||||
/**
|
||||
* Class responsible for handling the Backup product
|
||||
*/
|
||||
class Backup extends Product {
|
||||
class Backup extends Hybrid_Product {
|
||||
|
||||
/**
|
||||
* The product slug
|
||||
@ -44,6 +44,13 @@ class Backup extends Product {
|
||||
*/
|
||||
public static $plugin_slug = 'jetpack-backup';
|
||||
|
||||
/**
|
||||
* Backup has a standalone plugin
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public static $has_standalone_plugin = true;
|
||||
|
||||
/**
|
||||
* Get the internationalized product name
|
||||
*
|
||||
@ -198,7 +205,9 @@ class Backup extends Product {
|
||||
* @return ?string
|
||||
*/
|
||||
public static function get_manage_url() {
|
||||
if ( static::is_plugin_active() ) {
|
||||
if ( static::is_jetpack_plugin_active() ) {
|
||||
return Redirect::get_url( 'my-jetpack-manage-backup' );
|
||||
} elseif ( static::is_plugin_active() ) {
|
||||
return admin_url( 'admin.php?page=jetpack-backup' );
|
||||
}
|
||||
}
|
||||
@ -211,4 +220,15 @@ class Backup extends Product {
|
||||
public static function is_active() {
|
||||
return parent::is_active() && static::has_required_plan();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL where the user should be redirected after checkout
|
||||
*/
|
||||
public static function get_post_checkout_url() {
|
||||
if ( static::is_jetpack_plugin_active() ) {
|
||||
return admin_url( 'admin.php?page=jetpack#/recommendations' );
|
||||
} elseif ( static::is_plugin_active() ) {
|
||||
return admin_url( 'admin.php?page=jetpack-backup' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,12 +8,17 @@
|
||||
namespace Automattic\Jetpack\My_Jetpack\Products;
|
||||
|
||||
use Automattic\Jetpack\My_Jetpack\Product;
|
||||
use Automattic\Jetpack\My_Jetpack\Wpcom_Products;
|
||||
|
||||
/**
|
||||
* Class responsible for handling the Boost product
|
||||
*/
|
||||
class Boost extends Product {
|
||||
|
||||
const FREE_TIER_SLUG = 'free';
|
||||
const UPGRADED_TIER_SLUG = 'upgraded';
|
||||
const UPGRADED_TIER_PRODUCT_SLUG = 'jetpack_boost_yearly';
|
||||
|
||||
/**
|
||||
* The product slug
|
||||
*
|
||||
@ -69,7 +74,7 @@ class Boost extends Product {
|
||||
* @return string
|
||||
*/
|
||||
public static function get_description() {
|
||||
return __( 'Instant speed and SEO', 'jetpack-my-jetpack' );
|
||||
return __( 'The easiest speed optimization plugin for WordPress', 'jetpack-my-jetpack' );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -94,6 +99,144 @@ class Boost extends Product {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the product's available tiers
|
||||
*
|
||||
* @return string[] Slugs of the available tiers
|
||||
*/
|
||||
public static function get_tiers() {
|
||||
return array(
|
||||
self::UPGRADED_TIER_SLUG,
|
||||
self::FREE_TIER_SLUG,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the internationalized comparison of free vs upgraded features
|
||||
*
|
||||
* @return array[] Protect features comparison
|
||||
*/
|
||||
public static function get_features_by_tier() {
|
||||
return array(
|
||||
array(
|
||||
'name' => __( 'Optimize CSS Loading', 'jetpack-my-jetpack' ),
|
||||
'info' => array(
|
||||
'content' => __(
|
||||
'Move important styling information to the start of the page, which helps pages display your content sooner, so your users don’t have to wait for the entire page to load. Commonly referred to as Critical CSS.',
|
||||
'jetpack-my-jetpack'
|
||||
),
|
||||
),
|
||||
'tiers' => array(
|
||||
self::FREE_TIER_SLUG => array(
|
||||
'included' => true,
|
||||
'description' => __( 'Must be done manually', 'jetpack-my-jetpack' ),
|
||||
'info' => array(
|
||||
'title' => __( 'Manual Critical CSS regeneration', 'jetpack-my-jetpack' ),
|
||||
'content' => __(
|
||||
'<p>To enhance the speed of your site, with this plan you will need to optimize CSS by using the Manual Critical CSS generation feature whenever you:</p>
|
||||
<ul>
|
||||
<li>Make theme changes.</li>
|
||||
<li>Write a new post/page.</li>
|
||||
<li>Edit a post/page.</li>
|
||||
<li>Activate, deactivate, or update plugins that impact your site layout or HTML structure.</li>
|
||||
<li>Change settings of plugins that impact your site layout or HTML structure.</li>
|
||||
<li>Upgrade your WordPress version if the new release includes core CSS changes.</li>
|
||||
</ul>',
|
||||
'jetpack-my-jetpack'
|
||||
),
|
||||
),
|
||||
),
|
||||
self::UPGRADED_TIER_SLUG => array(
|
||||
'included' => true,
|
||||
'description' => __( 'Automatically updated', 'jetpack-my-jetpack' ),
|
||||
'info' => array(
|
||||
'title' => __( 'Automatic Critical CSS regeneration', 'jetpack-my-jetpack' ),
|
||||
'content' => __(
|
||||
'<p>It’s essential to regenerate Critical CSS to optimize your site speed whenever your HTML or CSS structure changes. Being on top of this can be tedious and time-consuming.</p>
|
||||
<p>Boost’s cloud service can automatically detect when your site needs the Critical CSS regenerated, and perform this function behind the scenes without requiring you to monitor it manually.</p>',
|
||||
'jetpack-my-jetpack'
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => __( 'Defer non-essential JavaScript', 'jetpack-my-jetpack' ),
|
||||
'info' => array(
|
||||
'content' => __(
|
||||
'Run non-essential JavaScript after the page has loaded so that styles and images can load more quickly.',
|
||||
'jetpack-my-jetpack'
|
||||
),
|
||||
'link' => array(
|
||||
'id' => 'jetpack-boost-defer-js',
|
||||
'title' => 'web.dev',
|
||||
),
|
||||
),
|
||||
'tiers' => array(
|
||||
self::FREE_TIER_SLUG => array( 'included' => true ),
|
||||
self::UPGRADED_TIER_SLUG => array( 'included' => true ),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => __( 'Lazy image loading', 'jetpack-my-jetpack' ),
|
||||
'info' => array(
|
||||
'content' => __(
|
||||
'Improve page loading speed by only loading images when they are required.',
|
||||
'jetpack-my-jetpack'
|
||||
),
|
||||
'link' => array(
|
||||
'id' => 'jetpack-boost-lazy-load',
|
||||
'title' => 'web.dev',
|
||||
),
|
||||
),
|
||||
'tiers' => array(
|
||||
self::FREE_TIER_SLUG => array( 'included' => true ),
|
||||
self::UPGRADED_TIER_SLUG => array( 'included' => true ),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => __( 'Image guide', 'jetpack-my-jetpack' ),
|
||||
'info' => array(
|
||||
'content' => __(
|
||||
'Discover and fix images with a suboptimal resolution, aspect ratio, or file size, improving user experience and page speed.',
|
||||
'jetpack-my-jetpack'
|
||||
),
|
||||
),
|
||||
'tiers' => array(
|
||||
self::FREE_TIER_SLUG => array( 'included' => true ),
|
||||
self::UPGRADED_TIER_SLUG => array( 'included' => true ),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => __( 'Image CDN', 'jetpack-my-jetpack' ),
|
||||
'info' => array(
|
||||
'content' => __(
|
||||
'Deliver images from Jetpack\'s Content Delivery Network. Automatically resizes your images to an appropriate size, converts them to modern efficient formats like WebP, and serves them from a worldwide network of servers.',
|
||||
'jetpack-my-jetpack'
|
||||
),
|
||||
),
|
||||
'tiers' => array(
|
||||
self::FREE_TIER_SLUG => array( 'included' => true ),
|
||||
self::UPGRADED_TIER_SLUG => array( 'included' => true ),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => __( 'Dedicated email support', 'jetpack-my-jetpack' ),
|
||||
'info' => array(
|
||||
'content' => __(
|
||||
'<p>Paid customers get dedicated email support from our world-class Happiness Engineers to help with any issue.</p>
|
||||
<p>All other questions are handled by our team as quickly as we are able to go through the WordPress support forum.</p>',
|
||||
'jetpack-my-jetpack'
|
||||
),
|
||||
),
|
||||
'tiers' => array(
|
||||
self::FREE_TIER_SLUG => array( 'included' => false ),
|
||||
self::UPGRADED_TIER_SLUG => array( 'included' => true ),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the product princing details
|
||||
*
|
||||
@ -101,8 +244,19 @@ class Boost extends Product {
|
||||
*/
|
||||
public static function get_pricing_for_ui() {
|
||||
return array(
|
||||
'available' => true,
|
||||
'is_free' => true,
|
||||
'tiers' => array(
|
||||
self::FREE_TIER_SLUG => array(
|
||||
'available' => true,
|
||||
'is_free' => true,
|
||||
),
|
||||
self::UPGRADED_TIER_SLUG => array_merge(
|
||||
array(
|
||||
'available' => true,
|
||||
'wpcom_product_slug' => self::UPGRADED_TIER_PRODUCT_SLUG,
|
||||
),
|
||||
Wpcom_Products::get_product_pricing( self::UPGRADED_TIER_PRODUCT_SLUG )
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -114,4 +268,25 @@ class Boost extends Product {
|
||||
public static function get_manage_url() {
|
||||
return admin_url( 'admin.php?page=jetpack-boost' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Activates the product by installing and activating its plugin
|
||||
*
|
||||
* @param bool|WP_Error $current_result Is the result of the top level activation actions. You probably won't do anything if it is an WP_Error.
|
||||
* @return boolean|\WP_Error
|
||||
*/
|
||||
public static function do_product_specific_activation( $current_result ) {
|
||||
|
||||
$product_activation = parent::do_product_specific_activation( $current_result );
|
||||
|
||||
if ( is_wp_error( $product_activation ) && 'module_activation_failed' === $product_activation->get_error_code() ) {
|
||||
// A bundle is not a module. There's nothing in the plugin to be activated, so it's ok to fail to activate the module.
|
||||
$product_activation = true;
|
||||
}
|
||||
|
||||
// We just "got started" in My Jetpack, so skip the in-plugin experience.
|
||||
update_option( 'jb_get_started', false );
|
||||
|
||||
return $product_activation;
|
||||
}
|
||||
}
|
||||
|
@ -12,13 +12,6 @@ use Automattic\Jetpack\Plugins_Installer;
|
||||
use WP_Error;
|
||||
|
||||
/**
|
||||
*
|
||||
* DEPRECATED: This class is deprecated and will be removed in a future version.
|
||||
*
|
||||
* All product classes have been moved out of the hybrid class concept
|
||||
*
|
||||
* @deprecated 2.7.2
|
||||
*
|
||||
* Class responsible for handling the hybrid products
|
||||
*
|
||||
* Hybrid products are those that may work both as a stand-alone plugin or with the Jetpack plugin.
|
||||
@ -29,6 +22,13 @@ use WP_Error;
|
||||
*/
|
||||
abstract class Hybrid_Product extends Product {
|
||||
|
||||
/**
|
||||
* All hybrid products have a standalone plugin
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public static $has_standalone_plugin = true;
|
||||
|
||||
/**
|
||||
* Checks whether the Product is active
|
||||
*
|
||||
@ -38,6 +38,15 @@ abstract class Hybrid_Product extends Product {
|
||||
return parent::is_plugin_active() || parent::is_jetpack_plugin_active();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the standalone plugin for this product is active
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function is_standalone_plugin_active() {
|
||||
return parent::is_plugin_active();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the plugin is installed
|
||||
*
|
||||
@ -129,4 +138,55 @@ abstract class Hybrid_Product extends Product {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install and activate the standalone plugin in the case it's missing.
|
||||
*
|
||||
* @return boolean|WP_Error
|
||||
*/
|
||||
final public static function install_and_activate_standalone() {
|
||||
/**
|
||||
* Check for the presence of the standalone plugin, ignoring Jetpack presence.
|
||||
*
|
||||
* If the standalone plugin is not installed and the user can install plugins, proceed with the installation.
|
||||
*/
|
||||
if ( ! parent::is_plugin_installed() ) {
|
||||
/**
|
||||
* Check for permissions
|
||||
*/
|
||||
if ( ! current_user_can( 'install_plugins' ) ) {
|
||||
return new WP_Error( 'not_allowed', __( 'You are not allowed to install plugins on this site.', 'jetpack-my-jetpack' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Install the plugin
|
||||
*/
|
||||
$installed = Plugins_Installer::install_plugin( static::get_plugin_slug() );
|
||||
if ( is_wp_error( $installed ) ) {
|
||||
return $installed;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate the installed plugin
|
||||
*/
|
||||
$result = static::activate_plugin();
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate the module as well, if the user has a plan
|
||||
* or the product does not require a plan to work
|
||||
*/
|
||||
if ( static::has_required_plan() ) {
|
||||
$module_activation = ( new Modules() )->activate( static::$module_name, false, false );
|
||||
|
||||
if ( ! $module_activation ) {
|
||||
return new WP_Error( 'module_activation_failed', __( 'Error activating Jetpack module', 'jetpack-my-jetpack' ) );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,205 @@
|
||||
<?php
|
||||
/**
|
||||
* Boost product
|
||||
*
|
||||
* @package my-jetpack
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\My_Jetpack\Products;
|
||||
|
||||
use Automattic\Jetpack\My_Jetpack\Product;
|
||||
use Automattic\Jetpack\My_Jetpack\Wpcom_Products;
|
||||
|
||||
/**
|
||||
* Class responsible for handling the Jetpack AI product
|
||||
*/
|
||||
class Jetpack_Ai extends Product {
|
||||
|
||||
/**
|
||||
* The product slug
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $slug = 'jetpack-ai';
|
||||
|
||||
/**
|
||||
* Get the Product info for the API
|
||||
*
|
||||
* @throws \Exception If required attribute is not declared in the child class.
|
||||
* @return array
|
||||
*/
|
||||
public static function get_info() {
|
||||
// Call parent method to get the default info.
|
||||
$info = parent::get_info();
|
||||
|
||||
// Populate the product with the feature data.
|
||||
$info['ai-assistant-feature'] = self::get_ai_assistant_feature();
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugin slug - ovewrite it and return Jetpack's
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public static function get_plugin_slug() {
|
||||
return self::JETPACK_PLUGIN_SLUG;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugin filename - ovewrite it and return Jetpack's
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public static function get_plugin_filename() {
|
||||
return self::JETPACK_PLUGIN_FILENAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the internationalized product name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_name() {
|
||||
return __( 'Jetpack AI', 'jetpack-my-jetpack' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the internationalized product title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_title() {
|
||||
return __( 'Jetpack AI', 'jetpack-my-jetpack' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the internationalized product description
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_description() {
|
||||
return __( 'Experimental tool to add AI to your editor', 'jetpack-my-jetpack' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the internationalized product long description
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_long_description() {
|
||||
return __( 'Jetpack AI Assistant brings the power of AI right into your WordPress editor, letting your content creation soar to new heights.', 'jetpack-my-jetpack' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the internationalized features list
|
||||
*
|
||||
* @return array CRM features list
|
||||
*/
|
||||
public static function get_features() {
|
||||
return array(
|
||||
__( 'Artificial intelligence chatbot', 'jetpack-my-jetpack' ),
|
||||
__( 'Generate text, tables, lists, and forms', 'jetpack-my-jetpack' ),
|
||||
__( 'Refine the tone and content to your liking', 'jetpack-my-jetpack' ),
|
||||
__( 'Get feedback about your post', 'jetpack-my-jetpack' ),
|
||||
__( 'Seamless WordPress editor Integration', 'jetpack-my-jetpack' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the product princing details
|
||||
*
|
||||
* @return array Pricing details
|
||||
*/
|
||||
public static function get_pricing_for_ui() {
|
||||
return array_merge(
|
||||
array(
|
||||
'available' => true,
|
||||
'wpcom_product_slug' => static::get_wpcom_product_slug(),
|
||||
),
|
||||
Wpcom_Products::get_product_pricing( static::get_wpcom_product_slug() )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the WPCOM product slug used to make the purchase
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public static function get_wpcom_product_slug() {
|
||||
return 'jetpack_ai_yearly';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the WPCOM monthly product slug used to make the purchase
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public static function get_wpcom_monthly_product_slug() {
|
||||
return 'jetpack_ai_monthly';
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the current plan (or purchases) of the site already supports the product
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function has_required_plan() {
|
||||
$purchases_data = Wpcom_Products::get_site_current_purchases();
|
||||
if ( is_wp_error( $purchases_data ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( is_array( $purchases_data ) && ! empty( $purchases_data ) ) {
|
||||
foreach ( $purchases_data as $purchase ) {
|
||||
if ( 0 === strpos( $purchase->product_slug, static::get_wpcom_product_slug() ) ) {
|
||||
return true;
|
||||
}
|
||||
if ( 0 === strpos( $purchase->product_slug, static::get_wpcom_monthly_product_slug() ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL where the user manages the product
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public static function get_manage_url() {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data about the AI Assistant feature
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_ai_assistant_feature() {
|
||||
// Bail early if the plugin is not active.
|
||||
if ( ! self::is_jetpack_plugin_installed() ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// Check if the global constant is defined.
|
||||
if ( ! defined( 'JETPACK__PLUGIN_DIR' ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// Check if class exists. If not, try to require it once.
|
||||
if ( ! class_exists( 'Jetpack_AI_Helper' ) ) {
|
||||
$class_file_path = JETPACK__PLUGIN_DIR . '_inc/lib/class-jetpack-ai-helper.php';
|
||||
|
||||
// Check whether the file exists
|
||||
if ( ! file_exists( $class_file_path ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
require_once $class_file_path;
|
||||
}
|
||||
|
||||
return \Jetpack_AI_Helper::get_ai_assistance_feature();
|
||||
}
|
||||
}
|
@ -130,5 +130,4 @@ abstract class Module_Product extends Product {
|
||||
}
|
||||
return Jetpack::deactivate_module( static::$module_name );
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -61,6 +61,13 @@ abstract class Product {
|
||||
*/
|
||||
public static $requires_user_connection = true;
|
||||
|
||||
/**
|
||||
* Whether this product has a standalone plugin
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public static $has_standalone_plugin = false;
|
||||
|
||||
/**
|
||||
* Get the plugin slug
|
||||
*
|
||||
@ -117,19 +124,26 @@ abstract class Product {
|
||||
'title' => static::get_title(),
|
||||
'description' => static::get_description(),
|
||||
'long_description' => static::get_long_description(),
|
||||
'tiers' => static::get_tiers(),
|
||||
'features' => static::get_features(),
|
||||
'features_by_tier' => static::get_features_by_tier(),
|
||||
'disclaimers' => static::get_disclaimers(),
|
||||
'status' => static::get_status(),
|
||||
'pricing_for_ui' => static::get_pricing_for_ui(),
|
||||
'is_bundle' => static::is_bundle_product(),
|
||||
'is_plugin_active' => static::is_plugin_active(),
|
||||
'is_upgradable_by_bundle' => static::is_upgradable_by_bundle(),
|
||||
'supported_products' => static::get_supported_products(),
|
||||
'wpcom_product_slug' => static::get_wpcom_product_slug(),
|
||||
'requires_user_connection' => static::$requires_user_connection,
|
||||
'has_required_plan' => static::has_required_plan(),
|
||||
'has_required_tier' => static::has_required_tier(),
|
||||
'manage_url' => static::get_manage_url(),
|
||||
'purchase_url' => static::get_purchase_url(),
|
||||
'post_activation_url' => static::get_post_activation_url(),
|
||||
'class' => get_called_class(),
|
||||
'standalone_plugin_info' => static::get_standalone_info(),
|
||||
'class' => static::class,
|
||||
'post_checkout_url' => static::get_post_checkout_url(),
|
||||
);
|
||||
}
|
||||
|
||||
@ -161,6 +175,15 @@ abstract class Product {
|
||||
*/
|
||||
abstract public static function get_long_description();
|
||||
|
||||
/**
|
||||
* Get the tiers for the product
|
||||
*
|
||||
* @return boolean|string[] The slugs of the tiers (i.e. [ "free", "basic", "advanced" ]), or False if the product has no tiers.
|
||||
*/
|
||||
public static function get_tiers() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the internationalized features list
|
||||
*
|
||||
@ -168,6 +191,15 @@ abstract class Product {
|
||||
*/
|
||||
abstract public static function get_features();
|
||||
|
||||
/**
|
||||
* Get the internationalized comparison of features grouped by each tier
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_features_by_tier() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the product pricing
|
||||
*
|
||||
@ -175,6 +207,16 @@ abstract class Product {
|
||||
*/
|
||||
abstract public static function get_pricing_for_ui();
|
||||
|
||||
/**
|
||||
* Get the URL where the user can purchase the product iff it doesn't have an interstitial page in My Jetpack.
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public static function get_purchase_url() {
|
||||
// Declare as concrete method as most Jetpack products use an interstitial page within My Jetpack.
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL where the user manages the product
|
||||
*
|
||||
@ -191,6 +233,15 @@ abstract class Product {
|
||||
return static::get_manage_url();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL the user is taken after purchasing the product through the checkout
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public static function get_post_checkout_url() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the WPCOM product slug used to make the purchase
|
||||
*
|
||||
@ -209,6 +260,22 @@ abstract class Product {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the standalone plugin related info
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_standalone_info() {
|
||||
$is_standalone_installed = static::$has_standalone_plugin && self::is_plugin_installed();
|
||||
$is_standalone_active = static::$has_standalone_plugin && self::is_plugin_active();
|
||||
|
||||
return array(
|
||||
'has_standalone_plugin' => static::$has_standalone_plugin,
|
||||
'is_standalone_installed' => $is_standalone_installed,
|
||||
'is_standalone_active' => $is_standalone_active,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the current plan (or purchases) of the site already supports the product
|
||||
*
|
||||
@ -222,6 +289,15 @@ abstract class Product {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the current plan (or purchases) of the site already supports the tiers
|
||||
*
|
||||
* @return array Key/value pairs of tier slugs and whether they are supported or not.
|
||||
*/
|
||||
public static function has_required_tier() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the product supports trial or not
|
||||
*
|
||||
@ -235,6 +311,15 @@ abstract class Product {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the product can be upgraded to a different product.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function is_upgradable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether product is a bundle.
|
||||
*
|
||||
@ -271,14 +356,19 @@ abstract class Product {
|
||||
* @return string
|
||||
*/
|
||||
public static function get_status() {
|
||||
|
||||
if ( ! static::is_plugin_installed() ) {
|
||||
$status = 'plugin_absent';
|
||||
if ( static::has_required_plan() ) {
|
||||
$status = 'plugin_absent_with_plan';
|
||||
}
|
||||
} elseif ( static::is_active() ) {
|
||||
$status = 'active';
|
||||
// We only consider missing user connection an error when the Product is active.
|
||||
if ( static::$requires_user_connection && ! ( new Connection_Manager() )->has_connected_owner() ) {
|
||||
$status = 'error';
|
||||
} elseif ( static::is_upgradable() ) {
|
||||
// Upgradable plans should ignore whether or not they have the required plan.
|
||||
$status = 'can_upgrade';
|
||||
} elseif ( ! static::has_required_plan() ) { // We need needs_purchase here as well because some products we consider active without the required plan.
|
||||
if ( static::has_trial_support() ) {
|
||||
$status = 'needs_purchase_or_free';
|
||||
@ -464,5 +554,4 @@ abstract class Product {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user