updated plugin Jetpack Protect version 1.3.0

This commit is contained in:
2023-03-17 22:34:13 +00:00
committed by Gitium
parent 19e086d1c4
commit 1e9ac45ec6
183 changed files with 4388 additions and 2345 deletions

View File

@ -0,0 +1,244 @@
<?php
/**
* Admin connection notices.
*
* @package automattic/jetpack-admin-ui
*/
namespace Automattic\Jetpack\Connection;
use Automattic\Jetpack\Redirect;
use Automattic\Jetpack\Tracking;
/**
* Admin connection notices.
*/
class Connection_Notice {
/**
* Whether the class has been initialized.
*
* @var bool
*/
private static $is_initialized = false;
/**
* The constructor.
*/
public function __construct() {
if ( ! static::$is_initialized ) {
add_action( 'current_screen', array( $this, 'initialize_notices' ) );
static::$is_initialized = true;
}
}
/**
* Initialize the notices if needed.
*
* @param \WP_Screen $screen WP Core's screen object.
*
* @return void
*/
public function initialize_notices( $screen ) {
if ( ! in_array(
$screen->id,
array(
'jetpack_page_akismet-key-config',
'admin_page_jetpack_modules',
),
true
) ) {
add_action( 'admin_notices', array( $this, 'delete_user_update_connection_owner_notice' ) );
}
}
/**
* This is an entire admin notice dedicated to messaging and handling of the case where a user is trying to delete
* the connection owner.
*/
public function delete_user_update_connection_owner_notice() {
global $current_screen;
/*
* phpcs:disable WordPress.Security.NonceVerification.Recommended
*
* This function is firing within wp-admin and checks (below) if it is in the midst of a deletion on the users
* page. Nonce will be already checked by WordPress, so we do not need to check ourselves.
*/
if ( ! isset( $current_screen->base ) || 'users' !== $current_screen->base ) {
return;
}
if ( ! isset( $_REQUEST['action'] ) || 'delete' !== $_REQUEST['action'] ) {
return;
}
// Get connection owner or bail.
$connection_manager = new Manager();
$connection_owner_id = $connection_manager->get_connection_owner_id();
if ( ! $connection_owner_id ) {
return;
}
$connection_owner_userdata = get_userdata( $connection_owner_id );
// Bail if we're not trying to delete connection owner.
$user_ids_to_delete = array();
if ( isset( $_REQUEST['users'] ) ) {
$user_ids_to_delete = array_map( 'sanitize_text_field', wp_unslash( $_REQUEST['users'] ) );
} elseif ( isset( $_REQUEST['user'] ) ) {
$user_ids_to_delete[] = sanitize_text_field( wp_unslash( $_REQUEST['user'] ) );
}
// phpcs:enable
$user_ids_to_delete = array_map( 'absint', $user_ids_to_delete );
$deleting_connection_owner = in_array( $connection_owner_id, (array) $user_ids_to_delete, true );
if ( ! $deleting_connection_owner ) {
return;
}
// Bail if they're trying to delete themselves to avoid confusion.
if ( get_current_user_id() === $connection_owner_id ) {
return;
}
$tracking = new Tracking();
// Track it!
if ( method_exists( $tracking, 'record_user_event' ) ) {
$tracking->record_user_event( 'delete_connection_owner_notice_view' );
}
$connected_admins = $connection_manager->get_connected_users( 'jetpack_disconnect' );
$user = is_a( $connection_owner_userdata, 'WP_User' ) ? esc_html( $connection_owner_userdata->data->user_login ) : '';
echo "<div class='notice notice-warning' id='jetpack-notice-switch-connection-owner'>";
echo '<h2>' . esc_html__( 'Important notice about your Jetpack connection:', 'jetpack-connection' ) . '</h2>';
echo '<p>' . sprintf(
/* translators: WordPress User, if available. */
esc_html__( 'Warning! You are about to delete the Jetpack connection owner (%s) for this site, which may cause some of your Jetpack features to stop working.', 'jetpack-connection' ),
esc_html( $user )
) . '</p>';
if ( ! empty( $connected_admins ) && count( $connected_admins ) > 1 ) {
echo '<form id="jp-switch-connection-owner" action="" method="post">';
echo "<label for='owner'>" . esc_html__( 'You can choose to transfer connection ownership to one of these already-connected admins:', 'jetpack-connection' ) . ' </label>';
$connected_admin_ids = array_map(
function ( $connected_admin ) {
return $connected_admin->ID;
},
$connected_admins
);
wp_dropdown_users(
array(
'name' => 'owner',
'include' => array_diff( $connected_admin_ids, array( $connection_owner_id ) ),
'show' => 'display_name_with_login',
)
);
echo '<p>';
submit_button( esc_html__( 'Set new connection owner', 'jetpack-connection' ), 'primary', 'jp-switch-connection-owner-submit', false );
echo '</p>';
echo "<div id='jp-switch-user-results'></div>";
echo '</form>';
?>
<script type="text/javascript">
( function() {
const switchOwnerButton = document.getElementById('jp-switch-connection-owner');
if ( ! switchOwnerButton ) {
return;
}
switchOwnerButton.addEventListener( 'submit', function ( e ) {
e.preventDefault();
const submitBtn = document.getElementById('jp-switch-connection-owner-submit');
submitBtn.disabled = true;
const results = document.getElementById('jp-switch-user-results');
results.innerHTML = '';
results.classList.remove( 'error-message' );
const handleAPIError = ( message ) => {
submitBtn.disabled = false;
results.classList.add( 'error-message' );
results.innerHTML = message || "<?php esc_html_e( 'Something went wrong. Please try again.', 'jetpack-connection' ); ?>";
}
fetch(
<?php echo wp_json_encode( esc_url_raw( get_rest_url() . 'jetpack/v4/connection/owner' ), JSON_HEX_TAG | JSON_HEX_AMP ); ?>,
{
method: 'POST',
headers: {
'X-WP-Nonce': <?php echo wp_json_encode( wp_create_nonce( 'wp_rest' ), JSON_HEX_TAG | JSON_HEX_AMP ); ?>,
},
body: new URLSearchParams( new FormData( this ) ),
}
)
.then( response => response.json() )
.then( data => {
if ( data.hasOwnProperty( 'code' ) && data.code === 'success' ) {
// Owner successfully changed.
results.innerHTML = <?php echo wp_json_encode( esc_html__( 'Success!', 'jetpack-connection' ), JSON_HEX_TAG | JSON_HEX_AMP ); ?>;
setTimeout(function () {
document.getElementById( 'jetpack-notice-switch-connection-owner' ).style.display = 'none';
}, 1000);
return;
}
handleAPIError( data?.message );
} )
.catch( () => handleAPIError() );
});
} )();
</script>
<?php
} else {
echo '<p>' . esc_html__( 'Every Jetpack site needs at least one connected admin for the features to work properly. Please connect to your WordPress.com account via the button below. Once you connect, you may refresh this page to see an option to change the connection owner.', 'jetpack-connection' ) . '</p>';
$connect_url = $connection_manager->get_authorization_url();
$connect_url = add_query_arg( 'from', 'delete_connection_owner_notice', $connect_url );
echo "<a href='" . esc_url( $connect_url ) . "' target='_blank' rel='noopener noreferrer' class='button-primary'>" . esc_html__( 'Connect to WordPress.com', 'jetpack-connection' ) . '</a>';
}
echo '<p>';
printf(
wp_kses(
/* translators: URL to Jetpack support doc regarding the primary user. */
__( "<a href='%s' target='_blank' rel='noopener noreferrer'>Learn more</a> about the connection owner and what will break if you do not have one.", 'jetpack-connection' ),
array(
'a' => array(
'href' => true,
'target' => true,
'rel' => true,
),
)
),
esc_url( Redirect::get_url( 'jetpack-support-primary-user' ) )
);
echo '</p>';
echo '<p>';
printf(
wp_kses(
/* translators: URL to contact Jetpack support. */
__( 'As always, feel free to <a href="%s" target="_blank" rel="noopener noreferrer">contact our support team</a> if you have any questions.', 'jetpack-connection' ),
array(
'a' => array(
'href' => true,
'target' => true,
'rel' => true,
),
)
),
esc_url( Redirect::get_url( 'jetpack-contact-support' ) )
);
echo '</p>';
echo '</div>';
}
}

View File

@ -288,7 +288,6 @@ class Error_Handler {
}
return false;
}
/**
@ -326,7 +325,6 @@ class Error_Handler {
);
return $error_array;
}
/**
@ -380,7 +378,6 @@ class Error_Handler {
}
return $encrypted_data;
}
/**
@ -401,7 +398,6 @@ class Error_Handler {
}
return $user_id;
}
/**
@ -566,7 +562,6 @@ class Error_Handler {
$verified_errors[ $error_code ][ $user_id ] = $error;
update_option( self::STORED_VERIFIED_ERRORS_OPTION, $verified_errors );
}
/**
@ -612,7 +607,6 @@ class Error_Handler {
}
return new \WP_REST_Response( false, 200 );
}
/**

View File

@ -164,7 +164,6 @@ class Heartbeat {
}
return $return;
}
/**

View File

@ -45,6 +45,20 @@ class Manager {
*/
private $plugin = null;
/**
* Error handler object.
*
* @var Error_Handler
*/
public $error_handler = null;
/**
* Jetpack_XMLRPC_Server object
*
* @var Jetpack_XMLRPC_Server
*/
public $xmlrpc_server = null;
/**
* Holds extra parameters that will be sent along in the register request body.
*
@ -117,6 +131,9 @@ class Manager {
if ( defined( 'JETPACK__SANDBOX_DOMAIN' ) && JETPACK__SANDBOX_DOMAIN ) {
( new Server_Sandbox() )->init();
}
// Initialize connection notices.
new Connection_Notice();
}
/**
@ -900,7 +917,8 @@ class Manager {
* @return true|WP_Error True if owner successfully changed, WP_Error otherwise.
*/
public function update_connection_owner( $new_owner_id ) {
if ( ! user_can( $new_owner_id, 'administrator' ) ) {
$roles = new Roles();
if ( ! user_can( $new_owner_id, $roles->translate_role_to_cap( 'administrator' ) ) ) {
return new WP_Error(
'new_owner_not_admin',
__( 'New owner is not admin', 'jetpack-connection' ),
@ -1764,7 +1782,6 @@ class Manager {
* Should be changed to protected.
*/
public function handle_authorization() {
}
/**
@ -1857,7 +1874,7 @@ class Manager {
'user_email' => $user->user_email,
'user_login' => $user->user_login,
'is_active' => $this->has_connected_owner(), // TODO Deprecate this.
'jp_version' => Constants::get_constant( 'JETPACK__VERSION' ),
'jp_version' => (string) Constants::get_constant( 'JETPACK__VERSION' ),
'auth_type' => $auth_type,
'secret' => $secrets['secret_1'],
'blogname' => get_option( 'blogname' ),
@ -2474,4 +2491,22 @@ class Manager {
}
return $stats;
}
/**
* Get the WPCOM or self-hosted site ID.
*
* @return int|WP_Error
*/
public static function get_site_id() {
$is_wpcom = ( defined( 'IS_WPCOM' ) && IS_WPCOM );
$site_id = $is_wpcom ? get_current_blog_id() : \Jetpack_Options::get_option( 'id' );
if ( ! $site_id ) {
return new \WP_Error(
'unavailable_site_id',
__( 'Sorry, something is wrong with your Jetpack connection.', 'jetpack-connection' ),
403
);
}
return (int) $site_id;
}
}

View File

@ -12,7 +12,7 @@ namespace Automattic\Jetpack\Connection;
*/
class Package_Version {
const PACKAGE_VERSION = '1.47.1';
const PACKAGE_VERSION = '1.51.1';
const PACKAGE_SLUG = 'connection';

View File

@ -180,7 +180,6 @@ class Plugin_Storage {
}
self::$configured = true;
}
/**

View File

@ -365,7 +365,6 @@ class REST_Connector {
}
return array_values( $plugins );
}
/**
@ -398,7 +397,6 @@ class REST_Connector {
}
return new WP_Error( 'invalid_user_permission_activate_plugins', self::get_user_permissions_error_msg(), array( 'status' => rest_authorization_required_code() ) );
}
/**
@ -495,7 +493,6 @@ class REST_Connector {
}
return $response;
}
/**
@ -513,7 +510,6 @@ class REST_Connector {
self::get_user_permissions_error_msg(),
array( 'status' => rest_authorization_required_code() )
);
}
/**

View File

@ -40,7 +40,7 @@ class Secrets {
$attempts = 1;
$secret_length = strlen( $secret );
while ( $secret_length < 32 && $attempts < 32 ) {
$attempts++;
++$attempts;
$secret .= wp_generate_password( 32, false );
$secret_length = strlen( $secret );
}

View File

@ -146,7 +146,6 @@ class Server_Sandbox {
} else {
$this->log_new_signature_error( 'Empty Authorization Header' );
}
}
/**

View File

@ -316,6 +316,5 @@ class Tracking {
'_ut' => 'anon',
'_ui' => $anon_id,
);
}
}

View File

@ -128,7 +128,7 @@ class Urls {
Constants::get_constant( 'JETPACK_SYNC_USE_RAW_URL' )
) {
$scheme = is_ssl() ? 'https' : 'http';
$url = self::get_raw_url( $url_type );
$url = (string) self::get_raw_url( $url_type );
$url = set_url_scheme( $url, $scheme );
} else {
$url = self::normalize_www_in_url( $url_type, $url_function );

View File

@ -93,7 +93,6 @@ class Webhooks {
break;
// Class Jetpack::admin_page_load() still handles other cases.
}
}
/**
@ -193,23 +192,20 @@ class Webhooks {
}
wp_safe_redirect( $connect_url );
$this->do_exit();
} elseif ( ! isset( $_GET['calypso_env'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- no site changes.
( new CookieState() )->state( 'message', 'already_authorized' );
wp_safe_redirect( $redirect );
$this->do_exit();
} else {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- no site changes.
if ( ! isset( $_GET['calypso_env'] ) ) {
( new CookieState() )->state( 'message', 'already_authorized' );
wp_safe_redirect( $redirect );
$this->do_exit();
} else {
$connect_url = add_query_arg(
array(
'from' => $from,
'already_authorized' => true,
),
$this->connection->get_authorization_url()
);
wp_safe_redirect( $connect_url );
$this->do_exit();
}
$connect_url = add_query_arg(
array(
'from' => $from,
'already_authorized' => true,
),
$this->connection->get_authorization_url()
);
wp_safe_redirect( $connect_url );
$this->do_exit();
}
}
}

View File

@ -1,63 +0,0 @@
/* global jpTracksAJAX */
( function ( $, jpTracksAJAX ) {
window.jpTracksAJAX = window.jpTracksAJAX || {};
const debugSet = localStorage.getItem( 'debug' ) === 'dops:analytics';
window.jpTracksAJAX.record_ajax_event = function ( eventName, eventType, eventProp ) {
const data = {
tracksNonce: jpTracksAJAX.jpTracksAJAX_nonce,
action: 'jetpack_tracks',
tracksEventType: eventType,
tracksEventName: eventName,
tracksEventProp: eventProp || false,
};
return $.ajax( {
type: 'POST',
url: jpTracksAJAX.ajaxurl,
data: data,
success: function ( response ) {
if ( debugSet ) {
// eslint-disable-next-line
console.log( 'AJAX tracks event recorded: ', data, response );
}
},
} );
};
$( document ).ready( function () {
$( 'body' ).on( 'click', '.jptracks a, a.jptracks', function ( event ) {
const $this = $( event.target );
// We know that the jptracks element is either this, or its ancestor
const $jptracks = $this.closest( '.jptracks' );
// We need an event name at least
const eventName = $jptracks.attr( 'data-jptracks-name' );
if ( undefined === eventName ) {
return;
}
const eventProp = $jptracks.attr( 'data-jptracks-prop' ) || false;
const url = $this.attr( 'href' );
const target = $this.get( 0 ).target;
let newTabWindow = null;
if ( url && target && '_self' !== target ) {
newTabWindow = window.open( '', target );
newTabWindow.opener = null;
}
event.preventDefault();
window.jpTracksAJAX.record_ajax_event( eventName, 'click', eventProp ).always( function () {
// Continue on to whatever url they were trying to get to.
if ( url && ! $this.hasClass( 'thickbox' ) ) {
if ( newTabWindow ) {
newTabWindow.location = url;
return;
}
window.location = url;
}
} );
} );
} );
} )( jQuery, jpTracksAJAX );

View File

@ -1,94 +0,0 @@
/**
* This was abstracted from wp-calypso's analytics lib: https://github.com/Automattic/wp-calypso/blob/trunk/client/lib/analytics/README.md
* Some stuff was removed like GA tracking and other things not necessary for Jetpack tracking.
*
* This library should only be used and loaded if the Jetpack site is connected.
*/
// Load tracking scripts
window._tkq = window._tkq || [];
let _user;
const debug = console.error; // eslint-disable-line no-console
/**
* Build a query string.
*
* @param {string|object} group - Stat group, or object mapping groups to names.
* @param {string} [name] - Stat name, when `group` is a string.
* @returns {string} Query string fragment.
*/
function buildQuerystring( group, name ) {
let uriComponent = '';
if ( 'object' === typeof group ) {
for ( const key in group ) {
uriComponent += '&x_' + encodeURIComponent( key ) + '=' + encodeURIComponent( group[ key ] );
}
} else {
uriComponent = '&x_' + encodeURIComponent( group ) + '=' + encodeURIComponent( name );
}
return uriComponent;
}
const analytics = {
initialize: function ( userId, username ) {
analytics.setUser( userId, username );
analytics.identifyUser();
},
mc: {
bumpStat: function ( group, name ) {
const uriComponent = buildQuerystring( group, name ); // prints debug info
new Image().src =
document.location.protocol +
'//pixel.wp.com/g.gif?v=wpcom-no-pv' +
uriComponent +
'&t=' +
Math.random();
},
},
tracks: {
recordEvent: function ( eventName, eventProperties ) {
eventProperties = eventProperties || {};
if ( eventName.indexOf( 'jetpack_' ) !== 0 ) {
debug( '- Event name must be prefixed by "jetpack_"' );
return;
}
window._tkq.push( [ 'recordEvent', eventName, eventProperties ] );
},
recordPageView: function ( urlPath ) {
analytics.tracks.recordEvent( 'jetpack_page_view', {
path: urlPath,
} );
},
},
setUser: function ( userId, username ) {
_user = { ID: userId, username: username };
},
identifyUser: function () {
// Don't identify the user if we don't have one
if ( _user ) {
window._tkq.push( [ 'identifyUser', _user.ID, _user.username ] );
}
},
clearedIdentity: function () {
window._tkq.push( [ 'clearIdentity' ] );
},
};
if ( typeof module !== 'undefined' ) {
// Bundled by Webpack.
module.exports = analytics;
} else {
// Direct load.
window.analytics = analytics;
}

View File

@ -9,6 +9,7 @@ namespace Automattic\Jetpack\Connection\Webhooks;
use Automattic\Jetpack\Admin_UI\Admin_Menu;
use Automattic\Jetpack\Constants;
use Automattic\Jetpack\Licensing;
use Automattic\Jetpack\Tracking;
use GP_Locales;
use Jetpack_Network;
@ -56,8 +57,12 @@ class Authorize_Redirect {
exit;
}
// The user is either already connected, or finished the connection process.
if ( $this->connection->is_connected() && $this->connection->is_user_connected() ) {
// The user is either already connected, or finished the connection process.
if ( class_exists( '\Automattic\Jetpack\Licensing' ) && method_exists( '\Automattic\Jetpack\Licensing', 'handle_user_connected_redirect' ) ) {
Licensing::instance()->handle_user_connected_redirect( $dest_url );
}
wp_safe_redirect( $dest_url );
exit;
} elseif ( ! empty( $_GET['done'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended