iron-session 2.0.0-alpha.17 → 2.0.0-alpha.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +181 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +37 -31
- package/dist/index.js +64 -59
- package/dist/index.js.map +2 -2
- package/express/dist/index.cjs +65 -0
- package/express/dist/index.cjs.map +7 -0
- package/express/dist/index.d.ts +6 -0
- package/express/dist/index.js +37 -0
- package/express/dist/index.js.map +7 -0
- package/next/dist/index.cjs +74 -0
- package/next/dist/index.cjs.map +7 -0
- package/next/dist/index.d.ts +9 -4
- package/next/dist/index.js +37 -36
- package/next/dist/index.js.map +3 -3
- package/package.json +68 -33
- package/dist/index.mjs +0 -119
- package/dist/index.mjs.map +0 -7
- package/next/dist/index.mjs +0 -16
- package/next/dist/index.mjs.map +0 -7
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
__markAsModule(target);
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __reExport = (target, module2, desc) => {
|
|
14
|
+
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(module2))
|
|
16
|
+
if (!__hasOwnProp.call(target, key) && key !== "default")
|
|
17
|
+
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return target;
|
|
20
|
+
};
|
|
21
|
+
var __toModule = (module2) => {
|
|
22
|
+
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// src/index.ts
|
|
26
|
+
__export(exports, {
|
|
27
|
+
getIronSession: () => getIronSession,
|
|
28
|
+
sealData: () => sealData,
|
|
29
|
+
unsealData: () => unsealData
|
|
30
|
+
});
|
|
31
|
+
var import_iron = __toModule(require("@hapi/iron"));
|
|
32
|
+
var import_cookie = __toModule(require("cookie"));
|
|
33
|
+
var timestampSkewSec = 60;
|
|
34
|
+
var fourteenDaysInSeconds = 15 * 24 * 3600;
|
|
35
|
+
var currentMajorVersion = 2;
|
|
36
|
+
var versionDelimiter = "#";
|
|
37
|
+
var defaultOptions = {
|
|
38
|
+
ttl: fourteenDaysInSeconds,
|
|
39
|
+
cookieOptions: {
|
|
40
|
+
httpOnly: true,
|
|
41
|
+
secure: true,
|
|
42
|
+
sameSite: "lax",
|
|
43
|
+
path: "/"
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
async function getIronSession(req, res, userSessionOptions) {
|
|
47
|
+
var _a, _b;
|
|
48
|
+
if (!req || !res || !userSessionOptions || !userSessionOptions.cookieName || !userSessionOptions.password) {
|
|
49
|
+
throw new Error(`iron-session: Bad usage. Minimum usage is const session = await getIronSession(req, res, { cookieName: "...", password: "...". Check the usage here: https://github.com/vvo/iron-session`);
|
|
50
|
+
}
|
|
51
|
+
const passwordsAsMap = normalizeStringPasswordToMap(userSessionOptions.password);
|
|
52
|
+
Object.values(normalizeStringPasswordToMap(userSessionOptions.password)).forEach((password) => {
|
|
53
|
+
if (password.length < 32) {
|
|
54
|
+
throw new Error(`iron-session: Bad usage. Password must be at least 32 characters long.`);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
const isHttps = req.socket.encrypted === true;
|
|
58
|
+
if (((_a = userSessionOptions.cookieOptions) == null ? void 0 : _a.secure) === true && isHttps === false) {
|
|
59
|
+
throw new Error(`iron-session: Can't use secure cookies when not in https. See usage at https://github.com/vvo/iron-session/`);
|
|
60
|
+
}
|
|
61
|
+
const options = {
|
|
62
|
+
...defaultOptions,
|
|
63
|
+
...userSessionOptions,
|
|
64
|
+
cookieOptions: {
|
|
65
|
+
...defaultOptions.cookieOptions,
|
|
66
|
+
...userSessionOptions.cookieOptions || {}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
if (((_b = userSessionOptions.cookieOptions) == null ? void 0 : _b.secure) === void 0) {
|
|
70
|
+
options.cookieOptions.secure = isHttps;
|
|
71
|
+
}
|
|
72
|
+
if (options.ttl === 0) {
|
|
73
|
+
options.ttl = 2147483647;
|
|
74
|
+
}
|
|
75
|
+
if (userSessionOptions.cookieOptions && "maxAge" in userSessionOptions.cookieOptions) {
|
|
76
|
+
if (userSessionOptions.cookieOptions.maxAge === void 0) {
|
|
77
|
+
options.ttl = 0;
|
|
78
|
+
} else {
|
|
79
|
+
options.cookieOptions.maxAge = computeCookieMaxAge(userSessionOptions.cookieOptions.maxAge);
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
options.cookieOptions.maxAge = computeCookieMaxAge(options.ttl);
|
|
83
|
+
}
|
|
84
|
+
const sealFromCookies = (0, import_cookie.parse)(req.headers.cookie || "")[options.cookieName];
|
|
85
|
+
const session = sealFromCookies === void 0 ? {} : await unsealData(sealFromCookies, passwordsAsMap, options.ttl);
|
|
86
|
+
Object.defineProperties(session, {
|
|
87
|
+
save: {
|
|
88
|
+
value: async function save() {
|
|
89
|
+
if (res.headersSent === true) {
|
|
90
|
+
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()`);
|
|
91
|
+
}
|
|
92
|
+
const seal = await sealData(session, passwordsAsMap, options.ttl);
|
|
93
|
+
const cookieValue = (0, import_cookie.serialize)(options.cookieName, seal, options.cookieOptions);
|
|
94
|
+
if (cookieValue.length > 4096) {
|
|
95
|
+
throw new Error(`iron-session: Cookie length is too big ${cookieValue.length}, browsers will refuse it. Try to remove some data.`);
|
|
96
|
+
}
|
|
97
|
+
addToCookies(cookieValue, res);
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
destroy: {
|
|
101
|
+
value: function destroy() {
|
|
102
|
+
Object.keys(session).forEach((key) => {
|
|
103
|
+
delete session[key];
|
|
104
|
+
});
|
|
105
|
+
const cookieValue = (0, import_cookie.serialize)(options.cookieName, "", {
|
|
106
|
+
...options.cookieOptions,
|
|
107
|
+
maxAge: 0
|
|
108
|
+
});
|
|
109
|
+
addToCookies(cookieValue, res);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
return session;
|
|
114
|
+
}
|
|
115
|
+
function addToCookies(cookieValue, res) {
|
|
116
|
+
var _a;
|
|
117
|
+
let existingSetCookie = (_a = res.getHeader("set-cookie")) != null ? _a : [];
|
|
118
|
+
if (typeof existingSetCookie === "string") {
|
|
119
|
+
existingSetCookie = [existingSetCookie];
|
|
120
|
+
}
|
|
121
|
+
res.setHeader("set-cookie", [...existingSetCookie, cookieValue]);
|
|
122
|
+
}
|
|
123
|
+
function computeCookieMaxAge(ttl) {
|
|
124
|
+
return ttl - timestampSkewSec;
|
|
125
|
+
}
|
|
126
|
+
async function unsealData(seal, password, ttl = fourteenDaysInSeconds) {
|
|
127
|
+
const passwordsAsMap = normalizeStringPasswordToMap(password);
|
|
128
|
+
const { sealWithoutVersion, tokenVersion } = parseSeal(seal);
|
|
129
|
+
try {
|
|
130
|
+
const data = await import_iron.default.unseal(sealWithoutVersion, passwordsAsMap, {
|
|
131
|
+
...import_iron.default.defaults,
|
|
132
|
+
ttl: ttl * 1e3
|
|
133
|
+
});
|
|
134
|
+
if (tokenVersion === 2) {
|
|
135
|
+
return data;
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
...data.persistent
|
|
139
|
+
};
|
|
140
|
+
} catch (error) {
|
|
141
|
+
if (error instanceof Error) {
|
|
142
|
+
if (error.message === "Expired seal" || error.message === "Bad hmac value" || error.message === "Cannot find password: " || error.message === "Incorrect number of sealed components") {
|
|
143
|
+
return {};
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function parseSeal(seal) {
|
|
150
|
+
if (seal[seal.length - 2] === versionDelimiter) {
|
|
151
|
+
const [sealWithoutVersion, tokenVersionAsString] = seal.split(versionDelimiter);
|
|
152
|
+
return {
|
|
153
|
+
sealWithoutVersion,
|
|
154
|
+
tokenVersion: parseInt(tokenVersionAsString, 10)
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
return { sealWithoutVersion: seal, tokenVersion: null };
|
|
158
|
+
}
|
|
159
|
+
async function sealData(data, password, ttl = fourteenDaysInSeconds) {
|
|
160
|
+
const passwordsAsMap = normalizeStringPasswordToMap(password);
|
|
161
|
+
const mostRecentPasswordId = Math.max(...Object.keys(passwordsAsMap).map((id) => parseInt(id, 10)));
|
|
162
|
+
const passwordForSeal = {
|
|
163
|
+
id: mostRecentPasswordId.toString(),
|
|
164
|
+
secret: passwordsAsMap[mostRecentPasswordId]
|
|
165
|
+
};
|
|
166
|
+
const seal = await import_iron.default.seal(data, passwordForSeal, {
|
|
167
|
+
...import_iron.default.defaults,
|
|
168
|
+
ttl: ttl * 1e3
|
|
169
|
+
});
|
|
170
|
+
return `${seal}${versionDelimiter}${currentMajorVersion}`;
|
|
171
|
+
}
|
|
172
|
+
function normalizeStringPasswordToMap(password) {
|
|
173
|
+
return typeof password === "string" ? { 1: password } : password;
|
|
174
|
+
}
|
|
175
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
176
|
+
0 && (module.exports = {
|
|
177
|
+
getIronSession,
|
|
178
|
+
sealData,
|
|
179
|
+
unsealData
|
|
180
|
+
});
|
|
181
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts"],
|
|
4
|
+
"sourcesContent": ["import Iron from \"@hapi/iron\";\nimport type { CookieSerializeOptions } from \"cookie\";\nimport { parse as parseCookie, serialize as serializeCookie } from \"cookie\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport type { TLSSocket } from \"tls\";\n\n// default time allowed to check for iron seal validity when ttl passed\n// see https://hapi.dev/family/iron/api/?v=6.0.0#options\nconst timestampSkewSec = 60;\n\ntype passwordsMap = { [id: string]: string };\ntype password = string | passwordsMap;\n\nconst fourteenDaysInSeconds = 15 * 24 * 3600;\n\n// We store a token major version to handle data format changes when any. So that when you upgrade the cookies\n// can be kept alive between upgrades, no need to disconnect everyone.\nconst currentMajorVersion = 2;\nconst versionDelimiter = \"#\";\n\nconst defaultOptions: {\n ttl: number;\n cookieOptions: CookieSerializeOptions;\n} = {\n ttl: fourteenDaysInSeconds,\n cookieOptions: {\n httpOnly: true,\n secure: true,\n sameSite: \"lax\",\n path: \"/\",\n },\n};\n\nexport interface IronSessionOptions {\n /**\n * This is the cookie name that will be used inside the browser. You should make sure it's unique given\n * your application. Example: vercel-session\n */\n cookieName: string;\n\n /**\n * This is the password(s) that will be used to encrypt the cookie. It can be either a string or an object\n * like {1: \"password\", 2: password}.\n *\n * When you provide multiple passwords then all of them will be used to decrypt the cookie and only the most\n * recent (= highest key, 2 in this example) password will be used to encrypt the cookie. This allow you\n * to use password rotation (security)\n */\n password: password;\n\n /**\n * This is the time in seconds that the session will be valid for. This also set the max-age attribute of\n * the cookie automatically (minus 60 seconds so that the cookie always expire before the session).\n */\n ttl?: number;\n\n /**\n * This is the options that will be passed to the cookie library.\n * You can see all of them here: https://github.com/jshttp/cookie#options-1.\n *\n * If you want to use \"session cookies\" (cookies that are deleted when the browser is closed) then you need\n * to pass cookieOptions: { maxAge: undefined }.\n */\n cookieOptions?: CookieSerializeOptions;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface IronSessionData {\n // If we allow for any keys, then there's no more type check on unknown properties which is not good\n // If we allow for any keys, the later delete will work but I prefer to disable the check at this stage and\n // provide good type checking instead\n // [key: string]: unknown;\n}\n\nexport type IronSession = IronSessionData & {\n /**\n * Destroys the session data and removes the cookie.\n */\n destroy: () => void;\n\n /**\n * Encrypts the session data and sets the cookie.\n */\n save: () => Promise<void>;\n};\n\ndeclare module \"http\" {\n interface IncomingMessage {\n session: IronSession;\n }\n}\n\nexport async function getIronSession(\n req: IncomingMessage,\n res: ServerResponse,\n userSessionOptions: IronSessionOptions,\n): Promise<IronSession> {\n if (\n !req ||\n !res ||\n !userSessionOptions ||\n !userSessionOptions.cookieName ||\n !userSessionOptions.password\n ) {\n throw new Error(\n `iron-session: Bad usage. Minimum usage is const session = await getIronSession(req, res, { cookieName: \"...\", password: \"...\". Check the usage here: https://github.com/vvo/iron-session`,\n );\n }\n\n const passwordsAsMap = normalizeStringPasswordToMap(\n userSessionOptions.password,\n );\n\n Object.values(\n normalizeStringPasswordToMap(userSessionOptions.password),\n ).forEach((password) => {\n if (password.length < 32) {\n throw new Error(\n `iron-session: Bad usage. Password must be at least 32 characters long.`,\n );\n }\n });\n\n const isHttps = (req.socket as TLSSocket).encrypted === true;\n\n if (userSessionOptions.cookieOptions?.secure === true && isHttps === false) {\n throw new Error(\n `iron-session: Can't use secure cookies when not in https. See usage at https://github.com/vvo/iron-session/`,\n );\n }\n\n const options: Required<IronSessionOptions> = {\n ...defaultOptions,\n ...userSessionOptions,\n cookieOptions: {\n ...defaultOptions.cookieOptions,\n ...(userSessionOptions.cookieOptions || {}),\n },\n };\n\n // if the user did not set the secure flag themselves, we automatically configure it\n if (userSessionOptions.cookieOptions?.secure === undefined) {\n options.cookieOptions.secure = isHttps;\n }\n\n if (options.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 options.ttl = 2147483647;\n }\n\n if (\n userSessionOptions.cookieOptions &&\n \"maxAge\" in userSessionOptions.cookieOptions\n ) {\n // session cookie, do not set maxAge, consider token as infinite\n if (userSessionOptions.cookieOptions.maxAge === undefined) {\n options.ttl = 0;\n } else {\n options.cookieOptions.maxAge = computeCookieMaxAge(\n userSessionOptions.cookieOptions.maxAge,\n );\n }\n } else {\n options.cookieOptions.maxAge = computeCookieMaxAge(options.ttl);\n }\n\n const sealFromCookies = parseCookie(req.headers.cookie || \"\")[\n options.cookieName\n ];\n\n const session =\n sealFromCookies === undefined\n ? {}\n : await unsealData(sealFromCookies, passwordsAsMap, options.ttl);\n\n Object.defineProperties(session, {\n save: {\n value: async function save() {\n if (res.headersSent === true) {\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 const seal = await sealData(session, passwordsAsMap, options.ttl);\n const cookieValue = serializeCookie(\n options.cookieName,\n seal,\n options.cookieOptions,\n );\n\n if (cookieValue.length > 4096) {\n throw new Error(\n `iron-session: Cookie length is too big ${cookieValue.length}, browsers will refuse it. Try to remove some data.`,\n );\n }\n\n addToCookies(cookieValue, res);\n },\n },\n destroy: {\n value: function destroy() {\n Object.keys(session).forEach((key) => {\n // @ts-ignore See comment on the IronSessionData interface\n delete session[key];\n });\n\n const cookieValue = serializeCookie(options.cookieName, \"\", {\n ...options.cookieOptions,\n maxAge: 0,\n });\n addToCookies(cookieValue, res);\n },\n },\n });\n\n return session as IronSession;\n}\n\nfunction addToCookies(cookieValue: string, res: ServerResponse) {\n let existingSetCookie =\n (res.getHeader(\"set-cookie\") as string[] | string) ?? [];\n if (typeof existingSetCookie === \"string\") {\n existingSetCookie = [existingSetCookie];\n }\n res.setHeader(\"set-cookie\", [...existingSetCookie, cookieValue]);\n}\n\nfunction computeCookieMaxAge(ttl: number) {\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 maximum between server and clients.\n // It also makes sure to expire the cookie immediately when value is 0\n return ttl - timestampSkewSec;\n}\n\nexport async function unsealData(\n seal: string,\n password: password,\n ttl: number = fourteenDaysInSeconds,\n): Promise<IronSessionData> {\n const passwordsAsMap = normalizeStringPasswordToMap(password);\n const { sealWithoutVersion, tokenVersion } = parseSeal(seal);\n\n try {\n const data = await Iron.unseal(sealWithoutVersion, passwordsAsMap, {\n ...Iron.defaults,\n ttl: ttl * 1000,\n });\n\n if (tokenVersion === 2) {\n return data;\n }\n\n return {\n ...data.persistent,\n };\n } catch (error) {\n if (error instanceof Error) {\n if (\n error.message === \"Expired seal\" ||\n error.message === \"Bad hmac value\" ||\n error.message === \"Cannot find password: \" ||\n error.message === \"Incorrect number of sealed components\"\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 {};\n }\n }\n\n throw error;\n }\n}\n\nfunction parseSeal(seal: string): {\n sealWithoutVersion: string;\n tokenVersion: number | null;\n} {\n if (seal[seal.length - 2] === versionDelimiter) {\n const [sealWithoutVersion, tokenVersionAsString] =\n seal.split(versionDelimiter);\n return {\n sealWithoutVersion,\n tokenVersion: parseInt(tokenVersionAsString, 10),\n };\n }\n\n return { sealWithoutVersion: seal, tokenVersion: null };\n}\n\nexport async function sealData(\n data: IronSessionData,\n password: password,\n ttl: number = fourteenDaysInSeconds,\n) {\n const passwordsAsMap = normalizeStringPasswordToMap(password);\n\n const mostRecentPasswordId = Math.max(\n ...Object.keys(passwordsAsMap).map((id) => parseInt(id, 10)),\n );\n\n const passwordForSeal = {\n id: mostRecentPasswordId.toString(),\n secret: passwordsAsMap[mostRecentPasswordId],\n };\n\n const seal = await Iron.seal(data, passwordForSeal, {\n ...Iron.defaults,\n ttl: ttl * 1000,\n });\n\n return `${seal}${versionDelimiter}${currentMajorVersion}`;\n}\n\nfunction normalizeStringPasswordToMap(password: password) {\n return typeof password === \"string\" ? { 1: password } : password;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,51 +2,57 @@ import { CookieSerializeOptions } from 'cookie';
|
|
|
2
2
|
import { IncomingMessage, ServerResponse } from 'http';
|
|
3
3
|
|
|
4
4
|
declare type passwordsMap = {
|
|
5
|
-
[id:
|
|
5
|
+
[id: string]: string;
|
|
6
6
|
};
|
|
7
7
|
declare type password = string | passwordsMap;
|
|
8
8
|
interface IronSessionOptions {
|
|
9
|
+
/**
|
|
10
|
+
* This is the cookie name that will be used inside the browser. You should make sure it's unique given
|
|
11
|
+
* your application. Example: vercel-session
|
|
12
|
+
*/
|
|
9
13
|
cookieName: string;
|
|
14
|
+
/**
|
|
15
|
+
* This is the password(s) that will be used to encrypt the cookie. It can be either a string or an object
|
|
16
|
+
* like {1: "password", 2: password}.
|
|
17
|
+
*
|
|
18
|
+
* When you provide multiple passwords then all of them will be used to decrypt the cookie and only the most
|
|
19
|
+
* recent (= highest key, 2 in this example) password will be used to encrypt the cookie. This allow you
|
|
20
|
+
* to use password rotation (security)
|
|
21
|
+
*/
|
|
10
22
|
password: password;
|
|
23
|
+
/**
|
|
24
|
+
* This is the time in seconds that the session will be valid for. This also set the max-age attribute of
|
|
25
|
+
* the cookie automatically (minus 60 seconds so that the cookie always expire before the session).
|
|
26
|
+
*/
|
|
11
27
|
ttl?: number;
|
|
28
|
+
/**
|
|
29
|
+
* This is the options that will be passed to the cookie library.
|
|
30
|
+
* You can see all of them here: https://github.com/jshttp/cookie#options-1.
|
|
31
|
+
*
|
|
32
|
+
* If you want to use "session cookies" (cookies that are deleted when the browser is closed) then you need
|
|
33
|
+
* to pass cookieOptions: { maxAge: undefined }.
|
|
34
|
+
*/
|
|
12
35
|
cookieOptions?: CookieSerializeOptions;
|
|
13
36
|
}
|
|
14
|
-
|
|
15
|
-
interface IronSessionData {
|
|
16
|
-
[key: string]: unknown;
|
|
17
|
-
}
|
|
37
|
+
interface IronSessionData {
|
|
18
38
|
}
|
|
19
|
-
|
|
39
|
+
declare type IronSession = IronSessionData & {
|
|
40
|
+
/**
|
|
41
|
+
* Destroys the session data and removes the cookie.
|
|
42
|
+
*/
|
|
20
43
|
destroy: () => void;
|
|
44
|
+
/**
|
|
45
|
+
* Encrypts the session data and sets the cookie.
|
|
46
|
+
*/
|
|
21
47
|
save: () => Promise<void>;
|
|
22
|
-
}
|
|
23
|
-
declare type IronSession<T = IronSessionData> = T & IronSessionBase;
|
|
48
|
+
};
|
|
24
49
|
declare module "http" {
|
|
25
50
|
interface IncomingMessage {
|
|
26
|
-
/**
|
|
27
|
-
* This request's `Session` object.
|
|
28
|
-
* Even though this property isn't marked as optional, it won't exist until you use the `express-session` middleware
|
|
29
|
-
* [Declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) can be used to add your own properties.
|
|
30
|
-
*
|
|
31
|
-
* @see SessionData
|
|
32
|
-
*/
|
|
33
51
|
session: IronSession;
|
|
34
52
|
}
|
|
35
53
|
}
|
|
36
|
-
declare
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
* This request's `Session` object.
|
|
40
|
-
* Even though this property isn't marked as optional, it won't exist until you use the `express-session` middleware
|
|
41
|
-
* [Declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) can be used to add your own properties.
|
|
42
|
-
*
|
|
43
|
-
* @see SessionData
|
|
44
|
-
*/
|
|
45
|
-
session: IronSession<IronSessionData>;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
declare function getIronSession<T = IronSessionData>(req: IncomingMessage, res: ServerResponse, userSessionOptions: IronSessionOptions): Promise<IronSession<Partial<T>>>;
|
|
49
|
-
declare function unsealSession(seal: string, password: passwordsMap, ttl: number): Promise<IronSessionData>;
|
|
50
|
-
declare function sealSession(data: Record<string, unknown>, password: passwordsMap, ttl: number): Promise<string>;
|
|
54
|
+
declare function getIronSession(req: IncomingMessage, res: ServerResponse, userSessionOptions: IronSessionOptions): Promise<IronSession>;
|
|
55
|
+
declare function unsealData(seal: string, password: password, ttl?: number): Promise<IronSessionData>;
|
|
56
|
+
declare function sealData(data: IronSessionData, password: password, ttl?: number): Promise<string>;
|
|
51
57
|
|
|
52
|
-
export { IronSession, IronSessionOptions, getIronSession,
|
|
58
|
+
export { IronSession, IronSessionData, IronSessionOptions, getIronSession, sealData, unsealData };
|
package/dist/index.js
CHANGED
|
@@ -1,38 +1,12 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
|
|
8
|
-
var __export = (target, all) => {
|
|
9
|
-
__markAsModule(target);
|
|
10
|
-
for (var name in all)
|
|
11
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
-
};
|
|
13
|
-
var __reExport = (target, module2, desc) => {
|
|
14
|
-
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
|
|
15
|
-
for (let key of __getOwnPropNames(module2))
|
|
16
|
-
if (!__hasOwnProp.call(target, key) && key !== "default")
|
|
17
|
-
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
|
|
18
|
-
}
|
|
19
|
-
return target;
|
|
20
|
-
};
|
|
21
|
-
var __toModule = (module2) => {
|
|
22
|
-
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
|
|
23
|
-
};
|
|
24
|
-
|
|
25
1
|
// src/index.ts
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
sealSession: () => sealSession,
|
|
29
|
-
unsealSession: () => unsealSession
|
|
30
|
-
});
|
|
31
|
-
var import_iron = __toModule(require("@hapi/iron"));
|
|
32
|
-
var import_cookie = __toModule(require("cookie"));
|
|
2
|
+
import Iron from "@hapi/iron";
|
|
3
|
+
import { parse as parseCookie, serialize as serializeCookie } from "cookie";
|
|
33
4
|
var timestampSkewSec = 60;
|
|
5
|
+
var fourteenDaysInSeconds = 15 * 24 * 3600;
|
|
6
|
+
var currentMajorVersion = 2;
|
|
7
|
+
var versionDelimiter = "#";
|
|
34
8
|
var defaultOptions = {
|
|
35
|
-
ttl:
|
|
9
|
+
ttl: fourteenDaysInSeconds,
|
|
36
10
|
cookieOptions: {
|
|
37
11
|
httpOnly: true,
|
|
38
12
|
secure: true,
|
|
@@ -41,15 +15,20 @@ var defaultOptions = {
|
|
|
41
15
|
}
|
|
42
16
|
};
|
|
43
17
|
async function getIronSession(req, res, userSessionOptions) {
|
|
18
|
+
var _a, _b;
|
|
44
19
|
if (!req || !res || !userSessionOptions || !userSessionOptions.cookieName || !userSessionOptions.password) {
|
|
45
20
|
throw new Error(`iron-session: Bad usage. Minimum usage is const session = await getIronSession(req, res, { cookieName: "...", password: "...". Check the usage here: https://github.com/vvo/iron-session`);
|
|
46
21
|
}
|
|
47
|
-
const passwordsAsMap =
|
|
48
|
-
Object.values(
|
|
22
|
+
const passwordsAsMap = normalizeStringPasswordToMap(userSessionOptions.password);
|
|
23
|
+
Object.values(normalizeStringPasswordToMap(userSessionOptions.password)).forEach((password) => {
|
|
49
24
|
if (password.length < 32) {
|
|
50
25
|
throw new Error(`iron-session: Bad usage. Password must be at least 32 characters long.`);
|
|
51
26
|
}
|
|
52
27
|
});
|
|
28
|
+
const isHttps = req.socket.encrypted === true;
|
|
29
|
+
if (((_a = userSessionOptions.cookieOptions) == null ? void 0 : _a.secure) === true && isHttps === false) {
|
|
30
|
+
throw new Error(`iron-session: Can't use secure cookies when not in https. See usage at https://github.com/vvo/iron-session/`);
|
|
31
|
+
}
|
|
53
32
|
const options = {
|
|
54
33
|
...defaultOptions,
|
|
55
34
|
...userSessionOptions,
|
|
@@ -58,8 +37,8 @@ async function getIronSession(req, res, userSessionOptions) {
|
|
|
58
37
|
...userSessionOptions.cookieOptions || {}
|
|
59
38
|
}
|
|
60
39
|
};
|
|
61
|
-
if (
|
|
62
|
-
|
|
40
|
+
if (((_b = userSessionOptions.cookieOptions) == null ? void 0 : _b.secure) === void 0) {
|
|
41
|
+
options.cookieOptions.secure = isHttps;
|
|
63
42
|
}
|
|
64
43
|
if (options.ttl === 0) {
|
|
65
44
|
options.ttl = 2147483647;
|
|
@@ -73,26 +52,28 @@ async function getIronSession(req, res, userSessionOptions) {
|
|
|
73
52
|
} else {
|
|
74
53
|
options.cookieOptions.maxAge = computeCookieMaxAge(options.ttl);
|
|
75
54
|
}
|
|
76
|
-
const sealFromCookies = (
|
|
77
|
-
const
|
|
78
|
-
|
|
55
|
+
const sealFromCookies = parseCookie(req.headers.cookie || "")[options.cookieName];
|
|
56
|
+
const session = sealFromCookies === void 0 ? {} : await unsealData(sealFromCookies, passwordsAsMap, options.ttl);
|
|
57
|
+
Object.defineProperties(session, {
|
|
79
58
|
save: {
|
|
80
59
|
value: async function save() {
|
|
81
60
|
if (res.headersSent === true) {
|
|
82
61
|
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()`);
|
|
83
62
|
}
|
|
84
|
-
const seal = await
|
|
85
|
-
const cookieValue = (
|
|
63
|
+
const seal = await sealData(session, passwordsAsMap, options.ttl);
|
|
64
|
+
const cookieValue = serializeCookie(options.cookieName, seal, options.cookieOptions);
|
|
86
65
|
if (cookieValue.length > 4096) {
|
|
87
66
|
throw new Error(`iron-session: Cookie length is too big ${cookieValue.length}, browsers will refuse it. Try to remove some data.`);
|
|
88
67
|
}
|
|
89
68
|
addToCookies(cookieValue, res);
|
|
90
|
-
return cookieValue;
|
|
91
69
|
}
|
|
92
70
|
},
|
|
93
71
|
destroy: {
|
|
94
72
|
value: function destroy() {
|
|
95
|
-
|
|
73
|
+
Object.keys(session).forEach((key) => {
|
|
74
|
+
delete session[key];
|
|
75
|
+
});
|
|
76
|
+
const cookieValue = serializeCookie(options.cookieName, "", {
|
|
96
77
|
...options.cookieOptions,
|
|
97
78
|
maxAge: 0
|
|
98
79
|
});
|
|
@@ -113,12 +94,20 @@ function addToCookies(cookieValue, res) {
|
|
|
113
94
|
function computeCookieMaxAge(ttl) {
|
|
114
95
|
return ttl - timestampSkewSec;
|
|
115
96
|
}
|
|
116
|
-
async function
|
|
97
|
+
async function unsealData(seal, password, ttl = fourteenDaysInSeconds) {
|
|
98
|
+
const passwordsAsMap = normalizeStringPasswordToMap(password);
|
|
99
|
+
const { sealWithoutVersion, tokenVersion } = parseSeal(seal);
|
|
117
100
|
try {
|
|
118
|
-
await
|
|
119
|
-
...
|
|
120
|
-
ttl
|
|
101
|
+
const data = await Iron.unseal(sealWithoutVersion, passwordsAsMap, {
|
|
102
|
+
...Iron.defaults,
|
|
103
|
+
ttl: ttl * 1e3
|
|
121
104
|
});
|
|
105
|
+
if (tokenVersion === 2) {
|
|
106
|
+
return data;
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
...data.persistent
|
|
110
|
+
};
|
|
122
111
|
} catch (error) {
|
|
123
112
|
if (error instanceof Error) {
|
|
124
113
|
if (error.message === "Expired seal" || error.message === "Bad hmac value" || error.message === "Cannot find password: " || error.message === "Incorrect number of sealed components") {
|
|
@@ -127,20 +116,36 @@ async function unsealSession(seal, password, ttl) {
|
|
|
127
116
|
}
|
|
128
117
|
throw error;
|
|
129
118
|
}
|
|
130
|
-
return {};
|
|
131
119
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
120
|
+
function parseSeal(seal) {
|
|
121
|
+
if (seal[seal.length - 2] === versionDelimiter) {
|
|
122
|
+
const [sealWithoutVersion, tokenVersionAsString] = seal.split(versionDelimiter);
|
|
123
|
+
return {
|
|
124
|
+
sealWithoutVersion,
|
|
125
|
+
tokenVersion: parseInt(tokenVersionAsString, 10)
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
return { sealWithoutVersion: seal, tokenVersion: null };
|
|
129
|
+
}
|
|
130
|
+
async function sealData(data, password, ttl = fourteenDaysInSeconds) {
|
|
131
|
+
const passwordsAsMap = normalizeStringPasswordToMap(password);
|
|
132
|
+
const mostRecentPasswordId = Math.max(...Object.keys(passwordsAsMap).map((id) => parseInt(id, 10)));
|
|
133
|
+
const passwordForSeal = {
|
|
134
|
+
id: mostRecentPasswordId.toString(),
|
|
135
|
+
secret: passwordsAsMap[mostRecentPasswordId]
|
|
136
|
+
};
|
|
137
|
+
const seal = await Iron.seal(data, passwordForSeal, {
|
|
138
|
+
...Iron.defaults,
|
|
139
|
+
ttl: ttl * 1e3
|
|
137
140
|
});
|
|
138
|
-
return seal
|
|
141
|
+
return `${seal}${versionDelimiter}${currentMajorVersion}`;
|
|
142
|
+
}
|
|
143
|
+
function normalizeStringPasswordToMap(password) {
|
|
144
|
+
return typeof password === "string" ? { 1: password } : password;
|
|
139
145
|
}
|
|
140
|
-
|
|
141
|
-
0 && (module.exports = {
|
|
146
|
+
export {
|
|
142
147
|
getIronSession,
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
148
|
+
sealData,
|
|
149
|
+
unsealData
|
|
150
|
+
};
|
|
146
151
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["import Iron from \"@hapi/iron\";\nimport {\n parse as parseCookie,\n serialize as serializeCookie,\n CookieSerializeOptions,\n} from \"cookie\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport { TLSSocket } from \"tls\";\n\n// default time allowed to check for iron seal validity when ttl passed\n// see https://hapi.dev/family/iron/api/?v=6.0.0#options\nconst timestampSkewSec = 60;\n\ntype passwordsMap = { [id: number]: string };\ntype password = string | passwordsMap;\n\nconst defaultOptions: {\n ttl: number;\n cookieOptions: CookieSerializeOptions;\n} = {\n ttl: 15 * 24 * 3600,\n cookieOptions: {\n httpOnly: true,\n secure: true,\n sameSite: \"lax\",\n path: \"/\",\n },\n};\n\nexport interface IronSessionOptions {\n cookieName: string;\n password: password;\n ttl?: number;\n cookieOptions?: CookieSerializeOptions;\n}\n\ndeclare module \"iron-session\" {\n interface IronSessionData {\n [key: string]: unknown;\n }\n}\n\ndeclare module \"http\" {\n interface IncomingMessage {\n /**\n * This request's `Session` object.\n * Even though this property isn't marked as optional, it won't exist until you use the `express-session` middleware\n * [Declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) can be used to add your own properties.\n *\n * @see SessionData\n */\n session: IronSession;\n }\n}\ninterface IronSessionBase {\n destroy: () => void;\n save: () => Promise<void>;\n}\n\nexport type IronSession<T = IronSessionData> = T & IronSessionBase;\n\ndeclare module \"http\" {\n interface IncomingMessage {\n /**\n * This request's `Session` object.\n * Even though this property isn't marked as optional, it won't exist until you use the `express-session` middleware\n * [Declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) can be used to add your own properties.\n *\n * @see SessionData\n */\n session: IronSession<IronSessionData>;\n }\n}\n\nexport async function getIronSession<T = IronSessionData>(\n req: IncomingMessage,\n res: ServerResponse,\n userSessionOptions: IronSessionOptions,\n): Promise<IronSession<Partial<T>>> {\n if (\n !req ||\n !res ||\n !userSessionOptions ||\n !userSessionOptions.cookieName ||\n !userSessionOptions.password\n ) {\n throw new Error(\n `iron-session: Bad usage. Minimum usage is const session = await getIronSession(req, res, { cookieName: \"...\", password: \"...\". Check the usage here: https://github.com/vvo/iron-session`,\n );\n }\n\n const passwordsAsMap =\n typeof userSessionOptions.password === \"string\"\n ? { 1: userSessionOptions.password }\n : userSessionOptions.password;\n\n Object.values(passwordsAsMap).forEach((password) => {\n if (password.length < 32) {\n throw new Error(\n `iron-session: Bad usage. Password must be at least 32 characters long.`,\n );\n }\n });\n\n const options: Required<IronSessionOptions> = {\n ...defaultOptions,\n ...userSessionOptions,\n cookieOptions: {\n ...defaultOptions.cookieOptions,\n ...(userSessionOptions.cookieOptions || {}),\n },\n };\n\n if (\n !(req.socket as TLSSocket).encrypted &&\n options.cookieOptions.secure === true\n ) {\n throw new Error(\n `iron-session: Can't use secure cookies when not in https. See usage at https://github.com/vvo/iron-session/`,\n );\n }\n\n if (options.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 options.ttl = 2147483647;\n }\n\n if (\n userSessionOptions.cookieOptions &&\n \"maxAge\" in userSessionOptions.cookieOptions\n ) {\n // session cookie, do not set maxAge, consider token as infinite\n if (userSessionOptions.cookieOptions.maxAge === undefined) {\n options.ttl = 0;\n } else {\n options.cookieOptions.maxAge = computeCookieMaxAge(\n userSessionOptions.cookieOptions.maxAge,\n );\n }\n } else {\n options.cookieOptions.maxAge = computeCookieMaxAge(options.ttl);\n }\n\n const sealFromCookies = parseCookie(req.headers.cookie || \"\")[\n options.cookieName\n ];\n\n const sessionData = await unsealSession(\n sealFromCookies,\n passwordsAsMap,\n options.ttl * 1000,\n );\n\n const session = Object.defineProperties(sessionData, {\n save: {\n value: async function save() {\n if (res.headersSent === true) {\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 const seal = await sealSession(\n sessionData,\n passwordsAsMap,\n options.ttl * 1000,\n );\n const cookieValue = serializeCookie(\n options.cookieName,\n seal,\n options.cookieOptions,\n );\n\n if (cookieValue.length > 4096) {\n throw new Error(\n `iron-session: Cookie length is too big ${cookieValue.length}, browsers will refuse it. Try to remove some data.`,\n );\n }\n\n addToCookies(cookieValue, res);\n return cookieValue;\n },\n },\n destroy: {\n value: function destroy() {\n const cookieValue = serializeCookie(options.cookieName, \"\", {\n ...options.cookieOptions,\n maxAge: 0,\n });\n addToCookies(cookieValue, res);\n },\n },\n }) as IronSession<Partial<T>>;\n\n return session;\n}\n\nfunction addToCookies(cookieValue: string, res: ServerResponse) {\n let existingSetCookie =\n (res.getHeader(\"set-cookie\") as string[] | string) ?? [];\n if (typeof existingSetCookie === \"string\") {\n existingSetCookie = [existingSetCookie];\n }\n res.setHeader(\"set-cookie\", [...existingSetCookie, cookieValue]);\n}\n\nfunction computeCookieMaxAge(ttl: number) {\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 maximum between server and clients.\n // It also makes sure to expire the cookie immediately when value is 0\n return ttl - timestampSkewSec;\n}\n\nexport async function unsealSession(\n seal: string,\n password: passwordsMap,\n ttl: number,\n): Promise<IronSessionData> {\n try {\n await Iron.unseal(seal, password, {\n ...Iron.defaults,\n ttl,\n });\n } catch (error) {\n if (error instanceof Error) {\n if (\n error.message === \"Expired seal\" ||\n error.message === \"Bad hmac value\" ||\n error.message === \"Cannot find password: \" ||\n error.message === \"Incorrect number of sealed components\"\n ) {\n // if seal expired or\n // if seal is not valid (encrypted using a different password, when passwords are updated) or\n // if we can't find back the password in the seal\n // then we just start a new session over\n return {};\n }\n }\n\n throw error;\n }\n\n return {};\n}\n\nexport async function sealSession(\n data: Record<string, unknown>,\n password: passwordsMap,\n ttl: number,\n) {\n const mostRecentPasswordId = Math.max(\n ...Object.keys(password).map((id) => parseInt(id, 10)),\n );\n\n const seal = await Iron.seal(data, password[mostRecentPasswordId], {\n ...Iron.defaults,\n ttl,\n });\n\n return seal;\n}\n"],
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import Iron from \"@hapi/iron\";\nimport type { CookieSerializeOptions } from \"cookie\";\nimport { parse as parseCookie, serialize as serializeCookie } from \"cookie\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport type { TLSSocket } from \"tls\";\n\n// default time allowed to check for iron seal validity when ttl passed\n// see https://hapi.dev/family/iron/api/?v=6.0.0#options\nconst timestampSkewSec = 60;\n\ntype passwordsMap = { [id: string]: string };\ntype password = string | passwordsMap;\n\nconst fourteenDaysInSeconds = 15 * 24 * 3600;\n\n// We store a token major version to handle data format changes when any. So that when you upgrade the cookies\n// can be kept alive between upgrades, no need to disconnect everyone.\nconst currentMajorVersion = 2;\nconst versionDelimiter = \"#\";\n\nconst defaultOptions: {\n ttl: number;\n cookieOptions: CookieSerializeOptions;\n} = {\n ttl: fourteenDaysInSeconds,\n cookieOptions: {\n httpOnly: true,\n secure: true,\n sameSite: \"lax\",\n path: \"/\",\n },\n};\n\nexport interface IronSessionOptions {\n /**\n * This is the cookie name that will be used inside the browser. You should make sure it's unique given\n * your application. Example: vercel-session\n */\n cookieName: string;\n\n /**\n * This is the password(s) that will be used to encrypt the cookie. It can be either a string or an object\n * like {1: \"password\", 2: password}.\n *\n * When you provide multiple passwords then all of them will be used to decrypt the cookie and only the most\n * recent (= highest key, 2 in this example) password will be used to encrypt the cookie. This allow you\n * to use password rotation (security)\n */\n password: password;\n\n /**\n * This is the time in seconds that the session will be valid for. This also set the max-age attribute of\n * the cookie automatically (minus 60 seconds so that the cookie always expire before the session).\n */\n ttl?: number;\n\n /**\n * This is the options that will be passed to the cookie library.\n * You can see all of them here: https://github.com/jshttp/cookie#options-1.\n *\n * If you want to use \"session cookies\" (cookies that are deleted when the browser is closed) then you need\n * to pass cookieOptions: { maxAge: undefined }.\n */\n cookieOptions?: CookieSerializeOptions;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface IronSessionData {\n // If we allow for any keys, then there's no more type check on unknown properties which is not good\n // If we allow for any keys, the later delete will work but I prefer to disable the check at this stage and\n // provide good type checking instead\n // [key: string]: unknown;\n}\n\nexport type IronSession = IronSessionData & {\n /**\n * Destroys the session data and removes the cookie.\n */\n destroy: () => void;\n\n /**\n * Encrypts the session data and sets the cookie.\n */\n save: () => Promise<void>;\n};\n\ndeclare module \"http\" {\n interface IncomingMessage {\n session: IronSession;\n }\n}\n\nexport async function getIronSession(\n req: IncomingMessage,\n res: ServerResponse,\n userSessionOptions: IronSessionOptions,\n): Promise<IronSession> {\n if (\n !req ||\n !res ||\n !userSessionOptions ||\n !userSessionOptions.cookieName ||\n !userSessionOptions.password\n ) {\n throw new Error(\n `iron-session: Bad usage. Minimum usage is const session = await getIronSession(req, res, { cookieName: \"...\", password: \"...\". Check the usage here: https://github.com/vvo/iron-session`,\n );\n }\n\n const passwordsAsMap = normalizeStringPasswordToMap(\n userSessionOptions.password,\n );\n\n Object.values(\n normalizeStringPasswordToMap(userSessionOptions.password),\n ).forEach((password) => {\n if (password.length < 32) {\n throw new Error(\n `iron-session: Bad usage. Password must be at least 32 characters long.`,\n );\n }\n });\n\n const isHttps = (req.socket as TLSSocket).encrypted === true;\n\n if (userSessionOptions.cookieOptions?.secure === true && isHttps === false) {\n throw new Error(\n `iron-session: Can't use secure cookies when not in https. See usage at https://github.com/vvo/iron-session/`,\n );\n }\n\n const options: Required<IronSessionOptions> = {\n ...defaultOptions,\n ...userSessionOptions,\n cookieOptions: {\n ...defaultOptions.cookieOptions,\n ...(userSessionOptions.cookieOptions || {}),\n },\n };\n\n // if the user did not set the secure flag themselves, we automatically configure it\n if (userSessionOptions.cookieOptions?.secure === undefined) {\n options.cookieOptions.secure = isHttps;\n }\n\n if (options.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 options.ttl = 2147483647;\n }\n\n if (\n userSessionOptions.cookieOptions &&\n \"maxAge\" in userSessionOptions.cookieOptions\n ) {\n // session cookie, do not set maxAge, consider token as infinite\n if (userSessionOptions.cookieOptions.maxAge === undefined) {\n options.ttl = 0;\n } else {\n options.cookieOptions.maxAge = computeCookieMaxAge(\n userSessionOptions.cookieOptions.maxAge,\n );\n }\n } else {\n options.cookieOptions.maxAge = computeCookieMaxAge(options.ttl);\n }\n\n const sealFromCookies = parseCookie(req.headers.cookie || \"\")[\n options.cookieName\n ];\n\n const session =\n sealFromCookies === undefined\n ? {}\n : await unsealData(sealFromCookies, passwordsAsMap, options.ttl);\n\n Object.defineProperties(session, {\n save: {\n value: async function save() {\n if (res.headersSent === true) {\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 const seal = await sealData(session, passwordsAsMap, options.ttl);\n const cookieValue = serializeCookie(\n options.cookieName,\n seal,\n options.cookieOptions,\n );\n\n if (cookieValue.length > 4096) {\n throw new Error(\n `iron-session: Cookie length is too big ${cookieValue.length}, browsers will refuse it. Try to remove some data.`,\n );\n }\n\n addToCookies(cookieValue, res);\n },\n },\n destroy: {\n value: function destroy() {\n Object.keys(session).forEach((key) => {\n // @ts-ignore See comment on the IronSessionData interface\n delete session[key];\n });\n\n const cookieValue = serializeCookie(options.cookieName, \"\", {\n ...options.cookieOptions,\n maxAge: 0,\n });\n addToCookies(cookieValue, res);\n },\n },\n });\n\n return session as IronSession;\n}\n\nfunction addToCookies(cookieValue: string, res: ServerResponse) {\n let existingSetCookie =\n (res.getHeader(\"set-cookie\") as string[] | string) ?? [];\n if (typeof existingSetCookie === \"string\") {\n existingSetCookie = [existingSetCookie];\n }\n res.setHeader(\"set-cookie\", [...existingSetCookie, cookieValue]);\n}\n\nfunction computeCookieMaxAge(ttl: number) {\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 maximum between server and clients.\n // It also makes sure to expire the cookie immediately when value is 0\n return ttl - timestampSkewSec;\n}\n\nexport async function unsealData(\n seal: string,\n password: password,\n ttl: number = fourteenDaysInSeconds,\n): Promise<IronSessionData> {\n const passwordsAsMap = normalizeStringPasswordToMap(password);\n const { sealWithoutVersion, tokenVersion } = parseSeal(seal);\n\n try {\n const data = await Iron.unseal(sealWithoutVersion, passwordsAsMap, {\n ...Iron.defaults,\n ttl: ttl * 1000,\n });\n\n if (tokenVersion === 2) {\n return data;\n }\n\n return {\n ...data.persistent,\n };\n } catch (error) {\n if (error instanceof Error) {\n if (\n error.message === \"Expired seal\" ||\n error.message === \"Bad hmac value\" ||\n error.message === \"Cannot find password: \" ||\n error.message === \"Incorrect number of sealed components\"\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 {};\n }\n }\n\n throw error;\n }\n}\n\nfunction parseSeal(seal: string): {\n sealWithoutVersion: string;\n tokenVersion: number | null;\n} {\n if (seal[seal.length - 2] === versionDelimiter) {\n const [sealWithoutVersion, tokenVersionAsString] =\n seal.split(versionDelimiter);\n return {\n sealWithoutVersion,\n tokenVersion: parseInt(tokenVersionAsString, 10),\n };\n }\n\n return { sealWithoutVersion: seal, tokenVersion: null };\n}\n\nexport async function sealData(\n data: IronSessionData,\n password: password,\n ttl: number = fourteenDaysInSeconds,\n) {\n const passwordsAsMap = normalizeStringPasswordToMap(password);\n\n const mostRecentPasswordId = Math.max(\n ...Object.keys(passwordsAsMap).map((id) => parseInt(id, 10)),\n );\n\n const passwordForSeal = {\n id: mostRecentPasswordId.toString(),\n secret: passwordsAsMap[mostRecentPasswordId],\n };\n\n const seal = await Iron.seal(data, passwordForSeal, {\n ...Iron.defaults,\n ttl: ttl * 1000,\n });\n\n return `${seal}${versionDelimiter}${currentMajorVersion}`;\n}\n\nfunction normalizeStringPasswordToMap(password: password) {\n return typeof password === \"string\" ? { 1: password } : password;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
__markAsModule(target);
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __reExport = (target, module2, desc) => {
|
|
14
|
+
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(module2))
|
|
16
|
+
if (!__hasOwnProp.call(target, key) && key !== "default")
|
|
17
|
+
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return target;
|
|
20
|
+
};
|
|
21
|
+
var __toModule = (module2) => {
|
|
22
|
+
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// express/index.ts
|
|
26
|
+
__export(exports, {
|
|
27
|
+
ironSession: () => ironSession
|
|
28
|
+
});
|
|
29
|
+
var import_iron_session = __toModule(require("iron-session"));
|
|
30
|
+
|
|
31
|
+
// src/getPropertyDescriptorForReqSession.ts
|
|
32
|
+
function getPropertyDescriptorForReqSession(session) {
|
|
33
|
+
return {
|
|
34
|
+
enumerable: true,
|
|
35
|
+
get() {
|
|
36
|
+
return session;
|
|
37
|
+
},
|
|
38
|
+
set(value) {
|
|
39
|
+
const keys = Object.keys(value);
|
|
40
|
+
const currentKeys = Object.keys(session);
|
|
41
|
+
currentKeys.forEach((key) => {
|
|
42
|
+
if (!keys.includes(key)) {
|
|
43
|
+
delete session[key];
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
keys.forEach((key) => {
|
|
47
|
+
session[key] = value[key];
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// express/index.ts
|
|
54
|
+
function ironSession(sessionOptions) {
|
|
55
|
+
return async function ironSessionMiddleware(req, res, next) {
|
|
56
|
+
const session = await (0, import_iron_session.getIronSession)(req, res, sessionOptions);
|
|
57
|
+
Object.defineProperty(req, "session", getPropertyDescriptorForReqSession(session));
|
|
58
|
+
next();
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
62
|
+
0 && (module.exports = {
|
|
63
|
+
ironSession
|
|
64
|
+
});
|
|
65
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../index.ts", "../../src/getPropertyDescriptorForReqSession.ts"],
|
|
4
|
+
"sourcesContent": ["import type { IronSessionOptions } from \"iron-session\";\nimport { getIronSession } from \"iron-session\";\nimport type { Request, Response, NextFunction } from \"express\";\nimport getPropertyDescriptorForReqSession from \"../src/getPropertyDescriptorForReqSession\";\n\nexport function ironSession(\n sessionOptions: IronSessionOptions,\n): (req: Request, res: Response, next: NextFunction) => Promise<void> {\n return async function ironSessionMiddleware(req, res, next) {\n const session = await getIronSession(req, res, sessionOptions);\n Object.defineProperty(\n req,\n \"session\",\n getPropertyDescriptorForReqSession(session),\n );\n\n next();\n };\n}\n", "import type { IronSession } from \".\";\n\nexport default function getPropertyDescriptorForReqSession(\n session: IronSession,\n): PropertyDescriptor {\n return {\n enumerable: true,\n get() {\n return session;\n },\n set(value) {\n const keys = Object.keys(value);\n const currentKeys = Object.keys(session);\n\n currentKeys.forEach((key) => {\n if (!keys.includes(key)) {\n // @ts-ignore See comment in IronSessionData interface\n delete session[key];\n }\n });\n\n keys.forEach((key) => {\n // @ts-ignore See comment in IronSessionData interface\n session[key] = value[key];\n });\n },\n };\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AACA,0BAA+B;;;ACChB,4CACb,SACoB;AACpB,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,MAAM;AACJ,aAAO;AAAA;AAAA,IAET,IAAI,OAAO;AACT,YAAM,OAAO,OAAO,KAAK;AACzB,YAAM,cAAc,OAAO,KAAK;AAEhC,kBAAY,QAAQ,CAAC,QAAQ;AAC3B,YAAI,CAAC,KAAK,SAAS,MAAM;AAEvB,iBAAO,QAAQ;AAAA;AAAA;AAInB,WAAK,QAAQ,CAAC,QAAQ;AAEpB,gBAAQ,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;;;ADlBtB,qBACL,gBACoE;AACpE,SAAO,qCAAqC,KAAK,KAAK,MAAM;AAC1D,UAAM,UAAU,MAAM,wCAAe,KAAK,KAAK;AAC/C,WAAO,eACL,KACA,WACA,mCAAmC;AAGrC;AAAA;AAAA;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { IronSessionOptions } from 'iron-session';
|
|
2
|
+
import { Request, Response, NextFunction } from 'express';
|
|
3
|
+
|
|
4
|
+
declare function ironSession(sessionOptions: IronSessionOptions): (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
5
|
+
|
|
6
|
+
export { ironSession };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// express/index.ts
|
|
2
|
+
import { getIronSession } from "iron-session";
|
|
3
|
+
|
|
4
|
+
// src/getPropertyDescriptorForReqSession.ts
|
|
5
|
+
function getPropertyDescriptorForReqSession(session) {
|
|
6
|
+
return {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get() {
|
|
9
|
+
return session;
|
|
10
|
+
},
|
|
11
|
+
set(value) {
|
|
12
|
+
const keys = Object.keys(value);
|
|
13
|
+
const currentKeys = Object.keys(session);
|
|
14
|
+
currentKeys.forEach((key) => {
|
|
15
|
+
if (!keys.includes(key)) {
|
|
16
|
+
delete session[key];
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
keys.forEach((key) => {
|
|
20
|
+
session[key] = value[key];
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// express/index.ts
|
|
27
|
+
function ironSession(sessionOptions) {
|
|
28
|
+
return async function ironSessionMiddleware(req, res, next) {
|
|
29
|
+
const session = await getIronSession(req, res, sessionOptions);
|
|
30
|
+
Object.defineProperty(req, "session", getPropertyDescriptorForReqSession(session));
|
|
31
|
+
next();
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
ironSession
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../index.ts", "../../src/getPropertyDescriptorForReqSession.ts"],
|
|
4
|
+
"sourcesContent": ["import type { IronSessionOptions } from \"iron-session\";\nimport { getIronSession } from \"iron-session\";\nimport type { Request, Response, NextFunction } from \"express\";\nimport getPropertyDescriptorForReqSession from \"../src/getPropertyDescriptorForReqSession\";\n\nexport function ironSession(\n sessionOptions: IronSessionOptions,\n): (req: Request, res: Response, next: NextFunction) => Promise<void> {\n return async function ironSessionMiddleware(req, res, next) {\n const session = await getIronSession(req, res, sessionOptions);\n Object.defineProperty(\n req,\n \"session\",\n getPropertyDescriptorForReqSession(session),\n );\n\n next();\n };\n}\n", "import type { IronSession } from \".\";\n\nexport default function getPropertyDescriptorForReqSession(\n session: IronSession,\n): PropertyDescriptor {\n return {\n enumerable: true,\n get() {\n return session;\n },\n set(value) {\n const keys = Object.keys(value);\n const currentKeys = Object.keys(session);\n\n currentKeys.forEach((key) => {\n if (!keys.includes(key)) {\n // @ts-ignore See comment in IronSessionData interface\n delete session[key];\n }\n });\n\n keys.forEach((key) => {\n // @ts-ignore See comment in IronSessionData interface\n session[key] = value[key];\n });\n },\n };\n}\n"],
|
|
5
|
+
"mappings": ";AACA;;;ACCe,4CACb,SACoB;AACpB,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,MAAM;AACJ,aAAO;AAAA;AAAA,IAET,IAAI,OAAO;AACT,YAAM,OAAO,OAAO,KAAK;AACzB,YAAM,cAAc,OAAO,KAAK;AAEhC,kBAAY,QAAQ,CAAC,QAAQ;AAC3B,YAAI,CAAC,KAAK,SAAS,MAAM;AAEvB,iBAAO,QAAQ;AAAA;AAAA;AAInB,WAAK,QAAQ,CAAC,QAAQ;AAEpB,gBAAQ,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;;;ADlBtB,qBACL,gBACoE;AACpE,SAAO,qCAAqC,KAAK,KAAK,MAAM;AAC1D,UAAM,UAAU,MAAM,eAAe,KAAK,KAAK;AAC/C,WAAO,eACL,KACA,WACA,mCAAmC;AAGrC;AAAA;AAAA;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
__markAsModule(target);
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __reExport = (target, module2, desc) => {
|
|
14
|
+
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(module2))
|
|
16
|
+
if (!__hasOwnProp.call(target, key) && key !== "default")
|
|
17
|
+
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return target;
|
|
20
|
+
};
|
|
21
|
+
var __toModule = (module2) => {
|
|
22
|
+
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// next/index.ts
|
|
26
|
+
__export(exports, {
|
|
27
|
+
withIronSessionApiRoute: () => withIronSessionApiRoute,
|
|
28
|
+
withIronSessionSsr: () => withIronSessionSsr
|
|
29
|
+
});
|
|
30
|
+
var import_iron_session = __toModule(require("iron-session"));
|
|
31
|
+
|
|
32
|
+
// src/getPropertyDescriptorForReqSession.ts
|
|
33
|
+
function getPropertyDescriptorForReqSession(session) {
|
|
34
|
+
return {
|
|
35
|
+
enumerable: true,
|
|
36
|
+
get() {
|
|
37
|
+
return session;
|
|
38
|
+
},
|
|
39
|
+
set(value) {
|
|
40
|
+
const keys = Object.keys(value);
|
|
41
|
+
const currentKeys = Object.keys(session);
|
|
42
|
+
currentKeys.forEach((key) => {
|
|
43
|
+
if (!keys.includes(key)) {
|
|
44
|
+
delete session[key];
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
keys.forEach((key) => {
|
|
48
|
+
session[key] = value[key];
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// next/index.ts
|
|
55
|
+
function withIronSessionApiRoute(handler, options) {
|
|
56
|
+
return async function nextApiHandlerWrappedWithIronSession(req, res) {
|
|
57
|
+
const session = await (0, import_iron_session.getIronSession)(req, res, options);
|
|
58
|
+
Object.defineProperty(req, "session", getPropertyDescriptorForReqSession(session));
|
|
59
|
+
return handler(req, res);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function withIronSessionSsr(handler, options) {
|
|
63
|
+
return async function nextGetServerSidePropsHandlerWrappedWithIronSession(context) {
|
|
64
|
+
const session = await (0, import_iron_session.getIronSession)(context.req, context.res, options);
|
|
65
|
+
Object.defineProperty(context.req, "session", getPropertyDescriptorForReqSession(session));
|
|
66
|
+
return handler(context);
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
70
|
+
0 && (module.exports = {
|
|
71
|
+
withIronSessionApiRoute,
|
|
72
|
+
withIronSessionSsr
|
|
73
|
+
});
|
|
74
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../index.ts", "../../src/getPropertyDescriptorForReqSession.ts"],
|
|
4
|
+
"sourcesContent": ["import type {\n NextApiHandler,\n GetServerSidePropsContext,\n GetServerSidePropsResult,\n} from \"next\";\nimport type { IronSessionOptions } from \"iron-session\";\nimport { getIronSession } from \"iron-session\";\nimport getPropertyDescriptorForReqSession from \"../src/getPropertyDescriptorForReqSession\";\n\nexport function withIronSessionApiRoute(\n handler: NextApiHandler,\n options: IronSessionOptions,\n): NextApiHandler {\n return async function nextApiHandlerWrappedWithIronSession(req, res) {\n const session = await getIronSession(req, res, options);\n\n // we define req.session as being enumerable (so console.log(req) shows it)\n // and we also want to allow people to do:\n // req.session = { admin: true }; or req.session = {...req.session, admin: true};\n // req.session.save();\n Object.defineProperty(\n req,\n \"session\",\n getPropertyDescriptorForReqSession(session),\n );\n return handler(req, res);\n };\n}\n\nexport function withIronSessionSsr<\n P extends { [key: string]: unknown } = { [key: string]: unknown },\n>(\n handler: (\n context: GetServerSidePropsContext,\n ) => GetServerSidePropsResult<P> | Promise<GetServerSidePropsResult<P>>,\n options: IronSessionOptions,\n) {\n return async function nextGetServerSidePropsHandlerWrappedWithIronSession(\n context: GetServerSidePropsContext,\n ) {\n const session = await getIronSession(context.req, context.res, options);\n Object.defineProperty(\n context.req,\n \"session\",\n getPropertyDescriptorForReqSession(session),\n );\n return handler(context);\n };\n}\n", "import type { IronSession } from \".\";\n\nexport default function getPropertyDescriptorForReqSession(\n session: IronSession,\n): PropertyDescriptor {\n return {\n enumerable: true,\n get() {\n return session;\n },\n set(value) {\n const keys = Object.keys(value);\n const currentKeys = Object.keys(session);\n\n currentKeys.forEach((key) => {\n if (!keys.includes(key)) {\n // @ts-ignore See comment in IronSessionData interface\n delete session[key];\n }\n });\n\n keys.forEach((key) => {\n // @ts-ignore See comment in IronSessionData interface\n session[key] = value[key];\n });\n },\n };\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAMA,0BAA+B;;;ACJhB,4CACb,SACoB;AACpB,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,MAAM;AACJ,aAAO;AAAA;AAAA,IAET,IAAI,OAAO;AACT,YAAM,OAAO,OAAO,KAAK;AACzB,YAAM,cAAc,OAAO,KAAK;AAEhC,kBAAY,QAAQ,CAAC,QAAQ;AAC3B,YAAI,CAAC,KAAK,SAAS,MAAM;AAEvB,iBAAO,QAAQ;AAAA;AAAA;AAInB,WAAK,QAAQ,CAAC,QAAQ;AAEpB,gBAAQ,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;;;ADdtB,iCACL,SACA,SACgB;AAChB,SAAO,oDAAoD,KAAK,KAAK;AACnE,UAAM,UAAU,MAAM,wCAAe,KAAK,KAAK;AAM/C,WAAO,eACL,KACA,WACA,mCAAmC;AAErC,WAAO,QAAQ,KAAK;AAAA;AAAA;AAIjB,4BAGL,SAGA,SACA;AACA,SAAO,mEACL,SACA;AACA,UAAM,UAAU,MAAM,wCAAe,QAAQ,KAAK,QAAQ,KAAK;AAC/D,WAAO,eACL,QAAQ,KACR,WACA,mCAAmC;AAErC,WAAO,QAAQ;AAAA;AAAA;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/next/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import { NextApiHandler } from 'next';
|
|
2
|
-
import {
|
|
1
|
+
import { NextApiHandler, GetServerSidePropsContext, GetServerSidePropsResult } from 'next';
|
|
2
|
+
import { IronSessionOptions } from 'iron-session';
|
|
3
3
|
|
|
4
|
-
declare function withIronSessionApiRoute
|
|
4
|
+
declare function withIronSessionApiRoute(handler: NextApiHandler, options: IronSessionOptions): NextApiHandler;
|
|
5
|
+
declare function withIronSessionSsr<P extends {
|
|
6
|
+
[key: string]: unknown;
|
|
7
|
+
} = {
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
}>(handler: (context: GetServerSidePropsContext) => GetServerSidePropsResult<P> | Promise<GetServerSidePropsResult<P>>, options: IronSessionOptions): (context: GetServerSidePropsContext) => Promise<GetServerSidePropsResult<P>>;
|
|
5
10
|
|
|
6
|
-
export { withIronSessionApiRoute };
|
|
11
|
+
export { withIronSessionApiRoute, withIronSessionSsr };
|
package/next/dist/index.js
CHANGED
|
@@ -1,44 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
};
|
|
1
|
+
// next/index.ts
|
|
2
|
+
import { getIronSession } from "iron-session";
|
|
3
|
+
|
|
4
|
+
// src/getPropertyDescriptorForReqSession.ts
|
|
5
|
+
function getPropertyDescriptorForReqSession(session) {
|
|
6
|
+
return {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get() {
|
|
9
|
+
return session;
|
|
10
|
+
},
|
|
11
|
+
set(value) {
|
|
12
|
+
const keys = Object.keys(value);
|
|
13
|
+
const currentKeys = Object.keys(session);
|
|
14
|
+
currentKeys.forEach((key) => {
|
|
15
|
+
if (!keys.includes(key)) {
|
|
16
|
+
delete session[key];
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
keys.forEach((key) => {
|
|
20
|
+
session[key] = value[key];
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
}
|
|
24
25
|
|
|
25
26
|
// next/index.ts
|
|
26
|
-
__export(exports, {
|
|
27
|
-
withIronSessionApiRoute: () => withIronSessionApiRoute
|
|
28
|
-
});
|
|
29
|
-
var import_iron_session = __toModule(require("iron-session"));
|
|
30
27
|
function withIronSessionApiRoute(handler, options) {
|
|
31
28
|
return async function nextApiHandlerWrappedWithIronSession(req, res) {
|
|
32
|
-
const session = await
|
|
33
|
-
Object.defineProperty(req, "session",
|
|
34
|
-
enumerable: true,
|
|
35
|
-
value: session
|
|
36
|
-
});
|
|
29
|
+
const session = await getIronSession(req, res, options);
|
|
30
|
+
Object.defineProperty(req, "session", getPropertyDescriptorForReqSession(session));
|
|
37
31
|
return handler(req, res);
|
|
38
32
|
};
|
|
39
33
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
34
|
+
function withIronSessionSsr(handler, options) {
|
|
35
|
+
return async function nextGetServerSidePropsHandlerWrappedWithIronSession(context) {
|
|
36
|
+
const session = await getIronSession(context.req, context.res, options);
|
|
37
|
+
Object.defineProperty(context.req, "session", getPropertyDescriptorForReqSession(session));
|
|
38
|
+
return handler(context);
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export {
|
|
42
|
+
withIronSessionApiRoute,
|
|
43
|
+
withIronSessionSsr
|
|
44
|
+
};
|
|
44
45
|
//# sourceMappingURL=index.js.map
|
package/next/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../index.ts"],
|
|
4
|
-
"sourcesContent": ["import type {
|
|
5
|
-
"mappings": "
|
|
3
|
+
"sources": ["../index.ts", "../../src/getPropertyDescriptorForReqSession.ts"],
|
|
4
|
+
"sourcesContent": ["import type {\n NextApiHandler,\n GetServerSidePropsContext,\n GetServerSidePropsResult,\n} from \"next\";\nimport type { IronSessionOptions } from \"iron-session\";\nimport { getIronSession } from \"iron-session\";\nimport getPropertyDescriptorForReqSession from \"../src/getPropertyDescriptorForReqSession\";\n\nexport function withIronSessionApiRoute(\n handler: NextApiHandler,\n options: IronSessionOptions,\n): NextApiHandler {\n return async function nextApiHandlerWrappedWithIronSession(req, res) {\n const session = await getIronSession(req, res, options);\n\n // we define req.session as being enumerable (so console.log(req) shows it)\n // and we also want to allow people to do:\n // req.session = { admin: true }; or req.session = {...req.session, admin: true};\n // req.session.save();\n Object.defineProperty(\n req,\n \"session\",\n getPropertyDescriptorForReqSession(session),\n );\n return handler(req, res);\n };\n}\n\nexport function withIronSessionSsr<\n P extends { [key: string]: unknown } = { [key: string]: unknown },\n>(\n handler: (\n context: GetServerSidePropsContext,\n ) => GetServerSidePropsResult<P> | Promise<GetServerSidePropsResult<P>>,\n options: IronSessionOptions,\n) {\n return async function nextGetServerSidePropsHandlerWrappedWithIronSession(\n context: GetServerSidePropsContext,\n ) {\n const session = await getIronSession(context.req, context.res, options);\n Object.defineProperty(\n context.req,\n \"session\",\n getPropertyDescriptorForReqSession(session),\n );\n return handler(context);\n };\n}\n", "import type { IronSession } from \".\";\n\nexport default function getPropertyDescriptorForReqSession(\n session: IronSession,\n): PropertyDescriptor {\n return {\n enumerable: true,\n get() {\n return session;\n },\n set(value) {\n const keys = Object.keys(value);\n const currentKeys = Object.keys(session);\n\n currentKeys.forEach((key) => {\n if (!keys.includes(key)) {\n // @ts-ignore See comment in IronSessionData interface\n delete session[key];\n }\n });\n\n keys.forEach((key) => {\n // @ts-ignore See comment in IronSessionData interface\n session[key] = value[key];\n });\n },\n };\n}\n"],
|
|
5
|
+
"mappings": ";AAMA;;;ACJe,4CACb,SACoB;AACpB,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,MAAM;AACJ,aAAO;AAAA;AAAA,IAET,IAAI,OAAO;AACT,YAAM,OAAO,OAAO,KAAK;AACzB,YAAM,cAAc,OAAO,KAAK;AAEhC,kBAAY,QAAQ,CAAC,QAAQ;AAC3B,YAAI,CAAC,KAAK,SAAS,MAAM;AAEvB,iBAAO,QAAQ;AAAA;AAAA;AAInB,WAAK,QAAQ,CAAC,QAAQ;AAEpB,gBAAQ,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;;;ADdtB,iCACL,SACA,SACgB;AAChB,SAAO,oDAAoD,KAAK,KAAK;AACnE,UAAM,UAAU,MAAM,eAAe,KAAK,KAAK;AAM/C,WAAO,eACL,KACA,WACA,mCAAmC;AAErC,WAAO,QAAQ,KAAK;AAAA;AAAA;AAIjB,4BAGL,SAGA,SACA;AACA,SAAO,mEACL,SACA;AACA,UAAM,UAAU,MAAM,eAAe,QAAQ,KAAK,QAAQ,KAAK;AAC/D,WAAO,eACL,QAAQ,KACR,WACA,mCAAmC;AAErC,WAAO,QAAQ;AAAA;AAAA;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iron-session",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.18",
|
|
4
|
+
"description": "Node.js stateless session utility using signed and encrypted cookies to store data. Works with Next.js, Express, NestJs, Fastify, and any Node.js HTTP framework.",
|
|
4
5
|
"license": "MIT",
|
|
5
6
|
"author": "Vincent Voyer <vincent@codeagain.com>",
|
|
7
|
+
"type": "module",
|
|
6
8
|
"exports": {
|
|
7
9
|
".": {
|
|
8
10
|
"import": "./dist/index.mjs",
|
|
@@ -28,46 +30,79 @@
|
|
|
28
30
|
"next/dist",
|
|
29
31
|
"express/dist"
|
|
30
32
|
],
|
|
31
|
-
"workspaces": [
|
|
32
|
-
"examples/next.js",
|
|
33
|
-
"examples/next.js-typescript"
|
|
34
|
-
],
|
|
35
33
|
"scripts": {
|
|
36
|
-
"build": "npm run build:clean && npm run build:src && npm run build:next",
|
|
34
|
+
"build": "npm run build:clean && npm run build:src && npm run build:next && npm run build:express",
|
|
37
35
|
"build:clean": "rimraf dist/ next/dist express/dist",
|
|
38
36
|
"build:express": "tsup express/index.ts -d express/dist",
|
|
39
37
|
"build:next": "tsup next/index.ts -d next/dist",
|
|
40
38
|
"build:src": "tsup src/index.ts",
|
|
41
|
-
"build:watch": "npm run build:clean && tsup src/index.ts --watch src/index.ts && tsup next/index.ts -d next/dist && tsup express/index.ts -d express/dist --watch express/index.ts",
|
|
42
39
|
"lint": "eslint --ext ts,js,jsx,tsx src/ next/ express/ examples/",
|
|
43
40
|
"prepublishOnly": "npm run build",
|
|
44
|
-
"test": "jest --coverage && npm run lint && tsc --noEmit"
|
|
41
|
+
"test": "jest --coverage && npm run lint && tsc --noEmit",
|
|
42
|
+
"watch": "npm run build:clean && concurrently \"npm:watch:*\"",
|
|
43
|
+
"watch:express": "tsup express/index.ts -d express/dist --watch express/index.ts",
|
|
44
|
+
"watch:next": "tsup next/index.ts -d next/dist --watch next/index.ts",
|
|
45
|
+
"watch:src": "tsup src/index.ts --watch src/index.ts"
|
|
45
46
|
},
|
|
46
47
|
"prettier": {
|
|
47
48
|
"trailingComma": "all"
|
|
48
49
|
},
|
|
49
50
|
"eslintConfig": {
|
|
50
|
-
"parser": "@typescript-eslint/parser",
|
|
51
|
-
"plugins": [
|
|
52
|
-
"@typescript-eslint"
|
|
53
|
-
],
|
|
54
51
|
"extends": [
|
|
55
|
-
"eslint:recommended"
|
|
56
|
-
"plugin:@typescript-eslint/recommended"
|
|
52
|
+
"eslint:recommended"
|
|
57
53
|
],
|
|
58
|
-
"
|
|
59
|
-
|
|
60
|
-
"
|
|
61
|
-
|
|
62
|
-
"
|
|
54
|
+
"overrides": [
|
|
55
|
+
{
|
|
56
|
+
"files": [
|
|
57
|
+
"**/*.ts",
|
|
58
|
+
"**/*.tsx"
|
|
59
|
+
],
|
|
60
|
+
"parser": "@typescript-eslint/parser",
|
|
61
|
+
"plugins": [
|
|
62
|
+
"@typescript-eslint"
|
|
63
|
+
],
|
|
64
|
+
"extends": [
|
|
65
|
+
"eslint:recommended",
|
|
66
|
+
"plugin:@typescript-eslint/recommended"
|
|
67
|
+
],
|
|
68
|
+
"rules": {
|
|
69
|
+
"@typescript-eslint/ban-ts-comment": [
|
|
70
|
+
"warn",
|
|
71
|
+
{
|
|
72
|
+
"ts-ignore": "allow-with-description"
|
|
73
|
+
}
|
|
74
|
+
]
|
|
63
75
|
}
|
|
64
|
-
|
|
65
|
-
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"files": "**/*.js",
|
|
79
|
+
"env": {
|
|
80
|
+
"node": true
|
|
81
|
+
},
|
|
82
|
+
"parser": "espree",
|
|
83
|
+
"parserOptions": {
|
|
84
|
+
"ecmaVersion": 2019
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
]
|
|
66
88
|
},
|
|
67
89
|
"jest": {
|
|
68
90
|
"transform": {
|
|
69
91
|
"^.+\\.(t|j)sx?$": [
|
|
70
|
-
"@swc/jest"
|
|
92
|
+
"@swc/jest",
|
|
93
|
+
{
|
|
94
|
+
"sourceMaps": true,
|
|
95
|
+
"jsc": {
|
|
96
|
+
"parser": {
|
|
97
|
+
"syntax": "typescript"
|
|
98
|
+
},
|
|
99
|
+
"paths": {
|
|
100
|
+
"iron-session": [
|
|
101
|
+
"../src/index.ts"
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
71
106
|
]
|
|
72
107
|
}
|
|
73
108
|
},
|
|
@@ -75,24 +110,24 @@
|
|
|
75
110
|
"@hapi/iron": "^6.0.0",
|
|
76
111
|
"@types/cookie": "^0.4.0",
|
|
77
112
|
"@types/express": "^4.17.13",
|
|
78
|
-
"@types/node": "^16.11.
|
|
79
|
-
"cookie": "^0.4.1"
|
|
80
|
-
"iron-store": "^1.3.5"
|
|
113
|
+
"@types/node": "^16.11.6",
|
|
114
|
+
"cookie": "^0.4.1"
|
|
81
115
|
},
|
|
82
116
|
"devDependencies": {
|
|
83
|
-
"@swc/core": "^1.2.
|
|
84
|
-
"@swc/
|
|
117
|
+
"@swc/core": "^1.2.104",
|
|
118
|
+
"@swc/core-darwin-x64": "^1.2.104",
|
|
119
|
+
"@swc/jest": "0.2.5",
|
|
85
120
|
"@tsconfig/node12": "1.0.9",
|
|
86
|
-
"@types/jest": "27.0.2",
|
|
87
|
-
"@typescript-eslint/eslint-plugin": "5.
|
|
88
|
-
"@typescript-eslint/parser": "5.
|
|
89
|
-
"
|
|
121
|
+
"@types/jest": "^27.0.2",
|
|
122
|
+
"@typescript-eslint/eslint-plugin": "5.2.0",
|
|
123
|
+
"@typescript-eslint/parser": "5.2.0",
|
|
124
|
+
"concurrently": "6.3.0",
|
|
125
|
+
"eslint": "^8.1.0",
|
|
90
126
|
"jest": "27.3.1",
|
|
91
|
-
"jest-date-mock": "1.0.8",
|
|
92
127
|
"prettier": "2.4.1",
|
|
93
128
|
"prettier-plugin-packagejson": "2.2.13",
|
|
94
129
|
"rimraf": "3.0.2",
|
|
95
|
-
"tsup": "5.
|
|
130
|
+
"tsup": "5.5.0",
|
|
96
131
|
"typescript": "4.4.4"
|
|
97
132
|
},
|
|
98
133
|
"peerDependencies": {
|
package/dist/index.mjs
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
// src/index.ts
|
|
2
|
-
import Iron from "@hapi/iron";
|
|
3
|
-
import {
|
|
4
|
-
parse as parseCookie,
|
|
5
|
-
serialize as serializeCookie
|
|
6
|
-
} from "cookie";
|
|
7
|
-
var timestampSkewSec = 60;
|
|
8
|
-
var defaultOptions = {
|
|
9
|
-
ttl: 15 * 24 * 3600,
|
|
10
|
-
cookieOptions: {
|
|
11
|
-
httpOnly: true,
|
|
12
|
-
secure: true,
|
|
13
|
-
sameSite: "lax",
|
|
14
|
-
path: "/"
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
async function getIronSession(req, res, userSessionOptions) {
|
|
18
|
-
if (!req || !res || !userSessionOptions || !userSessionOptions.cookieName || !userSessionOptions.password) {
|
|
19
|
-
throw new Error(`iron-session: Bad usage. Minimum usage is const session = await getIronSession(req, res, { cookieName: "...", password: "...". Check the usage here: https://github.com/vvo/iron-session`);
|
|
20
|
-
}
|
|
21
|
-
const passwordsAsMap = typeof userSessionOptions.password === "string" ? { 1: userSessionOptions.password } : userSessionOptions.password;
|
|
22
|
-
Object.values(passwordsAsMap).forEach((password) => {
|
|
23
|
-
if (password.length < 32) {
|
|
24
|
-
throw new Error(`iron-session: Bad usage. Password must be at least 32 characters long.`);
|
|
25
|
-
}
|
|
26
|
-
});
|
|
27
|
-
const options = {
|
|
28
|
-
...defaultOptions,
|
|
29
|
-
...userSessionOptions,
|
|
30
|
-
cookieOptions: {
|
|
31
|
-
...defaultOptions.cookieOptions,
|
|
32
|
-
...userSessionOptions.cookieOptions || {}
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
if (!req.socket.encrypted && options.cookieOptions.secure === true) {
|
|
36
|
-
throw new Error(`iron-session: Can't use secure cookies when not in https. See usage at https://github.com/vvo/iron-session/`);
|
|
37
|
-
}
|
|
38
|
-
if (options.ttl === 0) {
|
|
39
|
-
options.ttl = 2147483647;
|
|
40
|
-
}
|
|
41
|
-
if (userSessionOptions.cookieOptions && "maxAge" in userSessionOptions.cookieOptions) {
|
|
42
|
-
if (userSessionOptions.cookieOptions.maxAge === void 0) {
|
|
43
|
-
options.ttl = 0;
|
|
44
|
-
} else {
|
|
45
|
-
options.cookieOptions.maxAge = computeCookieMaxAge(userSessionOptions.cookieOptions.maxAge);
|
|
46
|
-
}
|
|
47
|
-
} else {
|
|
48
|
-
options.cookieOptions.maxAge = computeCookieMaxAge(options.ttl);
|
|
49
|
-
}
|
|
50
|
-
const sealFromCookies = parseCookie(req.headers.cookie || "")[options.cookieName];
|
|
51
|
-
const sessionData = await unsealSession(sealFromCookies, passwordsAsMap, options.ttl * 1e3);
|
|
52
|
-
const session = Object.defineProperties(sessionData, {
|
|
53
|
-
save: {
|
|
54
|
-
value: async function save() {
|
|
55
|
-
if (res.headersSent === true) {
|
|
56
|
-
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()`);
|
|
57
|
-
}
|
|
58
|
-
const seal = await sealSession(sessionData, passwordsAsMap, options.ttl * 1e3);
|
|
59
|
-
const cookieValue = serializeCookie(options.cookieName, seal, options.cookieOptions);
|
|
60
|
-
if (cookieValue.length > 4096) {
|
|
61
|
-
throw new Error(`iron-session: Cookie length is too big ${cookieValue.length}, browsers will refuse it. Try to remove some data.`);
|
|
62
|
-
}
|
|
63
|
-
addToCookies(cookieValue, res);
|
|
64
|
-
return cookieValue;
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
destroy: {
|
|
68
|
-
value: function destroy() {
|
|
69
|
-
const cookieValue = serializeCookie(options.cookieName, "", {
|
|
70
|
-
...options.cookieOptions,
|
|
71
|
-
maxAge: 0
|
|
72
|
-
});
|
|
73
|
-
addToCookies(cookieValue, res);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
return session;
|
|
78
|
-
}
|
|
79
|
-
function addToCookies(cookieValue, res) {
|
|
80
|
-
var _a;
|
|
81
|
-
let existingSetCookie = (_a = res.getHeader("set-cookie")) != null ? _a : [];
|
|
82
|
-
if (typeof existingSetCookie === "string") {
|
|
83
|
-
existingSetCookie = [existingSetCookie];
|
|
84
|
-
}
|
|
85
|
-
res.setHeader("set-cookie", [...existingSetCookie, cookieValue]);
|
|
86
|
-
}
|
|
87
|
-
function computeCookieMaxAge(ttl) {
|
|
88
|
-
return ttl - timestampSkewSec;
|
|
89
|
-
}
|
|
90
|
-
async function unsealSession(seal, password, ttl) {
|
|
91
|
-
try {
|
|
92
|
-
await Iron.unseal(seal, password, {
|
|
93
|
-
...Iron.defaults,
|
|
94
|
-
ttl
|
|
95
|
-
});
|
|
96
|
-
} catch (error) {
|
|
97
|
-
if (error instanceof Error) {
|
|
98
|
-
if (error.message === "Expired seal" || error.message === "Bad hmac value" || error.message === "Cannot find password: " || error.message === "Incorrect number of sealed components") {
|
|
99
|
-
return {};
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
throw error;
|
|
103
|
-
}
|
|
104
|
-
return {};
|
|
105
|
-
}
|
|
106
|
-
async function sealSession(data, password, ttl) {
|
|
107
|
-
const mostRecentPasswordId = Math.max(...Object.keys(password).map((id) => parseInt(id, 10)));
|
|
108
|
-
const seal = await Iron.seal(data, password[mostRecentPasswordId], {
|
|
109
|
-
...Iron.defaults,
|
|
110
|
-
ttl
|
|
111
|
-
});
|
|
112
|
-
return seal;
|
|
113
|
-
}
|
|
114
|
-
export {
|
|
115
|
-
getIronSession,
|
|
116
|
-
sealSession,
|
|
117
|
-
unsealSession
|
|
118
|
-
};
|
|
119
|
-
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["import Iron from \"@hapi/iron\";\nimport {\n parse as parseCookie,\n serialize as serializeCookie,\n CookieSerializeOptions,\n} from \"cookie\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport { TLSSocket } from \"tls\";\n\n// default time allowed to check for iron seal validity when ttl passed\n// see https://hapi.dev/family/iron/api/?v=6.0.0#options\nconst timestampSkewSec = 60;\n\ntype passwordsMap = { [id: number]: string };\ntype password = string | passwordsMap;\n\nconst defaultOptions: {\n ttl: number;\n cookieOptions: CookieSerializeOptions;\n} = {\n ttl: 15 * 24 * 3600,\n cookieOptions: {\n httpOnly: true,\n secure: true,\n sameSite: \"lax\",\n path: \"/\",\n },\n};\n\nexport interface IronSessionOptions {\n cookieName: string;\n password: password;\n ttl?: number;\n cookieOptions?: CookieSerializeOptions;\n}\n\ndeclare module \"iron-session\" {\n interface IronSessionData {\n [key: string]: unknown;\n }\n}\n\ndeclare module \"http\" {\n interface IncomingMessage {\n /**\n * This request's `Session` object.\n * Even though this property isn't marked as optional, it won't exist until you use the `express-session` middleware\n * [Declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) can be used to add your own properties.\n *\n * @see SessionData\n */\n session: IronSession;\n }\n}\ninterface IronSessionBase {\n destroy: () => void;\n save: () => Promise<void>;\n}\n\nexport type IronSession<T = IronSessionData> = T & IronSessionBase;\n\ndeclare module \"http\" {\n interface IncomingMessage {\n /**\n * This request's `Session` object.\n * Even though this property isn't marked as optional, it won't exist until you use the `express-session` middleware\n * [Declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) can be used to add your own properties.\n *\n * @see SessionData\n */\n session: IronSession<IronSessionData>;\n }\n}\n\nexport async function getIronSession<T = IronSessionData>(\n req: IncomingMessage,\n res: ServerResponse,\n userSessionOptions: IronSessionOptions,\n): Promise<IronSession<Partial<T>>> {\n if (\n !req ||\n !res ||\n !userSessionOptions ||\n !userSessionOptions.cookieName ||\n !userSessionOptions.password\n ) {\n throw new Error(\n `iron-session: Bad usage. Minimum usage is const session = await getIronSession(req, res, { cookieName: \"...\", password: \"...\". Check the usage here: https://github.com/vvo/iron-session`,\n );\n }\n\n const passwordsAsMap =\n typeof userSessionOptions.password === \"string\"\n ? { 1: userSessionOptions.password }\n : userSessionOptions.password;\n\n Object.values(passwordsAsMap).forEach((password) => {\n if (password.length < 32) {\n throw new Error(\n `iron-session: Bad usage. Password must be at least 32 characters long.`,\n );\n }\n });\n\n const options: Required<IronSessionOptions> = {\n ...defaultOptions,\n ...userSessionOptions,\n cookieOptions: {\n ...defaultOptions.cookieOptions,\n ...(userSessionOptions.cookieOptions || {}),\n },\n };\n\n if (\n !(req.socket as TLSSocket).encrypted &&\n options.cookieOptions.secure === true\n ) {\n throw new Error(\n `iron-session: Can't use secure cookies when not in https. See usage at https://github.com/vvo/iron-session/`,\n );\n }\n\n if (options.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 options.ttl = 2147483647;\n }\n\n if (\n userSessionOptions.cookieOptions &&\n \"maxAge\" in userSessionOptions.cookieOptions\n ) {\n // session cookie, do not set maxAge, consider token as infinite\n if (userSessionOptions.cookieOptions.maxAge === undefined) {\n options.ttl = 0;\n } else {\n options.cookieOptions.maxAge = computeCookieMaxAge(\n userSessionOptions.cookieOptions.maxAge,\n );\n }\n } else {\n options.cookieOptions.maxAge = computeCookieMaxAge(options.ttl);\n }\n\n const sealFromCookies = parseCookie(req.headers.cookie || \"\")[\n options.cookieName\n ];\n\n const sessionData = await unsealSession(\n sealFromCookies,\n passwordsAsMap,\n options.ttl * 1000,\n );\n\n const session = Object.defineProperties(sessionData, {\n save: {\n value: async function save() {\n if (res.headersSent === true) {\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 const seal = await sealSession(\n sessionData,\n passwordsAsMap,\n options.ttl * 1000,\n );\n const cookieValue = serializeCookie(\n options.cookieName,\n seal,\n options.cookieOptions,\n );\n\n if (cookieValue.length > 4096) {\n throw new Error(\n `iron-session: Cookie length is too big ${cookieValue.length}, browsers will refuse it. Try to remove some data.`,\n );\n }\n\n addToCookies(cookieValue, res);\n return cookieValue;\n },\n },\n destroy: {\n value: function destroy() {\n const cookieValue = serializeCookie(options.cookieName, \"\", {\n ...options.cookieOptions,\n maxAge: 0,\n });\n addToCookies(cookieValue, res);\n },\n },\n }) as IronSession<Partial<T>>;\n\n return session;\n}\n\nfunction addToCookies(cookieValue: string, res: ServerResponse) {\n let existingSetCookie =\n (res.getHeader(\"set-cookie\") as string[] | string) ?? [];\n if (typeof existingSetCookie === \"string\") {\n existingSetCookie = [existingSetCookie];\n }\n res.setHeader(\"set-cookie\", [...existingSetCookie, cookieValue]);\n}\n\nfunction computeCookieMaxAge(ttl: number) {\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 maximum between server and clients.\n // It also makes sure to expire the cookie immediately when value is 0\n return ttl - timestampSkewSec;\n}\n\nexport async function unsealSession(\n seal: string,\n password: passwordsMap,\n ttl: number,\n): Promise<IronSessionData> {\n try {\n await Iron.unseal(seal, password, {\n ...Iron.defaults,\n ttl,\n });\n } catch (error) {\n if (error instanceof Error) {\n if (\n error.message === \"Expired seal\" ||\n error.message === \"Bad hmac value\" ||\n error.message === \"Cannot find password: \" ||\n error.message === \"Incorrect number of sealed components\"\n ) {\n // if seal expired or\n // if seal is not valid (encrypted using a different password, when passwords are updated) or\n // if we can't find back the password in the seal\n // then we just start a new session over\n return {};\n }\n }\n\n throw error;\n }\n\n return {};\n}\n\nexport async function sealSession(\n data: Record<string, unknown>,\n password: passwordsMap,\n ttl: number,\n) {\n const mostRecentPasswordId = Math.max(\n ...Object.keys(password).map((id) => parseInt(id, 10)),\n );\n\n const seal = await Iron.seal(data, password[mostRecentPasswordId], {\n ...Iron.defaults,\n ttl,\n });\n\n return seal;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/next/dist/index.mjs
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
// next/index.ts
|
|
2
|
-
import { getIronSession } from "iron-session";
|
|
3
|
-
function withIronSessionApiRoute(handler, options) {
|
|
4
|
-
return async function nextApiHandlerWrappedWithIronSession(req, res) {
|
|
5
|
-
const session = await getIronSession(req, res, options);
|
|
6
|
-
Object.defineProperty(req, "session", {
|
|
7
|
-
enumerable: true,
|
|
8
|
-
value: session
|
|
9
|
-
});
|
|
10
|
-
return handler(req, res);
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
export {
|
|
14
|
-
withIronSessionApiRoute
|
|
15
|
-
};
|
|
16
|
-
//# sourceMappingURL=index.mjs.map
|
package/next/dist/index.mjs.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../index.ts"],
|
|
4
|
-
"sourcesContent": ["import type { NextApiHandler } from \"next\";\nimport type { IronSessionData, IronSessionOptions } from \"iron-session\";\nimport { getIronSession } from \"iron-session\";\n\nexport function withIronSessionApiRoute<T = IronSessionData>(\n handler: NextApiHandler,\n options: IronSessionOptions,\n): NextApiHandler {\n return async function nextApiHandlerWrappedWithIronSession(req, res) {\n const session = await getIronSession<T>(req, res, options);\n Object.defineProperty(req, \"session\", {\n enumerable: true,\n value: session,\n });\n return handler(req, res);\n };\n}\n\n// export function withIronSessionSsr<P = unknown>(\n// handler: NextGetServerSidePropsHandlerWithIronSession<P>,\n// options: IronSessionOptions,\n// ): NextGetServerSidePropsHandlerWithIronSession<P> {\n// return async function nextGetServerSidePropsHandlerWrappedWithIronSession(\n// context: NextGetServerSideContextWithIronSession,\n// ) {\n// context.req.session = await getIronSession(\n// context.req,\n// context.res,\n// options,\n// );\n// return handler(context);\n// };\n// }\n"],
|
|
5
|
-
"mappings": ";AAEA;AAEO,iCACL,SACA,SACgB;AAChB,SAAO,oDAAoD,KAAK,KAAK;AACnE,UAAM,UAAU,MAAM,eAAkB,KAAK,KAAK;AAClD,WAAO,eAAe,KAAK,WAAW;AAAA,MACpC,YAAY;AAAA,MACZ,OAAO;AAAA;AAET,WAAO,QAAQ,KAAK;AAAA;AAAA;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|