Skip to content

Commit 176ef7b

Browse files
authored
Preserve old refresh token if new token does not contain refresh token (#434)
1 parent 8ca734c commit 176ef7b

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

lib/access-token.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ module.exports = class AccessToken {
4848
const parameters = GrantTypeParams.forGrantType(REFRESH_TOKEN_PROPERTY_NAME, this.#config.options, refreshParams);
4949
const response = await this.#client.request(this.#config.auth.refreshPath, parameters.toObject(), httpOptions);
5050

51+
if (response[REFRESH_TOKEN_PROPERTY_NAME] === undefined) {
52+
response.refresh_token = this.refresh_token;
53+
}
5154
return new AccessToken(this.#config, this.#client, response);
5255
}
5356

test/_authorization-server-mock.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@ function createAuthorizationServer(authorizationServerUrl) {
8888
});
8989
}
9090

91+
function tokenSuccessWithoutRefreshToken(scopeOptions, params) {
92+
return nock(authorizationServerUrl, scopeOptions)
93+
.post('/oauth/token', params)
94+
.reply(200, { ...accessToken, refresh_token: undefined }, {
95+
'Content-Type': 'application/json',
96+
});
97+
}
98+
9199
return {
92100
tokenError,
93101
tokenAuthorizationError,
@@ -98,6 +106,7 @@ function createAuthorizationServer(authorizationServerUrl) {
98106
tokenSuccessWithNonJSONContent,
99107
tokenSuccessWithCustomPath,
100108
tokenSuccess,
109+
tokenSuccessWithoutRefreshToken,
101110
};
102111
}
103112

test/access-token-refresh.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,3 +271,27 @@ test.serial('@refresh => creates a new access token with custom (inline) http op
271271
scope.done();
272272
t.true(has(refreshAccessToken.token, 'access_token'));
273273
});
274+
275+
test.serial('@refresh => creates a new access token with keeping the old refresh token if refresh did not provide a new refresh token', async (t) => {
276+
const config = createModuleConfig();
277+
278+
const accessTokenResponse = chance.accessToken({
279+
expireMode: 'expires_in',
280+
});
281+
282+
const client = new Client(config);
283+
284+
const refreshParams = {
285+
grant_type: 'refresh_token',
286+
refresh_token: accessTokenResponse.refresh_token,
287+
};
288+
289+
const server = createAuthorizationServer('https://authorization-server.org:443');
290+
const scope = server.tokenSuccessWithoutRefreshToken(scopeOptions, refreshParams);
291+
292+
const accessToken = new AccessToken(config, client, accessTokenResponse);
293+
const refreshAccessToken = await accessToken.refresh();
294+
295+
scope.done();
296+
t.true(has(refreshAccessToken.token, 'refresh_token'));
297+
});

0 commit comments

Comments
 (0)