@@ -59,6 +59,20 @@ public static function init() {
5959 'add_auth_headers_to_response '
6060 ] );
6161
62+ /**
63+ * Add Auth Headers to REST REQUEST responses
64+ *
65+ * This allows clients to use WPGraphQL JWT Authentication
66+ * tokens with WPGraphQL _and_ with REST API requests, and
67+ * this exposes refresh tokens in the REST API response
68+ * so folks can refresh their tokens after each REST API
69+ * request.
70+ */
71+ add_filter ( 'rest_request_after_callbacks ' , [
72+ '\WPGraphQL\JWT_Authentication\ManageTokens ' ,
73+ 'add_auth_headers_to_rest_response '
74+ ], 10 , 3 );
75+
6276 add_filter ( 'graphql_access_control_allow_headers ' , [
6377 '\WPGraphQL\JWT_Authentication\ManageTokens ' ,
6478 'add_jwt_allowed_headers '
@@ -72,6 +86,7 @@ public static function init() {
7286 * @param array $fields The fields for the User type in the GraphQL Schema
7387 *
7488 * @return array $fields
89+ * @throws \Exception
7590 */
7691 public static function add_user_fields ( $ fields ) {
7792
@@ -278,6 +293,14 @@ public static function use_custom_user_expiration( $expiration ) {
278293 */
279294 public static function add_tokens_to_graphql_response_headers ( $ headers ) {
280295
296+ /**
297+ * If the request _is_ SSL, or GRAPHQL_DEBUG is defined, return the tokens
298+ * otherwise do not return them.
299+ */
300+ if ( ! is_ssl () && ( ! defined ( 'GRAPHQL_DEBUG ' ) || true !== GRAPHQL_DEBUG ) ) {
301+ return $ headers ;
302+ }
303+
281304 /**
282305 * If there's a Refresh-Authorization token in the request headers, validate it
283306 */
@@ -318,6 +341,56 @@ public static function add_tokens_to_graphql_response_headers( $headers ) {
318341
319342 }
320343
344+ /**
345+ * Expose X-JWT-Refresh tokens in the response headers for REST requests.
346+ *
347+ * This allows clients the ability to Authenticate with WPGraphQL, use the token
348+ * with REST API Requests, but get new refresh tokens from the REST API Headers
349+ *
350+ * @return \WP_HTTP_Response
351+ * @throws \Exception
352+ */
353+ public static function add_auth_headers_to_rest_response ( \WP_HTTP_Response $ response , $ handler , $ request ) {
354+
355+ /**
356+ * If the request _is_ SSL, or GRAPHQL_DEBUG is defined, return the tokens
357+ * otherwise do not return them.
358+ */
359+ if ( ! is_ssl () && ( ! defined ( 'GRAPHQL_DEBUG ' ) || true !== GRAPHQL_DEBUG ) ) {
360+ return $ response ;
361+ }
362+
363+ /**
364+ * Note: The Access-Control-Expose-Headers aren't directly filterable
365+ * for REST API responses, so this overrides them altogether.
366+ *
367+ * This isn't ideal, as any other plugin could override as well.
368+ *
369+ * Might need a patch to core to allow for individual filtering.
370+ */
371+ $ response ->set_headers ( [
372+ 'Access-Control-Expose-Headers ' => 'X-WP-Total, X-WP-TotalPages, X-JWT-Refresh ' ,
373+ ] );
374+
375+ $ refresh_token = null ;
376+
377+ $ validate_auth_header = Auth::validate_token ( str_ireplace ( 'Bearer ' , '' , Auth::get_auth_header () ), false );
378+
379+ if ( ! is_wp_error ( $ validate_auth_header ) && ! empty ( $ validate_auth_header ->data ->user ->id ) ) {
380+
381+ $ refresh_token = Auth::get_refresh_token ( new \WP_User ( $ validate_auth_header ->data ->user ->id ), false );
382+
383+ }
384+
385+ if ( $ refresh_token ) {
386+ $ response ->set_headers ( [
387+ 'X-JWT-Refresh ' => $ refresh_token ,
388+ ] );
389+ }
390+
391+ return $ response ;
392+ }
393+
321394 /**
322395 * Expose the X-JWT-Refresh tokens in the response headers. This allows
323396 * folks to grab new refresh tokens from authenticated requests for subsequent use.
0 commit comments