Completed
Push — renovate/wordpress-monorepo ( 8cdadc...6203b6 )
by
unknown
552:54 queued 542:45
created

Jetpack_WPCOM_Block_Editor::init_actions()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 0
dl 0
loc 22
rs 9.568
c 0
b 0
f 0
1
<?php
2
/**
3
 * WordPress.com Block Editor
4
 * Allow new block editor posts to be composed on WordPress.com.
5
 * This is auto-loaded as of Jetpack v7.4 for sites connected to WordPress.com only.
6
 *
7
 * @package automattic/jetpack
8
 */
9
10
use Automattic\Jetpack\Connection\Tokens;
11
/**
12
 * WordPress.com Block editor for Jetpack
13
 */
14
class Jetpack_WPCOM_Block_Editor {
15
	/**
16
	 * ID of the user who signed the nonce.
17
	 *
18
	 * @var int
19
	 */
20
	private $nonce_user_id;
21
22
	/**
23
	 * Singleton
24
	 */
25
	public static function init() {
26
		static $instance = false;
27
28
		if ( ! $instance ) {
29
			$instance = new Jetpack_WPCOM_Block_Editor();
30
		}
31
32
		return $instance;
33
	}
34
35
	/**
36
	 * Jetpack_WPCOM_Block_Editor constructor.
37
	 */
38
	private function __construct() {
39
		add_action( 'init', array( $this, 'init_actions' ) );
40
	}
41
42
	/**
43
	 * Add in all hooks.
44
	 */
45
	public function init_actions() {
46
		// Bail early if Jetpack's block editor extensions are disabled on the site.
47
		/* This filter is documented in class.jetpack-gutenberg.php */
48
		if ( ! apply_filters( 'jetpack_gutenberg', true ) ) {
49
			return;
50
		}
51
52
		if ( $this->is_iframed_block_editor() ) {
53
			add_action( 'admin_init', array( $this, 'disable_send_frame_options_header' ), 9 );
54
			add_filter( 'admin_body_class', array( $this, 'add_iframed_body_class' ) );
55
		}
56
57
		require_once __DIR__ . '/functions.editor-type.php';
58
		add_action( 'edit_form_top', 'Jetpack\EditorType\remember_classic_editor' );
59
		add_filter( 'block_editor_settings', 'Jetpack\EditorType\remember_block_editor', 10, 2 );
60
		add_action( 'login_init', array( $this, 'allow_block_editor_login' ), 1 );
61
		add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ), 9 );
62
		add_action( 'enqueue_block_assets', array( $this, 'enqueue_block_assets' ) );
63
		add_filter( 'mce_external_plugins', array( $this, 'add_tinymce_plugins' ) );
64
65
		$this->enable_cross_site_auth_cookies();
66
	}
67
68
	/**
69
	 * Checks if we are embedding the block editor in an iframe in WordPress.com.
70
	 *
71
	 * @return bool Whether the current request is from the iframed block editor.
72
	 */
73
	public function is_iframed_block_editor() {
74
		global $pagenow;
75
76
		// phpcs:ignore WordPress.Security.NonceVerification
77
		return ( 'post.php' === $pagenow || 'post-new.php' === $pagenow ) && ! empty( $_GET['frame-nonce'] );
78
	}
79
80
	/**
81
	 * Prevents frame options header from firing if this is a allowed iframe request.
82
	 */
83
	public function disable_send_frame_options_header() {
84
		// phpcs:ignore WordPress.Security.NonceVerification
85
		if ( $this->framing_allowed( $_GET['frame-nonce'] ) ) {
86
			remove_action( 'admin_init', 'send_frame_options_header' );
87
		}
88
	}
89
90
	/**
91
	 * Adds custom admin body class if this is a allowed iframe request.
92
	 *
93
	 * @param string $classes Admin body classes.
94
	 * @return string
95
	 */
96
	public function add_iframed_body_class( $classes ) {
97
		// phpcs:ignore WordPress.Security.NonceVerification
98
		if ( $this->framing_allowed( $_GET['frame-nonce'] ) ) {
99
			$classes .= ' is-iframed ';
100
		}
101
102
		return $classes;
103
	}
104
105
	/**
106
	 * Checks to see if cookie can be set in current context. If 3rd party cookie blocking
107
	 * is enabled the editor can't load in iFrame, so emiting X-Frame-Options: DENY will
108
	 * force the editor to break out of the iFrame.
109
	 */
110
	private function check_iframe_cookie_setting() {
111
		if ( ! isset( $_SERVER['QUERY_STRING'] ) || ! strpos( $_SERVER['QUERY_STRING'], 'calypsoify%3D1%26block-editor' ) || isset( $_COOKIE['wordpress_test_cookie'] ) ) {
112
			return;
113
		}
114
115
		if ( empty( $_GET['calypsoify_cookie_check'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
116
			header( 'Location: ' . esc_url_raw( $_SERVER['REQUEST_URI'] . '&calypsoify_cookie_check=true' ) );
117
			exit;
118
		}
119
120
		header( 'X-Frame-Options: DENY' );
121
		exit;
122
	}
123
124
	/**
125
	 * Allows to iframe the login page if a user is logged out
126
	 * while trying to access the block editor from wordpress.com.
127
	 */
128
	public function allow_block_editor_login() {
129
		// phpcs:ignore WordPress.Security.NonceVerification
130
		if ( empty( $_REQUEST['redirect_to'] ) ) {
131
			return;
132
		}
133
134
		$this->check_iframe_cookie_setting();
135
136
		// phpcs:ignore WordPress.Security.NonceVerification
137
		$query = wp_parse_url( urldecode( $_REQUEST['redirect_to'] ), PHP_URL_QUERY );
138
		$args  = wp_parse_args( $query );
139
140
		// Check nonce and make sure this is a Gutenframe request.
141
		if ( ! empty( $args['frame-nonce'] ) && $this->framing_allowed( $args['frame-nonce'] ) ) {
142
143
			// If SSO is active, we'll let WordPress.com handle authentication...
144
			if ( Jetpack::is_module_active( 'sso' ) ) {
145
				// ...but only if it's not an Atomic site. They already do that.
146
				if ( ! jetpack_is_atomic_site() ) {
147
					add_filter( 'jetpack_sso_bypass_login_forward_wpcom', '__return_true' );
148
				}
149
			} else {
150
				$_REQUEST['interim-login'] = true;
151
				add_action( 'wp_login', array( $this, 'do_redirect' ) );
152
				add_action( 'login_form', array( $this, 'add_login_html' ) );
153
				add_filter( 'wp_login_errors', array( $this, 'add_login_message' ) );
154
				remove_action( 'login_init', 'send_frame_options_header' );
155
				wp_add_inline_style( 'login', '.interim-login #login{padding-top:8%}' );
156
			}
157
		}
158
	}
159
160
	/**
161
	 * Adds a login message.
162
	 *
163
	 * Intended to soften the expectation mismatch of ending up with a login screen rather than the editor.
164
	 *
165
	 * @param WP_Error $errors WP Error object.
166
	 * @return \WP_Error
167
	 */
168
	public function add_login_message( $errors ) {
169
		$errors->remove( 'expired' );
0 ignored issues
show
Bug introduced by
The method remove() does not seem to exist on object<WP_Error>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
170
		$errors->add( 'info', __( 'Before we continue, please log in to your Jetpack site.', 'jetpack' ), 'message' );
0 ignored issues
show
Bug introduced by
The method add() does not seem to exist on object<WP_Error>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
171
172
		return $errors;
173
	}
174
175
	/**
176
	 * Maintains the `redirect_to` parameter in login form links.
177
	 * Adds visual feedback of login in progress.
178
	 */
179
	public function add_login_html() {
180
		?>
181
		<input type="hidden" name="redirect_to" value="<?php echo esc_url( $_REQUEST['redirect_to'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended ?>" />
182
		<script type="application/javascript">
183
			document.getElementById( 'loginform' ).addEventListener( 'submit' , function() {
184
				document.getElementById( 'wp-submit' ).setAttribute( 'disabled', 'disabled' );
185
				document.getElementById( 'wp-submit' ).value = '<?php echo esc_js( __( 'Logging In...', 'jetpack' ) ); ?>';
186
			} );
187
		</script>
188
		<?php
189
	}
190
191
	/**
192
	 * Does the redirect to the block editor.
193
	 */
194
	public function do_redirect() {
195
		wp_safe_redirect( $GLOBALS['redirect_to'] );
196
		exit;
197
	}
198
199
	/**
200
	 * Checks whether this is an allowed iframe request.
201
	 *
202
	 * @param string $nonce Nonce to verify.
203
	 * @return bool
204
	 */
205
	public function framing_allowed( $nonce ) {
206
		$verified = $this->verify_frame_nonce( $nonce, 'frame-' . Jetpack_Options::get_option( 'id' ) );
207
208
		if ( is_wp_error( $verified ) ) {
209
			wp_die( $verified ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
210
		}
211
212
		if ( $verified && ! defined( 'IFRAME_REQUEST' ) ) {
213
			define( 'IFRAME_REQUEST', true );
214
		}
215
216
		return (bool) $verified;
217
	}
218
219
	/**
220
	 * Verify that correct nonce was used with time limit.
221
	 *
222
	 * The user is given an amount of time to use the token, so therefore, since the
223
	 * UID and $action remain the same, the independent variable is the time.
224
	 *
225
	 * @param string $nonce Nonce that was used in the form to verify.
226
	 * @param string $action Should give context to what is taking place and be the same when nonce was created.
227
	 * @return boolean|WP_Error Whether the nonce is valid.
228
	 */
229
	public function verify_frame_nonce( $nonce, $action ) {
230
		if ( empty( $nonce ) ) {
231
			return false;
232
		}
233
234
		list( $expiration, $user_id, $hash ) = explode( ':', $nonce, 3 );
235
236
		$this->nonce_user_id = (int) $user_id;
237
		if ( ! $this->nonce_user_id ) {
238
			return false;
239
		}
240
241
		$token = ( new Tokens() )->get_access_token( $this->nonce_user_id );
242
		if ( ! $token ) {
243
			return false;
244
		}
245
246
		/*
247
		 * Failures must return `false` (blocking the iframe) prior to the
248
		 * signature verification.
249
		 */
250
251
		add_filter( 'salt', array( $this, 'filter_salt' ), 10, 2 );
252
		$expected_hash = wp_hash( "$expiration|$action|{$this->nonce_user_id}", 'jetpack_frame_nonce' );
253
		remove_filter( 'salt', array( $this, 'filter_salt' ) );
254
255
		if ( ! hash_equals( $hash, $expected_hash ) ) {
256
			return false;
257
		}
258
259
		/*
260
		 * Failures may return `WP_Error` (showing an error in the iframe) after the
261
		 * signature verification passes.
262
		 */
263
264
		if ( time() > $expiration ) {
265
			return new WP_Error( 'nonce_invalid_expired', 'Expired nonce.', array( 'status' => 401 ) );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'nonce_invalid_expired'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
266
		}
267
268
		// Check if it matches the current user, unless they're trying to log in.
269
		if ( get_current_user_id() !== $this->nonce_user_id && ! doing_action( 'login_init' ) ) {
270
			return new WP_Error( 'nonce_invalid_user_mismatch', 'User ID mismatch.', array( 'status' => 401 ) );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'nonce_invalid_user_mismatch'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
271
		}
272
273
		return true;
274
	}
275
276
	/**
277
	 * Filters the WordPress salt.
278
	 *
279
	 * @param string $salt Salt for the given scheme.
280
	 * @param string $scheme Authentication scheme.
281
	 * @return string
282
	 */
283 View Code Duplication
	public function filter_salt( $salt, $scheme ) {
284
		if ( 'jetpack_frame_nonce' === $scheme ) {
285
			$token = ( new Tokens() )->get_access_token( $this->nonce_user_id );
286
287
			if ( $token ) {
288
				$salt = $token->secret;
289
			}
290
		}
291
292
		return $salt;
293
	}
294
295
	/**
296
	 * Enqueues the WordPress.com block editor integration assets for the editor.
297
	 */
298
	public function enqueue_block_editor_assets() {
299
		$debug   = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG;
300
		$version = gmdate( 'Ymd' );
301
302
		wp_enqueue_script(
303
			'wpcom-block-editor-default-editor-script',
304
			$debug
305
				? '//widgets.wp.com/wpcom-block-editor/default.editor.js?minify=false'
306
				: '//widgets.wp.com/wpcom-block-editor/default.editor.min.js',
307
			array(
308
				'jquery',
309
				'lodash',
310
				'wp-annotations',
311
				'wp-compose',
312
				'wp-data',
313
				'wp-editor',
314
				'wp-element',
315
				'wp-rich-text',
316
			),
317
			$version,
318
			true
319
		);
320
321
		wp_localize_script(
322
			'wpcom-block-editor-default-editor-script',
323
			'wpcomGutenberg',
324
			array(
325
				'richTextToolbar' => array(
326
					'justify'   => __( 'Justify', 'jetpack' ),
327
					'underline' => __( 'Underline', 'jetpack' ),
328
				),
329
			)
330
		);
331
332
		if ( jetpack_is_atomic_site() ) {
333
			wp_enqueue_script(
334
				'wpcom-block-editor-wpcom-editor-script',
335
				$debug
336
					? '//widgets.wp.com/wpcom-block-editor/wpcom.editor.js?minify=false'
337
					: '//widgets.wp.com/wpcom-block-editor/wpcom.editor.min.js',
338
				array(
339
					'lodash',
340
					'wp-blocks',
341
					'wp-data',
342
					'wp-dom-ready',
343
					'wp-plugins',
344
				),
345
				$version,
346
				true
347
			);
348
		}
349
350
		if ( $this->is_iframed_block_editor() ) {
351
			wp_enqueue_script(
352
				'wpcom-block-editor-calypso-editor-script',
353
				$debug
354
					? '//widgets.wp.com/wpcom-block-editor/calypso.editor.js?minify=false'
355
					: '//widgets.wp.com/wpcom-block-editor/calypso.editor.min.js',
356
				array(
357
					'calypsoify_wpadminmods_js',
358
					'jquery',
359
					'lodash',
360
					'react',
361
					'wp-blocks',
362
					'wp-data',
363
					'wp-hooks',
364
					'wp-tinymce',
365
					'wp-url',
366
				),
367
				$version,
368
				true
369
			);
370
371
			wp_enqueue_style(
372
				'wpcom-block-editor-calypso-editor-styles',
373
				$debug
374
					? '//widgets.wp.com/wpcom-block-editor/calypso.editor.css?minify=false'
375
					: '//widgets.wp.com/wpcom-block-editor/calypso.editor.min.css',
376
				array(),
377
				$version
378
			);
379
		}
380
	}
381
382
	/**
383
	 * Enqueues the WordPress.com block editor integration assets for both editor and front-end.
384
	 */
385
	public function enqueue_block_assets() {
386
		// These styles are manually copied from //widgets.wp.com/wpcom-block-editor/default.view.css in order to
387
		// improve the performance by avoiding an extra network request to download the CSS file on every page.
388
		wp_add_inline_style( 'wp-block-library', '.has-text-align-justify{text-align:justify;}' );
389
	}
390
391
	/**
392
	 * Determines if the current $post contains a justified paragraph block.
393
	 *
394
	 * @return boolean true if justified paragraph is found, false otherwise.
395
	 */
396
	public function has_justified_block() {
397
		global $post;
398
		if ( ! $post instanceof WP_Post ) {
0 ignored issues
show
Bug introduced by
The class WP_Post does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
399
			return false;
400
		};
401
402
		if ( ! has_blocks( $post ) ) {
403
			return false;
404
		}
405
406
		return false !== strpos( $post->post_content, '<!-- wp:paragraph {"align":"justify"' );
407
	}
408
409
	/**
410
	 * Register the Tiny MCE plugins for the WordPress.com block editor integration.
411
	 *
412
	 * @param array $plugin_array An array of external Tiny MCE plugins.
413
	 * @return array External TinyMCE plugins.
414
	 */
415
	public function add_tinymce_plugins( $plugin_array ) {
416
		if ( $this->is_iframed_block_editor() ) {
417
			$debug = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG;
418
419
			$plugin_array['gutenberg-wpcom-iframe-media-modal'] = add_query_arg(
420
				'v',
421
				gmdate( 'YW' ),
422
				$debug
423
					? '//widgets.wp.com/wpcom-block-editor/calypso.tinymce.js?minify=false'
424
					: '//widgets.wp.com/wpcom-block-editor/calypso.tinymce.min.js'
425
			);
426
		}
427
428
		return $plugin_array;
429
	}
430
431
	/**
432
	 * Ensures the authentication cookies are designated for cross-site access.
433
	 */
434
	private function enable_cross_site_auth_cookies() {
435
		/**
436
		 * Allow plugins to disable the cross-site auth cookies.
437
		 *
438
		 * @since 8.1.1
439
		 *
440
		 * @param false bool Whether auth cookies should be disabled for cross-site access. False by default.
441
		 */
442
		if ( apply_filters( 'jetpack_disable_cross_site_auth_cookies', false ) ) {
443
			return;
444
		}
445
446
		add_action( 'set_auth_cookie', array( $this, 'set_samesite_auth_cookies' ), 10, 5 );
447
		add_action( 'set_logged_in_cookie', array( $this, 'set_samesite_logged_in_cookies' ), 10, 4 );
448
		add_action( 'clear_auth_cookie', array( $this, 'clear_auth_cookies' ) );
449
		add_filter( 'send_auth_cookies', '__return_false' );
450
	}
451
452
	/**
453
	 * Gets the SameSite attribute to use in auth cookies.
454
	 *
455
	 * @param  bool $secure Whether the connection is secure.
456
	 * @return string SameSite attribute to use on auth cookies.
457
	 */
458
	public function get_samesite_attr_for_auth_cookies( $secure ) {
459
		$samesite = $secure ? 'None' : 'Lax';
460
		/**
461
		 * Filters the SameSite attribute to use in auth cookies.
462
		 *
463
		 * @param string $samesite SameSite attribute to use in auth cookies.
464
		 *
465
		 * @since 8.1.1
466
		 */
467
		$samesite = apply_filters( 'jetpack_auth_cookie_samesite', $samesite );
468
469
		return $samesite;
470
	}
471
472
	/**
473
	 * Generates cross-site auth cookies so they can be accessed by WordPress.com.
474
	 *
475
	 * @param string $auth_cookie Authentication cookie value.
476
	 * @param int    $expire      The time the login grace period expires as a UNIX timestamp.
477
	 *                            Default is 12 hours past the cookie's expiration time.
478
	 * @param int    $expiration  The time when the authentication cookie expires as a UNIX timestamp.
479
	 *                            Default is 14 days from now.
480
	 * @param int    $user_id     User ID.
481
	 * @param string $scheme      Authentication scheme. Values include 'auth' or 'secure_auth'.
482
	 */
483
	public function set_samesite_auth_cookies( $auth_cookie, $expire, $expiration, $user_id, $scheme ) {
484
		if ( wp_startswith( $scheme, 'secure_' ) ) {
485
			$secure           = true;
486
			$auth_cookie_name = SECURE_AUTH_COOKIE;
487
		} else {
488
			$secure           = false;
489
			$auth_cookie_name = AUTH_COOKIE;
490
		}
491
		$samesite = $this->get_samesite_attr_for_auth_cookies( $secure );
492
493
		jetpack_shim_setcookie(
494
			$auth_cookie_name,
495
			$auth_cookie,
496
			array(
497
				'expires'  => $expire,
498
				'path'     => PLUGINS_COOKIE_PATH,
499
				'domain'   => COOKIE_DOMAIN,
500
				'secure'   => $secure,
501
				'httponly' => true,
502
				'samesite' => $samesite,
503
			)
504
		);
505
506
		jetpack_shim_setcookie(
507
			$auth_cookie_name,
508
			$auth_cookie,
509
			array(
510
				'expires'  => $expire,
511
				'path'     => ADMIN_COOKIE_PATH,
512
				'domain'   => COOKIE_DOMAIN,
513
				'secure'   => $secure,
514
				'httponly' => true,
515
				'samesite' => $samesite,
516
			)
517
		);
518
	}
519
520
	/**
521
	 * Generates cross-site logged in cookies so they can be accessed by WordPress.com.
522
	 *
523
	 * @param string $logged_in_cookie The logged-in cookie value.
524
	 * @param int    $expire           The time the login grace period expires as a UNIX timestamp.
525
	 *                                 Default is 12 hours past the cookie's expiration time.
526
	 * @param int    $expiration       The time when the logged-in cookie expires as a UNIX timestamp.
527
	 *                                 Default is 14 days from now.
528
	 * @param int    $user_id          User ID.
529
	 */
530
	public function set_samesite_logged_in_cookies( $logged_in_cookie, $expire, $expiration, $user_id ) {
531
		$secure = is_ssl();
532
533
		// Front-end cookie is secure when the auth cookie is secure and the site's home URL is forced HTTPS.
534
		$secure_logged_in_cookie = $secure && 'https' === wp_parse_url( get_option( 'home' ), PHP_URL_SCHEME );
535
536
		/** This filter is documented in core/src/wp-includes/pluggable.php */
537
		$secure = apply_filters( 'secure_auth_cookie', $secure, $user_id );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $user_id.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
538
539
		/** This filter is documented in core/src/wp-includes/pluggable.php */
540
		$secure_logged_in_cookie = apply_filters( 'secure_logged_in_cookie', $secure_logged_in_cookie, $user_id, $secure );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $user_id.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
541
542
		$samesite = $this->get_samesite_attr_for_auth_cookies( $secure_logged_in_cookie );
543
544
		jetpack_shim_setcookie(
545
			LOGGED_IN_COOKIE,
546
			$logged_in_cookie,
547
			array(
548
				'expires'  => $expire,
549
				'path'     => COOKIEPATH,
550
				'domain'   => COOKIE_DOMAIN,
551
				'secure'   => $secure_logged_in_cookie,
552
				'httponly' => true,
553
				'samesite' => $samesite,
554
			)
555
		);
556
557
		if ( COOKIEPATH !== SITECOOKIEPATH ) {
558
			jetpack_shim_setcookie(
559
				LOGGED_IN_COOKIE,
560
				$logged_in_cookie,
561
				array(
562
					'expires'  => $expire,
563
					'path'     => SITECOOKIEPATH,
564
					'domain'   => COOKIE_DOMAIN,
565
					'secure'   => $secure_logged_in_cookie,
566
					'httponly' => true,
567
					'samesite' => $samesite,
568
				)
569
			);
570
		}
571
	}
572
573
	/**
574
	 * Removes all of the cookies associated with authentication.
575
	 *
576
	 * This is copied from core's `wp_clear_auth_cookie` since disabling the core auth cookies prevents also the auth
577
	 * cookies from being cleared.
578
	 *
579
	 * @see wp_clear_auth_cookie
580
	 */
581
	public function clear_auth_cookies() {
582
		// Auth cookies.
583
		setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, ADMIN_COOKIE_PATH, COOKIE_DOMAIN );
584
		setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, ADMIN_COOKIE_PATH, COOKIE_DOMAIN );
585
		setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN );
586
		setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN );
587
		setcookie( LOGGED_IN_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
588
		setcookie( LOGGED_IN_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN );
589
590
		// Settings cookies.
591
		setcookie( 'wp-settings-' . get_current_user_id(), ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH );
592
		setcookie( 'wp-settings-time-' . get_current_user_id(), ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH );
593
594
		// Old cookies.
595
		setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
596
		setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN );
597
		setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
598
		setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN );
599
600
		// Even older cookies.
601
		setcookie( USER_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
602
		setcookie( PASS_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
603
		setcookie( USER_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN );
604
		setcookie( PASS_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN );
605
606
		// Post password cookie.
607
		setcookie( 'wp-postpass_' . COOKIEHASH, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
608
	}
609
}
610
611
Jetpack_WPCOM_Block_Editor::init();
612