iron-session 1.0.3 → 2.0.0-alpha.10
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/LICENSE +16 -4
- package/README.md +66 -77
- package/dist/index.d.ts +29 -0
- package/dist/index.js +127 -0
- package/dist/index.js.map +7 -0
- package/dist/index.mjs +99 -0
- package/dist/index.mjs.map +7 -0
- package/next/dist/index.d.ts +15 -0
- package/next/dist/index.js +48 -0
- package/next/dist/index.js.map +7 -0
- package/next/dist/index.mjs +19 -0
- package/next/dist/index.mjs.map +7 -0
- package/package.json +112 -53
- package/index.dist.js +0 -103
- package/index.dist.js.map +0 -1
package/LICENSE
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2021 Vincent Voyer
|
|
4
4
|
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
6
11
|
|
|
7
|
-
The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
8
14
|
|
|
9
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,114 +1,103 @@
|
|
|
1
|
-
#
|
|
1
|
+
# TSDX User Guide
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Congrats! You just saved yourself hours of work by bootstrapping this project with TSDX. Let’s get you oriented with what’s here and how to use it.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> This TSDX setup is meant for developing libraries (not apps!) that can be published to NPM. If you’re looking to build a Node app, you could use `ts-node-dev`, plain `ts-node`, or simple `tsc`.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
> If you’re new to TypeScript, checkout [this handy cheatsheet](https://devhints.io/typescript)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## Commands
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
TSDX scaffolds your new library inside `/src`.
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
- application not supporting cookies won't work, this could be solved in the future by exposing the underlying token instead of signed and encrypted cookies. Open an issue if you're interested.
|
|
15
|
-
- on most browsers, you're limited to 4,096 bytes per cookie. To give you an idea, an `iron-session` containing `{user: {id: 230, admin: true}}` is 358 bytes signed and encrypted: still plenty of available cookie space in here.
|
|
13
|
+
To run TSDX, use:
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
```bash
|
|
16
|
+
npm start # or yarn start
|
|
17
|
+
```
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
This builds to `/dist` and runs the project in watch mode so any edits you save inside `src` causes a rebuild to `/dist`.
|
|
20
20
|
|
|
21
|
-
-
|
|
22
|
-
- https://owasp.org/www-project-cheat-sheets/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#encryption-based-token-pattern
|
|
21
|
+
To do a one-off build, use `npm run build` or `yarn build`.
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
To run tests, use `npm test` or `yarn test`.
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
## Configuration
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
- JWT tokens are not encrypted, the payload is visible by customers if they manage to inspect the token. You would have to use [JWE](https://tools.ietf.org/html/rfc7516) to achieve the same.
|
|
30
|
-
- @hapi/iron mechanism is not a standard, it's a way to sign and encrypt data into tokens
|
|
27
|
+
Code quality is set up for you with `prettier`, `husky`, and `lint-staged`. Adjust the respective fields in `package.json` accordingly.
|
|
31
28
|
|
|
32
|
-
|
|
29
|
+
### Jest
|
|
33
30
|
|
|
34
|
-
|
|
31
|
+
Jest tests are set up to run with `npm test` or `yarn test`.
|
|
35
32
|
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
### Bundle Analysis
|
|
34
|
+
|
|
35
|
+
[`size-limit`](https://github.com/ai/size-limit) is set up to calculate the real cost of your library with `npm run size` and visualize the bundle with `npm run analyze`.
|
|
36
|
+
|
|
37
|
+
#### Setup Files
|
|
38
|
+
|
|
39
|
+
This is the folder structure we set up for you:
|
|
40
|
+
|
|
41
|
+
```txt
|
|
42
|
+
/src
|
|
43
|
+
index.tsx # EDIT THIS
|
|
44
|
+
/test
|
|
45
|
+
blah.test.tsx # EDIT THIS
|
|
46
|
+
.gitignore
|
|
47
|
+
package.json
|
|
48
|
+
README.md # EDIT THIS
|
|
49
|
+
tsconfig.json
|
|
38
50
|
```
|
|
39
51
|
|
|
40
|
-
|
|
52
|
+
### Rollup
|
|
41
53
|
|
|
42
|
-
|
|
54
|
+
TSDX uses [Rollup](https://rollupjs.org) as a bundler and generates multiple rollup configs for various module formats and build settings. See [Optimizations](#optimizations) for details.
|
|
43
55
|
|
|
44
|
-
|
|
56
|
+
### TypeScript
|
|
45
57
|
|
|
46
|
-
|
|
58
|
+
`tsconfig.json` is set up to interpret `dom` and `esnext` types, as well as `react` for `jsx`. Adjust according to your needs.
|
|
47
59
|
|
|
48
|
-
|
|
49
|
-
import { createSession } from "iron-session";
|
|
50
|
-
export default async (req, res) => {
|
|
51
|
-
// when user successfully logs in using email/password, oauth, ... then we create a session
|
|
52
|
-
// const user = ...
|
|
60
|
+
## Continuous Integration
|
|
53
61
|
|
|
54
|
-
|
|
55
|
-
password: process.env.SECRET_SESSION_PASSWORD
|
|
56
|
-
});
|
|
62
|
+
### GitHub Actions
|
|
57
63
|
|
|
58
|
-
|
|
59
|
-
session.set({ name: "message", value: "Login success", flash: true });
|
|
64
|
+
Two actions are added by default:
|
|
60
65
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
});
|
|
66
|
+
- `main` which installs deps w/ cache, lints, tests, and builds on all pushes against a Node and OS matrix
|
|
67
|
+
- `size` which comments cost comparison of your library on every pull request using [`size-limit`](https://github.com/ai/size-limit)
|
|
64
68
|
|
|
65
|
-
|
|
66
|
-
};
|
|
67
|
-
```
|
|
69
|
+
## Optimizations
|
|
68
70
|
|
|
69
|
-
|
|
71
|
+
Please see the main `tsdx` [optimizations docs](https://github.com/palmerhq/tsdx#optimizations). In particular, know that you can take advantage of development-only optimizations:
|
|
70
72
|
|
|
71
73
|
```js
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
// ./types/index.d.ts
|
|
75
|
+
declare var __DEV__: boolean;
|
|
76
|
+
|
|
77
|
+
// inside your code...
|
|
78
|
+
if (__DEV__) {
|
|
79
|
+
console.log('foo');
|
|
77
80
|
}
|
|
78
81
|
```
|
|
79
82
|
|
|
80
|
-
|
|
83
|
+
You can also choose to install and use [invariant](https://github.com/palmerhq/tsdx#invariant) and [warning](https://github.com/palmerhq/tsdx#warning) functions.
|
|
81
84
|
|
|
82
|
-
|
|
83
|
-
import { getSession, parseCookie } from "iron-session";
|
|
84
|
-
export default async (req, res) => {
|
|
85
|
-
const session = await getSession({
|
|
86
|
-
password: process.env.SECRET_SESSION_PASSWORD,
|
|
87
|
-
sealed: parseCookie({ cookie: req.getHeader("cookie") })
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
const user = session.get({ name: "user" });
|
|
91
|
-
const flashMessage = session.get({ name: "message" });
|
|
92
|
-
|
|
93
|
-
res.end("ok");
|
|
94
|
-
};
|
|
95
|
-
```
|
|
85
|
+
## Module Formats
|
|
96
86
|
|
|
97
|
-
|
|
87
|
+
CJS, ESModules, and UMD module formats are supported.
|
|
98
88
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
```
|
|
89
|
+
The appropriate paths are configured in `package.json` and `dist/index.js` accordingly. Please report if any issues are found.
|
|
90
|
+
|
|
91
|
+
## Named Exports
|
|
92
|
+
|
|
93
|
+
Per Palmer Group guidelines, [always use named exports.](https://github.com/palmerhq/typescript#exports) Code split inside your React app instead of your React library.
|
|
94
|
+
|
|
95
|
+
## Including Styles
|
|
96
|
+
|
|
97
|
+
There are many ways to ship styles, including with CSS-in-JS. TSDX has no opinion on this, configure how you like.
|
|
109
98
|
|
|
110
|
-
|
|
99
|
+
For vanilla CSS, you can include it at the root directory and add it to the `files` section in your `package.json`, so that it can be imported separately by your users and run through their bundler's loader.
|
|
111
100
|
|
|
112
|
-
|
|
101
|
+
## Publishing to NPM
|
|
113
102
|
|
|
114
|
-
|
|
103
|
+
We recommend using [np](https://github.com/sindresorhus/np).
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { CookieSerializeOptions } from 'cookie';
|
|
2
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
3
|
+
|
|
4
|
+
declare type password = string | {
|
|
5
|
+
id: number;
|
|
6
|
+
password: string;
|
|
7
|
+
}[];
|
|
8
|
+
interface IronSessionOptions {
|
|
9
|
+
cookieName: string;
|
|
10
|
+
password: password;
|
|
11
|
+
ttl?: number;
|
|
12
|
+
cookieOptions?: CookieSerializeOptions;
|
|
13
|
+
}
|
|
14
|
+
interface IronSession {
|
|
15
|
+
set: <T = unknown>(name: string, value: T) => T;
|
|
16
|
+
get: <T = unknown>(name: string) => T | undefined;
|
|
17
|
+
unset: (name: string) => void;
|
|
18
|
+
destroy: () => void;
|
|
19
|
+
save: () => Promise<string>;
|
|
20
|
+
}
|
|
21
|
+
declare function getIronSession<RequestType extends IncomingMessage, ResponseType extends ServerResponse>(req: RequestType, res: ResponseType, userOptions: IronSessionOptions): Promise<{
|
|
22
|
+
set: <T = any>(name: string, value: T) => T;
|
|
23
|
+
get: (name?: string | undefined) => any;
|
|
24
|
+
unset: (name: string) => void;
|
|
25
|
+
save(): Promise<string>;
|
|
26
|
+
destroy(): void;
|
|
27
|
+
}>;
|
|
28
|
+
|
|
29
|
+
export { IronSession, IronSessionOptions, getIronSession };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
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
|
+
});
|
|
29
|
+
var import_iron_store = __toModule(require("iron-store"));
|
|
30
|
+
var import_cookie = __toModule(require("cookie"));
|
|
31
|
+
var timestampSkewSec = 60;
|
|
32
|
+
var defaultOptions = {
|
|
33
|
+
ttl: 15 * 24 * 3600,
|
|
34
|
+
cookieOptions: {
|
|
35
|
+
httpOnly: true,
|
|
36
|
+
secure: true,
|
|
37
|
+
sameSite: "lax",
|
|
38
|
+
path: "/"
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
async function getIronSession(req, res, userOptions) {
|
|
42
|
+
var _a, _b;
|
|
43
|
+
if (!req || !res || !userOptions || !userOptions.cookieName || !userOptions.password) {
|
|
44
|
+
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`);
|
|
45
|
+
}
|
|
46
|
+
const passwordAsAnArray = Array.isArray(userOptions.password) ? userOptions.password : [{ id: 1, password: userOptions.password }];
|
|
47
|
+
passwordAsAnArray.forEach(({ password }) => {
|
|
48
|
+
if (password.length < 32) {
|
|
49
|
+
throw new Error(`iron-session: Bad usage. Password must be at least 32 characters long.`);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
const options = {
|
|
53
|
+
...defaultOptions,
|
|
54
|
+
...userOptions,
|
|
55
|
+
cookieOptions: {
|
|
56
|
+
...defaultOptions.cookieOptions,
|
|
57
|
+
...userOptions.cookieOptions || {}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
if (options.ttl === 0) {
|
|
61
|
+
options.ttl = 2147483647;
|
|
62
|
+
}
|
|
63
|
+
options.cookieOptions.maxAge = computeCookieMaxAge((_b = (_a = userOptions.cookieOptions) == null ? void 0 : _a.maxAge) != null ? _b : options.ttl);
|
|
64
|
+
const store = await getOrCreateStore({
|
|
65
|
+
sealed: import_cookie.default.parse(req.headers.cookie || "")[options.cookieName],
|
|
66
|
+
password: passwordAsAnArray,
|
|
67
|
+
ttl: options.ttl * 1e3
|
|
68
|
+
});
|
|
69
|
+
return {
|
|
70
|
+
set: store.set,
|
|
71
|
+
get: store.get,
|
|
72
|
+
unset: store.unset,
|
|
73
|
+
async save() {
|
|
74
|
+
const seal = await store.seal();
|
|
75
|
+
const cookieValue = import_cookie.default.serialize(options.cookieName, seal, options.cookieOptions);
|
|
76
|
+
if (cookieValue.length > 4096) {
|
|
77
|
+
throw new Error(`iron-session: Cookie length is too big ${cookieValue.length}, browsers will refuse it. Try to remove some data.`);
|
|
78
|
+
}
|
|
79
|
+
addToCookies(cookieValue, res);
|
|
80
|
+
return cookieValue;
|
|
81
|
+
},
|
|
82
|
+
destroy() {
|
|
83
|
+
store.clear();
|
|
84
|
+
const cookieValue = import_cookie.default.serialize(options.cookieName, "", {
|
|
85
|
+
...options.cookieOptions,
|
|
86
|
+
maxAge: 0
|
|
87
|
+
});
|
|
88
|
+
addToCookies(cookieValue, res);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function addToCookies(cookieValue, res) {
|
|
93
|
+
var _a;
|
|
94
|
+
let existingSetCookie = (_a = res.getHeader("set-cookie")) != null ? _a : [];
|
|
95
|
+
if (typeof existingSetCookie === "string") {
|
|
96
|
+
existingSetCookie = [existingSetCookie];
|
|
97
|
+
}
|
|
98
|
+
res.setHeader("set-cookie", [...existingSetCookie, cookieValue]);
|
|
99
|
+
}
|
|
100
|
+
function computeCookieMaxAge(ttl) {
|
|
101
|
+
return ttl - timestampSkewSec;
|
|
102
|
+
}
|
|
103
|
+
async function getOrCreateStore({
|
|
104
|
+
sealed,
|
|
105
|
+
password,
|
|
106
|
+
ttl
|
|
107
|
+
}) {
|
|
108
|
+
try {
|
|
109
|
+
return await (0, import_iron_store.default)({
|
|
110
|
+
sealed,
|
|
111
|
+
password,
|
|
112
|
+
ttl
|
|
113
|
+
});
|
|
114
|
+
} catch (error) {
|
|
115
|
+
if (error instanceof Error) {
|
|
116
|
+
if (error.message === "Expired seal" || error.message === "Bad hmac value" || error.message === "Cannot find password: ") {
|
|
117
|
+
return await (0, import_iron_store.default)({ password, ttl });
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
124
|
+
0 && (module.exports = {
|
|
125
|
+
getIronSession
|
|
126
|
+
});
|
|
127
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts"],
|
|
4
|
+
"sourcesContent": ["import ironStore from \"iron-store\";\nimport cookie, { CookieSerializeOptions } from \"cookie\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\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 password = string | { id: number; password: string }[];\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\nexport interface IronSession {\n set: <T = unknown>(name: string, value: T) => T;\n get: <T = unknown>(name: string) => T | undefined;\n unset: (name: string) => void;\n destroy: () => void;\n save: () => Promise<string>;\n}\n\nexport async function getIronSession<\n RequestType extends IncomingMessage,\n ResponseType extends ServerResponse,\n>(req: RequestType, res: ResponseType, userOptions: IronSessionOptions) {\n if (\n !req ||\n !res ||\n !userOptions ||\n !userOptions.cookieName ||\n !userOptions.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 passwordAsAnArray = Array.isArray(userOptions.password)\n ? userOptions.password\n : [{ id: 1, password: userOptions.password }];\n\n passwordAsAnArray.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 ...userOptions,\n cookieOptions: {\n ...defaultOptions.cookieOptions,\n ...(userOptions.cookieOptions || {}),\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 options.cookieOptions.maxAge = computeCookieMaxAge(\n userOptions.cookieOptions?.maxAge ?? options.ttl,\n );\n\n const store = await getOrCreateStore({\n sealed: cookie.parse(req.headers.cookie || \"\")[options.cookieName],\n password: passwordAsAnArray,\n ttl: options.ttl * 1000,\n });\n\n return {\n set: store.set,\n get: store.get,\n unset: store.unset,\n async save() {\n const seal = await store.seal();\n const cookieValue = cookie.serialize(\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 destroy() {\n store.clear();\n const cookieValue = cookie.serialize(options.cookieName, \"\", {\n ...options.cookieOptions,\n maxAge: 0,\n });\n addToCookies(cookieValue, res);\n },\n };\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\nasync function getOrCreateStore({\n sealed,\n password,\n ttl,\n}: {\n sealed: string;\n password: password;\n ttl: number;\n}) {\n try {\n return await ironStore({\n sealed,\n password,\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 ) {\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 await ironStore({ password, ttl });\n }\n }\n\n throw error;\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,wBAAsB;AACtB,oBAA+C;AAK/C,IAAM,mBAAmB;AAIzB,IAAM,iBAGF;AAAA,EACF,KAAK,KAAK,KAAK;AAAA,EACf,eAAe;AAAA,IACb,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,MAAM;AAAA;AAAA;AAmBV,8BAGE,KAAkB,KAAmB,aAAiC;AAzCxE;AA0CE,MACE,CAAC,OACD,CAAC,OACD,CAAC,eACD,CAAC,YAAY,cACb,CAAC,YAAY,UACb;AACA,UAAM,IAAI,MACR;AAAA;AAIJ,QAAM,oBAAoB,MAAM,QAAQ,YAAY,YAChD,YAAY,WACZ,CAAC,EAAE,IAAI,GAAG,UAAU,YAAY;AAEpC,oBAAkB,QAAQ,CAAC,EAAE,eAAe;AAC1C,QAAI,SAAS,SAAS,IAAI;AACxB,YAAM,IAAI,MACR;AAAA;AAAA;AAKN,QAAM,UAAwC;AAAA,OACzC;AAAA,OACA;AAAA,IACH,eAAe;AAAA,SACV,eAAe;AAAA,SACd,YAAY,iBAAiB;AAAA;AAAA;AAIrC,MAAI,QAAQ,QAAQ,GAAG;AAKrB,YAAQ,MAAM;AAAA;AAGhB,UAAQ,cAAc,SAAS,oBAC7B,wBAAY,kBAAZ,mBAA2B,WAA3B,YAAqC,QAAQ;AAG/C,QAAM,QAAQ,MAAM,iBAAiB;AAAA,IACnC,QAAQ,sBAAO,MAAM,IAAI,QAAQ,UAAU,IAAI,QAAQ;AAAA,IACvD,UAAU;AAAA,IACV,KAAK,QAAQ,MAAM;AAAA;AAGrB,SAAO;AAAA,IACL,KAAK,MAAM;AAAA,IACX,KAAK,MAAM;AAAA,IACX,OAAO,MAAM;AAAA,UACP,OAAO;AACX,YAAM,OAAO,MAAM,MAAM;AACzB,YAAM,cAAc,sBAAO,UACzB,QAAQ,YACR,MACA,QAAQ;AAGV,UAAI,YAAY,SAAS,MAAM;AAC7B,cAAM,IAAI,MACR,0CAA0C,YAAY;AAAA;AAI1D,mBAAa,aAAa;AAC1B,aAAO;AAAA;AAAA,IAET,UAAU;AACR,YAAM;AACN,YAAM,cAAc,sBAAO,UAAU,QAAQ,YAAY,IAAI;AAAA,WACxD,QAAQ;AAAA,QACX,QAAQ;AAAA;AAEV,mBAAa,aAAa;AAAA;AAAA;AAAA;AAKhC,sBAAsB,aAAqB,KAAqB;AA7HhE;AA8HE,MAAI,oBACD,UAAI,UAAU,kBAAd,YAAqD;AACxD,MAAI,OAAO,sBAAsB,UAAU;AACzC,wBAAoB,CAAC;AAAA;AAEvB,MAAI,UAAU,cAAc,CAAC,GAAG,mBAAmB;AAAA;AAGrD,6BAA6B,KAAa;AAIxC,SAAO,MAAM;AAAA;AAGf,gCAAgC;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,GAKC;AACD,MAAI;AACF,WAAO,MAAM,+BAAU;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA;AAAA,WAEK,OAAP;AACA,QAAI,iBAAiB,OAAO;AAC1B,UACE,MAAM,YAAY,kBAClB,MAAM,YAAY,oBAClB,MAAM,YAAY,0BAClB;AAKA,eAAO,MAAM,+BAAU,EAAE,UAAU;AAAA;AAAA;AAIvC,UAAM;AAAA;AAAA;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import ironStore from "iron-store";
|
|
3
|
+
import cookie from "cookie";
|
|
4
|
+
var timestampSkewSec = 60;
|
|
5
|
+
var defaultOptions = {
|
|
6
|
+
ttl: 15 * 24 * 3600,
|
|
7
|
+
cookieOptions: {
|
|
8
|
+
httpOnly: true,
|
|
9
|
+
secure: true,
|
|
10
|
+
sameSite: "lax",
|
|
11
|
+
path: "/"
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
async function getIronSession(req, res, userOptions) {
|
|
15
|
+
var _a, _b;
|
|
16
|
+
if (!req || !res || !userOptions || !userOptions.cookieName || !userOptions.password) {
|
|
17
|
+
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`);
|
|
18
|
+
}
|
|
19
|
+
const passwordAsAnArray = Array.isArray(userOptions.password) ? userOptions.password : [{ id: 1, password: userOptions.password }];
|
|
20
|
+
passwordAsAnArray.forEach(({ password }) => {
|
|
21
|
+
if (password.length < 32) {
|
|
22
|
+
throw new Error(`iron-session: Bad usage. Password must be at least 32 characters long.`);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
const options = {
|
|
26
|
+
...defaultOptions,
|
|
27
|
+
...userOptions,
|
|
28
|
+
cookieOptions: {
|
|
29
|
+
...defaultOptions.cookieOptions,
|
|
30
|
+
...userOptions.cookieOptions || {}
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
if (options.ttl === 0) {
|
|
34
|
+
options.ttl = 2147483647;
|
|
35
|
+
}
|
|
36
|
+
options.cookieOptions.maxAge = computeCookieMaxAge((_b = (_a = userOptions.cookieOptions) == null ? void 0 : _a.maxAge) != null ? _b : options.ttl);
|
|
37
|
+
const store = await getOrCreateStore({
|
|
38
|
+
sealed: cookie.parse(req.headers.cookie || "")[options.cookieName],
|
|
39
|
+
password: passwordAsAnArray,
|
|
40
|
+
ttl: options.ttl * 1e3
|
|
41
|
+
});
|
|
42
|
+
return {
|
|
43
|
+
set: store.set,
|
|
44
|
+
get: store.get,
|
|
45
|
+
unset: store.unset,
|
|
46
|
+
async save() {
|
|
47
|
+
const seal = await store.seal();
|
|
48
|
+
const cookieValue = cookie.serialize(options.cookieName, seal, options.cookieOptions);
|
|
49
|
+
if (cookieValue.length > 4096) {
|
|
50
|
+
throw new Error(`iron-session: Cookie length is too big ${cookieValue.length}, browsers will refuse it. Try to remove some data.`);
|
|
51
|
+
}
|
|
52
|
+
addToCookies(cookieValue, res);
|
|
53
|
+
return cookieValue;
|
|
54
|
+
},
|
|
55
|
+
destroy() {
|
|
56
|
+
store.clear();
|
|
57
|
+
const cookieValue = cookie.serialize(options.cookieName, "", {
|
|
58
|
+
...options.cookieOptions,
|
|
59
|
+
maxAge: 0
|
|
60
|
+
});
|
|
61
|
+
addToCookies(cookieValue, res);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function addToCookies(cookieValue, res) {
|
|
66
|
+
var _a;
|
|
67
|
+
let existingSetCookie = (_a = res.getHeader("set-cookie")) != null ? _a : [];
|
|
68
|
+
if (typeof existingSetCookie === "string") {
|
|
69
|
+
existingSetCookie = [existingSetCookie];
|
|
70
|
+
}
|
|
71
|
+
res.setHeader("set-cookie", [...existingSetCookie, cookieValue]);
|
|
72
|
+
}
|
|
73
|
+
function computeCookieMaxAge(ttl) {
|
|
74
|
+
return ttl - timestampSkewSec;
|
|
75
|
+
}
|
|
76
|
+
async function getOrCreateStore({
|
|
77
|
+
sealed,
|
|
78
|
+
password,
|
|
79
|
+
ttl
|
|
80
|
+
}) {
|
|
81
|
+
try {
|
|
82
|
+
return await ironStore({
|
|
83
|
+
sealed,
|
|
84
|
+
password,
|
|
85
|
+
ttl
|
|
86
|
+
});
|
|
87
|
+
} catch (error) {
|
|
88
|
+
if (error instanceof Error) {
|
|
89
|
+
if (error.message === "Expired seal" || error.message === "Bad hmac value" || error.message === "Cannot find password: ") {
|
|
90
|
+
return await ironStore({ password, ttl });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export {
|
|
97
|
+
getIronSession
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts"],
|
|
4
|
+
"sourcesContent": ["import ironStore from \"iron-store\";\nimport cookie, { CookieSerializeOptions } from \"cookie\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\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 password = string | { id: number; password: string }[];\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\nexport interface IronSession {\n set: <T = unknown>(name: string, value: T) => T;\n get: <T = unknown>(name: string) => T | undefined;\n unset: (name: string) => void;\n destroy: () => void;\n save: () => Promise<string>;\n}\n\nexport async function getIronSession<\n RequestType extends IncomingMessage,\n ResponseType extends ServerResponse,\n>(req: RequestType, res: ResponseType, userOptions: IronSessionOptions) {\n if (\n !req ||\n !res ||\n !userOptions ||\n !userOptions.cookieName ||\n !userOptions.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 passwordAsAnArray = Array.isArray(userOptions.password)\n ? userOptions.password\n : [{ id: 1, password: userOptions.password }];\n\n passwordAsAnArray.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 ...userOptions,\n cookieOptions: {\n ...defaultOptions.cookieOptions,\n ...(userOptions.cookieOptions || {}),\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 options.cookieOptions.maxAge = computeCookieMaxAge(\n userOptions.cookieOptions?.maxAge ?? options.ttl,\n );\n\n const store = await getOrCreateStore({\n sealed: cookie.parse(req.headers.cookie || \"\")[options.cookieName],\n password: passwordAsAnArray,\n ttl: options.ttl * 1000,\n });\n\n return {\n set: store.set,\n get: store.get,\n unset: store.unset,\n async save() {\n const seal = await store.seal();\n const cookieValue = cookie.serialize(\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 destroy() {\n store.clear();\n const cookieValue = cookie.serialize(options.cookieName, \"\", {\n ...options.cookieOptions,\n maxAge: 0,\n });\n addToCookies(cookieValue, res);\n },\n };\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\nasync function getOrCreateStore({\n sealed,\n password,\n ttl,\n}: {\n sealed: string;\n password: password;\n ttl: number;\n}) {\n try {\n return await ironStore({\n sealed,\n password,\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 ) {\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 await ironStore({ password, ttl });\n }\n }\n\n throw error;\n }\n}\n"],
|
|
5
|
+
"mappings": ";AAAA;AACA;AAKA,IAAM,mBAAmB;AAIzB,IAAM,iBAGF;AAAA,EACF,KAAK,KAAK,KAAK;AAAA,EACf,eAAe;AAAA,IACb,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,MAAM;AAAA;AAAA;AAmBV,8BAGE,KAAkB,KAAmB,aAAiC;AAzCxE;AA0CE,MACE,CAAC,OACD,CAAC,OACD,CAAC,eACD,CAAC,YAAY,cACb,CAAC,YAAY,UACb;AACA,UAAM,IAAI,MACR;AAAA;AAIJ,QAAM,oBAAoB,MAAM,QAAQ,YAAY,YAChD,YAAY,WACZ,CAAC,EAAE,IAAI,GAAG,UAAU,YAAY;AAEpC,oBAAkB,QAAQ,CAAC,EAAE,eAAe;AAC1C,QAAI,SAAS,SAAS,IAAI;AACxB,YAAM,IAAI,MACR;AAAA;AAAA;AAKN,QAAM,UAAwC;AAAA,OACzC;AAAA,OACA;AAAA,IACH,eAAe;AAAA,SACV,eAAe;AAAA,SACd,YAAY,iBAAiB;AAAA;AAAA;AAIrC,MAAI,QAAQ,QAAQ,GAAG;AAKrB,YAAQ,MAAM;AAAA;AAGhB,UAAQ,cAAc,SAAS,oBAC7B,wBAAY,kBAAZ,mBAA2B,WAA3B,YAAqC,QAAQ;AAG/C,QAAM,QAAQ,MAAM,iBAAiB;AAAA,IACnC,QAAQ,OAAO,MAAM,IAAI,QAAQ,UAAU,IAAI,QAAQ;AAAA,IACvD,UAAU;AAAA,IACV,KAAK,QAAQ,MAAM;AAAA;AAGrB,SAAO;AAAA,IACL,KAAK,MAAM;AAAA,IACX,KAAK,MAAM;AAAA,IACX,OAAO,MAAM;AAAA,UACP,OAAO;AACX,YAAM,OAAO,MAAM,MAAM;AACzB,YAAM,cAAc,OAAO,UACzB,QAAQ,YACR,MACA,QAAQ;AAGV,UAAI,YAAY,SAAS,MAAM;AAC7B,cAAM,IAAI,MACR,0CAA0C,YAAY;AAAA;AAI1D,mBAAa,aAAa;AAC1B,aAAO;AAAA;AAAA,IAET,UAAU;AACR,YAAM;AACN,YAAM,cAAc,OAAO,UAAU,QAAQ,YAAY,IAAI;AAAA,WACxD,QAAQ;AAAA,QACX,QAAQ;AAAA;AAEV,mBAAa,aAAa;AAAA;AAAA;AAAA;AAKhC,sBAAsB,aAAqB,KAAqB;AA7HhE;AA8HE,MAAI,oBACD,UAAI,UAAU,kBAAd,YAAqD;AACxD,MAAI,OAAO,sBAAsB,UAAU;AACzC,wBAAoB,CAAC;AAAA;AAEvB,MAAI,UAAU,cAAc,CAAC,GAAG,mBAAmB;AAAA;AAGrD,6BAA6B,KAAa;AAIxC,SAAO,MAAM;AAAA;AAGf,gCAAgC;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,GAKC;AACD,MAAI;AACF,WAAO,MAAM,UAAU;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA;AAAA,WAEK,OAAP;AACA,QAAI,iBAAiB,OAAO;AAC1B,UACE,MAAM,YAAY,kBAClB,MAAM,YAAY,oBAClB,MAAM,YAAY,0BAClB;AAKA,eAAO,MAAM,UAAU,EAAE,UAAU;AAAA;AAAA;AAIvC,UAAM;AAAA;AAAA;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { NextApiRequest, NextApiResponse, GetServerSidePropsResult, GetServerSidePropsContext } from 'next';
|
|
2
|
+
import { IronSession, IronSessionOptions } from 'iron-session';
|
|
3
|
+
|
|
4
|
+
interface NextApiRequestWithIronSession extends NextApiRequest {
|
|
5
|
+
session: IronSession;
|
|
6
|
+
}
|
|
7
|
+
declare type NextApiHandlerWithIronSession<T = unknown> = (req: NextApiRequestWithIronSession, res: NextApiResponse<T>) => void | Promise<void>;
|
|
8
|
+
interface NextGetSeverSideContextWithIronSession extends GetServerSidePropsContext {
|
|
9
|
+
req: NextApiRequestWithIronSession;
|
|
10
|
+
}
|
|
11
|
+
declare type NextGetServerSidePropsHandlerWithIronSession<P> = (context: NextGetSeverSideContextWithIronSession) => Promise<GetServerSidePropsResult<P>>;
|
|
12
|
+
declare function withIronSessionApiRoute(handler: NextApiHandlerWithIronSession, options: IronSessionOptions): NextApiHandlerWithIronSession;
|
|
13
|
+
declare function withIronSessionSsr<P>(handler: NextGetServerSidePropsHandlerWithIronSession<P>, options: IronSessionOptions): NextGetServerSidePropsHandlerWithIronSession<P>;
|
|
14
|
+
|
|
15
|
+
export { NextApiHandlerWithIronSession, NextApiRequestWithIronSession, NextGetServerSidePropsHandlerWithIronSession, withIronSessionApiRoute, withIronSessionSsr };
|
|
@@ -0,0 +1,48 @@
|
|
|
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
|
+
function withIronSessionApiRoute(handler, options) {
|
|
32
|
+
return async function nextApiHandlerWrappedWithIronSession(req, res) {
|
|
33
|
+
req.session = await (0, import_iron_session.getIronSession)(req, res, options);
|
|
34
|
+
return handler(req, res);
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function withIronSessionSsr(handler, options) {
|
|
38
|
+
return async function nextGetServerSidePropsHandlerWrappedWithIronSession(context) {
|
|
39
|
+
context.req.session = await (0, import_iron_session.getIronSession)(context.req, context.res, options);
|
|
40
|
+
return handler(context);
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
44
|
+
0 && (module.exports = {
|
|
45
|
+
withIronSessionApiRoute,
|
|
46
|
+
withIronSessionSsr
|
|
47
|
+
});
|
|
48
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../index.ts"],
|
|
4
|
+
"sourcesContent": ["import type {\n GetServerSidePropsContext,\n GetServerSidePropsResult,\n NextApiRequest,\n NextApiResponse,\n} from \"next\";\nimport type { IronSession, IronSessionOptions } from \"iron-session\";\nimport { getIronSession } from \"iron-session\";\n\nexport interface NextApiRequestWithIronSession extends NextApiRequest {\n session: IronSession;\n}\n\nexport declare type NextApiHandlerWithIronSession<T = unknown> = (\n req: NextApiRequestWithIronSession,\n res: NextApiResponse<T>,\n) => void | Promise<void>;\n\ninterface NextGetSeverSideContextWithIronSession\n extends GetServerSidePropsContext {\n req: NextApiRequestWithIronSession;\n}\n\nexport declare type NextGetServerSidePropsHandlerWithIronSession<P> = (\n context: NextGetSeverSideContextWithIronSession,\n) => Promise<GetServerSidePropsResult<P>>;\n\nexport function withIronSessionApiRoute(\n handler: NextApiHandlerWithIronSession,\n options: IronSessionOptions,\n): NextApiHandlerWithIronSession {\n return async function nextApiHandlerWrappedWithIronSession(req, res) {\n req.session = await getIronSession(req, res, options);\n return handler(req, res);\n };\n}\n\nexport function withIronSessionSsr<P>(\n handler: NextGetServerSidePropsHandlerWithIronSession<P>,\n options: IronSessionOptions,\n): NextGetServerSidePropsHandlerWithIronSession<P> {\n return async function nextGetServerSidePropsHandlerWrappedWithIronSession(\n context: NextGetSeverSideContextWithIronSession,\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": ";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAOA,0BAA+B;AAoBxB,iCACL,SACA,SAC+B;AAC/B,SAAO,oDAAoD,KAAK,KAAK;AACnE,QAAI,UAAU,MAAM,wCAAe,KAAK,KAAK;AAC7C,WAAO,QAAQ,KAAK;AAAA;AAAA;AAIjB,4BACL,SACA,SACiD;AACjD,SAAO,mEACL,SACA;AACA,YAAQ,IAAI,UAAU,MAAM,wCAC1B,QAAQ,KACR,QAAQ,KACR;AAEF,WAAO,QAAQ;AAAA;AAAA;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// next/index.ts
|
|
2
|
+
import { getIronSession } from "iron-session";
|
|
3
|
+
function withIronSessionApiRoute(handler, options) {
|
|
4
|
+
return async function nextApiHandlerWrappedWithIronSession(req, res) {
|
|
5
|
+
req.session = await getIronSession(req, res, options);
|
|
6
|
+
return handler(req, res);
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
function withIronSessionSsr(handler, options) {
|
|
10
|
+
return async function nextGetServerSidePropsHandlerWrappedWithIronSession(context) {
|
|
11
|
+
context.req.session = await getIronSession(context.req, context.res, options);
|
|
12
|
+
return handler(context);
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
withIronSessionApiRoute,
|
|
17
|
+
withIronSessionSsr
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../index.ts"],
|
|
4
|
+
"sourcesContent": ["import type {\n GetServerSidePropsContext,\n GetServerSidePropsResult,\n NextApiRequest,\n NextApiResponse,\n} from \"next\";\nimport type { IronSession, IronSessionOptions } from \"iron-session\";\nimport { getIronSession } from \"iron-session\";\n\nexport interface NextApiRequestWithIronSession extends NextApiRequest {\n session: IronSession;\n}\n\nexport declare type NextApiHandlerWithIronSession<T = unknown> = (\n req: NextApiRequestWithIronSession,\n res: NextApiResponse<T>,\n) => void | Promise<void>;\n\ninterface NextGetSeverSideContextWithIronSession\n extends GetServerSidePropsContext {\n req: NextApiRequestWithIronSession;\n}\n\nexport declare type NextGetServerSidePropsHandlerWithIronSession<P> = (\n context: NextGetSeverSideContextWithIronSession,\n) => Promise<GetServerSidePropsResult<P>>;\n\nexport function withIronSessionApiRoute(\n handler: NextApiHandlerWithIronSession,\n options: IronSessionOptions,\n): NextApiHandlerWithIronSession {\n return async function nextApiHandlerWrappedWithIronSession(req, res) {\n req.session = await getIronSession(req, res, options);\n return handler(req, res);\n };\n}\n\nexport function withIronSessionSsr<P>(\n handler: NextGetServerSidePropsHandlerWithIronSession<P>,\n options: IronSessionOptions,\n): NextGetServerSidePropsHandlerWithIronSession<P> {\n return async function nextGetServerSidePropsHandlerWrappedWithIronSession(\n context: NextGetSeverSideContextWithIronSession,\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": ";AAOA;AAoBO,iCACL,SACA,SAC+B;AAC/B,SAAO,oDAAoD,KAAK,KAAK;AACnE,QAAI,UAAU,MAAM,eAAe,KAAK,KAAK;AAC7C,WAAO,QAAQ,KAAK;AAAA;AAAA;AAIjB,4BACL,SACA,SACiD;AACjD,SAAO,mEACL,SACA;AACA,YAAQ,IAAI,UAAU,MAAM,eAC1B,QAAQ,KACR,QAAQ,KACR;AAEF,WAAO,QAAQ;AAAA;AAAA;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,83 +1,142 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iron-session",
|
|
3
|
-
"version": "
|
|
4
|
-
"private": false,
|
|
5
|
-
"description": "Backend agnostic session utility based on @hapi/iron with signed and encrypted cookie serialization ability",
|
|
6
|
-
"repository": {
|
|
7
|
-
"type": "git",
|
|
8
|
-
"url": "https://github.com/vvo/iron-session.git"
|
|
9
|
-
},
|
|
3
|
+
"version": "2.0.0-alpha.10",
|
|
10
4
|
"license": "MIT",
|
|
11
5
|
"author": "Vincent Voyer <vincent@codeagain.com>",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"import": "./dist/index.mjs",
|
|
9
|
+
"require": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"./next": {
|
|
13
|
+
"import": "./next/dist/index.mjs",
|
|
14
|
+
"require": "./next/dist/index.js",
|
|
15
|
+
"types": "./next/dist/index.d.ts"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"main": "./dist/index.js",
|
|
19
|
+
"module": "./dist/index.mjs",
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
12
21
|
"files": [
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
22
|
+
"dist",
|
|
23
|
+
"next/dist"
|
|
24
|
+
],
|
|
25
|
+
"workspaces": [
|
|
26
|
+
"examples/next.js",
|
|
27
|
+
"examples/next.js-typescript"
|
|
17
28
|
],
|
|
18
|
-
"main": "index.dist.js",
|
|
19
29
|
"scripts": {
|
|
20
|
-
"build": "
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"test": "jest --coverage &&
|
|
30
|
+
"build": "rimraf dist/ next/dist && tsup src/index.ts && tsup next/index.ts -d next/dist",
|
|
31
|
+
"lint": "eslint . && (cd examples/next.js && npm run lint) && (cd examples/next.js-typescript && npm run lint)",
|
|
32
|
+
"prepublishOnly": "npm run build",
|
|
33
|
+
"test": "jest --coverage && npm run lint"
|
|
24
34
|
},
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
[
|
|
28
|
-
"@babel/preset-env",
|
|
29
|
-
{
|
|
30
|
-
"targets": {
|
|
31
|
-
"node": "12"
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
]
|
|
35
|
-
]
|
|
35
|
+
"prettier": {
|
|
36
|
+
"trailingComma": "all"
|
|
36
37
|
},
|
|
37
38
|
"eslintConfig": {
|
|
38
|
-
"
|
|
39
|
-
"jest": true,
|
|
40
|
-
"node": true
|
|
41
|
-
},
|
|
39
|
+
"parser": "@typescript-eslint/parser",
|
|
42
40
|
"parserOptions": {
|
|
43
|
-
"ecmaVersion":
|
|
41
|
+
"ecmaVersion": 2021,
|
|
44
42
|
"sourceType": "module"
|
|
45
43
|
},
|
|
46
44
|
"plugins": [
|
|
47
|
-
"
|
|
45
|
+
"@typescript-eslint"
|
|
48
46
|
],
|
|
49
47
|
"extends": [
|
|
50
48
|
"eslint:recommended",
|
|
51
|
-
"plugin
|
|
52
|
-
]
|
|
49
|
+
"plugin:@typescript-eslint/recommended"
|
|
50
|
+
],
|
|
51
|
+
"rules": {
|
|
52
|
+
"@typescript-eslint/ban-ts-comment": [
|
|
53
|
+
"warn",
|
|
54
|
+
{
|
|
55
|
+
"ts-ignore": "allow-with-description"
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
}
|
|
53
59
|
},
|
|
54
60
|
"jest": {
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
|
|
61
|
+
"collectCoverageFrom": [
|
|
62
|
+
"src/*.ts",
|
|
63
|
+
"next/*.ts"
|
|
64
|
+
],
|
|
65
|
+
"coverageProvider": "v8",
|
|
66
|
+
"coverageReporters": [
|
|
67
|
+
"text"
|
|
68
|
+
],
|
|
69
|
+
"transform": {
|
|
70
|
+
".ts$": [
|
|
71
|
+
"@swc-node/jest",
|
|
72
|
+
{
|
|
73
|
+
"jsc": {
|
|
74
|
+
"minify": false
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
}
|
|
58
79
|
},
|
|
59
80
|
"dependencies": {
|
|
60
|
-
"@
|
|
61
|
-
"
|
|
62
|
-
"cookie": "^0.4.
|
|
81
|
+
"@types/cookie": "^0.4.0",
|
|
82
|
+
"@types/node": "^16.11.1",
|
|
83
|
+
"cookie": "^0.4.1",
|
|
84
|
+
"iron-store": "^1.3.5"
|
|
63
85
|
},
|
|
64
86
|
"devDependencies": {
|
|
65
|
-
"@
|
|
66
|
-
"@
|
|
67
|
-
"@
|
|
68
|
-
"@
|
|
69
|
-
"
|
|
70
|
-
"eslint": "
|
|
71
|
-
"
|
|
72
|
-
"jest": "25.1.0",
|
|
87
|
+
"@swc-node/jest": "1.3.3",
|
|
88
|
+
"@tsconfig/node12": "1.0.9",
|
|
89
|
+
"@types/jest": "27.0.2",
|
|
90
|
+
"@typescript-eslint/eslint-plugin": "5.1.0",
|
|
91
|
+
"@typescript-eslint/parser": "5.1.0",
|
|
92
|
+
"eslint": "8.0.1",
|
|
93
|
+
"jest": "27.3.1",
|
|
73
94
|
"jest-date-mock": "1.0.8",
|
|
74
|
-
"prettier": "
|
|
75
|
-
"prettier-plugin-packagejson": "2.
|
|
76
|
-
"
|
|
95
|
+
"prettier": "2.4.1",
|
|
96
|
+
"prettier-plugin-packagejson": "2.2.13",
|
|
97
|
+
"rimraf": "3.0.2",
|
|
98
|
+
"tsup": "5.4.1",
|
|
99
|
+
"typescript": "4.4.4"
|
|
100
|
+
},
|
|
101
|
+
"peerDependencies": {
|
|
102
|
+
"next": ">=10"
|
|
103
|
+
},
|
|
104
|
+
"peerDependenciesMeta": {
|
|
105
|
+
"next": {
|
|
106
|
+
"optional": true
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
"engines": {
|
|
110
|
+
"node": ">=12"
|
|
77
111
|
},
|
|
78
112
|
"renovate": {
|
|
79
113
|
"extends": [
|
|
80
|
-
"config:js-lib"
|
|
114
|
+
"config:js-lib",
|
|
115
|
+
":automergePatch",
|
|
116
|
+
":automergeBranch",
|
|
117
|
+
":automergePatch",
|
|
118
|
+
":automergeBranch",
|
|
119
|
+
":automergeLinters",
|
|
120
|
+
":automergeTesters",
|
|
121
|
+
":automergeTypes"
|
|
122
|
+
],
|
|
123
|
+
"timezone": "Europe/Paris",
|
|
124
|
+
"schedule": [
|
|
125
|
+
"before 3am on Monday"
|
|
126
|
+
]
|
|
127
|
+
},
|
|
128
|
+
"tsup": {
|
|
129
|
+
"splitting": false,
|
|
130
|
+
"sourcemap": true,
|
|
131
|
+
"clean": true,
|
|
132
|
+
"dts": true,
|
|
133
|
+
"target": "es2019",
|
|
134
|
+
"format": [
|
|
135
|
+
"esm",
|
|
136
|
+
"cjs"
|
|
137
|
+
],
|
|
138
|
+
"external": [
|
|
139
|
+
"iron-session"
|
|
81
140
|
]
|
|
82
141
|
}
|
|
83
142
|
}
|
package/index.dist.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.createSession = createSession;
|
|
7
|
-
exports.getSession = getSession;
|
|
8
|
-
exports.parseCookie = parseCookie;
|
|
9
|
-
exports.deleteCookie = deleteCookie;
|
|
10
|
-
|
|
11
|
-
var _iron = _interopRequireDefault(require("@hapi/iron"));
|
|
12
|
-
|
|
13
|
-
var _cookie = _interopRequireDefault(require("cookie"));
|
|
14
|
-
|
|
15
|
-
var _clone = _interopRequireDefault(require("clone"));
|
|
16
|
-
|
|
17
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
18
|
-
|
|
19
|
-
const defaultTtl = 15 * 24 * 3600;
|
|
20
|
-
const cookieName = "__ironSession";
|
|
21
|
-
|
|
22
|
-
async function createSession({
|
|
23
|
-
password,
|
|
24
|
-
ttl = defaultTtl
|
|
25
|
-
}) {
|
|
26
|
-
return getSession({
|
|
27
|
-
password,
|
|
28
|
-
ttl
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async function getSession({
|
|
33
|
-
sealed,
|
|
34
|
-
password,
|
|
35
|
-
ttl = defaultTtl
|
|
36
|
-
}) {
|
|
37
|
-
const options = { ..._iron.default.defaults,
|
|
38
|
-
ttl
|
|
39
|
-
};
|
|
40
|
-
const store = sealed !== undefined ? await _iron.default.unseal(sealed, password, options) : {
|
|
41
|
-
persistent: {},
|
|
42
|
-
flash: {}
|
|
43
|
-
};
|
|
44
|
-
return {
|
|
45
|
-
set({
|
|
46
|
-
name,
|
|
47
|
-
value,
|
|
48
|
-
flash = false
|
|
49
|
-
}) {
|
|
50
|
-
if (flash === true) {
|
|
51
|
-
store.flash[name] = (0, _clone.default)(value);
|
|
52
|
-
} else {
|
|
53
|
-
store.persistent[name] = (0, _clone.default)(value);
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
|
|
57
|
-
get({
|
|
58
|
-
name = undefined
|
|
59
|
-
} = {}) {
|
|
60
|
-
if (name === undefined) {
|
|
61
|
-
const flash = store.flash;
|
|
62
|
-
store.flash = {};
|
|
63
|
-
return (0, _clone.default)({ ...flash,
|
|
64
|
-
...store.persistent
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (store.flash[name] !== undefined) {
|
|
69
|
-
const value = store.flash[name];
|
|
70
|
-
delete store.flash[name];
|
|
71
|
-
return value; // no need to clone, we removed the reference from the flash store
|
|
72
|
-
} else {
|
|
73
|
-
return (0, _clone.default)(store.persistent[name]);
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
|
|
77
|
-
async serializeCookie(cookieOptions = {}) {
|
|
78
|
-
return _cookie.default.serialize(cookieName, (await _iron.default.seal(store, password, options)), {
|
|
79
|
-
httpOnly: true,
|
|
80
|
-
secure: true,
|
|
81
|
-
sameSite: "lax",
|
|
82
|
-
maxAge: (ttl === 0 ? 2147483647 : ttl) - 60,
|
|
83
|
-
// For Iron, ttl 0 means it will never expire. For browser cookies, maxAge 0 means it will expire immediately. WhilCookie must expire before the seal, otherwise you could have expired seals stored in a cookie
|
|
84
|
-
...cookieOptions
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function parseCookie({
|
|
92
|
-
cookie: cookieValue
|
|
93
|
-
}) {
|
|
94
|
-
return _cookie.default.parse(cookieValue)[cookieName];
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function deleteCookie() {
|
|
98
|
-
return _cookie.default.serialize(cookieName, "", {
|
|
99
|
-
maxAge: 0
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
//# sourceMappingURL=index.dist.js.map
|
package/index.dist.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["index.js"],"names":[],"mappings":";;;;;;;;;;AAAA;;AACA;;AACA;;;;AAEA,MAAM,UAAU,GAAG,KAAK,EAAL,GAAU,IAA7B;AACA,MAAM,UAAU,GAAG,eAAnB;;AAEO,eAAe,aAAf,CAA6B;AAAE,EAAA,QAAF;AAAY,EAAA,GAAG,GAAG;AAAlB,CAA7B,EAA6D;AAClE,SAAO,UAAU,CAAC;AAAE,IAAA,QAAF;AAAY,IAAA;AAAZ,GAAD,CAAjB;AACD;;AAEM,eAAe,UAAf,CAA0B;AAAE,EAAA,MAAF;AAAU,EAAA,QAAV;AAAoB,EAAA,GAAG,GAAG;AAA1B,CAA1B,EAAkE;AACvE,QAAM,OAAO,GAAG,EAAE,GAAG,cAAK,QAAV;AAAoB,IAAA;AAApB,GAAhB;AACA,QAAM,KAAK,GACT,MAAM,KAAK,SAAX,GACI,MAAM,cAAK,MAAL,CAAY,MAAZ,EAAoB,QAApB,EAA8B,OAA9B,CADV,GAEI;AAAE,IAAA,UAAU,EAAE,EAAd;AAAkB,IAAA,KAAK,EAAE;AAAzB,GAHN;AAKA,SAAO;AACL,IAAA,GAAG,CAAC;AAAE,MAAA,IAAF;AAAQ,MAAA,KAAR;AAAe,MAAA,KAAK,GAAG;AAAvB,KAAD,EAAiC;AAClC,UAAI,KAAK,KAAK,IAAd,EAAoB;AAClB,QAAA,KAAK,CAAC,KAAN,CAAY,IAAZ,IAAoB,oBAAM,KAAN,CAApB;AACD,OAFD,MAEO;AACL,QAAA,KAAK,CAAC,UAAN,CAAiB,IAAjB,IAAyB,oBAAM,KAAN,CAAzB;AACD;AACF,KAPI;;AAQL,IAAA,GAAG,CAAC;AAAE,MAAA,IAAI,GAAG;AAAT,QAAuB,EAAxB,EAA4B;AAC7B,UAAI,IAAI,KAAK,SAAb,EAAwB;AACtB,cAAM,KAAK,GAAG,KAAK,CAAC,KAApB;AACA,QAAA,KAAK,CAAC,KAAN,GAAc,EAAd;AACA,eAAO,oBAAM,EACX,GAAG,KADQ;AAEX,aAAG,KAAK,CAAC;AAFE,SAAN,CAAP;AAID;;AAED,UAAI,KAAK,CAAC,KAAN,CAAY,IAAZ,MAAsB,SAA1B,EAAqC;AACnC,cAAM,KAAK,GAAG,KAAK,CAAC,KAAN,CAAY,IAAZ,CAAd;AACA,eAAO,KAAK,CAAC,KAAN,CAAY,IAAZ,CAAP;AACA,eAAO,KAAP,CAHmC,CAGrB;AACf,OAJD,MAIO;AACL,eAAO,oBAAM,KAAK,CAAC,UAAN,CAAiB,IAAjB,CAAN,CAAP;AACD;AACF,KAzBI;;AA0BL,UAAM,eAAN,CAAsB,aAAa,GAAG,EAAtC,EAA0C;AACxC,aAAO,gBAAO,SAAP,CACL,UADK,GAEL,MAAM,cAAK,IAAL,CAAU,KAAV,EAAiB,QAAjB,EAA2B,OAA3B,CAFD,GAGL;AACE,QAAA,QAAQ,EAAE,IADZ;AAEE,QAAA,MAAM,EAAE,IAFV;AAGE,QAAA,QAAQ,EAAE,KAHZ;AAIE,QAAA,MAAM,EAAE,CAAC,GAAG,KAAK,CAAR,GAAY,UAAZ,GAAyB,GAA1B,IAAiC,EAJ3C;AAI+C;AAC7C,WAAG;AALL,OAHK,CAAP;AAWD;;AAtCI,GAAP;AAwCD;;AAEM,SAAS,WAAT,CAAqB;AAAE,EAAA,MAAM,EAAE;AAAV,CAArB,EAA8C;AACnD,SAAO,gBAAO,KAAP,CAAa,WAAb,EAA0B,UAA1B,CAAP;AACD;;AAEM,SAAS,YAAT,GAAwB;AAC7B,SAAO,gBAAO,SAAP,CAAiB,UAAjB,EAA6B,EAA7B,EAAiC;AACtC,IAAA,MAAM,EAAE;AAD8B,GAAjC,CAAP;AAGD","file":"index.dist.js","sourcesContent":["import Iron from \"@hapi/iron\";\nimport cookie from \"cookie\";\nimport clone from \"clone\";\n\nconst defaultTtl = 15 * 24 * 3600;\nconst cookieName = \"__ironSession\";\n\nexport async function createSession({ password, ttl = defaultTtl }) {\n return getSession({ password, ttl });\n}\n\nexport async function getSession({ sealed, password, ttl = defaultTtl }) {\n const options = { ...Iron.defaults, ttl };\n const store =\n sealed !== undefined\n ? await Iron.unseal(sealed, password, options)\n : { persistent: {}, flash: {} };\n\n return {\n set({ name, value, flash = false }) {\n if (flash === true) {\n store.flash[name] = clone(value);\n } else {\n store.persistent[name] = clone(value);\n }\n },\n get({ name = undefined } = {}) {\n if (name === undefined) {\n const flash = store.flash;\n store.flash = {};\n return clone({\n ...flash,\n ...store.persistent\n });\n }\n\n if (store.flash[name] !== undefined) {\n const value = store.flash[name];\n delete store.flash[name];\n return value; // no need to clone, we removed the reference from the flash store\n } else {\n return clone(store.persistent[name]);\n }\n },\n async serializeCookie(cookieOptions = {}) {\n return cookie.serialize(\n cookieName,\n await Iron.seal(store, password, options),\n {\n httpOnly: true,\n secure: true,\n sameSite: \"lax\",\n maxAge: (ttl === 0 ? 2147483647 : ttl) - 60, // For Iron, ttl 0 means it will never expire. For browser cookies, maxAge 0 means it will expire immediately. WhilCookie must expire before the seal, otherwise you could have expired seals stored in a cookie\n ...cookieOptions\n }\n );\n }\n };\n}\n\nexport function parseCookie({ cookie: cookieValue }) {\n return cookie.parse(cookieValue)[cookieName];\n}\n\nexport function deleteCookie() {\n return cookie.serialize(cookieName, \"\", {\n maxAge: 0\n });\n}\n"]}
|