PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.2-a.1
Jetpack – WP Security, Backup, Speed, & Growth v16.2-a.1
16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / jetpack_vendor / automattic / jetpack-connection / src / class-webhooks.php
jetpack / jetpack_vendor / automattic / jetpack-connection / src Last commit date
abilities 3 days ago connectors 3 days ago health 3 days ago identity-crisis 1 month ago sso 1 month ago traits 8 months ago webhooks 8 months ago class-authorize-json-api.php 1 month ago class-client.php 3 days ago class-connection-assets.php 1 year ago class-connection-notice.php 8 months ago class-error-handler.php 3 days ago class-external-storage.php 4 months ago class-heartbeat.php 1 month ago class-initial-state.php 3 weeks ago class-manager.php 3 days ago class-nonce-handler.php 8 months ago class-package-version-tracker.php 1 month ago class-package-version.php 3 days ago class-partner-coupon.php 2 months ago class-partner.php 2 years ago class-plugin-storage.php 8 months ago class-plugin.php 8 months ago class-rest-authentication.php 3 days ago class-rest-connector.php 3 days ago class-secrets.php 8 months ago class-server-sandbox.php 2 months ago class-site-health.php 3 days ago class-terms-of-service.php 3 days ago class-tokens-locks.php 8 months ago class-tokens.php 3 days ago class-tracking.php 3 days ago class-urls.php 6 months ago class-user-account-status.php 3 days ago class-users-connection-admin.php 2 months ago class-utils.php 2 years ago class-webhooks.php 1 month ago class-xmlrpc-async-call.php 2 years ago class-xmlrpc-connector.php 8 months ago interface-manager.php 4 years ago interface-storage-provider.php 6 months ago
class-webhooks.php
232 lines
1 <?php
2 /**
3 * Connection Webhooks class.
4 *
5 * @package automattic/jetpack-connection
6 */
7
8 namespace Automattic\Jetpack\Connection;
9
10 use Automattic\Jetpack\CookieState;
11 use Automattic\Jetpack\Roles;
12 use Automattic\Jetpack\Status\Host;
13 use Automattic\Jetpack\Tracking;
14 use Jetpack_Options;
15
16 /**
17 * Connection Webhooks class.
18 */
19 class Webhooks {
20
21 /**
22 * The Connection Manager object.
23 *
24 * @var Manager
25 */
26 private $connection;
27
28 /**
29 * Webhooks constructor.
30 *
31 * @param Manager $connection The Connection Manager object.
32 */
33 public function __construct( $connection ) {
34 $this->connection = $connection;
35 }
36
37 /**
38 * Initialize the webhooks.
39 *
40 * @param Manager $connection The Connection Manager object.
41 */
42 public static function init( $connection ) {
43 $webhooks = new static( $connection );
44
45 add_action( 'init', array( $webhooks, 'controller' ) );
46 add_action( 'load-toplevel_page_jetpack', array( $webhooks, 'fallback_jetpack_controller' ) );
47 }
48
49 /**
50 * Jetpack plugin used to trigger this webhooks in Jetpack::admin_page_load()
51 *
52 * The Jetpack toplevel menu is still accessible for stand-alone plugins, and while there's no content for that page, there are still
53 * actions from Calypso and WPCOM that reach that route regardless of the site having the Jetpack plugin or not. That's why we are still handling it here.
54 */
55 public function fallback_jetpack_controller() {
56 $this->controller( true );
57 }
58
59 /**
60 * The "controller" decides which handler we need to run.
61 *
62 * @param bool $force Do not check if it's a webhook request and just run the controller.
63 */
64 public function controller( $force = false ) {
65 if ( ! $force ) {
66 // The nonce is verified in specific handlers.
67 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
68 if ( empty( $_GET['handler'] ) || 'jetpack-connection-webhooks' !== $_GET['handler'] ) {
69 return;
70 }
71 }
72
73 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
74 if ( isset( $_GET['connect_url_redirect'] ) ) {
75 $this->handle_connect_url_redirect();
76 }
77
78 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
79 if ( empty( $_GET['action'] ) ) {
80 return;
81 }
82
83 // The nonce is verified in specific handlers.
84 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
85 switch ( $_GET['action'] ) {
86 case 'authorize':
87 $this->handle_authorize();
88 $this->do_exit();
89 break; // @phan-suppress-current-line PhanPluginUnreachableCode -- Safer to include it even though do_exit never returns.
90 case 'authorize_redirect':
91 $this->handle_authorize_redirect();
92 $this->do_exit();
93 break; // @phan-suppress-current-line PhanPluginUnreachableCode -- Safer to include it even though do_exit never returns.
94 // Class Jetpack::admin_page_load() still handles other cases.
95 }
96 }
97
98 /**
99 * Perform the authorization action.
100 */
101 public function handle_authorize() {
102 if ( $this->connection->is_connected() && $this->connection->is_user_connected() ) {
103 $redirect_url = apply_filters( 'jetpack_client_authorize_already_authorized_url', admin_url() );
104
105 if ( ! empty( $_GET['redirect'] ) ) {
106 $explicit = esc_url_raw( wp_unslash( $_GET['redirect'] ) );
107 if ( wp_validate_redirect( $explicit ) ) {
108 $redirect_url = $explicit;
109 }
110 }
111
112 wp_safe_redirect( $redirect_url );
113
114 return;
115 }
116 do_action( 'jetpack_client_authorize_processing' );
117
118 $data = stripslashes_deep( $_GET ); // We need all request data under the context of an authorization request.
119 $data['auth_type'] = 'client';
120 $roles = new Roles();
121 $role = $roles->translate_current_user_to_role();
122 $redirect = isset( $data['redirect'] ) ? esc_url_raw( (string) $data['redirect'] ) : '';
123
124 check_admin_referer( "jetpack-authorize_{$role}_{$redirect}" );
125
126 $tracking = new Tracking();
127
128 $result = $this->connection->authorize( $data );
129
130 if ( is_wp_error( $result ) ) {
131 do_action( 'jetpack_client_authorize_error', $result );
132
133 $tracking->record_user_event(
134 'jpc_client_authorize_fail',
135 array(
136 'error_code' => $result->get_error_code(),
137 'error_message' => $result->get_error_message(),
138 )
139 );
140 } else {
141 /**
142 * Fires after the Jetpack client is authorized to communicate with WordPress.com.
143 *
144 * @param int Jetpack Blog ID.
145 *
146 * @since 1.7.0
147 * @since-jetpack 4.2.0
148 */
149 do_action( 'jetpack_client_authorized', Jetpack_Options::get_option( 'id' ) );
150
151 $tracking->record_user_event( 'jpc_client_authorize_success' );
152 }
153
154 $fallback_redirect = apply_filters( 'jetpack_client_authorize_fallback_url', admin_url() );
155 $redirect = wp_validate_redirect( $redirect ) ? $redirect : $fallback_redirect;
156
157 wp_safe_redirect( $redirect );
158 }
159
160 /**
161 * The authorhize_redirect webhook handler
162 */
163 public function handle_authorize_redirect() {
164 $authorize_redirect_handler = new Webhooks\Authorize_Redirect( $this->connection );
165 $authorize_redirect_handler->handle();
166 }
167
168 /**
169 * The `exit` is wrapped into a method so we could mock it.
170 *
171 * @return never
172 */
173 protected function do_exit() {
174 exit( 0 );
175 }
176
177 /**
178 * Handle the `connect_url_redirect` action,
179 * which is usually called to repeat an attempt for user to authorize the connection.
180 *
181 * @return void
182 */
183 public function handle_connect_url_redirect() {
184 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- no site changes.
185 $from = ! empty( $_GET['from'] ) ? sanitize_text_field( wp_unslash( $_GET['from'] ) ) : 'iframe';
186
187 $skip_pricing = filter_input( INPUT_GET, 'skip_pricing', FILTER_VALIDATE_BOOLEAN );
188
189 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- no site changes, sanitization happens in get_authorization_url()
190 $redirect = ! empty( $_GET['redirect_after_auth'] ) ? wp_unslash( $_GET['redirect_after_auth'] ) : false;
191
192 add_filter( 'allowed_redirect_hosts', array( Host::class, 'allow_wpcom_environments' ) );
193
194 if ( ! $this->connection->is_user_connected() ) {
195 if ( ! $this->connection->is_connected() ) {
196 $this->connection->register();
197 }
198
199 $connect_url = add_query_arg( 'from', $from, $this->connection->get_authorization_url( null, $redirect ) );
200
201 if ( $skip_pricing ) {
202 $connect_url = add_query_arg( 'skip_pricing', '1', $connect_url );
203 }
204
205 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- no site changes.
206 if ( isset( $_GET['notes_iframe'] ) ) {
207 $connect_url .= '&notes_iframe';
208 }
209 wp_safe_redirect( $connect_url );
210 $this->do_exit();
211 } elseif ( ! isset( $_GET['calypso_env'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- no site changes.
212 ( new CookieState() )->state( 'message', 'already_authorized' );
213 wp_safe_redirect( $redirect );
214 $this->do_exit();
215 } else {
216 if ( 'connect-after-checkout' === $from && $redirect ) {
217 wp_safe_redirect( $redirect );
218 $this->do_exit();
219 }
220 $connect_url = add_query_arg(
221 array(
222 'from' => $from,
223 'already_authorized' => true,
224 ),
225 $this->connection->get_authorization_url()
226 );
227 wp_safe_redirect( $connect_url );
228 $this->do_exit();
229 }
230 }
231 }
232