diff --git a/src/js/_enqueues/admin/auth-app.js b/src/js/_enqueues/admin/auth-app.js index 99478d1824a2d..2de15c1d55a95 100644 --- a/src/js/_enqueues/admin/auth-app.js +++ b/src/js/_enqueues/admin/auth-app.js @@ -12,6 +12,7 @@ context = { userLogin: authApp.user_login, successUrl: authApp.success, + successFormat: authApp.success_format, rejectUrl: authApp.reject }; @@ -48,8 +49,9 @@ * @param {Object} request The request data. * @param {Object} context Context about the Application Password request. * @param {string} context.userLogin The user's login username. - * @param {string} context.successUrl The URL the user will be redirected to after approving the request. - * @param {string} context.rejectUrl The URL the user will be redirected to after rejecting the request. + * @param {string} context.successUrl The URL the user will be redirected to after approving the request. + * @param {string} context.successFormat The transport used for the success payload. + * @param {string} context.rejectUrl The URL the user will be redirected to after rejecting the request. */ request = wp.hooks.applyFilters( 'wp_application_passwords_approve_app_request', request, context ); @@ -75,15 +77,27 @@ wp.hooks.doAction( 'wp_application_passwords_approve_app_request_success', response, textStatus, jqXHR ); var raw = authApp.success, - url, message, $notice; + url, message, $notice, $callbackForm; if ( raw ) { - url = raw + ( -1 === raw.indexOf( '?' ) ? '?' : '&' ) + - 'site_url=' + encodeURIComponent( authApp.site_url ) + - '&user_login=' + encodeURIComponent( authApp.user_login ) + - '&password=' + encodeURIComponent( response.password ); - - window.location = url; + if ( 'form_post' === authApp.success_format ) { + $callbackForm = $( '
+ + + + site_url(), + 'user_login' => $user->user_login, + 'password' => $new_password, + ), + $success_url + ); + } } } } @@ -65,9 +104,10 @@ // Used in the HTML title tag. $title = __( 'Authorize Application' ); -$app_name = ! empty( $_REQUEST['app_name'] ) ? $_REQUEST['app_name'] : ''; -$app_id = ! empty( $_REQUEST['app_id'] ) ? $_REQUEST['app_id'] : ''; -$success_url = ! empty( $_REQUEST['success_url'] ) ? $_REQUEST['success_url'] : null; +$app_name = ! empty( $_REQUEST['app_name'] ) ? $_REQUEST['app_name'] : ''; +$app_id = ! empty( $_REQUEST['app_id'] ) ? $_REQUEST['app_id'] : ''; +$success_url = ! empty( $_REQUEST['success_url'] ) ? $_REQUEST['success_url'] : null; +$success_format = ! empty( $_REQUEST['success_format'] ) ? $_REQUEST['success_format'] : 'query'; if ( ! empty( $_REQUEST['reject_url'] ) ) { $reject_url = $_REQUEST['reject_url']; @@ -77,9 +117,7 @@ $reject_url = null; } -$user = wp_get_current_user(); - -$request = compact( 'app_name', 'app_id', 'success_url', 'reject_url' ); +$request = compact( 'app_name', 'app_id', 'success_url', 'reject_url', 'success_format' ); $is_valid = wp_is_authorize_application_password_request_valid( $request, $user ); if ( is_wp_error( $is_valid ) ) { @@ -124,10 +162,11 @@ 'auth-app', 'authApp', array( - 'site_url' => site_url(), - 'user_login' => $user->user_login, - 'success' => $success_url, - 'reject' => $reject_url ? $reject_url : admin_url(), + 'site_url' => site_url(), + 'user_login' => $user->user_login, + 'success' => $success_url, + 'success_format' => $success_format, + 'reject' => $reject_url ? $reject_url : admin_url(), ) ); @@ -241,6 +280,7 @@ +
' . esc_html(
- add_query_arg(
- array(
- 'site_url' => site_url(),
- 'user_login' => $user->user_login,
- 'password' => '[------]',
- ),
- $success_url
- )
- ) . ''
- );
+ if ( 'form_post' === $success_format ) {
+ printf(
+ /* translators: %s: The URL the user is being redirected to. */
+ __( 'Your connection details will be sent to %s.' ),
+ '' . esc_html( $success_url ) . ''
+ );
+ } else {
+ printf(
+ /* translators: %s: The URL the user is being redirected to. */
+ __( 'You will be sent to %s' ),
+ '' . esc_html(
+ add_query_arg(
+ array(
+ 'site_url' => site_url(),
+ 'user_login' => $user->user_login,
+ 'password' => '[------]',
+ ),
+ $success_url
+ )
+ ) . ''
+ );
+ }
} else {
_e( 'You will be given a password to manually enter into the application in question.' );
}
diff --git a/src/wp-admin/includes/user.php b/src/wp-admin/includes/user.php
index 477ee9b5af4b7..d042314e8abad 100644
--- a/src/wp-admin/includes/user.php
+++ b/src/wp-admin/includes/user.php
@@ -643,10 +643,11 @@ function admin_created_user_email( $text ) {
* @param array $request {
* The array of request data. All arguments are optional and may be empty.
*
- * @type string $app_name The suggested name of the application.
- * @type string $app_id A UUID provided by the application to uniquely identify it.
- * @type string $success_url The URL the user will be redirected to after approving the application.
- * @type string $reject_url The URL the user will be redirected to after rejecting the application.
+ * @type string $app_name The suggested name of the application.
+ * @type string $app_id A UUID provided by the application to uniquely identify it.
+ * @type string $success_url The URL the user will be redirected to after approving the application.
+ * @type string $success_format The transport to use for the success payload. Accepts 'query' or 'form_post'.
+ * @type string $reject_url The URL the user will be redirected to after rejecting the application.
* }
* @param WP_User $user The user authorizing the application.
* @return true|WP_Error True if the request is valid, a WP_Error object contains errors if not.
@@ -674,6 +675,27 @@ function wp_is_authorize_application_password_request_valid( $request, $user ) {
}
}
+ if ( isset( $request['success_format'] ) && ! in_array( $request['success_format'], array( 'query', 'form_post' ), true ) ) {
+ $error->add(
+ 'invalid_success_format',
+ __( 'The success format must be "query" or "form_post".' )
+ );
+ }
+
+ $success_url_scheme = ! empty( $request['success_url'] ) ? wp_parse_url( $request['success_url'], PHP_URL_SCHEME ) : '';
+
+ if (
+ ! empty( $request['success_url'] ) &&
+ isset( $request['success_format'] ) &&
+ 'form_post' === $request['success_format'] &&
+ ! in_array( strtolower( (string) $success_url_scheme ), array( 'http', 'https' ), true )
+ ) {
+ $error->add(
+ 'invalid_success_format',
+ __( 'The form_post success format requires an HTTP or HTTPS success URL.' )
+ );
+ }
+
if ( ! empty( $request['app_id'] ) && ! wp_is_uuid( $request['app_id'] ) ) {
$error->add(
'invalid_app_id',
diff --git a/tests/phpunit/tests/admin/includes/user/WpIsAuthorizeApplicationPasswordRequestValid_Test.php b/tests/phpunit/tests/admin/includes/user/WpIsAuthorizeApplicationPasswordRequestValid_Test.php
index a2e1320b2a150..866629a0ef97e 100644
--- a/tests/phpunit/tests/admin/includes/user/WpIsAuthorizeApplicationPasswordRequestValid_Test.php
+++ b/tests/phpunit/tests/admin/includes/user/WpIsAuthorizeApplicationPasswordRequestValid_Test.php
@@ -93,6 +93,36 @@ public function data_is_authorize_application_password_request_valid() {
'expected_error_code' => '',
'env' => $environment_type,
);
+
+ $datasets[ $environment_type . ' and a "query" success_format' ] = array(
+ 'request' => array( 'success_format' => 'query' ),
+ 'expected_error_code' => '',
+ 'env' => $environment_type,
+ );
+
+ $datasets[ $environment_type . ' and a "form_post" success_format with an "https" scheme "success_url"' ] = array(
+ 'request' => array(
+ 'success_url' => 'https://example.org',
+ 'success_format' => 'form_post',
+ ),
+ 'expected_error_code' => '',
+ 'env' => $environment_type,
+ );
+
+ $datasets[ $environment_type . ' and an invalid success_format' ] = array(
+ 'request' => array( 'success_format' => 'invalid' ),
+ 'expected_error_code' => 'invalid_success_format',
+ 'env' => $environment_type,
+ );
+
+ $datasets[ $environment_type . ' and a "form_post" success_format with an app scheme "success_url"' ] = array(
+ 'request' => array(
+ 'success_url' => 'wordpress://example',
+ 'success_format' => 'form_post',
+ ),
+ 'expected_error_code' => 'invalid_success_format',
+ 'env' => $environment_type,
+ );
}
return $datasets;