Skip to content

Commit 281cf0b

Browse files
Save existing refresh_token in store if no new refresh_token is returned (#483)
As described in https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#name-refresh-token-response, server MAY return a new refresh_token. In case it doesn't, current implementation discard initial refresh token if it was still valid.
1 parent 1d860bb commit 281cf0b

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

src/client/auth.test.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,9 @@ describe("OAuth Authorization", () => {
506506
access_token: "newaccess123",
507507
token_type: "Bearer",
508508
expires_in: 3600,
509+
}
510+
const validTokensWithNewRefreshToken = {
511+
...validTokens,
509512
refresh_token: "newrefresh123",
510513
};
511514

@@ -520,15 +523,15 @@ describe("OAuth Authorization", () => {
520523
mockFetch.mockResolvedValueOnce({
521524
ok: true,
522525
status: 200,
523-
json: async () => validTokens,
526+
json: async () => validTokensWithNewRefreshToken,
524527
});
525528

526529
const tokens = await refreshAuthorization("https://auth.example.com", {
527530
clientInformation: validClientInfo,
528531
refreshToken: "refresh123",
529532
});
530533

531-
expect(tokens).toEqual(validTokens);
534+
expect(tokens).toEqual(validTokensWithNewRefreshToken);
532535
expect(mockFetch).toHaveBeenCalledWith(
533536
expect.objectContaining({
534537
href: "https://auth.example.com/token",
@@ -548,6 +551,22 @@ describe("OAuth Authorization", () => {
548551
expect(body.get("client_secret")).toBe("secret123");
549552
});
550553

554+
it("exchanges refresh token for new tokens and keep existing refresh token if none is returned", async () => {
555+
mockFetch.mockResolvedValueOnce({
556+
ok: true,
557+
status: 200,
558+
json: async () => validTokens,
559+
});
560+
561+
const refreshToken = "refresh123";
562+
const tokens = await refreshAuthorization("https://auth.example.com", {
563+
clientInformation: validClientInfo,
564+
refreshToken,
565+
});
566+
567+
expect(tokens).toEqual({ refresh_token: refreshToken, ...validTokens });
568+
});
569+
551570
it("validates token response schema", async () => {
552571
mockFetch.mockResolvedValueOnce({
553572
ok: true,

src/client/auth.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ export async function refreshAuthorization(
474474
throw new Error(`Token refresh failed: HTTP ${response.status}`);
475475
}
476476

477-
return OAuthTokensSchema.parse(await response.json());
477+
return OAuthTokensSchema.parse({ refresh_token: refreshToken, ...(await response.json()) });
478478
}
479479

480480
/**

0 commit comments

Comments
 (0)