@opensourceframework/next-iron-session
Advanced tools
@@ -1,1 +0,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<string, string>;\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<CookieSerializeOptions, \"httpOnly\" | \"maxAge\" | \"priority\">;\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<ResponseCookie>): 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<CookieSerializeOptions, \"encode\">;\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> = T & {\n /**\n * Encrypts the session data and sets the cookie.\n */\n readonly save: () => Promise<void>;\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<Pick<SessionOptions, \"ttl\" | \"cookieOptions\">> =\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<string> {\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<T>(\n seal: string,\n {\n password,\n ttl = fourteenDaysInSeconds,\n }: { password: Password; ttl?: number },\n ): Promise<T> {\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<SessionOptions> {\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<typeof createSealData>,\n unsealData: ReturnType<typeof createUnsealData>,\n) {\n return getIronSession;\n\n async function getIronSession<T extends object>(\n cookies: CookieStore,\n sessionOptions: SessionOptions,\n ): Promise<IronSession<T>>;\n async function getIronSession<T extends object>(\n req: RequestType,\n res: ResponseType,\n sessionOptions: SessionOptions,\n ): Promise<IronSession<T>>;\n async function getIronSession<T extends object>(\n reqOrCookieStore: RequestType | CookieStore,\n resOrsessionOptions: ResponseType | SessionOptions,\n sessionOptions?: SessionOptions,\n ): Promise<IronSession<T>> {\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<T>(\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<T>(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<string, unknown>)[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<T>;\n }\n}\n\nasync function getIronSessionFromCookieStore<T extends object>(\n cookieStore: CookieStore,\n sessionOptions: SessionOptions,\n sealData: ReturnType<typeof createSealData>,\n unsealData: ReturnType<typeof createUnsealData>,\n): Promise<IronSession<T>> {\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<T>(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<string, unknown>)[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<T>;\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"]} | ||
| {"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<string, string>;\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<CookieSerializeOptions, \"httpOnly\" | \"maxAge\" | \"priority\">;\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<ResponseCookie>): 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<CookieSerializeOptions, \"encode\">;\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> = T & {\n /**\n * Encrypts the session data and sets the cookie.\n */\n readonly save: () => Promise<void>;\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<Pick<SessionOptions, \"ttl\" | \"cookieOptions\">> =\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<string> {\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<T>(\n seal: string,\n {\n password,\n ttl = fourteenDaysInSeconds,\n }: { password: Password; ttl?: number },\n ): Promise<T> {\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<SessionOptions> {\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<typeof createSealData>,\n unsealData: ReturnType<typeof createUnsealData>,\n) {\n return getIronSession;\n\n async function getIronSession<T extends object>(\n cookies: CookieStore,\n sessionOptions: SessionOptions,\n ): Promise<IronSession<T>>;\n async function getIronSession<T extends object>(\n req: RequestType,\n res: ResponseType,\n sessionOptions: SessionOptions,\n ): Promise<IronSession<T>>;\n async function getIronSession<T extends object>(\n reqOrCookieStore: RequestType | CookieStore,\n resOrsessionOptions: ResponseType | SessionOptions,\n sessionOptions?: SessionOptions,\n ): Promise<IronSession<T>> {\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<T>(\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<T>(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<string, unknown>)[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<T>;\n }\n}\n\nasync function getIronSessionFromCookieStore<T extends object>(\n cookieStore: CookieStore,\n sessionOptions: SessionOptions,\n sealData: ReturnType<typeof createSealData>,\n unsealData: ReturnType<typeof createUnsealData>,\n): Promise<IronSession<T>> {\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<T>(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<string, unknown>)[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<T>;\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"]} |
@@ -1,1 +0,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<string, string>;\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<CookieSerializeOptions, \"httpOnly\" | \"maxAge\" | \"priority\">;\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<ResponseCookie>): 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<CookieSerializeOptions, \"encode\">;\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> = T & {\n /**\n * Encrypts the session data and sets the cookie.\n */\n readonly save: () => Promise<void>;\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<Pick<SessionOptions, \"ttl\" | \"cookieOptions\">> =\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<string> {\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<T>(\n seal: string,\n {\n password,\n ttl = fourteenDaysInSeconds,\n }: { password: Password; ttl?: number },\n ): Promise<T> {\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<SessionOptions> {\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<typeof createSealData>,\n unsealData: ReturnType<typeof createUnsealData>,\n) {\n return getIronSession;\n\n async function getIronSession<T extends object>(\n cookies: CookieStore,\n sessionOptions: SessionOptions,\n ): Promise<IronSession<T>>;\n async function getIronSession<T extends object>(\n req: RequestType,\n res: ResponseType,\n sessionOptions: SessionOptions,\n ): Promise<IronSession<T>>;\n async function getIronSession<T extends object>(\n reqOrCookieStore: RequestType | CookieStore,\n resOrsessionOptions: ResponseType | SessionOptions,\n sessionOptions?: SessionOptions,\n ): Promise<IronSession<T>> {\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<T>(\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<T>(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<string, unknown>)[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<T>;\n }\n}\n\nasync function getIronSessionFromCookieStore<T extends object>(\n cookieStore: CookieStore,\n sessionOptions: SessionOptions,\n sealData: ReturnType<typeof createSealData>,\n unsealData: ReturnType<typeof createUnsealData>,\n): Promise<IronSession<T>> {\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<T>(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<string, unknown>)[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<T>;\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"]} | ||
| {"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<string, string>;\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<CookieSerializeOptions, \"httpOnly\" | \"maxAge\" | \"priority\">;\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<ResponseCookie>): 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<CookieSerializeOptions, \"encode\">;\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> = T & {\n /**\n * Encrypts the session data and sets the cookie.\n */\n readonly save: () => Promise<void>;\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<Pick<SessionOptions, \"ttl\" | \"cookieOptions\">> =\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<string> {\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<T>(\n seal: string,\n {\n password,\n ttl = fourteenDaysInSeconds,\n }: { password: Password; ttl?: number },\n ): Promise<T> {\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<SessionOptions> {\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<typeof createSealData>,\n unsealData: ReturnType<typeof createUnsealData>,\n) {\n return getIronSession;\n\n async function getIronSession<T extends object>(\n cookies: CookieStore,\n sessionOptions: SessionOptions,\n ): Promise<IronSession<T>>;\n async function getIronSession<T extends object>(\n req: RequestType,\n res: ResponseType,\n sessionOptions: SessionOptions,\n ): Promise<IronSession<T>>;\n async function getIronSession<T extends object>(\n reqOrCookieStore: RequestType | CookieStore,\n resOrsessionOptions: ResponseType | SessionOptions,\n sessionOptions?: SessionOptions,\n ): Promise<IronSession<T>> {\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<T>(\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<T>(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<string, unknown>)[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<T>;\n }\n}\n\nasync function getIronSessionFromCookieStore<T extends object>(\n cookieStore: CookieStore,\n sessionOptions: SessionOptions,\n sealData: ReturnType<typeof createSealData>,\n unsealData: ReturnType<typeof createUnsealData>,\n): Promise<IronSession<T>> {\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<T>(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<string, unknown>)[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<T>;\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"]} |
+20
-21
| { | ||
| "name": "@opensourceframework/next-iron-session", | ||
| "version": "8.0.4", | ||
| "version": "8.0.5", | ||
| "description": "Secure, stateless, and cookie-based session library for JavaScript", | ||
@@ -15,2 +15,3 @@ "keywords": [ | ||
| ], | ||
| "homepage": "https://github.com/riceharvest/opensourceframework/tree/main/packages/next-iron-session#readme", | ||
| "bugs": "https://github.com/vvo/iron-session/issues", | ||
@@ -24,2 +25,8 @@ "repository": "github:vvo/iron-session", | ||
| "author": "OpenSource Framework Contributors (fork), Original: Unknown", | ||
| "contributors": [ | ||
| { | ||
| "name": "Unknown", | ||
| "url": "https://github.com/next-iron-session" | ||
| } | ||
| ], | ||
| "sideEffects": false, | ||
@@ -35,11 +42,2 @@ "type": "module", | ||
| ], | ||
| "scripts": { | ||
| "build": "tsup", | ||
| "dev": "pnpm build && concurrently \"pnpm build --watch\" \"pnpm --filter=next-example dev\" ", | ||
| "lint": "tsc --noEmit && tsc --noEmit -p examples/next/tsconfig.json && pnpm eslint . && publint", | ||
| "prepare": "pnpm build", | ||
| "start": "turbo start --filter=next-example", | ||
| "test": "vitest run && pnpm build", | ||
| "test:watch": "vitest" | ||
| }, | ||
| "prettier": { | ||
@@ -78,16 +76,17 @@ "plugins": [ | ||
| }, | ||
| "packageManager": "pnpm@9.6.0", | ||
| "engines": { | ||
| "node": ">=18.0.0" | ||
| }, | ||
| "publishConfig": { | ||
| "access": "public" | ||
| }, | ||
| "contributors": [ | ||
| { | ||
| "name": "Unknown", | ||
| "url": "https://github.com/next-iron-session" | ||
| } | ||
| ], | ||
| "homepage": "https://github.com/riceharvest/opensourceframework/tree/main/packages/next-iron-session#readme", | ||
| "engines": { | ||
| "node": ">=18.0.0" | ||
| "scripts": { | ||
| "build": "tsup", | ||
| "dev": "pnpm build && concurrently \"pnpm build --watch\" \"pnpm --filter=next-example dev\" ", | ||
| "lint": "eslint .", | ||
| "start": "turbo start --filter=next-example", | ||
| "test": "vitest run --passWithNoTests && pnpm build", | ||
| "test:coverage": "vitest run --coverage", | ||
| "test:watch": "vitest" | ||
| } | ||
| } | ||
| } |
88393
0.31%