diff --git a/go/lib/session/session.ts b/go/lib/session/session.ts index 34653a507d..6b77754b89 100644 --- a/go/lib/session/session.ts +++ b/go/lib/session/session.ts @@ -24,6 +24,9 @@ export const getSessionOptions = (): SessionOptions => { }, // TODO: Decide on the session ttl. ttl: 60 * 60 * 24 * 7, // 1 week + chunking: { + enabled: true, + }, } } diff --git a/go/package.json b/go/package.json index 6837b06ad3..61a0ebf24f 100644 --- a/go/package.json +++ b/go/package.json @@ -36,7 +36,8 @@ "cypress:run:mobile": "NODE_ENV=test cypress run --env viewport=mobile", "cypress:run:desktop": "NODE_ENV=test cypress run --env viewport=desktop", "shadcn:add": "npx shadcn@canary add $MODULE", - "post-process-dpl-cms-graphql": "tsx ./scripts/graphql-codegen/post-process-dpl-cms-graphql.ts" + "post-process-dpl-cms-graphql": "tsx ./scripts/graphql-codegen/post-process-dpl-cms-graphql.ts", + "postinstall": "patch-package" }, "dependencies": { "@danskernesdigitalebibliotek/dpl-service-layer": "file:../packages/service-layer", @@ -59,7 +60,7 @@ "date-fns": "^4.4.0", "framer-motion": "12.40.0", "graphql": "^16.14.0", - "iron-session": "^8.0.4", + "iron-session": "8.0.4", "js-md5": "^0.8.3", "keen-slider": "^6.8.6", "lodash": "^4.18.1", @@ -135,6 +136,7 @@ "next-test-api-route-handler": "^5.0.5", "node-mocks-http": "^1.17.2", "orval": "^7.21.0", + "patch-package": "^8.0.1", "postcss": "^8.5.15", "prepend-file": "^2.0.1", "prettier": "^3.8.3", diff --git a/go/patches/iron-session+8.0.4.patch b/go/patches/iron-session+8.0.4.patch new file mode 100644 index 0000000000..e09b71ea3c --- /dev/null +++ b/go/patches/iron-session+8.0.4.patch @@ -0,0 +1,572 @@ +diff --git a/node_modules/iron-session/dist/index.cjs b/node_modules/iron-session/dist/index.cjs +index a0d108b..2a2ff59 100644 +--- a/node_modules/iron-session/dist/index.cjs ++++ b/node_modules/iron-session/dist/index.cjs +@@ -74,6 +74,49 @@ function setCookie(res, cookieValue) { + cookieValue + ]); + } ++function splitCookieIntoChunks(value, chunkSize) { ++ const chunks = []; ++ for (let i = 0; i < value.length; i += chunkSize) { ++ chunks.push(value.slice(i, i + chunkSize)); ++ } ++ return chunks; ++} ++function reconstructCookie(req, cookieName) { ++ const directCookie = getCookie(req, cookieName); ++ if (directCookie) { ++ return directCookie; ++ } ++ const chunks = []; ++ let chunkIndex = 0; ++ while (true) { ++ const chunkName = `${cookieName}.${chunkIndex}`; ++ const chunk = getCookie(req, chunkName); ++ if (!chunk) { ++ break; ++ } ++ chunks.push(chunk); ++ chunkIndex++; ++ } ++ return chunks.join(""); ++} ++function reconstructCookieWithStore(cookieHandler, cookieName) { ++ const directCookie = getServerActionCookie(cookieName, cookieHandler); ++ if (directCookie) { ++ return directCookie; ++ } ++ const chunks = []; ++ let chunkIndex = 0; ++ while (true) { ++ const chunkName = `${cookieName}.${chunkIndex}`; ++ const chunk = getServerActionCookie(chunkName, cookieHandler); ++ if (!chunk) { ++ break; ++ } ++ chunks.push(chunk); ++ chunkIndex++; ++ } ++ return chunks.join(""); ++} + function createSealData(_crypto) { + return async function sealData2(data, { + password, +@@ -174,7 +217,7 @@ function createGetIronSession(sealData2, unsealData2) { + ); + } + let sessionConfig = getSessionConfig(sessionOptions); +- const sealFromCookies = getCookie(req, sessionConfig.cookieName); ++ const sealFromCookies = reconstructCookie(req, sessionConfig.cookieName); + const session = sealFromCookies ? await unsealData2(sealFromCookies, { + password: passwordsMap, + ttl: sessionConfig.ttl +@@ -196,17 +239,57 @@ function createGetIronSession(sealData2, unsealData2) { + password: passwordsMap, + ttl: sessionConfig.ttl + }); +- const cookieValue = cookie.serialize( +- sessionConfig.cookieName, +- seal, +- sessionConfig.cookieOptions +- ); +- if (cookieValue.length > 4096) { +- throw new Error( +- `iron-session: Cookie length is too big (${cookieValue.length} bytes), browsers will refuse it. Try to remove some data.` ++ if (sessionConfig.chunking?.enabled) { ++ const chunkSize = sessionConfig.chunking.chunkSize ?? 3500; ++ let oldChunkIndex = 0; ++ while (true) { ++ const oldChunkName = `${sessionConfig.cookieName}.${oldChunkIndex}`; ++ const oldChunk = getCookie(req, oldChunkName); ++ if (!oldChunk) break; ++ const cleanupCookie = cookie.serialize(oldChunkName, "", { ++ ...sessionConfig.cookieOptions, ++ maxAge: 0 ++ }); ++ setCookie(res, cleanupCookie); ++ oldChunkIndex++; ++ } ++ const testCookieValue = cookie.serialize( ++ sessionConfig.cookieName, ++ seal, ++ sessionConfig.cookieOptions + ); ++ if (testCookieValue.length <= 4096) { ++ setCookie(res, testCookieValue); ++ return; ++ } ++ const chunks = splitCookieIntoChunks(seal, chunkSize); ++ chunks.forEach((chunk, index) => { ++ const chunkName = `${sessionConfig.cookieName}.${index}`; ++ const chunkCookieValue = cookie.serialize( ++ chunkName, ++ chunk, ++ sessionConfig.cookieOptions ++ ); ++ setCookie(res, chunkCookieValue); ++ }); ++ const deleteCookie = cookie.serialize(sessionConfig.cookieName, "", { ++ ...sessionConfig.cookieOptions, ++ maxAge: 0 ++ }); ++ setCookie(res, deleteCookie); ++ } else { ++ const cookieValue = cookie.serialize( ++ sessionConfig.cookieName, ++ seal, ++ sessionConfig.cookieOptions ++ ); ++ if (cookieValue.length > 4096) { ++ throw new Error( ++ `iron-session: Cookie length is too big (${cookieValue.length} bytes), browsers will refuse it. Try to remove some data.` ++ ); ++ } ++ setCookie(res, cookieValue); + } +- setCookie(res, cookieValue); + } + }, + destroy: { +@@ -219,6 +302,20 @@ function createGetIronSession(sealData2, unsealData2) { + maxAge: 0 + }); + setCookie(res, cookieValue); ++ if (sessionConfig.chunking?.enabled) { ++ let chunkIndex = 0; ++ while (true) { ++ const chunkName = `${sessionConfig.cookieName}.${chunkIndex}`; ++ const chunk = getCookie(req, chunkName); ++ if (!chunk) break; ++ const chunkCookieValue = cookie.serialize(chunkName, "", { ++ ...sessionConfig.cookieOptions, ++ maxAge: 0 ++ }); ++ setCookie(res, chunkCookieValue); ++ chunkIndex++; ++ } ++ } + } + } + }); +@@ -239,10 +336,7 @@ async function getIronSessionFromCookieStore(cookieStore, sessionOptions, sealDa + ); + } + let sessionConfig = getSessionConfig(sessionOptions); +- const sealFromCookies = getServerActionCookie( +- sessionConfig.cookieName, +- cookieStore +- ); ++ const sealFromCookies = reconstructCookieWithStore(cookieStore, sessionConfig.cookieName); + const session = sealFromCookies ? await unsealData2(sealFromCookies, { + password: passwordsMap, + ttl: sessionConfig.ttl +@@ -259,17 +353,50 @@ async function getIronSessionFromCookieStore(cookieStore, sessionOptions, sealDa + password: passwordsMap, + ttl: sessionConfig.ttl + }); +- const cookieLength = sessionConfig.cookieName.length + seal.length + JSON.stringify(sessionConfig.cookieOptions).length; +- if (cookieLength > 4096) { +- throw new Error( +- `iron-session: Cookie length is too big (${cookieLength} bytes), browsers will refuse it. Try to remove some data.` ++ if (sessionConfig.chunking?.enabled) { ++ const chunkSize = sessionConfig.chunking.chunkSize ?? 3500; ++ let oldChunkIndex = 0; ++ while (true) { ++ const oldChunkName = `${sessionConfig.cookieName}.${oldChunkIndex}`; ++ const oldChunk = getServerActionCookie(oldChunkName, cookieStore); ++ if (!oldChunk) break; ++ cookieStore.set(oldChunkName, "", { ++ ...sessionConfig.cookieOptions, ++ maxAge: 0 ++ }); ++ oldChunkIndex++; ++ } ++ const cookieLength = sessionConfig.cookieName.length + seal.length + JSON.stringify(sessionConfig.cookieOptions).length; ++ if (cookieLength <= 4096) { ++ cookieStore.set( ++ sessionConfig.cookieName, ++ seal, ++ sessionConfig.cookieOptions ++ ); ++ return; ++ } ++ const chunks = splitCookieIntoChunks(seal, chunkSize); ++ chunks.forEach((chunk, index) => { ++ const chunkName = `${sessionConfig.cookieName}.${index}`; ++ cookieStore.set(chunkName, chunk, sessionConfig.cookieOptions); ++ }); ++ cookieStore.set(sessionConfig.cookieName, "", { ++ ...sessionConfig.cookieOptions, ++ maxAge: 0 ++ }); ++ } else { ++ const cookieLength = sessionConfig.cookieName.length + seal.length + JSON.stringify(sessionConfig.cookieOptions).length; ++ if (cookieLength > 4096) { ++ throw new Error( ++ `iron-session: Cookie length is too big (${cookieLength} bytes), browsers will refuse it. Try to remove some data.` ++ ); ++ } ++ cookieStore.set( ++ sessionConfig.cookieName, ++ seal, ++ sessionConfig.cookieOptions + ); + } +- cookieStore.set( +- sessionConfig.cookieName, +- seal, +- sessionConfig.cookieOptions +- ); + } + }, + destroy: { +@@ -279,6 +406,16 @@ async function getIronSessionFromCookieStore(cookieStore, sessionOptions, sealDa + }); + const cookieOptions = { ...sessionConfig.cookieOptions, maxAge: 0 }; + cookieStore.set(sessionConfig.cookieName, "", cookieOptions); ++ if (sessionConfig.chunking?.enabled) { ++ let chunkIndex = 0; ++ while (true) { ++ const chunkName = `${sessionConfig.cookieName}.${chunkIndex}`; ++ const chunk = getServerActionCookie(chunkName, cookieStore); ++ if (!chunk) break; ++ cookieStore.set(chunkName, "", cookieOptions); ++ chunkIndex++; ++ } ++ } + } + } + }); +diff --git a/node_modules/iron-session/dist/index.cjs.map b/node_modules/iron-session/dist/index.cjs.map +index a311bde..b86c7d6 100644 +--- a/node_modules/iron-session/dist/index.cjs.map ++++ b/node_modules/iron-session/dist/index.cjs.map +@@ -1 +1 @@ +-{"version":3,"sources":["../src/core.ts","../src/index.ts"],"names":["parse","sealData","ironSeal","ironDefaults","unsealData","ironUnseal","getIronSession","serialize","crypto"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { IncomingMessage, ServerResponse } from \"http\";\nimport { parse, serialize, type CookieSerializeOptions } from \"cookie\";\nimport {\n defaults as ironDefaults,\n seal as ironSeal,\n unseal as ironUnseal,\n} from \"iron-webcrypto\";\n\ntype PasswordsMap = Record;\ntype Password = PasswordsMap | string;\ntype RequestType = IncomingMessage | Request;\ntype ResponseType = Response | ServerResponse;\n\n/**\n * {@link https://wicg.github.io/cookie-store/#dictdef-cookielistitem CookieListItem}\n * as specified by W3C.\n */\ninterface CookieListItem\n extends Pick<\n CookieSerializeOptions,\n \"domain\" | \"path\" | \"sameSite\" | \"secure\"\n > {\n /** A string with the name of a cookie. */\n name: string;\n /** A string containing the value of the cookie. */\n value: string;\n /** A number of milliseconds or Date interface containing the expires of the cookie. */\n expires?: CookieSerializeOptions[\"expires\"] | number;\n}\n\n/**\n * Superset of {@link CookieListItem} extending it with\n * the `httpOnly`, `maxAge` and `priority` properties.\n */\ntype ResponseCookie = CookieListItem &\n Pick;\n\n/**\n * The high-level type definition of the .get() and .set() methods\n * of { cookies() } from \"next/headers\"\n */\nexport interface CookieStore {\n get: (name: string) => { name: string; value: string } | undefined;\n set: {\n (name: string, value: string, cookie?: Partial): void;\n (options: ResponseCookie): void;\n };\n}\n\n/**\n * Set-Cookie Attributes do not include `encode`. We omit this from our `cookieOptions` type.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie\n * @see https://developer.chrome.com/docs/devtools/application/cookies/\n */\ntype CookieOptions = Omit;\n\nexport interface SessionOptions {\n /**\n * The cookie name that will be used inside the browser. Make sure it's unique\n * given your application.\n *\n * @example 'vercel-session'\n */\n cookieName: string;\n\n /**\n * The password(s) that will be used to encrypt the cookie. Can either be a string\n * or an object.\n *\n * When you provide multiple passwords then all of them will be used to decrypt\n * the cookie. But only the most recent (`= highest key`, `2` in the example)\n * password will be used to encrypt the cookie. This allows password rotation.\n *\n * @example { 1: 'password-1', 2: 'password-2' }\n */\n password: Password;\n\n /**\n * The time (in seconds) that the session will be valid for. Also sets the\n * `max-age` attribute of the cookie automatically (`= ttl - 60s`, so that the\n * cookie always expire before the session).\n *\n * `ttl = 0` means no expiration.\n *\n * @default 1209600\n */\n ttl?: number;\n\n /**\n * The options that will be passed to the cookie library.\n *\n * If you want to use \"session cookies\" (cookies that are deleted when the browser\n * is closed) then you need to pass `cookieOptions: { maxAge: undefined }`\n *\n * @see https://github.com/jshttp/cookie#options-1\n */\n cookieOptions?: CookieOptions;\n}\n\nexport type IronSession = T & {\n /**\n * Encrypts the session data and sets the cookie.\n */\n readonly save: () => Promise;\n\n /**\n * Destroys the session data and removes the cookie.\n */\n readonly destroy: () => void;\n\n /**\n * Update the session configuration. You still need to call save() to send the new cookie.\n */\n readonly updateConfig: (newSessionOptions: SessionOptions) => void;\n};\n\n// default time allowed to check for iron seal validity when ttl passed\n// see https://hapi.dev/module/iron/api/?v=7.0.1#options\nconst timestampSkewSec = 60;\nconst fourteenDaysInSeconds = 14 * 24 * 3600;\n\n// We store a token major version to handle data format changes so that the cookies\n// can be kept alive between upgrades, no need to disconnect everyone.\nconst currentMajorVersion = 2;\nconst versionDelimiter = \"~\";\n\nconst defaultOptions: Required> =\n {\n ttl: fourteenDaysInSeconds,\n cookieOptions: { httpOnly: true, secure: true, sameSite: \"lax\", path: \"/\" },\n };\n\nfunction normalizeStringPasswordToMap(password: Password): PasswordsMap {\n return typeof password === \"string\" ? { 1: password } : password;\n}\n\nfunction parseSeal(seal: string): {\n sealWithoutVersion: string;\n tokenVersion: number | null;\n} {\n const [sealWithoutVersion, tokenVersionAsString] =\n seal.split(versionDelimiter);\n const tokenVersion =\n tokenVersionAsString == null ? null : parseInt(tokenVersionAsString, 10);\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return { sealWithoutVersion: sealWithoutVersion!, tokenVersion };\n}\n\nfunction computeCookieMaxAge(ttl: number): number {\n if (ttl === 0) {\n // ttl = 0 means no expiration\n // but in reality cookies have to expire (can't have no max-age)\n // 2147483647 is the max value for max-age in cookies\n // see https://stackoverflow.com/a/11685301/147079\n return 2147483647;\n }\n\n // The next line makes sure browser will expire cookies before seals are considered expired by the server.\n // It also allows for clock difference of 60 seconds between server and clients.\n return ttl - timestampSkewSec;\n}\n\nfunction getCookie(req: RequestType, cookieName: string): string {\n return (\n parse(\n (\"headers\" in req && typeof req.headers.get === \"function\"\n ? req.headers.get(\"cookie\")\n : (req as IncomingMessage).headers.cookie) ?? \"\",\n )[cookieName] ?? \"\"\n );\n}\n\nfunction getServerActionCookie(\n cookieName: string,\n cookieHandler: CookieStore,\n): string {\n const cookieObject = cookieHandler.get(cookieName);\n const cookie = cookieObject?.value;\n if (typeof cookie === \"string\") {\n return cookie;\n }\n return \"\";\n}\n\nfunction setCookie(res: ResponseType, cookieValue: string): void {\n if (\"headers\" in res && typeof res.headers.append === \"function\") {\n res.headers.append(\"set-cookie\", cookieValue);\n return;\n }\n let existingSetCookie = (res as ServerResponse).getHeader(\"set-cookie\") ?? [];\n if (!Array.isArray(existingSetCookie)) {\n existingSetCookie = [existingSetCookie.toString()];\n }\n (res as ServerResponse).setHeader(\"set-cookie\", [\n ...existingSetCookie,\n cookieValue,\n ]);\n}\n\nexport function createSealData(_crypto: Crypto) {\n return async function sealData(\n data: unknown,\n {\n password,\n ttl = fourteenDaysInSeconds,\n }: { password: Password; ttl?: number },\n ): Promise {\n const passwordsMap = normalizeStringPasswordToMap(password);\n\n const mostRecentPasswordId = Math.max(\n ...Object.keys(passwordsMap).map(Number),\n );\n const passwordForSeal = {\n id: mostRecentPasswordId.toString(),\n secret: passwordsMap[mostRecentPasswordId]!,\n };\n\n const seal = await ironSeal(_crypto, data, passwordForSeal, {\n ...ironDefaults,\n ttl: ttl * 1000,\n });\n\n return `${seal}${versionDelimiter}${currentMajorVersion}`;\n };\n}\n\nexport function createUnsealData(_crypto: Crypto) {\n return async function unsealData(\n seal: string,\n {\n password,\n ttl = fourteenDaysInSeconds,\n }: { password: Password; ttl?: number },\n ): Promise {\n const passwordsMap = normalizeStringPasswordToMap(password);\n const { sealWithoutVersion, tokenVersion } = parseSeal(seal);\n\n try {\n const data =\n (await ironUnseal(_crypto, sealWithoutVersion, passwordsMap, {\n ...ironDefaults,\n ttl: ttl * 1000,\n })) ?? {};\n\n if (tokenVersion === 2) {\n return data as T;\n }\n\n // @ts-expect-error `persistent` does not exist on newer tokens\n return { ...data.persistent } as T;\n } catch (error) {\n if (\n error instanceof Error &&\n /^(Expired seal|Bad hmac value|Cannot find password|Incorrect number of sealed components)/.test(\n error.message,\n )\n ) {\n // if seal expired or\n // if seal is not valid (encrypted using a different password, when passwords are badly rotated) or\n // if we can't find back the password in the seal\n // then we just start a new session over\n return {} as T;\n }\n\n throw error;\n }\n };\n}\n\nfunction getSessionConfig(\n sessionOptions: SessionOptions,\n): Required {\n const options = {\n ...defaultOptions,\n ...sessionOptions,\n cookieOptions: {\n ...defaultOptions.cookieOptions,\n ...(sessionOptions.cookieOptions || {}),\n },\n };\n\n if (\n sessionOptions.cookieOptions &&\n \"maxAge\" in sessionOptions.cookieOptions\n ) {\n if (sessionOptions.cookieOptions.maxAge === undefined) {\n // session cookies, do not set maxAge, consider token as infinite\n options.ttl = 0;\n }\n } else {\n options.cookieOptions.maxAge = computeCookieMaxAge(options.ttl);\n }\n\n return options;\n}\n\nconst badUsageMessage =\n \"iron-session: Bad usage: use getIronSession(req, res, options) or getIronSession(cookieStore, options).\";\n\nexport function createGetIronSession(\n sealData: ReturnType,\n unsealData: ReturnType,\n) {\n return getIronSession;\n\n async function getIronSession(\n cookies: CookieStore,\n sessionOptions: SessionOptions,\n ): Promise>;\n async function getIronSession(\n req: RequestType,\n res: ResponseType,\n sessionOptions: SessionOptions,\n ): Promise>;\n async function getIronSession(\n reqOrCookieStore: RequestType | CookieStore,\n resOrsessionOptions: ResponseType | SessionOptions,\n sessionOptions?: SessionOptions,\n ): Promise> {\n if (!reqOrCookieStore) {\n throw new Error(badUsageMessage);\n }\n\n if (!resOrsessionOptions) {\n throw new Error(badUsageMessage);\n }\n\n if (!sessionOptions) {\n return getIronSessionFromCookieStore(\n reqOrCookieStore as CookieStore,\n resOrsessionOptions as SessionOptions,\n sealData,\n unsealData,\n );\n }\n\n const req = reqOrCookieStore as RequestType;\n const res = resOrsessionOptions as ResponseType;\n\n if (!sessionOptions) {\n throw new Error(badUsageMessage);\n }\n\n if (!sessionOptions.cookieName) {\n throw new Error(\"iron-session: Bad usage. Missing cookie name.\");\n }\n\n if (!sessionOptions.password) {\n throw new Error(\"iron-session: Bad usage. Missing password.\");\n }\n\n const passwordsMap = normalizeStringPasswordToMap(sessionOptions.password);\n\n if (Object.values(passwordsMap).some((password) => password.length < 32)) {\n throw new Error(\n \"iron-session: Bad usage. Password must be at least 32 characters long.\",\n );\n }\n\n let sessionConfig = getSessionConfig(sessionOptions);\n\n const sealFromCookies = getCookie(req, sessionConfig.cookieName);\n const session = sealFromCookies\n ? await unsealData(sealFromCookies, {\n password: passwordsMap,\n ttl: sessionConfig.ttl,\n })\n : ({} as T);\n\n Object.defineProperties(session, {\n updateConfig: {\n value: function updateConfig(newSessionOptions: SessionOptions) {\n sessionConfig = getSessionConfig(newSessionOptions);\n },\n },\n save: {\n value: async function save() {\n if (\"headersSent\" in res && res.headersSent) {\n throw new Error(\n \"iron-session: Cannot set session cookie: session.save() was called after headers were sent. Make sure to call it before any res.send() or res.end()\",\n );\n }\n\n const seal = await sealData(session, {\n password: passwordsMap,\n ttl: sessionConfig.ttl,\n });\n const cookieValue = serialize(\n sessionConfig.cookieName,\n seal,\n sessionConfig.cookieOptions,\n );\n\n if (cookieValue.length > 4096) {\n throw new Error(\n `iron-session: Cookie length is too big (${cookieValue.length} bytes), browsers will refuse it. Try to remove some data.`,\n );\n }\n\n setCookie(res, cookieValue);\n },\n },\n\n destroy: {\n value: function destroy() {\n Object.keys(session).forEach((key) => {\n delete (session as Record)[key];\n });\n const cookieValue = serialize(sessionConfig.cookieName, \"\", {\n ...sessionConfig.cookieOptions,\n maxAge: 0,\n });\n\n setCookie(res, cookieValue);\n },\n },\n });\n\n return session as IronSession;\n }\n}\n\nasync function getIronSessionFromCookieStore(\n cookieStore: CookieStore,\n sessionOptions: SessionOptions,\n sealData: ReturnType,\n unsealData: ReturnType,\n): Promise> {\n if (!sessionOptions.cookieName) {\n throw new Error(\"iron-session: Bad usage. Missing cookie name.\");\n }\n\n if (!sessionOptions.password) {\n throw new Error(\"iron-session: Bad usage. Missing password.\");\n }\n\n const passwordsMap = normalizeStringPasswordToMap(sessionOptions.password);\n\n if (Object.values(passwordsMap).some((password) => password.length < 32)) {\n throw new Error(\n \"iron-session: Bad usage. Password must be at least 32 characters long.\",\n );\n }\n\n let sessionConfig = getSessionConfig(sessionOptions);\n const sealFromCookies = getServerActionCookie(\n sessionConfig.cookieName,\n cookieStore,\n );\n const session = sealFromCookies\n ? await unsealData(sealFromCookies, {\n password: passwordsMap,\n ttl: sessionConfig.ttl,\n })\n : ({} as T);\n\n Object.defineProperties(session, {\n updateConfig: {\n value: function updateConfig(newSessionOptions: SessionOptions) {\n sessionConfig = getSessionConfig(newSessionOptions);\n },\n },\n save: {\n value: async function save() {\n const seal = await sealData(session, {\n password: passwordsMap,\n ttl: sessionConfig.ttl,\n });\n\n const cookieLength =\n sessionConfig.cookieName.length +\n seal.length +\n JSON.stringify(sessionConfig.cookieOptions).length;\n\n if (cookieLength > 4096) {\n throw new Error(\n `iron-session: Cookie length is too big (${cookieLength} bytes), browsers will refuse it. Try to remove some data.`,\n );\n }\n\n cookieStore.set(\n sessionConfig.cookieName,\n seal,\n sessionConfig.cookieOptions,\n );\n },\n },\n\n destroy: {\n value: function destroy() {\n Object.keys(session).forEach((key) => {\n delete (session as Record)[key];\n });\n\n const cookieOptions = { ...sessionConfig.cookieOptions, maxAge: 0 };\n cookieStore.set(sessionConfig.cookieName, \"\", cookieOptions);\n },\n },\n });\n\n return session as IronSession;\n}\n","import {\n createGetIronSession,\n createSealData,\n createUnsealData,\n} from \"./core.js\";\n\nimport * as crypto from \"uncrypto\";\n\nexport type { IronSession, SessionOptions } from \"./core.js\";\nexport const sealData = createSealData(crypto);\nexport const unsealData = createUnsealData(crypto);\nexport const getIronSession = createGetIronSession(sealData, unsealData);\n"]} +\ No newline at end of file ++{"version":3,"sources":["../src/core.ts","../src/index.ts"],"names":["parse","sealData","ironSeal","ironDefaults","unsealData","ironUnseal","getIronSession","serialize","crypto"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { IncomingMessage, ServerResponse } from \"http\";\nimport { parse, serialize, type CookieSerializeOptions } from \"cookie\";\nimport {\n defaults as ironDefaults,\n seal as ironSeal,\n unseal as ironUnseal,\n} from \"iron-webcrypto\";\n\ntype PasswordsMap = Record;\ntype Password = PasswordsMap | string;\ntype RequestType = IncomingMessage | Request;\ntype ResponseType = Response | ServerResponse;\n\n/**\n * {@link https://wicg.github.io/cookie-store/#dictdef-cookielistitem CookieListItem}\n * as specified by W3C.\n */\ninterface CookieListItem\n extends Pick<\n CookieSerializeOptions,\n \"domain\" | \"path\" | \"sameSite\" | \"secure\"\n > {\n /** A string with the name of a cookie. */\n name: string;\n /** A string containing the value of the cookie. */\n value: string;\n /** A number of milliseconds or Date interface containing the expires of the cookie. */\n expires?: CookieSerializeOptions[\"expires\"] | number;\n}\n\n/**\n * Superset of {@link CookieListItem} extending it with\n * the `httpOnly`, `maxAge` and `priority` properties.\n */\ntype ResponseCookie = CookieListItem &\n Pick;\n\n/**\n * The high-level type definition of the .get() and .set() methods\n * of { cookies() } from \"next/headers\"\n */\nexport interface CookieStore {\n get: (name: string) => { name: string; value: string } | undefined;\n set: {\n (name: string, value: string, cookie?: Partial): void;\n (options: ResponseCookie): void;\n };\n}\n\n/**\n * Set-Cookie Attributes do not include `encode`. We omit this from our `cookieOptions` type.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie\n * @see https://developer.chrome.com/docs/devtools/application/cookies/\n */\ntype CookieOptions = Omit;\n\nexport interface SessionOptions {\n /**\n * The cookie name that will be used inside the browser. Make sure it's unique\n * given your application.\n *\n * @example 'vercel-session'\n */\n cookieName: string;\n\n /**\n * The password(s) that will be used to encrypt the cookie. Can either be a string\n * or an object.\n *\n * When you provide multiple passwords then all of them will be used to decrypt\n * the cookie. But only the most recent (`= highest key`, `2` in the example)\n * password will be used to encrypt the cookie. This allows password rotation.\n *\n * @example { 1: 'password-1', 2: 'password-2' }\n */\n password: Password;\n\n /**\n * The time (in seconds) that the session will be valid for. Also sets the\n * `max-age` attribute of the cookie automatically (`= ttl - 60s`, so that the\n * cookie always expire before the session).\n *\n * `ttl = 0` means no expiration.\n *\n * @default 1209600\n */\n ttl?: number;\n\n /**\n * The options that will be passed to the cookie library.\n *\n * If you want to use \"session cookies\" (cookies that are deleted when the browser\n * is closed) then you need to pass `cookieOptions: { maxAge: undefined }`\n *\n * @see https://github.com/jshttp/cookie#options-1\n */\n cookieOptions?: CookieOptions;\n\n /**\n * Configure cookie chunking for large sessions that exceed browser cookie size limits.\n *\n * When enabled, iron-session will automatically split large cookies into multiple\n * smaller chunks (named `{cookieName}.0`, `{cookieName}.1`, etc.) and reassemble\n * them when reading. This allows sessions larger than the typical 4096-byte browser\n * limit.\n *\n * @example { enabled: true, chunkSize: 3500 }\n */\n chunking?: {\n /**\n * Enable cookie chunking. When `false` or `undefined`, the traditional 4096-byte\n * limit check will be enforced.\n *\n * @default false\n */\n enabled: boolean;\n /**\n * Maximum size in bytes for each cookie chunk. Should be less than 4096 to allow\n * room for cookie name and attributes.\n *\n * @default 3500\n */\n chunkSize?: number;\n };\n}\n\nexport type IronSession = T & {\n /**\n * Encrypts the session data and sets the cookie.\n */\n readonly save: () => Promise;\n\n /**\n * Destroys the session data and removes the cookie.\n */\n readonly destroy: () => void;\n\n /**\n * Update the session configuration. You still need to call save() to send the new cookie.\n */\n readonly updateConfig: (newSessionOptions: SessionOptions) => void;\n};\n\n// default time allowed to check for iron seal validity when ttl passed\n// see https://hapi.dev/module/iron/api/?v=7.0.1#options\nconst timestampSkewSec = 60;\nconst fourteenDaysInSeconds = 14 * 24 * 3600;\n\n// We store a token major version to handle data format changes so that the cookies\n// can be kept alive between upgrades, no need to disconnect everyone.\nconst currentMajorVersion = 2;\nconst versionDelimiter = \"~\";\n\nconst defaultOptions: Required> =\n {\n ttl: fourteenDaysInSeconds,\n cookieOptions: { httpOnly: true, secure: true, sameSite: \"lax\", path: \"/\" },\n };\n\nfunction normalizeStringPasswordToMap(password: Password): PasswordsMap {\n return typeof password === \"string\" ? { 1: password } : password;\n}\n\nfunction parseSeal(seal: string): {\n sealWithoutVersion: string;\n tokenVersion: number | null;\n} {\n const [sealWithoutVersion, tokenVersionAsString] =\n seal.split(versionDelimiter);\n const tokenVersion =\n tokenVersionAsString == null ? null : parseInt(tokenVersionAsString, 10);\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return { sealWithoutVersion: sealWithoutVersion!, tokenVersion };\n}\n\nfunction computeCookieMaxAge(ttl: number): number {\n if (ttl === 0) {\n // ttl = 0 means no expiration\n // but in reality cookies have to expire (can't have no max-age)\n // 2147483647 is the max value for max-age in cookies\n // see https://stackoverflow.com/a/11685301/147079\n return 2147483647;\n }\n\n // The next line makes sure browser will expire cookies before seals are considered expired by the server.\n // It also allows for clock difference of 60 seconds between server and clients.\n return ttl - timestampSkewSec;\n}\n\nfunction getCookie(req: RequestType, cookieName: string): string {\n return (\n parse(\n (\"headers\" in req && typeof req.headers.get === \"function\"\n ? req.headers.get(\"cookie\")\n : (req as IncomingMessage).headers.cookie) ?? \"\",\n )[cookieName] ?? \"\"\n );\n}\n\nfunction getServerActionCookie(\n cookieName: string,\n cookieHandler: CookieStore,\n): string {\n const cookieObject = cookieHandler.get(cookieName);\n const cookie = cookieObject?.value;\n if (typeof cookie === \"string\") {\n return cookie;\n }\n return \"\";\n}\n\nfunction setCookie(res: ResponseType, cookieValue: string): void {\n if (\"headers\" in res && typeof res.headers.append === \"function\") {\n res.headers.append(\"set-cookie\", cookieValue);\n return;\n }\n let existingSetCookie = (res as ServerResponse).getHeader(\"set-cookie\") ?? [];\n if (!Array.isArray(existingSetCookie)) {\n existingSetCookie = [existingSetCookie.toString()];\n }\n (res as ServerResponse).setHeader(\"set-cookie\", [\n ...existingSetCookie,\n cookieValue,\n ]);\n}\n\n/**\n * Splits a large cookie value into multiple chunks for browsers that enforce\n * size limits. Each chunk is named `{baseName}.{index}`.\n */\nfunction splitCookieIntoChunks(\n value: string,\n chunkSize: number,\n): string[] {\n const chunks: string[] = [];\n for (let i = 0; i < value.length; i += chunkSize) {\n chunks.push(value.slice(i, i + chunkSize));\n }\n return chunks;\n}\n\n/**\n * Reconstructs a cookie value from chunks. Tries direct cookie first,\n * then attempts to reassemble from indexed chunks if not found.\n * Works transparently for both chunked and non-chunked cookies.\n */\nfunction reconstructCookie(\n req: RequestType,\n cookieName: string,\n): string {\n // Try direct cookie first (for non-chunked or old sessions)\n const directCookie = getCookie(req, cookieName);\n if (directCookie) {\n return directCookie;\n }\n\n // Try to reconstruct from chunks\n const chunks: string[] = [];\n let chunkIndex = 0;\n\n while (true) {\n const chunkName = `${cookieName}.${chunkIndex}`;\n const chunk = getCookie(req, chunkName);\n\n if (!chunk) {\n break;\n }\n\n chunks.push(chunk);\n chunkIndex++;\n }\n\n return chunks.join(\"\");\n}\n\n/**\n * Reconstructs a cookie value from chunks using CookieStore.\n * For use with Next.js cookies() and similar APIs.\n * Works transparently for both chunked and non-chunked cookies.\n */\nfunction reconstructCookieWithStore(\n cookieHandler: CookieStore,\n cookieName: string,\n): string {\n // Try direct cookie first\n const directCookie = getServerActionCookie(cookieName, cookieHandler);\n if (directCookie) {\n return directCookie;\n }\n\n // Try to reconstruct from chunks\n const chunks: string[] = [];\n let chunkIndex = 0;\n\n while (true) {\n const chunkName = `${cookieName}.${chunkIndex}`;\n const chunk = getServerActionCookie(chunkName, cookieHandler);\n\n if (!chunk) {\n break;\n }\n\n chunks.push(chunk);\n chunkIndex++;\n }\n\n return chunks.join(\"\");\n}\n\nexport function createSealData(_crypto: Crypto) {\n return async function sealData(\n data: unknown,\n {\n password,\n ttl = fourteenDaysInSeconds,\n }: { password: Password; ttl?: number },\n ): Promise {\n const passwordsMap = normalizeStringPasswordToMap(password);\n\n const mostRecentPasswordId = Math.max(\n ...Object.keys(passwordsMap).map(Number),\n );\n const passwordForSeal = {\n id: mostRecentPasswordId.toString(),\n secret: passwordsMap[mostRecentPasswordId]!,\n };\n\n const seal = await ironSeal(_crypto, data, passwordForSeal, {\n ...ironDefaults,\n ttl: ttl * 1000,\n });\n\n return `${seal}${versionDelimiter}${currentMajorVersion}`;\n };\n}\n\nexport function createUnsealData(_crypto: Crypto) {\n return async function unsealData(\n seal: string,\n {\n password,\n ttl = fourteenDaysInSeconds,\n }: { password: Password; ttl?: number },\n ): Promise {\n const passwordsMap = normalizeStringPasswordToMap(password);\n const { sealWithoutVersion, tokenVersion } = parseSeal(seal);\n\n try {\n const data =\n (await ironUnseal(_crypto, sealWithoutVersion, passwordsMap, {\n ...ironDefaults,\n ttl: ttl * 1000,\n })) ?? {};\n\n if (tokenVersion === 2) {\n return data as T;\n }\n\n // @ts-expect-error `persistent` does not exist on newer tokens\n return { ...data.persistent } as T;\n } catch (error) {\n if (\n error instanceof Error &&\n /^(Expired seal|Bad hmac value|Cannot find password|Incorrect number of sealed components)/.test(\n error.message,\n )\n ) {\n // if seal expired or\n // if seal is not valid (encrypted using a different password, when passwords are badly rotated) or\n // if we can't find back the password in the seal\n // then we just start a new session over\n return {} as T;\n }\n\n throw error;\n }\n };\n}\n\nfunction getSessionConfig(\n sessionOptions: SessionOptions,\n): Required> & Pick {\n const options = {\n ...defaultOptions,\n ...sessionOptions,\n cookieOptions: {\n ...defaultOptions.cookieOptions,\n ...(sessionOptions.cookieOptions || {}),\n },\n };\n\n if (\n sessionOptions.cookieOptions &&\n \"maxAge\" in sessionOptions.cookieOptions\n ) {\n if (sessionOptions.cookieOptions.maxAge === undefined) {\n // session cookies, do not set maxAge, consider token as infinite\n options.ttl = 0;\n }\n } else {\n options.cookieOptions.maxAge = computeCookieMaxAge(options.ttl);\n }\n\n return options;\n}\n\nconst badUsageMessage =\n \"iron-session: Bad usage: use getIronSession(req, res, options) or getIronSession(cookieStore, options).\";\n\nexport function createGetIronSession(\n sealData: ReturnType,\n unsealData: ReturnType,\n) {\n return getIronSession;\n\n async function getIronSession(\n cookies: CookieStore,\n sessionOptions: SessionOptions,\n ): Promise>;\n async function getIronSession(\n req: RequestType,\n res: ResponseType,\n sessionOptions: SessionOptions,\n ): Promise>;\n async function getIronSession(\n reqOrCookieStore: RequestType | CookieStore,\n resOrsessionOptions: ResponseType | SessionOptions,\n sessionOptions?: SessionOptions,\n ): Promise> {\n if (!reqOrCookieStore) {\n throw new Error(badUsageMessage);\n }\n\n if (!resOrsessionOptions) {\n throw new Error(badUsageMessage);\n }\n\n if (!sessionOptions) {\n return getIronSessionFromCookieStore(\n reqOrCookieStore as CookieStore,\n resOrsessionOptions as SessionOptions,\n sealData,\n unsealData,\n );\n }\n\n const req = reqOrCookieStore as RequestType;\n const res = resOrsessionOptions as ResponseType;\n\n if (!sessionOptions) {\n throw new Error(badUsageMessage);\n }\n\n if (!sessionOptions.cookieName) {\n throw new Error(\"iron-session: Bad usage. Missing cookie name.\");\n }\n\n if (!sessionOptions.password) {\n throw new Error(\"iron-session: Bad usage. Missing password.\");\n }\n\n const passwordsMap = normalizeStringPasswordToMap(sessionOptions.password);\n\n if (Object.values(passwordsMap).some((password) => password.length < 32)) {\n throw new Error(\n \"iron-session: Bad usage. Password must be at least 32 characters long.\",\n );\n }\n\n let sessionConfig = getSessionConfig(sessionOptions);\n\n const sealFromCookies = reconstructCookie(req, sessionConfig.cookieName);\n const session = sealFromCookies\n ? await unsealData(sealFromCookies, {\n password: passwordsMap,\n ttl: sessionConfig.ttl,\n })\n : ({} as T);\n\n Object.defineProperties(session, {\n updateConfig: {\n value: function updateConfig(newSessionOptions: SessionOptions) {\n sessionConfig = getSessionConfig(newSessionOptions);\n },\n },\n save: {\n value: async function save() {\n if (\"headersSent\" in res && res.headersSent) {\n throw new Error(\n \"iron-session: Cannot set session cookie: session.save() was called after headers were sent. Make sure to call it before any res.send() or res.end()\",\n );\n }\n\n const seal = await sealData(session, {\n password: passwordsMap,\n ttl: sessionConfig.ttl,\n });\n\n // Check if chunking is enabled\n if (sessionConfig.chunking?.enabled) {\n const chunkSize = sessionConfig.chunking.chunkSize ?? 3500;\n\n // Clean up old chunks first\n let oldChunkIndex = 0;\n while (true) {\n const oldChunkName = `${sessionConfig.cookieName}.${oldChunkIndex}`;\n const oldChunk = getCookie(req, oldChunkName);\n if (!oldChunk) break;\n\n const cleanupCookie = serialize(oldChunkName, \"\", {\n ...sessionConfig.cookieOptions,\n maxAge: 0,\n });\n setCookie(res, cleanupCookie);\n oldChunkIndex++;\n }\n\n // If seal is small enough, use single cookie\n const testCookieValue = serialize(\n sessionConfig.cookieName,\n seal,\n sessionConfig.cookieOptions,\n );\n\n if (testCookieValue.length <= 4096) {\n setCookie(res, testCookieValue);\n return;\n }\n\n // Split into chunks\n const chunks = splitCookieIntoChunks(seal, chunkSize);\n chunks.forEach((chunk, index) => {\n const chunkName = `${sessionConfig.cookieName}.${index}`;\n const chunkCookieValue = serialize(\n chunkName,\n chunk,\n sessionConfig.cookieOptions,\n );\n setCookie(res, chunkCookieValue);\n });\n\n // Delete the main cookie if it exists (we're using chunks now)\n const deleteCookie = serialize(sessionConfig.cookieName, \"\", {\n ...sessionConfig.cookieOptions,\n maxAge: 0,\n });\n setCookie(res, deleteCookie);\n } else {\n // Original behavior - no chunking\n const cookieValue = serialize(\n sessionConfig.cookieName,\n seal,\n sessionConfig.cookieOptions,\n );\n\n if (cookieValue.length > 4096) {\n throw new Error(\n `iron-session: Cookie length is too big (${cookieValue.length} bytes), browsers will refuse it. Try to remove some data.`,\n );\n }\n\n setCookie(res, cookieValue);\n }\n },\n },\n\n destroy: {\n value: function destroy() {\n Object.keys(session).forEach((key) => {\n delete (session as Record)[key];\n });\n\n // Delete main cookie\n const cookieValue = serialize(sessionConfig.cookieName, \"\", {\n ...sessionConfig.cookieOptions,\n maxAge: 0,\n });\n setCookie(res, cookieValue);\n\n // Also delete chunks if chunking was enabled\n if (sessionConfig.chunking?.enabled) {\n let chunkIndex = 0;\n while (true) {\n const chunkName = `${sessionConfig.cookieName}.${chunkIndex}`;\n const chunk = getCookie(req, chunkName);\n if (!chunk) break;\n\n const chunkCookieValue = serialize(chunkName, \"\", {\n ...sessionConfig.cookieOptions,\n maxAge: 0,\n });\n setCookie(res, chunkCookieValue);\n chunkIndex++;\n }\n }\n },\n },\n });\n\n return session as IronSession;\n }\n}\n\nasync function getIronSessionFromCookieStore(\n cookieStore: CookieStore,\n sessionOptions: SessionOptions,\n sealData: ReturnType,\n unsealData: ReturnType,\n): Promise> {\n if (!sessionOptions.cookieName) {\n throw new Error(\"iron-session: Bad usage. Missing cookie name.\");\n }\n\n if (!sessionOptions.password) {\n throw new Error(\"iron-session: Bad usage. Missing password.\");\n }\n\n const passwordsMap = normalizeStringPasswordToMap(sessionOptions.password);\n\n if (Object.values(passwordsMap).some((password) => password.length < 32)) {\n throw new Error(\n \"iron-session: Bad usage. Password must be at least 32 characters long.\",\n );\n }\n\n let sessionConfig = getSessionConfig(sessionOptions);\n\n const sealFromCookies = reconstructCookieWithStore(cookieStore, sessionConfig.cookieName);\n const session = sealFromCookies\n ? await unsealData(sealFromCookies, {\n password: passwordsMap,\n ttl: sessionConfig.ttl,\n })\n : ({} as T);\n\n Object.defineProperties(session, {\n updateConfig: {\n value: function updateConfig(newSessionOptions: SessionOptions) {\n sessionConfig = getSessionConfig(newSessionOptions);\n },\n },\n save: {\n value: async function save() {\n const seal = await sealData(session, {\n password: passwordsMap,\n ttl: sessionConfig.ttl,\n });\n\n // Check if chunking is enabled\n if (sessionConfig.chunking?.enabled) {\n const chunkSize = sessionConfig.chunking.chunkSize ?? 3500;\n\n // Clean up old chunks first\n let oldChunkIndex = 0;\n while (true) {\n const oldChunkName = `${sessionConfig.cookieName}.${oldChunkIndex}`;\n const oldChunk = getServerActionCookie(oldChunkName, cookieStore);\n if (!oldChunk) break;\n\n cookieStore.set(oldChunkName, \"\", {\n ...sessionConfig.cookieOptions,\n maxAge: 0,\n });\n oldChunkIndex++;\n }\n\n // If seal is small enough, use single cookie\n const cookieLength =\n sessionConfig.cookieName.length +\n seal.length +\n JSON.stringify(sessionConfig.cookieOptions).length;\n\n if (cookieLength <= 4096) {\n cookieStore.set(\n sessionConfig.cookieName,\n seal,\n sessionConfig.cookieOptions,\n );\n return;\n }\n\n // Split into chunks\n const chunks = splitCookieIntoChunks(seal, chunkSize);\n chunks.forEach((chunk, index) => {\n const chunkName = `${sessionConfig.cookieName}.${index}`;\n cookieStore.set(chunkName, chunk, sessionConfig.cookieOptions);\n });\n\n // Delete the main cookie if it exists (we're using chunks now)\n cookieStore.set(sessionConfig.cookieName, \"\", {\n ...sessionConfig.cookieOptions,\n maxAge: 0,\n });\n } else {\n // Original behavior - no chunking\n const cookieLength =\n sessionConfig.cookieName.length +\n seal.length +\n JSON.stringify(sessionConfig.cookieOptions).length;\n\n if (cookieLength > 4096) {\n throw new Error(\n `iron-session: Cookie length is too big (${cookieLength} bytes), browsers will refuse it. Try to remove some data.`,\n );\n }\n\n cookieStore.set(\n sessionConfig.cookieName,\n seal,\n sessionConfig.cookieOptions,\n );\n }\n },\n },\n\n destroy: {\n value: function destroy() {\n Object.keys(session).forEach((key) => {\n delete (session as Record)[key];\n });\n\n // Delete main cookie\n const cookieOptions = { ...sessionConfig.cookieOptions, maxAge: 0 };\n cookieStore.set(sessionConfig.cookieName, \"\", cookieOptions);\n\n // Also delete chunks if chunking was enabled\n if (sessionConfig.chunking?.enabled) {\n let chunkIndex = 0;\n while (true) {\n const chunkName = `${sessionConfig.cookieName}.${chunkIndex}`;\n const chunk = getServerActionCookie(chunkName, cookieStore);\n if (!chunk) break;\n\n cookieStore.set(chunkName, \"\", cookieOptions);\n chunkIndex++;\n }\n }\n },\n },\n });\n\n return session as IronSession;\n}\n","import {\n createGetIronSession,\n createSealData,\n createUnsealData,\n} from \"./core.js\";\n\nimport * as crypto from \"uncrypto\";\n\nexport type { IronSession, SessionOptions } from \"./core.js\";\nexport const sealData = createSealData(crypto);\nexport const unsealData = createUnsealData(crypto);\nexport const getIronSession = createGetIronSession(sealData, unsealData);\n"]} +\ No newline at end of file +diff --git a/node_modules/iron-session/dist/index.d.cts b/node_modules/iron-session/dist/index.d.cts +index 539442e..c0619dd 100644 +--- a/node_modules/iron-session/dist/index.d.cts ++++ b/node_modules/iron-session/dist/index.d.cts +@@ -79,6 +79,32 @@ interface SessionOptions { + * @see https://github.com/jshttp/cookie#options-1 + */ + cookieOptions?: CookieOptions; ++ /** ++ * Configure cookie chunking for large sessions that exceed browser cookie size limits. ++ * ++ * When enabled, iron-session will automatically split large cookies into multiple ++ * smaller chunks (named `{cookieName}.0`, `{cookieName}.1`, etc.) and reassemble ++ * them when reading. This allows sessions larger than the typical 4096-byte browser ++ * limit. ++ * ++ * @example { enabled: true, chunkSize: 3500 } ++ */ ++ chunking?: { ++ /** ++ * Enable cookie chunking. When `false` or `undefined`, the traditional 4096-byte ++ * limit check will be enforced. ++ * ++ * @default false ++ */ ++ enabled: boolean; ++ /** ++ * Maximum size in bytes for each cookie chunk. Should be less than 4096 to allow ++ * room for cookie name and attributes. ++ * ++ * @default 3500 ++ */ ++ chunkSize?: number; ++ }; + } + type IronSession = T & { + /** +diff --git a/node_modules/iron-session/dist/index.d.ts b/node_modules/iron-session/dist/index.d.ts +index 539442e..c0619dd 100644 +--- a/node_modules/iron-session/dist/index.d.ts ++++ b/node_modules/iron-session/dist/index.d.ts +@@ -79,6 +79,32 @@ interface SessionOptions { + * @see https://github.com/jshttp/cookie#options-1 + */ + cookieOptions?: CookieOptions; ++ /** ++ * Configure cookie chunking for large sessions that exceed browser cookie size limits. ++ * ++ * When enabled, iron-session will automatically split large cookies into multiple ++ * smaller chunks (named `{cookieName}.0`, `{cookieName}.1`, etc.) and reassemble ++ * them when reading. This allows sessions larger than the typical 4096-byte browser ++ * limit. ++ * ++ * @example { enabled: true, chunkSize: 3500 } ++ */ ++ chunking?: { ++ /** ++ * Enable cookie chunking. When `false` or `undefined`, the traditional 4096-byte ++ * limit check will be enforced. ++ * ++ * @default false ++ */ ++ enabled: boolean; ++ /** ++ * Maximum size in bytes for each cookie chunk. Should be less than 4096 to allow ++ * room for cookie name and attributes. ++ * ++ * @default 3500 ++ */ ++ chunkSize?: number; ++ }; + } + type IronSession = T & { + /** +diff --git a/node_modules/iron-session/dist/index.js b/node_modules/iron-session/dist/index.js +index 9b4634f..496aa44 100644 +--- a/node_modules/iron-session/dist/index.js ++++ b/node_modules/iron-session/dist/index.js +@@ -52,6 +52,49 @@ function setCookie(res, cookieValue) { + cookieValue + ]); + } ++function splitCookieIntoChunks(value, chunkSize) { ++ const chunks = []; ++ for (let i = 0; i < value.length; i += chunkSize) { ++ chunks.push(value.slice(i, i + chunkSize)); ++ } ++ return chunks; ++} ++function reconstructCookie(req, cookieName) { ++ const directCookie = getCookie(req, cookieName); ++ if (directCookie) { ++ return directCookie; ++ } ++ const chunks = []; ++ let chunkIndex = 0; ++ while (true) { ++ const chunkName = `${cookieName}.${chunkIndex}`; ++ const chunk = getCookie(req, chunkName); ++ if (!chunk) { ++ break; ++ } ++ chunks.push(chunk); ++ chunkIndex++; ++ } ++ return chunks.join(""); ++} ++function reconstructCookieWithStore(cookieHandler, cookieName) { ++ const directCookie = getServerActionCookie(cookieName, cookieHandler); ++ if (directCookie) { ++ return directCookie; ++ } ++ const chunks = []; ++ let chunkIndex = 0; ++ while (true) { ++ const chunkName = `${cookieName}.${chunkIndex}`; ++ const chunk = getServerActionCookie(chunkName, cookieHandler); ++ if (!chunk) { ++ break; ++ } ++ chunks.push(chunk); ++ chunkIndex++; ++ } ++ return chunks.join(""); ++} + function createSealData(_crypto) { + return async function sealData2(data, { + password, +@@ -152,7 +195,7 @@ function createGetIronSession(sealData2, unsealData2) { + ); + } + let sessionConfig = getSessionConfig(sessionOptions); +- const sealFromCookies = getCookie(req, sessionConfig.cookieName); ++ const sealFromCookies = reconstructCookie(req, sessionConfig.cookieName); + const session = sealFromCookies ? await unsealData2(sealFromCookies, { + password: passwordsMap, + ttl: sessionConfig.ttl +@@ -174,17 +217,57 @@ function createGetIronSession(sealData2, unsealData2) { + password: passwordsMap, + ttl: sessionConfig.ttl + }); +- const cookieValue = serialize( +- sessionConfig.cookieName, +- seal, +- sessionConfig.cookieOptions +- ); +- if (cookieValue.length > 4096) { +- throw new Error( +- `iron-session: Cookie length is too big (${cookieValue.length} bytes), browsers will refuse it. Try to remove some data.` ++ if (sessionConfig.chunking?.enabled) { ++ const chunkSize = sessionConfig.chunking.chunkSize ?? 3500; ++ let oldChunkIndex = 0; ++ while (true) { ++ const oldChunkName = `${sessionConfig.cookieName}.${oldChunkIndex}`; ++ const oldChunk = getCookie(req, oldChunkName); ++ if (!oldChunk) break; ++ const cleanupCookie = serialize(oldChunkName, "", { ++ ...sessionConfig.cookieOptions, ++ maxAge: 0 ++ }); ++ setCookie(res, cleanupCookie); ++ oldChunkIndex++; ++ } ++ const testCookieValue = serialize( ++ sessionConfig.cookieName, ++ seal, ++ sessionConfig.cookieOptions + ); ++ if (testCookieValue.length <= 4096) { ++ setCookie(res, testCookieValue); ++ return; ++ } ++ const chunks = splitCookieIntoChunks(seal, chunkSize); ++ chunks.forEach((chunk, index) => { ++ const chunkName = `${sessionConfig.cookieName}.${index}`; ++ const chunkCookieValue = serialize( ++ chunkName, ++ chunk, ++ sessionConfig.cookieOptions ++ ); ++ setCookie(res, chunkCookieValue); ++ }); ++ const deleteCookie = serialize(sessionConfig.cookieName, "", { ++ ...sessionConfig.cookieOptions, ++ maxAge: 0 ++ }); ++ setCookie(res, deleteCookie); ++ } else { ++ const cookieValue = serialize( ++ sessionConfig.cookieName, ++ seal, ++ sessionConfig.cookieOptions ++ ); ++ if (cookieValue.length > 4096) { ++ throw new Error( ++ `iron-session: Cookie length is too big (${cookieValue.length} bytes), browsers will refuse it. Try to remove some data.` ++ ); ++ } ++ setCookie(res, cookieValue); + } +- setCookie(res, cookieValue); + } + }, + destroy: { +@@ -197,6 +280,20 @@ function createGetIronSession(sealData2, unsealData2) { + maxAge: 0 + }); + setCookie(res, cookieValue); ++ if (sessionConfig.chunking?.enabled) { ++ let chunkIndex = 0; ++ while (true) { ++ const chunkName = `${sessionConfig.cookieName}.${chunkIndex}`; ++ const chunk = getCookie(req, chunkName); ++ if (!chunk) break; ++ const chunkCookieValue = serialize(chunkName, "", { ++ ...sessionConfig.cookieOptions, ++ maxAge: 0 ++ }); ++ setCookie(res, chunkCookieValue); ++ chunkIndex++; ++ } ++ } + } + } + }); +@@ -217,10 +314,7 @@ async function getIronSessionFromCookieStore(cookieStore, sessionOptions, sealDa + ); + } + let sessionConfig = getSessionConfig(sessionOptions); +- const sealFromCookies = getServerActionCookie( +- sessionConfig.cookieName, +- cookieStore +- ); ++ const sealFromCookies = reconstructCookieWithStore(cookieStore, sessionConfig.cookieName); + const session = sealFromCookies ? await unsealData2(sealFromCookies, { + password: passwordsMap, + ttl: sessionConfig.ttl +@@ -237,17 +331,50 @@ async function getIronSessionFromCookieStore(cookieStore, sessionOptions, sealDa + password: passwordsMap, + ttl: sessionConfig.ttl + }); +- const cookieLength = sessionConfig.cookieName.length + seal.length + JSON.stringify(sessionConfig.cookieOptions).length; +- if (cookieLength > 4096) { +- throw new Error( +- `iron-session: Cookie length is too big (${cookieLength} bytes), browsers will refuse it. Try to remove some data.` ++ if (sessionConfig.chunking?.enabled) { ++ const chunkSize = sessionConfig.chunking.chunkSize ?? 3500; ++ let oldChunkIndex = 0; ++ while (true) { ++ const oldChunkName = `${sessionConfig.cookieName}.${oldChunkIndex}`; ++ const oldChunk = getServerActionCookie(oldChunkName, cookieStore); ++ if (!oldChunk) break; ++ cookieStore.set(oldChunkName, "", { ++ ...sessionConfig.cookieOptions, ++ maxAge: 0 ++ }); ++ oldChunkIndex++; ++ } ++ const cookieLength = sessionConfig.cookieName.length + seal.length + JSON.stringify(sessionConfig.cookieOptions).length; ++ if (cookieLength <= 4096) { ++ cookieStore.set( ++ sessionConfig.cookieName, ++ seal, ++ sessionConfig.cookieOptions ++ ); ++ return; ++ } ++ const chunks = splitCookieIntoChunks(seal, chunkSize); ++ chunks.forEach((chunk, index) => { ++ const chunkName = `${sessionConfig.cookieName}.${index}`; ++ cookieStore.set(chunkName, chunk, sessionConfig.cookieOptions); ++ }); ++ cookieStore.set(sessionConfig.cookieName, "", { ++ ...sessionConfig.cookieOptions, ++ maxAge: 0 ++ }); ++ } else { ++ const cookieLength = sessionConfig.cookieName.length + seal.length + JSON.stringify(sessionConfig.cookieOptions).length; ++ if (cookieLength > 4096) { ++ throw new Error( ++ `iron-session: Cookie length is too big (${cookieLength} bytes), browsers will refuse it. Try to remove some data.` ++ ); ++ } ++ cookieStore.set( ++ sessionConfig.cookieName, ++ seal, ++ sessionConfig.cookieOptions + ); + } +- cookieStore.set( +- sessionConfig.cookieName, +- seal, +- sessionConfig.cookieOptions +- ); + } + }, + destroy: { +@@ -257,6 +384,16 @@ async function getIronSessionFromCookieStore(cookieStore, sessionOptions, sealDa + }); + const cookieOptions = { ...sessionConfig.cookieOptions, maxAge: 0 }; + cookieStore.set(sessionConfig.cookieName, "", cookieOptions); ++ if (sessionConfig.chunking?.enabled) { ++ let chunkIndex = 0; ++ while (true) { ++ const chunkName = `${sessionConfig.cookieName}.${chunkIndex}`; ++ const chunk = getServerActionCookie(chunkName, cookieStore); ++ if (!chunk) break; ++ cookieStore.set(chunkName, "", cookieOptions); ++ chunkIndex++; ++ } ++ } + } + } + }); +diff --git a/node_modules/iron-session/dist/index.js.map b/node_modules/iron-session/dist/index.js.map +index d7cc756..77a583a 100644 +--- a/node_modules/iron-session/dist/index.js.map ++++ b/node_modules/iron-session/dist/index.js.map +@@ -1 +1 @@ +-{"version":3,"sources":["../src/core.ts","../src/index.ts"],"names":["sealData","seal","ironSeal","ironDefaults","unsealData","ironUnseal","getIronSession"],"mappings":"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","file":"index.js","sourcesContent":["import type { IncomingMessage, ServerResponse } from \"http\";\nimport { parse, serialize, type CookieSerializeOptions } from \"cookie\";\nimport {\n defaults as ironDefaults,\n seal as ironSeal,\n unseal as ironUnseal,\n} from \"iron-webcrypto\";\n\ntype PasswordsMap = Record;\ntype Password = PasswordsMap | string;\ntype RequestType = IncomingMessage | Request;\ntype ResponseType = Response | ServerResponse;\n\n/**\n * {@link https://wicg.github.io/cookie-store/#dictdef-cookielistitem CookieListItem}\n * as specified by W3C.\n */\ninterface CookieListItem\n extends Pick<\n CookieSerializeOptions,\n \"domain\" | \"path\" | \"sameSite\" | \"secure\"\n > {\n /** A string with the name of a cookie. */\n name: string;\n /** A string containing the value of the cookie. */\n value: string;\n /** A number of milliseconds or Date interface containing the expires of the cookie. */\n expires?: CookieSerializeOptions[\"expires\"] | number;\n}\n\n/**\n * Superset of {@link CookieListItem} extending it with\n * the `httpOnly`, `maxAge` and `priority` properties.\n */\ntype ResponseCookie = CookieListItem &\n Pick;\n\n/**\n * The high-level type definition of the .get() and .set() methods\n * of { cookies() } from \"next/headers\"\n */\nexport interface CookieStore {\n get: (name: string) => { name: string; value: string } | undefined;\n set: {\n (name: string, value: string, cookie?: Partial): void;\n (options: ResponseCookie): void;\n };\n}\n\n/**\n * Set-Cookie Attributes do not include `encode`. We omit this from our `cookieOptions` type.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie\n * @see https://developer.chrome.com/docs/devtools/application/cookies/\n */\ntype CookieOptions = Omit;\n\nexport interface SessionOptions {\n /**\n * The cookie name that will be used inside the browser. Make sure it's unique\n * given your application.\n *\n * @example 'vercel-session'\n */\n cookieName: string;\n\n /**\n * The password(s) that will be used to encrypt the cookie. Can either be a string\n * or an object.\n *\n * When you provide multiple passwords then all of them will be used to decrypt\n * the cookie. But only the most recent (`= highest key`, `2` in the example)\n * password will be used to encrypt the cookie. This allows password rotation.\n *\n * @example { 1: 'password-1', 2: 'password-2' }\n */\n password: Password;\n\n /**\n * The time (in seconds) that the session will be valid for. Also sets the\n * `max-age` attribute of the cookie automatically (`= ttl - 60s`, so that the\n * cookie always expire before the session).\n *\n * `ttl = 0` means no expiration.\n *\n * @default 1209600\n */\n ttl?: number;\n\n /**\n * The options that will be passed to the cookie library.\n *\n * If you want to use \"session cookies\" (cookies that are deleted when the browser\n * is closed) then you need to pass `cookieOptions: { maxAge: undefined }`\n *\n * @see https://github.com/jshttp/cookie#options-1\n */\n cookieOptions?: CookieOptions;\n}\n\nexport type IronSession = T & {\n /**\n * Encrypts the session data and sets the cookie.\n */\n readonly save: () => Promise;\n\n /**\n * Destroys the session data and removes the cookie.\n */\n readonly destroy: () => void;\n\n /**\n * Update the session configuration. You still need to call save() to send the new cookie.\n */\n readonly updateConfig: (newSessionOptions: SessionOptions) => void;\n};\n\n// default time allowed to check for iron seal validity when ttl passed\n// see https://hapi.dev/module/iron/api/?v=7.0.1#options\nconst timestampSkewSec = 60;\nconst fourteenDaysInSeconds = 14 * 24 * 3600;\n\n// We store a token major version to handle data format changes so that the cookies\n// can be kept alive between upgrades, no need to disconnect everyone.\nconst currentMajorVersion = 2;\nconst versionDelimiter = \"~\";\n\nconst defaultOptions: Required> =\n {\n ttl: fourteenDaysInSeconds,\n cookieOptions: { httpOnly: true, secure: true, sameSite: \"lax\", path: \"/\" },\n };\n\nfunction normalizeStringPasswordToMap(password: Password): PasswordsMap {\n return typeof password === \"string\" ? { 1: password } : password;\n}\n\nfunction parseSeal(seal: string): {\n sealWithoutVersion: string;\n tokenVersion: number | null;\n} {\n const [sealWithoutVersion, tokenVersionAsString] =\n seal.split(versionDelimiter);\n const tokenVersion =\n tokenVersionAsString == null ? null : parseInt(tokenVersionAsString, 10);\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return { sealWithoutVersion: sealWithoutVersion!, tokenVersion };\n}\n\nfunction computeCookieMaxAge(ttl: number): number {\n if (ttl === 0) {\n // ttl = 0 means no expiration\n // but in reality cookies have to expire (can't have no max-age)\n // 2147483647 is the max value for max-age in cookies\n // see https://stackoverflow.com/a/11685301/147079\n return 2147483647;\n }\n\n // The next line makes sure browser will expire cookies before seals are considered expired by the server.\n // It also allows for clock difference of 60 seconds between server and clients.\n return ttl - timestampSkewSec;\n}\n\nfunction getCookie(req: RequestType, cookieName: string): string {\n return (\n parse(\n (\"headers\" in req && typeof req.headers.get === \"function\"\n ? req.headers.get(\"cookie\")\n : (req as IncomingMessage).headers.cookie) ?? \"\",\n )[cookieName] ?? \"\"\n );\n}\n\nfunction getServerActionCookie(\n cookieName: string,\n cookieHandler: CookieStore,\n): string {\n const cookieObject = cookieHandler.get(cookieName);\n const cookie = cookieObject?.value;\n if (typeof cookie === \"string\") {\n return cookie;\n }\n return \"\";\n}\n\nfunction setCookie(res: ResponseType, cookieValue: string): void {\n if (\"headers\" in res && typeof res.headers.append === \"function\") {\n res.headers.append(\"set-cookie\", cookieValue);\n return;\n }\n let existingSetCookie = (res as ServerResponse).getHeader(\"set-cookie\") ?? [];\n if (!Array.isArray(existingSetCookie)) {\n existingSetCookie = [existingSetCookie.toString()];\n }\n (res as ServerResponse).setHeader(\"set-cookie\", [\n ...existingSetCookie,\n cookieValue,\n ]);\n}\n\nexport function createSealData(_crypto: Crypto) {\n return async function sealData(\n data: unknown,\n {\n password,\n ttl = fourteenDaysInSeconds,\n }: { password: Password; ttl?: number },\n ): Promise {\n const passwordsMap = normalizeStringPasswordToMap(password);\n\n const mostRecentPasswordId = Math.max(\n ...Object.keys(passwordsMap).map(Number),\n );\n const passwordForSeal = {\n id: mostRecentPasswordId.toString(),\n secret: passwordsMap[mostRecentPasswordId]!,\n };\n\n const seal = await ironSeal(_crypto, data, passwordForSeal, {\n ...ironDefaults,\n ttl: ttl * 1000,\n });\n\n return `${seal}${versionDelimiter}${currentMajorVersion}`;\n };\n}\n\nexport function createUnsealData(_crypto: Crypto) {\n return async function unsealData(\n seal: string,\n {\n password,\n ttl = fourteenDaysInSeconds,\n }: { password: Password; ttl?: number },\n ): Promise {\n const passwordsMap = normalizeStringPasswordToMap(password);\n const { sealWithoutVersion, tokenVersion } = parseSeal(seal);\n\n try {\n const data =\n (await ironUnseal(_crypto, sealWithoutVersion, passwordsMap, {\n ...ironDefaults,\n ttl: ttl * 1000,\n })) ?? {};\n\n if (tokenVersion === 2) {\n return data as T;\n }\n\n // @ts-expect-error `persistent` does not exist on newer tokens\n return { ...data.persistent } as T;\n } catch (error) {\n if (\n error instanceof Error &&\n /^(Expired seal|Bad hmac value|Cannot find password|Incorrect number of sealed components)/.test(\n error.message,\n )\n ) {\n // if seal expired or\n // if seal is not valid (encrypted using a different password, when passwords are badly rotated) or\n // if we can't find back the password in the seal\n // then we just start a new session over\n return {} as T;\n }\n\n throw error;\n }\n };\n}\n\nfunction getSessionConfig(\n sessionOptions: SessionOptions,\n): Required {\n const options = {\n ...defaultOptions,\n ...sessionOptions,\n cookieOptions: {\n ...defaultOptions.cookieOptions,\n ...(sessionOptions.cookieOptions || {}),\n },\n };\n\n if (\n sessionOptions.cookieOptions &&\n \"maxAge\" in sessionOptions.cookieOptions\n ) {\n if (sessionOptions.cookieOptions.maxAge === undefined) {\n // session cookies, do not set maxAge, consider token as infinite\n options.ttl = 0;\n }\n } else {\n options.cookieOptions.maxAge = computeCookieMaxAge(options.ttl);\n }\n\n return options;\n}\n\nconst badUsageMessage =\n \"iron-session: Bad usage: use getIronSession(req, res, options) or getIronSession(cookieStore, options).\";\n\nexport function createGetIronSession(\n sealData: ReturnType,\n unsealData: ReturnType,\n) {\n return getIronSession;\n\n async function getIronSession(\n cookies: CookieStore,\n sessionOptions: SessionOptions,\n ): Promise>;\n async function getIronSession(\n req: RequestType,\n res: ResponseType,\n sessionOptions: SessionOptions,\n ): Promise>;\n async function getIronSession(\n reqOrCookieStore: RequestType | CookieStore,\n resOrsessionOptions: ResponseType | SessionOptions,\n sessionOptions?: SessionOptions,\n ): Promise> {\n if (!reqOrCookieStore) {\n throw new Error(badUsageMessage);\n }\n\n if (!resOrsessionOptions) {\n throw new Error(badUsageMessage);\n }\n\n if (!sessionOptions) {\n return getIronSessionFromCookieStore(\n reqOrCookieStore as CookieStore,\n resOrsessionOptions as SessionOptions,\n sealData,\n unsealData,\n );\n }\n\n const req = reqOrCookieStore as RequestType;\n const res = resOrsessionOptions as ResponseType;\n\n if (!sessionOptions) {\n throw new Error(badUsageMessage);\n }\n\n if (!sessionOptions.cookieName) {\n throw new Error(\"iron-session: Bad usage. Missing cookie name.\");\n }\n\n if (!sessionOptions.password) {\n throw new Error(\"iron-session: Bad usage. Missing password.\");\n }\n\n const passwordsMap = normalizeStringPasswordToMap(sessionOptions.password);\n\n if (Object.values(passwordsMap).some((password) => password.length < 32)) {\n throw new Error(\n \"iron-session: Bad usage. Password must be at least 32 characters long.\",\n );\n }\n\n let sessionConfig = getSessionConfig(sessionOptions);\n\n const sealFromCookies = getCookie(req, sessionConfig.cookieName);\n const session = sealFromCookies\n ? await unsealData(sealFromCookies, {\n password: passwordsMap,\n ttl: sessionConfig.ttl,\n })\n : ({} as T);\n\n Object.defineProperties(session, {\n updateConfig: {\n value: function updateConfig(newSessionOptions: SessionOptions) {\n sessionConfig = getSessionConfig(newSessionOptions);\n },\n },\n save: {\n value: async function save() {\n if (\"headersSent\" in res && res.headersSent) {\n throw new Error(\n \"iron-session: Cannot set session cookie: session.save() was called after headers were sent. Make sure to call it before any res.send() or res.end()\",\n );\n }\n\n const seal = await sealData(session, {\n password: passwordsMap,\n ttl: sessionConfig.ttl,\n });\n const cookieValue = serialize(\n sessionConfig.cookieName,\n seal,\n sessionConfig.cookieOptions,\n );\n\n if (cookieValue.length > 4096) {\n throw new Error(\n `iron-session: Cookie length is too big (${cookieValue.length} bytes), browsers will refuse it. Try to remove some data.`,\n );\n }\n\n setCookie(res, cookieValue);\n },\n },\n\n destroy: {\n value: function destroy() {\n Object.keys(session).forEach((key) => {\n delete (session as Record)[key];\n });\n const cookieValue = serialize(sessionConfig.cookieName, \"\", {\n ...sessionConfig.cookieOptions,\n maxAge: 0,\n });\n\n setCookie(res, cookieValue);\n },\n },\n });\n\n return session as IronSession;\n }\n}\n\nasync function getIronSessionFromCookieStore(\n cookieStore: CookieStore,\n sessionOptions: SessionOptions,\n sealData: ReturnType,\n unsealData: ReturnType,\n): Promise> {\n if (!sessionOptions.cookieName) {\n throw new Error(\"iron-session: Bad usage. Missing cookie name.\");\n }\n\n if (!sessionOptions.password) {\n throw new Error(\"iron-session: Bad usage. Missing password.\");\n }\n\n const passwordsMap = normalizeStringPasswordToMap(sessionOptions.password);\n\n if (Object.values(passwordsMap).some((password) => password.length < 32)) {\n throw new Error(\n \"iron-session: Bad usage. Password must be at least 32 characters long.\",\n );\n }\n\n let sessionConfig = getSessionConfig(sessionOptions);\n const sealFromCookies = getServerActionCookie(\n sessionConfig.cookieName,\n cookieStore,\n );\n const session = sealFromCookies\n ? await unsealData(sealFromCookies, {\n password: passwordsMap,\n ttl: sessionConfig.ttl,\n })\n : ({} as T);\n\n Object.defineProperties(session, {\n updateConfig: {\n value: function updateConfig(newSessionOptions: SessionOptions) {\n sessionConfig = getSessionConfig(newSessionOptions);\n },\n },\n save: {\n value: async function save() {\n const seal = await sealData(session, {\n password: passwordsMap,\n ttl: sessionConfig.ttl,\n });\n\n const cookieLength =\n sessionConfig.cookieName.length +\n seal.length +\n JSON.stringify(sessionConfig.cookieOptions).length;\n\n if (cookieLength > 4096) {\n throw new Error(\n `iron-session: Cookie length is too big (${cookieLength} bytes), browsers will refuse it. Try to remove some data.`,\n );\n }\n\n cookieStore.set(\n sessionConfig.cookieName,\n seal,\n sessionConfig.cookieOptions,\n );\n },\n },\n\n destroy: {\n value: function destroy() {\n Object.keys(session).forEach((key) => {\n delete (session as Record)[key];\n });\n\n const cookieOptions = { ...sessionConfig.cookieOptions, maxAge: 0 };\n cookieStore.set(sessionConfig.cookieName, \"\", cookieOptions);\n },\n },\n });\n\n return session as IronSession;\n}\n","import {\n createGetIronSession,\n createSealData,\n createUnsealData,\n} from \"./core.js\";\n\nimport * as crypto from \"uncrypto\";\n\nexport type { IronSession, SessionOptions } from \"./core.js\";\nexport const sealData = createSealData(crypto);\nexport const unsealData = createUnsealData(crypto);\nexport const getIronSession = createGetIronSession(sealData, unsealData);\n"]} +\ No newline at end of file ++{"version":3,"sources":["../src/core.ts","../src/index.ts"],"names":["sealData","seal","ironSeal","ironDefaults","unsealData","ironUnseal","getIronSession"],"mappings":"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","file":"index.js","sourcesContent":["import type { IncomingMessage, ServerResponse } from \"http\";\nimport { parse, serialize, type CookieSerializeOptions } from \"cookie\";\nimport {\n defaults as ironDefaults,\n seal as ironSeal,\n unseal as ironUnseal,\n} from \"iron-webcrypto\";\n\ntype PasswordsMap = Record;\ntype Password = PasswordsMap | string;\ntype RequestType = IncomingMessage | Request;\ntype ResponseType = Response | ServerResponse;\n\n/**\n * {@link https://wicg.github.io/cookie-store/#dictdef-cookielistitem CookieListItem}\n * as specified by W3C.\n */\ninterface CookieListItem\n extends Pick<\n CookieSerializeOptions,\n \"domain\" | \"path\" | \"sameSite\" | \"secure\"\n > {\n /** A string with the name of a cookie. */\n name: string;\n /** A string containing the value of the cookie. */\n value: string;\n /** A number of milliseconds or Date interface containing the expires of the cookie. */\n expires?: CookieSerializeOptions[\"expires\"] | number;\n}\n\n/**\n * Superset of {@link CookieListItem} extending it with\n * the `httpOnly`, `maxAge` and `priority` properties.\n */\ntype ResponseCookie = CookieListItem &\n Pick;\n\n/**\n * The high-level type definition of the .get() and .set() methods\n * of { cookies() } from \"next/headers\"\n */\nexport interface CookieStore {\n get: (name: string) => { name: string; value: string } | undefined;\n set: {\n (name: string, value: string, cookie?: Partial): void;\n (options: ResponseCookie): void;\n };\n}\n\n/**\n * Set-Cookie Attributes do not include `encode`. We omit this from our `cookieOptions` type.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie\n * @see https://developer.chrome.com/docs/devtools/application/cookies/\n */\ntype CookieOptions = Omit;\n\nexport interface SessionOptions {\n /**\n * The cookie name that will be used inside the browser. Make sure it's unique\n * given your application.\n *\n * @example 'vercel-session'\n */\n cookieName: string;\n\n /**\n * The password(s) that will be used to encrypt the cookie. Can either be a string\n * or an object.\n *\n * When you provide multiple passwords then all of them will be used to decrypt\n * the cookie. But only the most recent (`= highest key`, `2` in the example)\n * password will be used to encrypt the cookie. This allows password rotation.\n *\n * @example { 1: 'password-1', 2: 'password-2' }\n */\n password: Password;\n\n /**\n * The time (in seconds) that the session will be valid for. Also sets the\n * `max-age` attribute of the cookie automatically (`= ttl - 60s`, so that the\n * cookie always expire before the session).\n *\n * `ttl = 0` means no expiration.\n *\n * @default 1209600\n */\n ttl?: number;\n\n /**\n * The options that will be passed to the cookie library.\n *\n * If you want to use \"session cookies\" (cookies that are deleted when the browser\n * is closed) then you need to pass `cookieOptions: { maxAge: undefined }`\n *\n * @see https://github.com/jshttp/cookie#options-1\n */\n cookieOptions?: CookieOptions;\n\n /**\n * Configure cookie chunking for large sessions that exceed browser cookie size limits.\n *\n * When enabled, iron-session will automatically split large cookies into multiple\n * smaller chunks (named `{cookieName}.0`, `{cookieName}.1`, etc.) and reassemble\n * them when reading. This allows sessions larger than the typical 4096-byte browser\n * limit.\n *\n * @example { enabled: true, chunkSize: 3500 }\n */\n chunking?: {\n /**\n * Enable cookie chunking. When `false` or `undefined`, the traditional 4096-byte\n * limit check will be enforced.\n *\n * @default false\n */\n enabled: boolean;\n /**\n * Maximum size in bytes for each cookie chunk. Should be less than 4096 to allow\n * room for cookie name and attributes.\n *\n * @default 3500\n */\n chunkSize?: number;\n };\n}\n\nexport type IronSession = T & {\n /**\n * Encrypts the session data and sets the cookie.\n */\n readonly save: () => Promise;\n\n /**\n * Destroys the session data and removes the cookie.\n */\n readonly destroy: () => void;\n\n /**\n * Update the session configuration. You still need to call save() to send the new cookie.\n */\n readonly updateConfig: (newSessionOptions: SessionOptions) => void;\n};\n\n// default time allowed to check for iron seal validity when ttl passed\n// see https://hapi.dev/module/iron/api/?v=7.0.1#options\nconst timestampSkewSec = 60;\nconst fourteenDaysInSeconds = 14 * 24 * 3600;\n\n// We store a token major version to handle data format changes so that the cookies\n// can be kept alive between upgrades, no need to disconnect everyone.\nconst currentMajorVersion = 2;\nconst versionDelimiter = \"~\";\n\nconst defaultOptions: Required> =\n {\n ttl: fourteenDaysInSeconds,\n cookieOptions: { httpOnly: true, secure: true, sameSite: \"lax\", path: \"/\" },\n };\n\nfunction normalizeStringPasswordToMap(password: Password): PasswordsMap {\n return typeof password === \"string\" ? { 1: password } : password;\n}\n\nfunction parseSeal(seal: string): {\n sealWithoutVersion: string;\n tokenVersion: number | null;\n} {\n const [sealWithoutVersion, tokenVersionAsString] =\n seal.split(versionDelimiter);\n const tokenVersion =\n tokenVersionAsString == null ? null : parseInt(tokenVersionAsString, 10);\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return { sealWithoutVersion: sealWithoutVersion!, tokenVersion };\n}\n\nfunction computeCookieMaxAge(ttl: number): number {\n if (ttl === 0) {\n // ttl = 0 means no expiration\n // but in reality cookies have to expire (can't have no max-age)\n // 2147483647 is the max value for max-age in cookies\n // see https://stackoverflow.com/a/11685301/147079\n return 2147483647;\n }\n\n // The next line makes sure browser will expire cookies before seals are considered expired by the server.\n // It also allows for clock difference of 60 seconds between server and clients.\n return ttl - timestampSkewSec;\n}\n\nfunction getCookie(req: RequestType, cookieName: string): string {\n return (\n parse(\n (\"headers\" in req && typeof req.headers.get === \"function\"\n ? req.headers.get(\"cookie\")\n : (req as IncomingMessage).headers.cookie) ?? \"\",\n )[cookieName] ?? \"\"\n );\n}\n\nfunction getServerActionCookie(\n cookieName: string,\n cookieHandler: CookieStore,\n): string {\n const cookieObject = cookieHandler.get(cookieName);\n const cookie = cookieObject?.value;\n if (typeof cookie === \"string\") {\n return cookie;\n }\n return \"\";\n}\n\nfunction setCookie(res: ResponseType, cookieValue: string): void {\n if (\"headers\" in res && typeof res.headers.append === \"function\") {\n res.headers.append(\"set-cookie\", cookieValue);\n return;\n }\n let existingSetCookie = (res as ServerResponse).getHeader(\"set-cookie\") ?? [];\n if (!Array.isArray(existingSetCookie)) {\n existingSetCookie = [existingSetCookie.toString()];\n }\n (res as ServerResponse).setHeader(\"set-cookie\", [\n ...existingSetCookie,\n cookieValue,\n ]);\n}\n\n/**\n * Splits a large cookie value into multiple chunks for browsers that enforce\n * size limits. Each chunk is named `{baseName}.{index}`.\n */\nfunction splitCookieIntoChunks(\n value: string,\n chunkSize: number,\n): string[] {\n const chunks: string[] = [];\n for (let i = 0; i < value.length; i += chunkSize) {\n chunks.push(value.slice(i, i + chunkSize));\n }\n return chunks;\n}\n\n/**\n * Reconstructs a cookie value from chunks. Tries direct cookie first,\n * then attempts to reassemble from indexed chunks if not found.\n * Works transparently for both chunked and non-chunked cookies.\n */\nfunction reconstructCookie(\n req: RequestType,\n cookieName: string,\n): string {\n // Try direct cookie first (for non-chunked or old sessions)\n const directCookie = getCookie(req, cookieName);\n if (directCookie) {\n return directCookie;\n }\n\n // Try to reconstruct from chunks\n const chunks: string[] = [];\n let chunkIndex = 0;\n\n while (true) {\n const chunkName = `${cookieName}.${chunkIndex}`;\n const chunk = getCookie(req, chunkName);\n\n if (!chunk) {\n break;\n }\n\n chunks.push(chunk);\n chunkIndex++;\n }\n\n return chunks.join(\"\");\n}\n\n/**\n * Reconstructs a cookie value from chunks using CookieStore.\n * For use with Next.js cookies() and similar APIs.\n * Works transparently for both chunked and non-chunked cookies.\n */\nfunction reconstructCookieWithStore(\n cookieHandler: CookieStore,\n cookieName: string,\n): string {\n // Try direct cookie first\n const directCookie = getServerActionCookie(cookieName, cookieHandler);\n if (directCookie) {\n return directCookie;\n }\n\n // Try to reconstruct from chunks\n const chunks: string[] = [];\n let chunkIndex = 0;\n\n while (true) {\n const chunkName = `${cookieName}.${chunkIndex}`;\n const chunk = getServerActionCookie(chunkName, cookieHandler);\n\n if (!chunk) {\n break;\n }\n\n chunks.push(chunk);\n chunkIndex++;\n }\n\n return chunks.join(\"\");\n}\n\nexport function createSealData(_crypto: Crypto) {\n return async function sealData(\n data: unknown,\n {\n password,\n ttl = fourteenDaysInSeconds,\n }: { password: Password; ttl?: number },\n ): Promise {\n const passwordsMap = normalizeStringPasswordToMap(password);\n\n const mostRecentPasswordId = Math.max(\n ...Object.keys(passwordsMap).map(Number),\n );\n const passwordForSeal = {\n id: mostRecentPasswordId.toString(),\n secret: passwordsMap[mostRecentPasswordId]!,\n };\n\n const seal = await ironSeal(_crypto, data, passwordForSeal, {\n ...ironDefaults,\n ttl: ttl * 1000,\n });\n\n return `${seal}${versionDelimiter}${currentMajorVersion}`;\n };\n}\n\nexport function createUnsealData(_crypto: Crypto) {\n return async function unsealData(\n seal: string,\n {\n password,\n ttl = fourteenDaysInSeconds,\n }: { password: Password; ttl?: number },\n ): Promise {\n const passwordsMap = normalizeStringPasswordToMap(password);\n const { sealWithoutVersion, tokenVersion } = parseSeal(seal);\n\n try {\n const data =\n (await ironUnseal(_crypto, sealWithoutVersion, passwordsMap, {\n ...ironDefaults,\n ttl: ttl * 1000,\n })) ?? {};\n\n if (tokenVersion === 2) {\n return data as T;\n }\n\n // @ts-expect-error `persistent` does not exist on newer tokens\n return { ...data.persistent } as T;\n } catch (error) {\n if (\n error instanceof Error &&\n /^(Expired seal|Bad hmac value|Cannot find password|Incorrect number of sealed components)/.test(\n error.message,\n )\n ) {\n // if seal expired or\n // if seal is not valid (encrypted using a different password, when passwords are badly rotated) or\n // if we can't find back the password in the seal\n // then we just start a new session over\n return {} as T;\n }\n\n throw error;\n }\n };\n}\n\nfunction getSessionConfig(\n sessionOptions: SessionOptions,\n): Required> & Pick {\n const options = {\n ...defaultOptions,\n ...sessionOptions,\n cookieOptions: {\n ...defaultOptions.cookieOptions,\n ...(sessionOptions.cookieOptions || {}),\n },\n };\n\n if (\n sessionOptions.cookieOptions &&\n \"maxAge\" in sessionOptions.cookieOptions\n ) {\n if (sessionOptions.cookieOptions.maxAge === undefined) {\n // session cookies, do not set maxAge, consider token as infinite\n options.ttl = 0;\n }\n } else {\n options.cookieOptions.maxAge = computeCookieMaxAge(options.ttl);\n }\n\n return options;\n}\n\nconst badUsageMessage =\n \"iron-session: Bad usage: use getIronSession(req, res, options) or getIronSession(cookieStore, options).\";\n\nexport function createGetIronSession(\n sealData: ReturnType,\n unsealData: ReturnType,\n) {\n return getIronSession;\n\n async function getIronSession(\n cookies: CookieStore,\n sessionOptions: SessionOptions,\n ): Promise>;\n async function getIronSession(\n req: RequestType,\n res: ResponseType,\n sessionOptions: SessionOptions,\n ): Promise>;\n async function getIronSession(\n reqOrCookieStore: RequestType | CookieStore,\n resOrsessionOptions: ResponseType | SessionOptions,\n sessionOptions?: SessionOptions,\n ): Promise> {\n if (!reqOrCookieStore) {\n throw new Error(badUsageMessage);\n }\n\n if (!resOrsessionOptions) {\n throw new Error(badUsageMessage);\n }\n\n if (!sessionOptions) {\n return getIronSessionFromCookieStore(\n reqOrCookieStore as CookieStore,\n resOrsessionOptions as SessionOptions,\n sealData,\n unsealData,\n );\n }\n\n const req = reqOrCookieStore as RequestType;\n const res = resOrsessionOptions as ResponseType;\n\n if (!sessionOptions) {\n throw new Error(badUsageMessage);\n }\n\n if (!sessionOptions.cookieName) {\n throw new Error(\"iron-session: Bad usage. Missing cookie name.\");\n }\n\n if (!sessionOptions.password) {\n throw new Error(\"iron-session: Bad usage. Missing password.\");\n }\n\n const passwordsMap = normalizeStringPasswordToMap(sessionOptions.password);\n\n if (Object.values(passwordsMap).some((password) => password.length < 32)) {\n throw new Error(\n \"iron-session: Bad usage. Password must be at least 32 characters long.\",\n );\n }\n\n let sessionConfig = getSessionConfig(sessionOptions);\n\n const sealFromCookies = reconstructCookie(req, sessionConfig.cookieName);\n const session = sealFromCookies\n ? await unsealData(sealFromCookies, {\n password: passwordsMap,\n ttl: sessionConfig.ttl,\n })\n : ({} as T);\n\n Object.defineProperties(session, {\n updateConfig: {\n value: function updateConfig(newSessionOptions: SessionOptions) {\n sessionConfig = getSessionConfig(newSessionOptions);\n },\n },\n save: {\n value: async function save() {\n if (\"headersSent\" in res && res.headersSent) {\n throw new Error(\n \"iron-session: Cannot set session cookie: session.save() was called after headers were sent. Make sure to call it before any res.send() or res.end()\",\n );\n }\n\n const seal = await sealData(session, {\n password: passwordsMap,\n ttl: sessionConfig.ttl,\n });\n\n // Check if chunking is enabled\n if (sessionConfig.chunking?.enabled) {\n const chunkSize = sessionConfig.chunking.chunkSize ?? 3500;\n\n // Clean up old chunks first\n let oldChunkIndex = 0;\n while (true) {\n const oldChunkName = `${sessionConfig.cookieName}.${oldChunkIndex}`;\n const oldChunk = getCookie(req, oldChunkName);\n if (!oldChunk) break;\n\n const cleanupCookie = serialize(oldChunkName, \"\", {\n ...sessionConfig.cookieOptions,\n maxAge: 0,\n });\n setCookie(res, cleanupCookie);\n oldChunkIndex++;\n }\n\n // If seal is small enough, use single cookie\n const testCookieValue = serialize(\n sessionConfig.cookieName,\n seal,\n sessionConfig.cookieOptions,\n );\n\n if (testCookieValue.length <= 4096) {\n setCookie(res, testCookieValue);\n return;\n }\n\n // Split into chunks\n const chunks = splitCookieIntoChunks(seal, chunkSize);\n chunks.forEach((chunk, index) => {\n const chunkName = `${sessionConfig.cookieName}.${index}`;\n const chunkCookieValue = serialize(\n chunkName,\n chunk,\n sessionConfig.cookieOptions,\n );\n setCookie(res, chunkCookieValue);\n });\n\n // Delete the main cookie if it exists (we're using chunks now)\n const deleteCookie = serialize(sessionConfig.cookieName, \"\", {\n ...sessionConfig.cookieOptions,\n maxAge: 0,\n });\n setCookie(res, deleteCookie);\n } else {\n // Original behavior - no chunking\n const cookieValue = serialize(\n sessionConfig.cookieName,\n seal,\n sessionConfig.cookieOptions,\n );\n\n if (cookieValue.length > 4096) {\n throw new Error(\n `iron-session: Cookie length is too big (${cookieValue.length} bytes), browsers will refuse it. Try to remove some data.`,\n );\n }\n\n setCookie(res, cookieValue);\n }\n },\n },\n\n destroy: {\n value: function destroy() {\n Object.keys(session).forEach((key) => {\n delete (session as Record)[key];\n });\n\n // Delete main cookie\n const cookieValue = serialize(sessionConfig.cookieName, \"\", {\n ...sessionConfig.cookieOptions,\n maxAge: 0,\n });\n setCookie(res, cookieValue);\n\n // Also delete chunks if chunking was enabled\n if (sessionConfig.chunking?.enabled) {\n let chunkIndex = 0;\n while (true) {\n const chunkName = `${sessionConfig.cookieName}.${chunkIndex}`;\n const chunk = getCookie(req, chunkName);\n if (!chunk) break;\n\n const chunkCookieValue = serialize(chunkName, \"\", {\n ...sessionConfig.cookieOptions,\n maxAge: 0,\n });\n setCookie(res, chunkCookieValue);\n chunkIndex++;\n }\n }\n },\n },\n });\n\n return session as IronSession;\n }\n}\n\nasync function getIronSessionFromCookieStore(\n cookieStore: CookieStore,\n sessionOptions: SessionOptions,\n sealData: ReturnType,\n unsealData: ReturnType,\n): Promise> {\n if (!sessionOptions.cookieName) {\n throw new Error(\"iron-session: Bad usage. Missing cookie name.\");\n }\n\n if (!sessionOptions.password) {\n throw new Error(\"iron-session: Bad usage. Missing password.\");\n }\n\n const passwordsMap = normalizeStringPasswordToMap(sessionOptions.password);\n\n if (Object.values(passwordsMap).some((password) => password.length < 32)) {\n throw new Error(\n \"iron-session: Bad usage. Password must be at least 32 characters long.\",\n );\n }\n\n let sessionConfig = getSessionConfig(sessionOptions);\n\n const sealFromCookies = reconstructCookieWithStore(cookieStore, sessionConfig.cookieName);\n const session = sealFromCookies\n ? await unsealData(sealFromCookies, {\n password: passwordsMap,\n ttl: sessionConfig.ttl,\n })\n : ({} as T);\n\n Object.defineProperties(session, {\n updateConfig: {\n value: function updateConfig(newSessionOptions: SessionOptions) {\n sessionConfig = getSessionConfig(newSessionOptions);\n },\n },\n save: {\n value: async function save() {\n const seal = await sealData(session, {\n password: passwordsMap,\n ttl: sessionConfig.ttl,\n });\n\n // Check if chunking is enabled\n if (sessionConfig.chunking?.enabled) {\n const chunkSize = sessionConfig.chunking.chunkSize ?? 3500;\n\n // Clean up old chunks first\n let oldChunkIndex = 0;\n while (true) {\n const oldChunkName = `${sessionConfig.cookieName}.${oldChunkIndex}`;\n const oldChunk = getServerActionCookie(oldChunkName, cookieStore);\n if (!oldChunk) break;\n\n cookieStore.set(oldChunkName, \"\", {\n ...sessionConfig.cookieOptions,\n maxAge: 0,\n });\n oldChunkIndex++;\n }\n\n // If seal is small enough, use single cookie\n const cookieLength =\n sessionConfig.cookieName.length +\n seal.length +\n JSON.stringify(sessionConfig.cookieOptions).length;\n\n if (cookieLength <= 4096) {\n cookieStore.set(\n sessionConfig.cookieName,\n seal,\n sessionConfig.cookieOptions,\n );\n return;\n }\n\n // Split into chunks\n const chunks = splitCookieIntoChunks(seal, chunkSize);\n chunks.forEach((chunk, index) => {\n const chunkName = `${sessionConfig.cookieName}.${index}`;\n cookieStore.set(chunkName, chunk, sessionConfig.cookieOptions);\n });\n\n // Delete the main cookie if it exists (we're using chunks now)\n cookieStore.set(sessionConfig.cookieName, \"\", {\n ...sessionConfig.cookieOptions,\n maxAge: 0,\n });\n } else {\n // Original behavior - no chunking\n const cookieLength =\n sessionConfig.cookieName.length +\n seal.length +\n JSON.stringify(sessionConfig.cookieOptions).length;\n\n if (cookieLength > 4096) {\n throw new Error(\n `iron-session: Cookie length is too big (${cookieLength} bytes), browsers will refuse it. Try to remove some data.`,\n );\n }\n\n cookieStore.set(\n sessionConfig.cookieName,\n seal,\n sessionConfig.cookieOptions,\n );\n }\n },\n },\n\n destroy: {\n value: function destroy() {\n Object.keys(session).forEach((key) => {\n delete (session as Record)[key];\n });\n\n // Delete main cookie\n const cookieOptions = { ...sessionConfig.cookieOptions, maxAge: 0 };\n cookieStore.set(sessionConfig.cookieName, \"\", cookieOptions);\n\n // Also delete chunks if chunking was enabled\n if (sessionConfig.chunking?.enabled) {\n let chunkIndex = 0;\n while (true) {\n const chunkName = `${sessionConfig.cookieName}.${chunkIndex}`;\n const chunk = getServerActionCookie(chunkName, cookieStore);\n if (!chunk) break;\n\n cookieStore.set(chunkName, \"\", cookieOptions);\n chunkIndex++;\n }\n }\n },\n },\n });\n\n return session as IronSession;\n}\n","import {\n createGetIronSession,\n createSealData,\n createUnsealData,\n} from \"./core.js\";\n\nimport * as crypto from \"uncrypto\";\n\nexport type { IronSession, SessionOptions } from \"./core.js\";\nexport const sealData = createSealData(crypto);\nexport const unsealData = createUnsealData(crypto);\nexport const getIronSession = createGetIronSession(sealData, unsealData);\n"]} +\ No newline at end of file diff --git a/go/yarn.lock b/go/yarn.lock index 2c30cc0245..333c003395 100644 --- a/go/yarn.lock +++ b/go/yarn.lock @@ -6275,6 +6275,11 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== +"@yarnpkg/lockfile@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" + integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== + abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -7472,6 +7477,11 @@ chrome-trace-event@^1.0.2: resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b" integrity sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ== +ci-info@^3.7.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== + ci-info@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-4.3.0.tgz#c39b1013f8fdbd28cd78e62318357d02da160cd7" @@ -9847,6 +9857,13 @@ find-up@^6.3.0: locate-path "^7.1.0" path-exists "^5.0.0" +find-yarn-workspace-root@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd" + integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ== + dependencies: + micromatch "^4.0.2" + fishery@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/fishery/-/fishery-2.4.0.tgz#181dc640968de88ed497dacc50a14eb39805c24a" @@ -10318,7 +10335,7 @@ gopd@^1.0.1, gopd@^1.2.0: resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== -graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4: +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -10776,7 +10793,7 @@ ipaddr.js@1.9.1: resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== -iron-session@^8.0.4: +iron-session@8.0.4: version "8.0.4" resolved "https://registry.yarnpkg.com/iron-session/-/iron-session-8.0.4.tgz#03ae73f9bb25b45c8a8506eccb7097837c3d9fed" integrity sha512-9ivNnaKOd08osD0lJ3i6If23GFS2LsxyMU8Gf/uBUEgm8/8CC1hrrCHFDpMo3IFbpBgwoo/eairRsaD3c5itxA== @@ -10882,6 +10899,11 @@ is-date-object@^1.0.5, is-date-object@^1.1.0: call-bound "^1.0.2" has-tostringtag "^1.0.2" +is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + is-docker@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" @@ -11124,6 +11146,13 @@ is-windows@^1.0.1, is-windows@^1.0.2: resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== +is-wsl@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + is-wsl@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-3.1.0.tgz#e1c657e39c10090afcbedec61720f6b924c3cbd2" @@ -11826,6 +11855,17 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== +json-stable-stringify@^1.0.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.3.0.tgz#8903cfac42ea1a0f97f35d63a4ce0518f0cc6a70" + integrity sha512-qtYiSSFlwot9XHtF9bD9c7rwKjr+RecWT//ZnPvSmEjpV5mmPOCN4j8UjY5hbjNkOwZ/jQv3J6R1/pL7RwgMsg== + dependencies: + call-bind "^1.0.8" + call-bound "^1.0.4" + isarray "^2.0.5" + jsonify "^0.0.1" + object-keys "^1.1.1" + json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" @@ -11877,6 +11917,11 @@ jsonfile@^6.0.1, jsonfile@^6.1.0: optionalDependencies: graceful-fs "^4.1.6" +jsonify@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.1.tgz#2aa3111dae3d34a0f151c63f3a45d995d9420978" + integrity sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg== + jsonpath-plus@^10.3.0, "jsonpath-plus@^6.0.1 || ^10.1.0": version "10.4.0" resolved "https://registry.yarnpkg.com/jsonpath-plus/-/jsonpath-plus-10.4.0.tgz#73cf545c231afda21452150b7a2a58e48e109702" @@ -11942,6 +11987,13 @@ keyv@^4.5.3, keyv@^4.5.4: dependencies: json-buffer "3.0.1" +klaw-sync@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/klaw-sync/-/klaw-sync-6.0.0.tgz#1fd2cfd56ebb6250181114f0a581167099c2b28c" + integrity sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ== + dependencies: + graceful-fs "^4.1.11" + kleur@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" @@ -13142,6 +13194,14 @@ open@^10.2.0: is-inside-container "^1.0.0" wsl-utils "^0.1.0" +open@^7.4.2: + version "7.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" + integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== + dependencies: + is-docker "^2.0.0" + is-wsl "^2.1.1" + openapi3-ts@4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/openapi3-ts/-/openapi3-ts-4.5.0.tgz#1241fcdac0a711d654dfa74feebc2ce7a210790a" @@ -13472,6 +13532,26 @@ pascal-case@^3.1.2: no-case "^3.0.4" tslib "^2.0.3" +patch-package@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-8.0.1.tgz#79d02f953f711e06d1f8949c8a13e5d3d7ba1a60" + integrity sha512-VsKRIA8f5uqHQ7NGhwIna6Bx6D9s/1iXlA1hthBVBEbkq+t4kXD0HHt+rJhf/Z+Ci0F/HCB2hvn0qLdLG+Qxlw== + dependencies: + "@yarnpkg/lockfile" "^1.1.0" + chalk "^4.1.2" + ci-info "^3.7.0" + cross-spawn "^7.0.3" + find-yarn-workspace-root "^2.0.0" + fs-extra "^10.0.0" + json-stable-stringify "^1.0.2" + klaw-sync "^6.0.0" + minimist "^1.2.6" + open "^7.4.2" + semver "^7.5.3" + slash "^2.0.0" + tmp "^0.2.4" + yaml "^2.2.2" + path-browserify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" @@ -14893,6 +14973,11 @@ sisteransi@^1.0.5: resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -15684,6 +15769,11 @@ tldts@^7.0.5: dependencies: tldts-core "^7.0.14" +tmp@^0.2.4: + version "0.2.7" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.7.tgz#26f4db11d1601ce8012dcb8a798ece1c06a99059" + integrity sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw== + tmp@~0.2.3: version "0.2.5" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.5.tgz#b06bcd23f0f3c8357b426891726d16015abfd8f8" @@ -16754,6 +16844,11 @@ yaml@^1.10.0: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.3.tgz#76e407ed95c42684fb8e14641e5de62fe65bbcb3" integrity sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA== +yaml@^2.2.2: + version "2.9.0" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.9.0.tgz#78274afd93598a1dfdd6130df6a566defcbf9aa4" + integrity sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA== + yaml@^2.3.1, yaml@^2.8.0, yaml@^2.8.3: version "2.8.3" resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.8.3.tgz#a0d6bd2efb3dd03c59370223701834e60409bd7d"