Skip to content

Commit 4302cd3

Browse files
Initsogarmatticbot
authored andcommitted
JPMT-28 Connection: add provider-specific authentication endpoints (#42602)
* Add provider-specific authorization URL endpoint for Jetpack connection * changelog * Add support for magic link authentication and update provider options * Replace string-based URL manipulation with proper URL parsing and construction for provider-specific authentication endpoints. * Update doc, bring back $raw parameter * Refactor email address assignment using null coalescing operator * Update permission callback to use the correct method and handle optional redirect URI and email address parameters * Refactor email address handling in magic link flow and ensure URL parameter values are properly encoded * Add unit tests for provider-specific authentication endpoints * Fix phan warning Committed via a GitHub action: https://github.com/Automattic/jetpack/actions/runs/14000537385 Upstream-Ref: Automattic/jetpack@96b2fa3
1 parent 4a7318e commit 4302cd3

File tree

20 files changed

+260
-135
lines changed

20 files changed

+260
-135
lines changed

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"automattic/jetpack-autoloader": "^5.0.5",
99
"automattic/jetpack-composer-plugin": "^4.0.4",
1010
"automattic/jetpack-config": "^3.0.1",
11-
"automattic/jetpack-connection": "^6.7.7",
11+
"automattic/jetpack-connection": "^6.8.0-alpha",
1212
"automattic/jetpack-my-jetpack": "^5.9.0-alpha",
1313
"automattic/jetpack-sync": "^4.9.2",
1414
"automattic/jetpack-videopress": "^0.27.5-alpha",

jetpack_vendor/automattic/jetpack-boost-core/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"license": "GPL-2.0-or-later",
66
"require": {
77
"php": ">=7.2",
8-
"automattic/jetpack-connection": "^6.7.7"
8+
"automattic/jetpack-connection": "^6.8.0-alpha"
99
},
1010
"require-dev": {
1111
"yoast/phpunit-polyfills": "^3.0.0",

jetpack_vendor/automattic/jetpack-connection/CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [6.8.0-alpha] - unreleased
9+
10+
This is an alpha version! The changes listed here are not final.
11+
12+
### Added
13+
- Add auth providers support
14+
815
## [6.7.7] - 2025-03-21
916
### Changed
1017
- Internal updates.
@@ -1362,6 +1369,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
13621369

13631370
- Separate the connection library into its own package.
13641371

1372+
[6.8.0-alpha]: https://github.com/Automattic/jetpack-connection/compare/v6.7.7...v6.8.0-alpha
13651373
[6.7.7]: https://github.com/Automattic/jetpack-connection/compare/v6.7.6...v6.7.7
13661374
[6.7.6]: https://github.com/Automattic/jetpack-connection/compare/v6.7.5...v6.7.6
13671375
[6.7.5]: https://github.com/Automattic/jetpack-connection/compare/v6.7.4...v6.7.5

jetpack_vendor/automattic/jetpack-connection/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
"link-template": "https://github.com/Automattic/jetpack-connection/compare/v${old}...v${new}"
6565
},
6666
"branch-alias": {
67-
"dev-trunk": "6.7.x-dev"
67+
"dev-trunk": "6.8.x-dev"
6868
},
6969
"dependencies": {
7070
"test-only": [

jetpack_vendor/automattic/jetpack-connection/src/class-package-version.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*/
1313
class Package_Version {
1414

15-
const PACKAGE_VERSION = '6.7.7';
15+
const PACKAGE_VERSION = '6.8.0-alpha';
1616

1717
const PACKAGE_SLUG = 'connection';
1818

jetpack_vendor/automattic/jetpack-connection/src/class-rest-connector.php

+77
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,34 @@ public function __construct( Manager $connection ) {
261261
)
262262
);
263263

264+
// Provider-specific authorization URL endpoint
265+
register_rest_route(
266+
'jetpack/v4',
267+
'/connection/authorize_url/(?P<provider>[a-zA-Z]+)',
268+
array(
269+
'methods' => WP_REST_Server::READABLE,
270+
'callback' => array( $this, 'connection_authorize_url_provider' ),
271+
'permission_callback' => __CLASS__ . '::user_connection_data_permission_check',
272+
'args' => array(
273+
'provider' => array(
274+
'description' => __( 'Authentication provider (google, github, apple, link)', 'jetpack-connection' ),
275+
'type' => 'string',
276+
'required' => true,
277+
'enum' => array( 'google', 'github', 'apple', 'link' ),
278+
),
279+
'redirect_uri' => array(
280+
'description' => __( 'URI of the admin page where the user should be redirected after connection flow', 'jetpack-connection' ),
281+
'type' => 'string',
282+
),
283+
'email_address' => array(
284+
'description' => __( 'Email address for magic link authentication', 'jetpack-connection' ),
285+
'type' => 'string',
286+
'format' => 'email',
287+
),
288+
),
289+
)
290+
);
291+
264292
register_rest_route(
265293
'jetpack/v4',
266294
'/user-token',
@@ -1110,4 +1138,53 @@ public function connection_check_permission_check() {
11101138
? true
11111139
: new WP_Error( 'invalid_permission_connection_check', self::get_user_permissions_error_msg(), array( 'status' => rest_authorization_required_code() ) );
11121140
}
1141+
1142+
/**
1143+
* Provider-specific authorization URL endpoint
1144+
*
1145+
* @param WP_REST_Request $request The request sent to the WP REST API.
1146+
*
1147+
* @return \WP_REST_Response|WP_Error
1148+
*/
1149+
public function connection_authorize_url_provider( $request ) {
1150+
$provider = $request['provider'];
1151+
$redirect_uri = $request['redirect_uri'] ?? '';
1152+
1153+
// Validate magic link parameters if provider is 'link'
1154+
if ( 'link' === $provider ) {
1155+
if ( empty( $request['email_address'] ) ) {
1156+
return new WP_Error(
1157+
'missing_email',
1158+
__( 'Email address is required for magic link authentication.', 'jetpack-connection' ),
1159+
array( 'status' => 400 )
1160+
);
1161+
}
1162+
1163+
// Sanitize email address
1164+
$email = sanitize_email( $request['email_address'] );
1165+
if ( ! is_email( $email ) ) {
1166+
return new WP_Error(
1167+
'invalid_email',
1168+
__( 'Invalid email address format.', 'jetpack-connection' ),
1169+
array( 'status' => 400 )
1170+
);
1171+
}
1172+
}
1173+
1174+
$authorize_url = ( new Authorize_Redirect( $this->connection ) )->build_authorize_url(
1175+
$redirect_uri,
1176+
false,
1177+
false,
1178+
$provider,
1179+
array(
1180+
'email_address' => $email ?? '',
1181+
)
1182+
);
1183+
1184+
return rest_ensure_response(
1185+
array(
1186+
'authorizeUrl' => $authorize_url,
1187+
)
1188+
);
1189+
}
11131190
}

jetpack_vendor/automattic/jetpack-connection/src/webhooks/class-authorize-redirect.php

+44-4
Original file line numberDiff line numberDiff line change
@@ -101,22 +101,59 @@ function ( $domains ) {
101101
* Create the Jetpack authorization URL.
102102
*
103103
* @since 2.7.6 Added optional $from and $raw parameters.
104+
* @since 6.8.0-alpha Added optional $provider and $provider_args parameters.
104105
*
105106
* @param bool|string $redirect URL to redirect to.
106107
* @param bool|string $from If not false, adds 'from=$from' param to the connect URL.
107108
* @param bool $raw If true, URL will not be escaped.
109+
* @param string|null $provider The authentication provider (google, github, apple, link).
110+
* @param array|null $provider_args Additional provider-specific arguments.
108111
*
109112
* @todo Update default value for redirect since the called function expects a string.
110113
*
111114
* @return mixed|void
112115
*/
113-
public function build_authorize_url( $redirect = false, $from = false, $raw = false ) {
116+
public function build_authorize_url( $redirect = false, $from = false, $raw = false, $provider = null, $provider_args = null ) {
114117

115118
add_filter( 'jetpack_connect_request_body', array( __CLASS__, 'filter_connect_request_body' ) );
116119
add_filter( 'jetpack_connect_redirect_url', array( __CLASS__, 'filter_connect_redirect_url' ) );
117120

118121
$url = $this->connection->get_authorization_url( wp_get_current_user(), $redirect, $from, $raw );
119122

123+
// If a provider is specified, modify the URL to use the provider-specific endpoint
124+
if ( $provider && in_array( $provider, array( 'google', 'github', 'apple', 'link' ), true ) ) {
125+
// Parse the URL to modify it safely
126+
$url_parts = wp_parse_url( $url );
127+
128+
if ( ! empty( $url_parts['host'] ) && ! empty( $url_parts['path'] ) ) {
129+
// Build the new URL using wordpress.com as the host
130+
$url_parts['host'] = 'wordpress.com';
131+
$url_parts['path'] = '/log-in/jetpack/' . $provider;
132+
133+
// Preserve the query parameters
134+
$query_params = array();
135+
if ( ! empty( $url_parts['query'] ) ) {
136+
parse_str( $url_parts['query'], $query_params );
137+
}
138+
139+
// Add magic link specific parameters if provider is 'link'
140+
if ( 'link' === $provider && is_array( $provider_args ) && ! empty( $provider_args['email_address'] ) ) {
141+
$query_params['email_address'] = $provider_args['email_address'];
142+
// Add flag to trigger magic link flow
143+
$query_params['auto_trigger'] = '1';
144+
}
145+
146+
// URL encode all parameter values
147+
$query_params = array_map( 'rawurlencode', $query_params );
148+
149+
// Rebuild the URL
150+
$url = 'https://' . $url_parts['host'] . $url_parts['path'];
151+
if ( ! empty( $query_params ) ) {
152+
$url = add_query_arg( $query_params, $url );
153+
}
154+
}
155+
}
156+
120157
remove_filter( 'jetpack_connect_request_body', array( __CLASS__, 'filter_connect_request_body' ) );
121158
remove_filter( 'jetpack_connect_redirect_url', array( __CLASS__, 'filter_connect_redirect_url' ) );
122159

@@ -125,11 +162,14 @@ public function build_authorize_url( $redirect = false, $from = false, $raw = fa
125162
*
126163
* @since jetpack-8.9.0
127164
* @since 2.7.6 Added $raw parameter.
165+
* @since 6.8.0-alpha Added $provider and $provider_args parameters.
128166
*
129-
* @param string $url Connection URL.
130-
* @param bool $raw If true, URL will not be escaped.
167+
* @param string $url Connection URL.
168+
* @param bool $raw If true, URL will not be escaped.
169+
* @param string|null $provider The authentication provider if specified.
170+
* @param array|null $provider_args Additional provider-specific arguments.
131171
*/
132-
return apply_filters( 'jetpack_build_authorize_url', $url, $raw );
172+
return apply_filters( 'jetpack_build_authorize_url', $url, $raw, $provider, $provider_args );
133173
}
134174

135175
/**

jetpack_vendor/automattic/jetpack-explat/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"license": "GPL-2.0-or-later",
66
"require": {
77
"php": ">=7.2",
8-
"automattic/jetpack-connection": "^6.7.7"
8+
"automattic/jetpack-connection": "^6.8.0-alpha"
99
},
1010
"require-dev": {
1111
"yoast/phpunit-polyfills": "^3.0.0",

jetpack_vendor/automattic/jetpack-jitm/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"php": ">=7.2",
88
"automattic/jetpack-a8c-mc-stats": "^3.0.4",
99
"automattic/jetpack-assets": "^4.0.14",
10-
"automattic/jetpack-connection": "^6.7.7",
10+
"automattic/jetpack-connection": "^6.8.0-alpha",
1111
"automattic/jetpack-device-detection": "^3.0.5",
1212
"automattic/jetpack-logo": "^3.0.4",
1313
"automattic/jetpack-redirect": "^3.0.5",

jetpack_vendor/automattic/jetpack-licensing/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"license": "GPL-2.0-or-later",
66
"require": {
77
"php": ">=7.2",
8-
"automattic/jetpack-connection": "^6.7.7"
8+
"automattic/jetpack-connection": "^6.8.0-alpha"
99
},
1010
"require-dev": {
1111
"automattic/jetpack-test-environment": "@dev",

jetpack_vendor/automattic/jetpack-my-jetpack/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"automattic/jetpack-admin-ui": "^0.5.7",
99
"automattic/jetpack-assets": "^4.0.14",
1010
"automattic/jetpack-boost-speed-score": "^0.4.6",
11-
"automattic/jetpack-connection": "^6.7.7",
11+
"automattic/jetpack-connection": "^6.8.0-alpha",
1212
"automattic/jetpack-explat": "^0.2.13",
1313
"automattic/jetpack-jitm": "^4.2.6",
1414
"automattic/jetpack-licensing": "^3.0.8",

jetpack_vendor/automattic/jetpack-protect-status/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"license": "GPL-2.0-or-later",
66
"require": {
77
"php": ">=7.2",
8-
"automattic/jetpack-connection": "^6.7.7",
8+
"automattic/jetpack-connection": "^6.8.0-alpha",
99
"automattic/jetpack-plugins-installer": "^0.5.4",
1010
"automattic/jetpack-sync": "^4.9.2",
1111
"automattic/jetpack-protect-models": "^0.5.4",

jetpack_vendor/automattic/jetpack-sync/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"license": "GPL-2.0-or-later",
66
"require": {
77
"php": ">=7.2",
8-
"automattic/jetpack-connection": "^6.7.7",
8+
"automattic/jetpack-connection": "^6.8.0-alpha",
99
"automattic/jetpack-constants": "^3.0.5",
1010
"automattic/jetpack-password-checker": "^0.4.7",
1111
"automattic/jetpack-ip": "^0.4.6",

jetpack_vendor/automattic/jetpack-videopress/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"php": ">=7.2",
88
"automattic/jetpack-admin-ui": "^0.5.7",
99
"automattic/jetpack-assets": "^4.0.14",
10-
"automattic/jetpack-connection": "^6.7.7",
10+
"automattic/jetpack-connection": "^6.8.0-alpha",
1111
"automattic/jetpack-my-jetpack": "^5.9.0-alpha",
1212
"automattic/jetpack-plans": "^0.6.1"
1313
},

jetpack_vendor/i18n-map.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
),
2727
'jetpack-connection' => array(
2828
'path' => 'jetpack_vendor/automattic/jetpack-connection',
29-
'ver' => '6.7.7',
29+
'ver' => '6.8.0-alpha1742589662',
3030
),
3131
'jetpack-explat' => array(
3232
'path' => 'jetpack_vendor/automattic/jetpack-explat',

vendor/automattic/jetpack-plans/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"license": "GPL-2.0-or-later",
66
"require": {
77
"php": ">=7.2",
8-
"automattic/jetpack-connection": "^6.7.7"
8+
"automattic/jetpack-connection": "^6.8.0-alpha"
99
},
1010
"require-dev": {
1111
"yoast/phpunit-polyfills": "^3.0.0",

0 commit comments

Comments
 (0)