diff --git a/.changeset/sad-worms-dream.md b/.changeset/sad-worms-dream.md new file mode 100644 index 0000000..1506509 --- /dev/null +++ b/.changeset/sad-worms-dream.md @@ -0,0 +1,5 @@ +--- +"@labdigital/federated-token": minor +--- + +Pass refreshToken.expiresIn option to setRefreshToken diff --git a/packages/core/src/tokensource/cookies-base.test.ts b/packages/core/src/tokensource/cookies-base.test.ts index fcecafb..5aa2342 100644 --- a/packages/core/src/tokensource/cookies-base.test.ts +++ b/packages/core/src/tokensource/cookies-base.test.ts @@ -235,8 +235,7 @@ describe("CookieTokenSource", () => { ]); }); - // Test for setting the refresh token for authenticated users - it("should set the refresh token for authenticated users", () => { + it("should set the refresh token with default Expires for authenticated users", () => { const request: Request = new Request("http://localhost"); const response: Response = new Response(); @@ -248,18 +247,82 @@ describe("CookieTokenSource", () => { cookieTokenSource.setRefreshToken(request, response, "FOOBAR", true); + const expectedExpires = new Date(Date.now() + 60 * 60 * 24 * 365 * 1000); + + const cookies = getCookies(response); + expect(cookies).toEqual([ + { + refreshToken: "FOOBAR", + Path: "/refresh", + SameSite: "None", + Expires: expectedExpires.toUTCString(), + }, + { + userRefreshTokenExists: "1", + SameSite: "None", + Expires: expectedExpires.toUTCString(), + }, + ]); + }); + + it("should set the refresh token with custom Expires for authenticated users", () => { + const request: Request = new Request("http://localhost"); + const response: Response = new Response(); + + const cookieTokenSource = new TestCookieTokenSource({ + secure: true, + sameSite: "none", + refreshTokenPath: "/refresh", + refreshToken: { + expiresIn: 60, + }, + }); + + const expectedExpires = new Date(Date.now() + 60 * 1000); + + cookieTokenSource.setRefreshToken(request, response, "FOOBAR", true); + + const cookies = getCookies(response); + expect(cookies).toEqual([ + { + refreshToken: "FOOBAR", + Path: "/refresh", + SameSite: "None", + Expires: expectedExpires.toUTCString(), + }, + { + userRefreshTokenExists: "1", + SameSite: "None", + Expires: expectedExpires.toUTCString(), + }, + ]); + }); + + it("should set the refresh token with session Expires for authenticated users", () => { + const request: Request = new Request("http://localhost"); + const response: Response = new Response(); + + const cookieTokenSource = new TestCookieTokenSource({ + secure: true, + sameSite: "none", + refreshTokenPath: "/refresh", + refreshToken: { + expiresIn: "session", + }, + }); + + cookieTokenSource.setRefreshToken(request, response, "FOOBAR", true); + const cookies = getCookies(response); expect(cookies).toEqual([ { refreshToken: "FOOBAR", Path: "/refresh", SameSite: "None", - Expires: expect.any(String), }, { userRefreshTokenExists: "1", SameSite: "None", - Expires: expect.any(String), }, ]); }); diff --git a/packages/core/src/tokensource/cookies-base.ts b/packages/core/src/tokensource/cookies-base.ts index c600c37..a93a3a2 100644 --- a/packages/core/src/tokensource/cookies-base.ts +++ b/packages/core/src/tokensource/cookies-base.ts @@ -285,12 +285,18 @@ export abstract class BaseCookieTokenSource token: string, isAuthenticated = false, ) { - const expiresAt = new Date(Date.now() + 1000 * 60 * 60 * 24 * 365); - const cookieOptions = { + const opts = this.options.refreshToken ?? { + expiresIn: 60 * 60 * 24 * 365, // Default expiration is one year + }; + + const cookieOptions: CookieOptions = { httpOnly: false, secure: this.options.secure, sameSite: this.options.sameSite, - expires: expiresAt, + expires: + opts.expiresIn === "session" + ? undefined + : new Date(Date.now() + opts.expiresIn * 1000), domain: this.adapter.getPublicDomain(request), };