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 / extensions / blocks / premium-content / login-button / login-button.php
jetpack / extensions / blocks / premium-content / login-button Last commit date
login-button.php 3 days ago
login-button.php
141 lines
1 <?php
2 /**
3 * Premium Content Login Button Child Block.
4 *
5 * @package automattic/jetpack
6 */
7
8 namespace Automattic\Jetpack\Extensions\Premium_Content;
9
10 use Automattic\Jetpack\Blocks;
11 use Automattic\Jetpack\Extensions\Premium_Content\Subscription_Service\Abstract_Token_Subscription_Service;
12 use Automattic\Jetpack\Status\Host;
13 use Jetpack_Gutenberg;
14 use Jetpack_Options;
15
16 require_once dirname( __DIR__ ) . '/_inc/subscription-service/include.php';
17
18 const LOGIN_BUTTON_NAME = 'premium-content/login-button';
19
20 /**
21 * Registers the block for use in Gutenberg
22 * This is done via an action so that we can disable
23 * registration if we need to.
24 */
25 function register_login_button_block() {
26 Blocks::jetpack_register_block(
27 LOGIN_BUTTON_NAME,
28 array(
29 'render_callback' => __NAMESPACE__ . '\render_login_button_block',
30 'render_email_callback' => __NAMESPACE__ . '\render_login_button_block_email',
31 )
32 );
33 }
34 add_action( 'init', __NAMESPACE__ . '\register_login_button_block' );
35
36 /**
37 * Returns current URL.
38 *
39 * @return string
40 */
41 function get_current_url() {
42 if ( ! isset( $_SERVER['HTTP_HOST'] ) || ! isset( $_SERVER['REQUEST_URI'] ) ) {
43 return '';
44 }
45
46 return ( is_ssl() ? 'https://' : 'http://' ) . wp_unslash( $_SERVER['HTTP_HOST'] ) . wp_unslash( $_SERVER['REQUEST_URI'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
47 }
48
49 /**
50 * Returns subscriber log in URL.
51 *
52 * @param string $redirect Path to redirect to on login.
53 *
54 * @return string
55 */
56 function get_subscriber_login_url( $redirect ) {
57 $redirect = ! empty( $redirect ) ? $redirect : get_site_url();
58
59 if ( ( new Host() )->is_wpcom_simple() ) {
60 // On WPCOM we will redirect immediately
61 return wpcom_logmein_redirect_url( $redirect, false, null, 'link', get_current_blog_id() );
62 }
63
64 // On self-hosted we will save and hide the token.
65 // rawurlencode the redirect before nesting it: it is already percent-encoded
66 // (e.g. an emoji or non-ASCII slug comes through as %F0%9F%8C%91), and add_query_arg
67 // does not encode the values it inserts. Without this extra layer the value is
68 // over-decoded to raw bytes by the time it reaches the subscribers/auth endpoint,
69 // which strips it and 404s. See NL-273.
70 $redirect_url = get_site_url() . '/wp-json/jetpack/v4/subscribers/auth';
71 $redirect_url = add_query_arg( 'redirect_url', rawurlencode( $redirect ), $redirect_url );
72
73 return add_query_arg(
74 array(
75 'site_id' => intval( Jetpack_Options::get_option( 'id' ) ),
76 'redirect_url' => rawurlencode( $redirect_url ),
77 ),
78 'https://subscribe.wordpress.com/memberships/jwt/'
79 );
80 }
81
82 /**
83 * Determines whether the current visitor is a confirmed subscriber -- someone who
84 * actually holds a premium-content session token, not merely someone with a
85 * WordPress session on this site.
86 *
87 * A bare WordPress session is not proof of a subscription (see NL-787): the
88 * previous is_user_logged_in() || has_token_from_cookie() check hid this block's
89 * only "Log in" link -- the sole way to mint a fresh token via the
90 * subscribe.wordpress.com magic-link round trip -- for anyone the site owner
91 * simply added as a WP user (or anyone else with an ordinary session and no
92 * token), leaving them with no way to recover.
93 *
94 * @return bool
95 */
96 function is_subscriber_logged_in() {
97 return is_user_logged_in() && Abstract_Token_Subscription_Service::has_token_from_cookie();
98 }
99
100 /**
101 * Render callback.
102 *
103 * @param array $attributes Array containing the block attributes.
104 * @param string $content String containing the block content.
105 *
106 * @return string
107 */
108 function render_login_button_block( $attributes, $content ) {
109 if ( ! pre_render_checks() ) {
110 return '';
111 }
112
113 // The viewer is logged it, so they shouldn't see the login button.
114 if ( is_subscriber_logged_in() ) {
115 return '';
116 }
117
118 Jetpack_Gutenberg::load_styles_as_required( LOGIN_BUTTON_NAME );
119
120 $redirect_url = get_current_url();
121 $url = get_subscriber_login_url( $redirect_url );
122
123 $content = preg_replace( '/(<a\b[^><]*)>/i', '$1 href="' . esc_url( $url ) . '">', $content );
124
125 // Defense in depth: the label is inner block content (KSES-filtered on save for
126 // roles without `unfiltered_html`), but escape it again on output so a stored
127 // payload can never render as live markup.
128 return wp_kses_post( $content );
129 }
130
131 /**
132 * Render email callback.
133 *
134 * @return string
135 */
136 function render_login_button_block_email() {
137 // We don't want to render the login button in emails.
138 // The subscriber is already considered logged in in emails.
139 return '';
140 }
141