Skip to content

Commit d33171b

Browse files
authored
Fix getVisitorAuthCookieMaxAge returning 60s even when token expiry is much later (#2974)
1 parent 6aaeae2 commit d33171b

File tree

2 files changed

+45
-2
lines changed

2 files changed

+45
-2
lines changed

packages/gitbook/src/lib/visitor-token.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { describe, expect, it } from 'bun:test';
22
import type { NextRequest } from 'next/server';
33

4+
import type { JwtPayload } from 'jwt-decode';
45
import {
6+
getVisitorAuthCookieMaxAge,
57
getVisitorAuthCookieName,
68
getVisitorAuthCookieValue,
79
getVisitorToken,
@@ -74,6 +76,47 @@ describe('getVisitorAuthToken', () => {
7476
});
7577
});
7678

79+
describe('getVisitorAuthCookieMaxAge', () => {
80+
const ONE_MINUTE_IN_SECONDS = 60;
81+
82+
it('returns the max age of 7 days if token expires in 7 days', () => {
83+
const SEVEN_DAYS_IN_SECONDS = 7 * 24 * 60 * 60;
84+
const now = Math.floor(Date.now() / 1000);
85+
const decoded: JwtPayload = { exp: now + SEVEN_DAYS_IN_SECONDS };
86+
87+
expect(getVisitorAuthCookieMaxAge(decoded)).toBe(SEVEN_DAYS_IN_SECONDS);
88+
});
89+
90+
it('returns the max age of 30 days if token expires in 30 days', () => {
91+
const THIRTY_DAYS_IN_SECONDS = 30 * 24 * 60 * 60;
92+
const now = Math.floor(Date.now() / 1000);
93+
const decoded: JwtPayload = { exp: now + THIRTY_DAYS_IN_SECONDS };
94+
95+
expect(getVisitorAuthCookieMaxAge(decoded)).toBe(THIRTY_DAYS_IN_SECONDS);
96+
});
97+
98+
it('returns the minimum max age of 60 seconds if token has already expired', () => {
99+
const now = Math.floor(Date.now() / 1000);
100+
const decoded: JwtPayload = { exp: now - 1000 };
101+
102+
expect(getVisitorAuthCookieMaxAge(decoded)).toBe(ONE_MINUTE_IN_SECONDS);
103+
});
104+
105+
it('returns the minimum max age of 60 seconds if token expires in less than 60 seconds', () => {
106+
const now = Math.floor(Date.now() / 1000);
107+
const decoded: JwtPayload = { exp: now + 30 }; // Expires in 30 seconds
108+
109+
expect(getVisitorAuthCookieMaxAge(decoded)).toBe(ONE_MINUTE_IN_SECONDS);
110+
});
111+
112+
it('returns the correct value if expiry is in the future but more than 60 seconds', () => {
113+
const now = Math.floor(Date.now() / 1000);
114+
const decoded: JwtPayload = { exp: now + 300 }; // Expires in 5 minutes
115+
116+
expect(getVisitorAuthCookieMaxAge(decoded)).toBe(300);
117+
});
118+
});
119+
77120
function assertVisitorAuthCookieValue(
78121
value: unknown
79122
): asserts value is { source: 'visitor-auth-cookie'; basePath: string; token: string } {

packages/gitbook/src/lib/visitor-token.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,13 +238,13 @@ function findVisitorAuthCookieForBasePath(
238238
* We want to store the token for as long as it's valid, but at least 1 minute.
239239
* If an invalid token is passed to the API, the API will return a redirect to the auth flow.
240240
*/
241-
function getVisitorAuthCookieMaxAge(decoded: JwtPayload): number {
241+
export function getVisitorAuthCookieMaxAge(decoded: JwtPayload): number {
242242
const defaultMaxAge = 7 * 24 * 60 * 60; // 7 days
243243
const minMaxAge = 60; // 1 min
244244
const exp = decoded.exp;
245245

246246
if (typeof exp === 'number') {
247-
const now = new Date().getTime();
247+
const now = Math.floor(new Date().getTime() / 1000);
248248
return Math.max(exp - now, minMaxAge);
249249
}
250250

0 commit comments

Comments
 (0)