'use strict'; var cookie = require('cookie'); var ironWebcrypto = require('iron-webcrypto'); var crypto = require('uncrypto'); function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var crypto__namespace = /*#__PURE__*/_interopNamespace(crypto); // src/core.ts var timestampSkewSec = 60; var fourteenDaysInSeconds = 14 * 24 * 3600; var currentMajorVersion = 2; var versionDelimiter = "~"; var defaultOptions = { ttl: fourteenDaysInSeconds, cookieOptions: { httpOnly: true, secure: true, sameSite: "lax", path: "/" } }; function normalizeStringPasswordToMap(password) { return typeof password === "string" ? { 1: password } : password; } function parseSeal(seal) { const [sealWithoutVersion, tokenVersionAsString] = seal.split(versionDelimiter); const tokenVersion = tokenVersionAsString == null ? null : parseInt(tokenVersionAsString, 10); return { sealWithoutVersion, tokenVersion }; } function computeCookieMaxAge(ttl) { if (ttl === 0) { return 2147483647; } return ttl - timestampSkewSec; } function getCookie(req, cookieName) { return cookie.parse( ("headers" in req && typeof req.headers.get === "function" ? req.headers.get("cookie") : req.headers.cookie) ?? "" )[cookieName] ?? ""; } function getServerActionCookie(cookieName, cookieHandler) { const cookieObject = cookieHandler.get(cookieName); const cookie = cookieObject?.value; if (typeof cookie === "string") { return cookie; } return ""; } function setCookie(res, cookieValue) { if ("headers" in res && typeof res.headers.append === "function") { res.headers.append("set-cookie", cookieValue); return; } let existingSetCookie = res.getHeader("set-cookie") ?? []; if (!Array.isArray(existingSetCookie)) { existingSetCookie = [existingSetCookie.toString()]; } res.setHeader("set-cookie", [ ...existingSetCookie, cookieValue ]); } function createSealData(_crypto) { return async function sealData2(data, { password, ttl = fourteenDaysInSeconds }) { const passwordsMap = normalizeStringPasswordToMap(password); const mostRecentPasswordId = Math.max( ...Object.keys(passwordsMap).map(Number) ); const passwordForSeal = { id: mostRecentPasswordId.toString(), secret: passwordsMap[mostRecentPasswordId] }; const seal = await ironWebcrypto.seal(_crypto, data, passwordForSeal, { ...ironWebcrypto.defaults, ttl: ttl * 1e3 }); return `${seal}${versionDelimiter}${currentMajorVersion}`; }; } function createUnsealData(_crypto) { return async function unsealData2(seal, { password, ttl = fourteenDaysInSeconds }) { const passwordsMap = normalizeStringPasswordToMap(password); const { sealWithoutVersion, tokenVersion } = parseSeal(seal); try { const data = await ironWebcrypto.unseal(_crypto, sealWithoutVersion, passwordsMap, { ...ironWebcrypto.defaults, ttl: ttl * 1e3 }) ?? {}; if (tokenVersion === 2) { return data; } return { ...data.persistent }; } catch (error) { if (error instanceof Error && /^(Expired seal|Bad hmac value|Cannot find password|Incorrect number of sealed components)/.test( error.message )) { return {}; } throw error; } }; } function getSessionConfig(sessionOptions) { const options = { ...defaultOptions, ...sessionOptions, cookieOptions: { ...defaultOptions.cookieOptions, ...sessionOptions.cookieOptions || {} } }; if (sessionOptions.cookieOptions && "maxAge" in sessionOptions.cookieOptions) { if (sessionOptions.cookieOptions.maxAge === void 0) { options.ttl = 0; } } else { options.cookieOptions.maxAge = computeCookieMaxAge(options.ttl); } return options; } var badUsageMessage = "iron-session: Bad usage: use getIronSession(req, res, options) or getIronSession(cookieStore, options)."; function createGetIronSession(sealData2, unsealData2) { return getIronSession2; async function getIronSession2(reqOrCookieStore, resOrsessionOptions, sessionOptions) { if (!reqOrCookieStore) { throw new Error(badUsageMessage); } if (!resOrsessionOptions) { throw new Error(badUsageMessage); } if (!sessionOptions) { return getIronSessionFromCookieStore( reqOrCookieStore, resOrsessionOptions, sealData2, unsealData2 ); } const req = reqOrCookieStore; const res = resOrsessionOptions; if (!sessionOptions) { throw new Error(badUsageMessage); } if (!sessionOptions.cookieName) { throw new Error("iron-session: Bad usage. Missing cookie name."); } if (!sessionOptions.password) { throw new Error("iron-session: Bad usage. Missing password."); } const passwordsMap = normalizeStringPasswordToMap(sessionOptions.password); if (Object.values(passwordsMap).some((password) => password.length < 32)) { throw new Error( "iron-session: Bad usage. Password must be at least 32 characters long." ); } let sessionConfig = getSessionConfig(sessionOptions); const sealFromCookies = getCookie(req, sessionConfig.cookieName); const session = sealFromCookies ? await unsealData2(sealFromCookies, { password: passwordsMap, ttl: sessionConfig.ttl }) : {}; Object.defineProperties(session, { updateConfig: { value: function updateConfig(newSessionOptions) { sessionConfig = getSessionConfig(newSessionOptions); } }, save: { value: async function save() { if ("headersSent" in res && res.headersSent) { throw new Error( "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()" ); } const seal = await sealData2(session, { 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.` ); } setCookie(res, cookieValue); } }, destroy: { value: function destroy() { Object.keys(session).forEach((key) => { delete session[key]; }); const cookieValue = cookie.serialize(sessionConfig.cookieName, "", { ...sessionConfig.cookieOptions, maxAge: 0 }); setCookie(res, cookieValue); } } }); return session; } } async function getIronSessionFromCookieStore(cookieStore, sessionOptions, sealData2, unsealData2) { if (!sessionOptions.cookieName) { throw new Error("iron-session: Bad usage. Missing cookie name."); } if (!sessionOptions.password) { throw new Error("iron-session: Bad usage. Missing password."); } const passwordsMap = normalizeStringPasswordToMap(sessionOptions.password); if (Object.values(passwordsMap).some((password) => password.length < 32)) { throw new Error( "iron-session: Bad usage. Password must be at least 32 characters long." ); } let sessionConfig = getSessionConfig(sessionOptions); const sealFromCookies = getServerActionCookie( sessionConfig.cookieName, cookieStore ); const session = sealFromCookies ? await unsealData2(sealFromCookies, { password: passwordsMap, ttl: sessionConfig.ttl }) : {}; Object.defineProperties(session, { updateConfig: { value: function updateConfig(newSessionOptions) { sessionConfig = getSessionConfig(newSessionOptions); } }, save: { value: async function save() { const seal = await sealData2(session, { 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.` ); } cookieStore.set( sessionConfig.cookieName, seal, sessionConfig.cookieOptions ); } }, destroy: { value: function destroy() { Object.keys(session).forEach((key) => { delete session[key]; }); const cookieOptions = { ...sessionConfig.cookieOptions, maxAge: 0 }; cookieStore.set(sessionConfig.cookieName, "", cookieOptions); } } }); return session; } var sealData = createSealData(crypto__namespace); var unsealData = createUnsealData(crypto__namespace); var getIronSession = createGetIronSession(sealData, unsealData); exports.getIronSession = getIronSession; exports.sealData = sealData; exports.unsealData = unsealData; //# sourceMappingURL=index.cjs.map //# sourceMappingURL=index.cjs.map