PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-a.7
Jetpack – WP Security, Backup, Speed, & Growth v16.3-a.7
16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 All 506 releases
jetpack / jetpack_vendor / automattic / jetpack-publicize / src / class-keyring-result-handler.php

class-keyring-result-handler.php in Jetpack – WP Security, Backup, Speed, & Growth 16.3-a.7, at jetpack_vendor/automattic/jetpack-publicize/src/class-keyring-result-handler.php

87 lines 2.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Same-origin completion handler for the publicize auth_flow=v2 connect flow.
4 *
5 * @package automattic/jetpack-publicize
6 */
7
8 namespace Automattic\Jetpack\Publicize;
9
10 /**
11 * Handles the popup landing page that public-api redirects back to after a connection is
12 * verified (auth_flow=v2).
13 *
14 * Because Meta/Threads sever `window.opener` via COOP, the popup cannot post its result back
15 * to the opener tab. Instead public-api redirects the popup to this same-origin admin-post
16 * endpoint, which broadcasts the request_id over a BroadcastChannel that the opener is
17 * listening on, then closes itself. The opener then fetches the verified result once.
18 */
19 class Keyring_Result_Handler {
20
21 /**
22 * The admin-post action that the connect popup is redirected back to.
23 */
24 const ACTION = 'jetpack_social_keyring_done';
25
26 /**
27 * The BroadcastChannel name shared with the client.
28 *
29 * Must match KEYRING_BROADCAST_CHANNEL in _inc/utils/request-external-access.js.
30 */
31 const CHANNEL = 'jetpack-social-keyring';
32
33 /**
34 * Register the handler.
35 */
36 public static function init() {
37 add_action( 'admin_post_' . self::ACTION, array( __CLASS__, 'handle' ) );
38 }
39
40 /**
41 * Output a minimal page that broadcasts the request_id to the opener and closes the popup.
42 *
43 * @return never
44 */
45 public static function handle() {
46 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only: the request_id is an opaque token reflected back to a same-origin BroadcastChannel; nothing is mutated.
47 $request_id = isset( $_GET['request_id'] ) ? sanitize_key( wp_unslash( $_GET['request_id'] ) ) : '';
48
49 nocache_headers();
50
51 if ( ! headers_sent() ) {
52 header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) );
53 }
54
55 $close_warning = esc_html__( 'You can close this window now.', 'jetpack-publicize-pkg' );
56 ?>
57 <!DOCTYPE html>
58 <html <?php language_attributes(); ?>>
59 <head>
60 <meta charset="<?php echo esc_attr( get_option( 'blog_charset' ) ); ?>" />
61 <title></title>
62 </head>
63 <body>
64 <p><?php echo $close_warning; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- already escaped above. ?></p>
65 <script>
66 ( function () {
67 try {
68 var channel = new BroadcastChannel( <?php echo wp_json_encode( self::CHANNEL, JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ); ?> );
69 channel.postMessage( {
70 type: 'keyring-result',
71 requestId: <?php echo wp_json_encode( $request_id, JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ); ?>,
72 } );
73 channel.close();
74 } catch ( e ) {}
75
76 window.setTimeout( function () {
77 window.close();
78 }, 50 );
79 } )();
80 </script>
81 </body>
82 </html>
83 <?php
84 exit;
85 }
86 }
87