Skip to content

Commit 38e84ff

Browse files
authored
Persist visitor auth token in cookie for as long as the token is valid (#2931)
1 parent 052e07a commit 38e84ff

File tree

4 files changed

+43
-3
lines changed

4 files changed

+43
-3
lines changed

biome.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,12 @@
6767
"useThrowOnlyError": "error"
6868
},
6969
"suspicious": {
70-
"noConsole": "warn",
70+
"noConsole": {
71+
"level": "warn",
72+
"options": {
73+
"allow": ["assert", "error", "warn"]
74+
}
75+
},
7176
"noExplicitAny": "warn",
7277
"noImplicitAnyLet": "warn",
7378
"noConfusingVoidType": "warn",

bun.lock

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
"framer-motion": "^10.16.14",
7878
"js-cookie": "^3.0.5",
7979
"jsontoxml": "^1.0.1",
80+
"jwt-decode": "^4.0.0",
8081
"katex": "^0.16.9",
8182
"mathjax": "^3.2.2",
8283
"mdast-util-to-markdown": "^2.1.2",
@@ -2251,6 +2252,8 @@
22512252

22522253
"jws": ["[email protected]", "", { "dependencies": { "jwa": "^1.4.1", "safe-buffer": "^5.0.1" } }, "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA=="],
22532254

2255+
"jwt-decode": ["[email protected]", "", {}, "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA=="],
2256+
22542257
"katex": ["[email protected]", "", { "dependencies": { "commander": "^8.3.0" }, "bin": { "katex": "cli.js" } }, "sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ=="],
22552258

22562259
"keyv": ["[email protected]", "", { "dependencies": { "json-buffer": "3.0.0" } }, "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA=="],

packages/gitbook/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@
6464
"tailwind-shades": "^1.1.2",
6565
"url-join": "^5.0.0",
6666
"usehooks-ts": "^3.1.0",
67-
"ai": "^4.1.46"
67+
"ai": "^4.1.46",
68+
"jwt-decode": "^4.0.0"
6869
},
6970
"devDependencies": {
7071
"@argos-ci/playwright": "^3.10.0",

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

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { type JwtPayload, jwtDecode } from 'jwt-decode';
12
import type { NextRequest } from 'next/server';
23
import hash from 'object-hash';
34

@@ -82,6 +83,18 @@ export function getResponseCookiesForVisitorAuth(
8283
basePath: string,
8384
visitorTokenLookup: VisitorTokenLookup
8485
): ResponseCookies {
86+
if (!visitorTokenLookup) {
87+
return {};
88+
}
89+
90+
let decoded: JwtPayload;
91+
try {
92+
decoded = jwtDecode(visitorTokenLookup.token);
93+
} catch (error) {
94+
console.error('Error decoding visitor token', error);
95+
return {};
96+
}
97+
8598
return {
8699
/**
87100
* If the visitor token has been retrieve from the URL, or if its a VA cookie and the basePath is the same, set it
@@ -99,7 +112,7 @@ export function getResponseCookiesForVisitorAuth(
99112
httpOnly: true,
100113
sameSite: process.env.NODE_ENV === 'production' ? 'none' : undefined,
101114
secure: process.env.NODE_ENV === 'production',
102-
maxAge: 7 * 24 * 60 * 60,
115+
maxAge: getVisitorAuthCookieMaxAge(decoded),
103116
},
104117
},
105118
}
@@ -212,3 +225,21 @@ function findVisitorAuthCookieForBasePath(
212225
undefined
213226
);
214227
}
228+
229+
/**
230+
* Get the max age to store a visitor auth token in a cookie.
231+
* We want to store the token for as long as it's valid, but at least 1 minute.
232+
* If an invalid token is passed to the API, the API will return a redirect to the auth flow.
233+
*/
234+
function getVisitorAuthCookieMaxAge(decoded: JwtPayload): number {
235+
const defaultMaxAge = 7 * 24 * 60 * 60; // 7 days
236+
const minMaxAge = 60; // 1 min
237+
const exp = decoded.exp;
238+
239+
if (typeof exp === 'number') {
240+
const now = new Date().getTime();
241+
return Math.max(exp - now, minMaxAge);
242+
}
243+
244+
return defaultMaxAge;
245+
}

0 commit comments

Comments
 (0)