Skip to content

Commit 57c1bb1

Browse files
authored
Merge pull request #23 from wp-graphql/feature/#22-expose-refresh-token-in-response-headers
#22 expose refresh token in response headers
2 parents a468039 + 6495640 commit 57c1bb1

File tree

1 file changed

+69
-19
lines changed

1 file changed

+69
-19
lines changed

src/ManageTokens.php

Lines changed: 69 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
23
namespace WPGraphQL\JWT_Authentication;
34

45
use GraphQL\Error\UserError;
@@ -52,10 +53,21 @@ public static function init() {
5253
'\WPGraphQL\JWT_Authentication\ManageTokens',
5354
'add_tokens_to_graphql_response_headers'
5455
] );
56+
57+
add_filter( 'graphql_response_headers_to_send', [
58+
'\WPGraphQL\JWT_Authentication\ManageTokens',
59+
'add_auth_headers_to_response'
60+
] );
61+
62+
add_filter( 'graphql_access_control_allow_headers', [
63+
'\WPGraphQL\JWT_Authentication\ManageTokens',
64+
'add_jwt_allowed_headers'
65+
] );
5566
}
5667

5768
/**
58-
* Filters the User type in the GraphQL Schema to provide fields for querying for user's jwtAuthToken and jwtUserSecret
69+
* Filters the User type in the GraphQL Schema to provide fields for querying for user's
70+
* jwtAuthToken and jwtUserSecret
5971
*
6072
* @param array $fields The fields for the User type in the GraphQL Schema
6173
*
@@ -64,9 +76,9 @@ public static function init() {
6476
public static function add_user_fields( $fields ) {
6577

6678
$fields['jwtAuthToken'] = [
67-
'type' => Types::string(),
79+
'type' => Types::string(),
6880
'description' => __( 'A JWT token that can be used in future requests for authentication/authorization', 'wp-graphql-jwt-authentication' ),
69-
'resolve' => function( \WP_User $user ) {
81+
'resolve' => function ( \WP_User $user ) {
7082

7183
/**
7284
* Get the token for the user
@@ -85,9 +97,9 @@ public static function add_user_fields( $fields ) {
8597
];
8698

8799
$fields['jwtRefreshToken'] = [
88-
'type' => Types::string(),
100+
'type' => Types::string(),
89101
'description' => __( 'A JWT token that can be used in future requests to get a refreshed jwtAuthToken. If the refresh token used in a request is revoked or otherwise invalid, a valid Auth token will NOT be issued in the response headers.', 'wp-graphql-jwt-authentication' ),
90-
'resolve' => function( \WP_User $user ) {
102+
'resolve' => function ( \WP_User $user ) {
91103

92104
/**
93105
* Get the token for the user
@@ -106,9 +118,9 @@ public static function add_user_fields( $fields ) {
106118
];
107119

108120
$fields['jwtUserSecret'] = [
109-
'type' => Types::string(),
121+
'type' => Types::string(),
110122
'description' => __( 'A unique secret tied to the users JWT token that can be revoked or refreshed. Revoking the secret prevents JWT tokens from being issued to the user. Refreshing the token invalidates previously issued tokens, but allows new tokens to be issued.', 'wp-graphql' ),
111-
'resolve' => function( \WP_User $user ) {
123+
'resolve' => function ( \WP_User $user ) {
112124

113125
/**
114126
* Get the user's JWT Secret
@@ -130,53 +142,55 @@ public static function add_user_fields( $fields ) {
130142
];
131143

132144
$fields['jwtAuthExpiration'] = [
133-
'type' => Types::string(),
145+
'type' => Types::string(),
134146
'description' => __( 'The expiration for the JWT Token for the user. If not set custom for the user, it will use the default sitewide expiration setting', 'wp-graphql-jwt-authentication' ),
135-
'resolve' => function( \WP_User $user ) {
147+
'resolve' => function ( \WP_User $user ) {
136148
$expiration = Auth::get_token_expiration();
149+
137150
return ! empty( $expiration ) ? $expiration : null;
138151
}
139152
];
140153

141154
$fields['isJwtAuthSecretRevoked'] = [
142-
'type' => Types::non_null( Types::boolean() ),
155+
'type' => Types::non_null( Types::boolean() ),
143156
'description' => __( 'Whether the JWT User secret has been revoked. If the secret has been revoked, auth tokens will not be issued until an admin, or user with proper capabilities re-issues a secret for the user.', 'wp-graphql-jwt-authentication' ),
144-
'resolve' => function( \WP_User $user ) {
157+
'resolve' => function ( \WP_User $user ) {
145158
$revoked = Auth::is_jwt_secret_revoked( $user->ID );
159+
146160
return true == $revoked ? true : false;
147161
}
148162
];
149163

150164

151-
152165
return $fields;
153166

154167
}
155168

156169
/**
157170
* Given an array of fields, this returns an array with the new fields added
171+
*
158172
* @param array $fields The input fields for user mutations
159173
*
160174
* @return array
161175
*/
162176
public static function add_user_mutation_input_fields( array $fields ) {
163177

164178
$fields['revokeJwtUserSecret'] = [
165-
'type' => Types::boolean(),
179+
'type' => Types::boolean(),
166180
'description' => __( 'If true, this will revoke the users JWT secret. If false, this will unrevoke the JWT secret AND issue a new one. To revoke, the user must have proper capabilities to edit users JWT secrets.', 'wp-graphql-jwt-authentication' ),
167181
];
168182

169183
$fields['refreshJwtUserSecret'] = [
170-
'type' => Types::boolean(),
184+
'type' => Types::boolean(),
171185
'description' => __( 'If true, this will refresh the users JWT secret.' ),
172186
];
173187

174188
return $fields;
175189
}
176190

177191
/**
178-
* @param int $user_id The ID of the user being mutated
179-
* @param array $input The input args of the GraphQL mutation request
192+
* @param int $user_id The ID of the user being mutated
193+
* @param array $input The input args of the GraphQL mutation request
180194
* @param string $mutation_name The name of the mutation
181195
*/
182196
public static function update_jwt_fields_during_mutation( $user_id, array $input, $mutation_name ) {
@@ -208,11 +222,11 @@ public static function update_jwt_fields_during_mutation( $user_id, array $input
208222
* This filters the token to prevent it from being issued if it has been revoked.
209223
*
210224
* @param string $token
211-
* @param int $user_id
225+
* @param int $user_id
212226
*
213227
* @return string $token
214228
*/
215-
public static function prevent_token_from_returning_if_revoked( $token, $user_id ) {
229+
public static function prevent_token_from_returning_if_revoked( $token, $user_id ) {
216230

217231
/**
218232
* Check to see if the user's auth secret has been revoked.
@@ -254,6 +268,14 @@ public static function use_custom_user_expiration( $expiration ) {
254268

255269
}
256270

271+
/**
272+
* Returns tokens in the response headers
273+
*
274+
* @param $headers
275+
*
276+
* @return mixed
277+
* @throws \Exception
278+
*/
257279
public static function add_tokens_to_graphql_response_headers( $headers ) {
258280

259281
/**
@@ -296,4 +318,32 @@ public static function add_tokens_to_graphql_response_headers( $headers ) {
296318

297319
}
298320

299-
}
321+
/**
322+
* Expose the X-JWT-Refresh tokens in the response headers. This allows
323+
* folks to grab new refresh tokens from authenticated requests for subsequent use.
324+
*
325+
* @param array $headers The existing response headers
326+
*
327+
* @return array
328+
*/
329+
public static function add_auth_headers_to_response( array $headers ) {
330+
$headers['Access-Control-Expose-Headers'] = 'X-JWT-Refresh';
331+
332+
return $headers;
333+
}
334+
335+
/**
336+
* Expose the X-JWT-Auth and X-JWT-Refresh as allowed headers in GraphQL responses
337+
*
338+
* @param array $allowed_headers The existing allowed headers
339+
*
340+
* @return array
341+
*/
342+
public static function add_jwt_allowed_headers( array $allowed_headers ) {
343+
$allowed_headers[] = 'X-JWT-Auth';
344+
$allowed_headers[] = 'X-JWT-Refresh';
345+
346+
return $allowed_headers;
347+
}
348+
349+
}

0 commit comments

Comments
 (0)