iron-session 2.0.0-alpha.9 → 6.0.2
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/README.md +608 -55
- package/dist/index.d.ts +52 -17
- package/dist/index.js +137 -46
- package/dist/index.js.map +2 -2
- package/dist/index.mjs +160 -0
- package/dist/index.mjs.map +7 -0
- package/express/dist/index.d.ts +6 -0
- package/express/dist/index.js +65 -0
- package/express/dist/index.js.map +7 -0
- package/express/dist/index.mjs +37 -0
- package/express/dist/index.mjs.map +7 -0
- package/express/index.d.ts +6 -0
- package/express/index.js +65 -0
- package/express/index.js.map +7 -0
- package/express/index.mjs +37 -0
- package/express/index.mjs.map +7 -0
- package/express/index.test.ts +41 -0
- package/express/index.ts +19 -0
- package/express/tsconfig.json +8 -0
- package/next/dist/index.d.ts +9 -13
- package/next/dist/index.js +60 -5
- package/next/dist/index.js.map +3 -3
- package/next/dist/index.mjs +45 -0
- package/next/dist/index.mjs.map +7 -0
- package/next/index.d.ts +11 -0
- package/next/{dist/index.cjs → index.js} +29 -3
- package/next/index.js.map +7 -0
- package/next/index.mjs +45 -0
- package/next/index.mjs.map +7 -0
- package/next/index.test.ts +184 -0
- package/next/index.ts +49 -0
- package/next/tsconfig.json +8 -0
- package/package.json +84 -49
- package/dist/index.cjs +0 -127
- package/dist/index.cjs.map +0 -7
- package/next/dist/index.cjs.map +0 -7
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GetServerSidePropsContext,
|
|
3
|
+
NextApiRequest,
|
|
4
|
+
NextApiResponse,
|
|
5
|
+
} from "next";
|
|
6
|
+
import { withIronSessionApiRoute, withIronSessionSsr } from ".";
|
|
7
|
+
const password = "Gbm49ATjnqnkCCCdhV4uDBhbfnPqsCW0";
|
|
8
|
+
const cookieName = "test";
|
|
9
|
+
|
|
10
|
+
// same structure as other tests otherwise linting will fail because you can have only one per running eslint
|
|
11
|
+
declare module "iron-session" {
|
|
12
|
+
interface IronSessionData {
|
|
13
|
+
user?: { id: number; meta?: string };
|
|
14
|
+
admin?: boolean;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
test("withIronSessionApiRoute: req.session exists", async () => {
|
|
19
|
+
const wrappedHandler = withIronSessionApiRoute(
|
|
20
|
+
function handler(req) {
|
|
21
|
+
expect(req.session).toMatchInlineSnapshot(`Object {}`);
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
password,
|
|
25
|
+
cookieName,
|
|
26
|
+
},
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
await wrappedHandler(getDefaultReq(), getDefaultRes());
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("withIronSessionApiRoute: req.session.save creates a cookie", async () => {
|
|
33
|
+
const wrappedHandler = withIronSessionApiRoute(
|
|
34
|
+
async function handler(req, res) {
|
|
35
|
+
expect(req.session).toMatchInlineSnapshot(`Object {}`);
|
|
36
|
+
req.session.user = { id: 200 };
|
|
37
|
+
await req.session.save();
|
|
38
|
+
const headerName = (res.setHeader as jest.Mock).mock.calls[0][0];
|
|
39
|
+
expect(headerName).toMatchInlineSnapshot(`"set-cookie"`);
|
|
40
|
+
|
|
41
|
+
const headerValue = (res.setHeader as jest.Mock).mock.calls[0][1];
|
|
42
|
+
expect(Array.isArray(headerValue)).toBe(true);
|
|
43
|
+
expect(headerValue).toHaveLength(1);
|
|
44
|
+
|
|
45
|
+
const cookie = headerValue[0];
|
|
46
|
+
const seal = cookie.split(";")[0].split("=")[1];
|
|
47
|
+
expect(seal).toHaveLength(265);
|
|
48
|
+
|
|
49
|
+
const cookieParams = cookie.split(";").slice(1).join(";");
|
|
50
|
+
expect(cookieParams).toMatchInlineSnapshot(
|
|
51
|
+
`" Max-Age=1295940; Path=/; HttpOnly; Secure; SameSite=Lax"`,
|
|
52
|
+
);
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
password,
|
|
56
|
+
cookieName,
|
|
57
|
+
},
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
await wrappedHandler(getDefaultReq(), getDefaultRes());
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("withIronSessionApiRoute: req.session.destroy removes the cookie", async () => {
|
|
64
|
+
const wrappedHandler = withIronSessionApiRoute(
|
|
65
|
+
async function handler(req, res) {
|
|
66
|
+
req.session.user = { id: 300 };
|
|
67
|
+
await req.session.save();
|
|
68
|
+
expect(req.session).toMatchInlineSnapshot(`
|
|
69
|
+
Object {
|
|
70
|
+
"user": Object {
|
|
71
|
+
"id": 300,
|
|
72
|
+
},
|
|
73
|
+
}
|
|
74
|
+
`);
|
|
75
|
+
req.session.destroy();
|
|
76
|
+
expect(req.session).toMatchInlineSnapshot(`Object {}`);
|
|
77
|
+
expect((res.setHeader as jest.Mock).mock.calls[1]).toMatchInlineSnapshot(`
|
|
78
|
+
Array [
|
|
79
|
+
"set-cookie",
|
|
80
|
+
Array [
|
|
81
|
+
"test=; Max-Age=0; Path=/; HttpOnly; Secure; SameSite=Lax",
|
|
82
|
+
],
|
|
83
|
+
]
|
|
84
|
+
`);
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
password,
|
|
88
|
+
cookieName,
|
|
89
|
+
},
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
await wrappedHandler(getDefaultReq(), getDefaultRes());
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test("withIronSessionApiRoute: full session rewrite works too", async () => {
|
|
96
|
+
const wrappedHandler = withIronSessionApiRoute(
|
|
97
|
+
async function handler(req) {
|
|
98
|
+
req.session.user = { id: 200 };
|
|
99
|
+
await req.session.save();
|
|
100
|
+
expect(req.session).toMatchInlineSnapshot(`
|
|
101
|
+
Object {
|
|
102
|
+
"user": Object {
|
|
103
|
+
"id": 200,
|
|
104
|
+
},
|
|
105
|
+
}
|
|
106
|
+
`);
|
|
107
|
+
// @ts-ignore TypeScript warns about save and destroy not being here,
|
|
108
|
+
// so this example is most probably to catch misuage of the API and because it works the same as destructuring code wise
|
|
109
|
+
req.session = {
|
|
110
|
+
admin: true,
|
|
111
|
+
};
|
|
112
|
+
expect(req.session).toMatchInlineSnapshot(`
|
|
113
|
+
Object {
|
|
114
|
+
"admin": true,
|
|
115
|
+
}
|
|
116
|
+
`);
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
password,
|
|
120
|
+
cookieName,
|
|
121
|
+
},
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
await wrappedHandler(getDefaultReq(), getDefaultRes());
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test("withIronSessionApiRoute: req.session can be overridden, save and destroy will stay", async () => {
|
|
128
|
+
const wrappedHandler = withIronSessionApiRoute(
|
|
129
|
+
async function handler(req) {
|
|
130
|
+
req.session = {
|
|
131
|
+
...req.session,
|
|
132
|
+
user: { id: 400 },
|
|
133
|
+
};
|
|
134
|
+
await req.session.save();
|
|
135
|
+
expect(req.session).toMatchInlineSnapshot(`
|
|
136
|
+
Object {
|
|
137
|
+
"user": Object {
|
|
138
|
+
"id": 400,
|
|
139
|
+
},
|
|
140
|
+
}
|
|
141
|
+
`);
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
password,
|
|
145
|
+
cookieName,
|
|
146
|
+
},
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
await wrappedHandler(getDefaultReq(), getDefaultRes());
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
test("withIronSessionSsr: req.session exists", async () => {
|
|
153
|
+
const getServerSideProps = withIronSessionSsr(
|
|
154
|
+
async function getServerSideProps({ req }) {
|
|
155
|
+
expect(req.session).toMatchInlineSnapshot(`Object {}`);
|
|
156
|
+
return { props: {} };
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
password,
|
|
160
|
+
cookieName,
|
|
161
|
+
},
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
await getServerSideProps({
|
|
165
|
+
req: getDefaultReq(),
|
|
166
|
+
res: getDefaultRes(),
|
|
167
|
+
} as unknown as GetServerSidePropsContext);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
function getDefaultReq() {
|
|
171
|
+
return {
|
|
172
|
+
headers: {},
|
|
173
|
+
socket: {
|
|
174
|
+
encrypted: true,
|
|
175
|
+
},
|
|
176
|
+
} as unknown as NextApiRequest;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function getDefaultRes() {
|
|
180
|
+
return {
|
|
181
|
+
getHeader: jest.fn(),
|
|
182
|
+
setHeader: jest.fn(),
|
|
183
|
+
} as unknown as NextApiResponse;
|
|
184
|
+
}
|
package/next/index.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
NextApiHandler,
|
|
3
|
+
GetServerSidePropsContext,
|
|
4
|
+
GetServerSidePropsResult,
|
|
5
|
+
} from "next";
|
|
6
|
+
import type { IronSessionOptions } from "iron-session";
|
|
7
|
+
import { getIronSession } from "iron-session";
|
|
8
|
+
import getPropertyDescriptorForReqSession from "../src/getPropertyDescriptorForReqSession";
|
|
9
|
+
|
|
10
|
+
export function withIronSessionApiRoute(
|
|
11
|
+
handler: NextApiHandler,
|
|
12
|
+
options: IronSessionOptions,
|
|
13
|
+
): NextApiHandler {
|
|
14
|
+
return async function nextApiHandlerWrappedWithIronSession(req, res) {
|
|
15
|
+
const session = await getIronSession(req, res, options);
|
|
16
|
+
|
|
17
|
+
// we define req.session as being enumerable (so console.log(req) shows it)
|
|
18
|
+
// and we also want to allow people to do:
|
|
19
|
+
// req.session = { admin: true }; or req.session = {...req.session, admin: true};
|
|
20
|
+
// req.session.save();
|
|
21
|
+
Object.defineProperty(
|
|
22
|
+
req,
|
|
23
|
+
"session",
|
|
24
|
+
getPropertyDescriptorForReqSession(session),
|
|
25
|
+
);
|
|
26
|
+
return handler(req, res);
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function withIronSessionSsr<
|
|
31
|
+
P extends { [key: string]: unknown } = { [key: string]: unknown },
|
|
32
|
+
>(
|
|
33
|
+
handler: (
|
|
34
|
+
context: GetServerSidePropsContext,
|
|
35
|
+
) => GetServerSidePropsResult<P> | Promise<GetServerSidePropsResult<P>>,
|
|
36
|
+
options: IronSessionOptions,
|
|
37
|
+
) {
|
|
38
|
+
return async function nextGetServerSidePropsHandlerWrappedWithIronSession(
|
|
39
|
+
context: GetServerSidePropsContext,
|
|
40
|
+
) {
|
|
41
|
+
const session = await getIronSession(context.req, context.res, options);
|
|
42
|
+
Object.defineProperty(
|
|
43
|
+
context.req,
|
|
44
|
+
"session",
|
|
45
|
+
getPropertyDescriptorForReqSession(session),
|
|
46
|
+
);
|
|
47
|
+
return handler(context);
|
|
48
|
+
};
|
|
49
|
+
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iron-session",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.2",
|
|
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>",
|
|
6
|
-
"type": "module",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": {
|
|
9
9
|
"import": "./dist/index.mjs",
|
|
@@ -14,95 +14,130 @@
|
|
|
14
14
|
"import": "./next/dist/index.mjs",
|
|
15
15
|
"require": "./next/dist/index.js",
|
|
16
16
|
"types": "./next/dist/index.d.ts"
|
|
17
|
+
},
|
|
18
|
+
"./express": {
|
|
19
|
+
"import": "./express/dist/index.mjs",
|
|
20
|
+
"require": "./express/dist/index.js",
|
|
21
|
+
"types": "./express/dist/index.d.ts"
|
|
17
22
|
}
|
|
18
23
|
},
|
|
19
24
|
"main": "./dist/index.js",
|
|
20
25
|
"module": "./dist/index.mjs",
|
|
21
26
|
"types": "./dist/index.d.ts",
|
|
22
27
|
"files": [
|
|
23
|
-
"dist",
|
|
24
|
-
"next/
|
|
25
|
-
|
|
26
|
-
"workspaces": [
|
|
27
|
-
"examples/next.js",
|
|
28
|
-
"examples/next.js-typescript"
|
|
28
|
+
"dist/",
|
|
29
|
+
"next/",
|
|
30
|
+
"express/"
|
|
29
31
|
],
|
|
30
32
|
"scripts": {
|
|
31
|
-
"build": "
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
33
|
+
"build": "npm run build:clean && npm run build:src && npm run build:next && npm run build:express",
|
|
34
|
+
"build:clean": "rimraf dist/ next/dist express/dist",
|
|
35
|
+
"build:express": "tsup express/index.ts -d express/dist",
|
|
36
|
+
"build:next": "tsup next/index.ts -d next/dist",
|
|
37
|
+
"build:src": "tsup src/index.ts",
|
|
38
|
+
"installExamples": "(cd examples/express && npm ci) && (cd examples/next.js && npm ci) && (cd examples/next.js-typescript && npm ci)",
|
|
39
|
+
"lint": "eslint --ext ts,js,jsx,tsx src/ next/ express/ examples/",
|
|
40
|
+
"prepublishOnly": "npm run build && cp next/dist/* next/ && cp express/dist/* express/",
|
|
41
|
+
"postpublish": "rm next/*.d.ts next/*.js next/*.map next/*.mjs && rm express/*.d.ts express/*.js express/*.map express/*.mjs",
|
|
42
|
+
"test": "jest --coverage --ci && npm run installExamples && npm run lint && tsc --noEmit && npm run build && npm run build:clean",
|
|
43
|
+
"watch": "npm run build:clean && concurrently \"npm:watch:*\"",
|
|
44
|
+
"watch:express": "tsup express/index.ts -d express/dist --watch express/index.ts",
|
|
45
|
+
"watch:next": "tsup next/index.ts -d next/dist --watch next/index.ts",
|
|
46
|
+
"watch:src": "tsup src/index.ts --watch src/index.ts"
|
|
35
47
|
},
|
|
36
48
|
"prettier": {
|
|
37
49
|
"trailingComma": "all"
|
|
38
50
|
},
|
|
39
51
|
"eslintConfig": {
|
|
40
|
-
"parser": "@typescript-eslint/parser",
|
|
41
|
-
"parserOptions": {
|
|
42
|
-
"ecmaVersion": 2021,
|
|
43
|
-
"sourceType": "module"
|
|
44
|
-
},
|
|
45
|
-
"plugins": [
|
|
46
|
-
"@typescript-eslint"
|
|
47
|
-
],
|
|
48
52
|
"extends": [
|
|
49
|
-
"eslint:recommended"
|
|
50
|
-
"plugin:@typescript-eslint/recommended"
|
|
53
|
+
"eslint:recommended"
|
|
51
54
|
],
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
"
|
|
55
|
-
|
|
56
|
-
"
|
|
55
|
+
"overrides": [
|
|
56
|
+
{
|
|
57
|
+
"files": [
|
|
58
|
+
"**/*.ts",
|
|
59
|
+
"**/*.tsx"
|
|
60
|
+
],
|
|
61
|
+
"parser": "@typescript-eslint/parser",
|
|
62
|
+
"plugins": [
|
|
63
|
+
"@typescript-eslint"
|
|
64
|
+
],
|
|
65
|
+
"extends": [
|
|
66
|
+
"eslint:recommended",
|
|
67
|
+
"plugin:@typescript-eslint/recommended"
|
|
68
|
+
],
|
|
69
|
+
"rules": {
|
|
70
|
+
"@typescript-eslint/ban-ts-comment": [
|
|
71
|
+
"warn",
|
|
72
|
+
{
|
|
73
|
+
"ts-ignore": "allow-with-description"
|
|
74
|
+
}
|
|
75
|
+
]
|
|
57
76
|
}
|
|
58
|
-
|
|
59
|
-
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"files": "**/*.js",
|
|
80
|
+
"env": {
|
|
81
|
+
"node": true
|
|
82
|
+
},
|
|
83
|
+
"parser": "espree",
|
|
84
|
+
"parserOptions": {
|
|
85
|
+
"ecmaVersion": 2019
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
]
|
|
60
89
|
},
|
|
61
90
|
"jest": {
|
|
62
|
-
"collectCoverageFrom": [
|
|
63
|
-
"src/*.ts",
|
|
64
|
-
"next/*.ts"
|
|
65
|
-
],
|
|
66
|
-
"coverageProvider": "v8",
|
|
67
|
-
"coverageReporters": [
|
|
68
|
-
"text"
|
|
69
|
-
],
|
|
70
91
|
"transform": {
|
|
71
|
-
"
|
|
72
|
-
"@swc
|
|
92
|
+
"^.+\\.(t|j)sx?$": [
|
|
93
|
+
"@swc/jest",
|
|
73
94
|
{
|
|
95
|
+
"sourceMaps": true,
|
|
74
96
|
"jsc": {
|
|
75
|
-
"
|
|
97
|
+
"parser": {
|
|
98
|
+
"syntax": "typescript"
|
|
99
|
+
},
|
|
100
|
+
"paths": {
|
|
101
|
+
"iron-session": [
|
|
102
|
+
"../src/index.ts"
|
|
103
|
+
]
|
|
104
|
+
}
|
|
76
105
|
}
|
|
77
106
|
}
|
|
78
107
|
]
|
|
79
108
|
}
|
|
80
109
|
},
|
|
81
110
|
"dependencies": {
|
|
111
|
+
"@hapi/iron": "^6.0.0",
|
|
82
112
|
"@types/cookie": "^0.4.0",
|
|
83
|
-
"@types/
|
|
84
|
-
"
|
|
85
|
-
"
|
|
113
|
+
"@types/express": "^4.17.13",
|
|
114
|
+
"@types/node": "^16.11.6",
|
|
115
|
+
"cookie": "^0.4.1"
|
|
86
116
|
},
|
|
87
117
|
"devDependencies": {
|
|
88
|
-
"@swc
|
|
118
|
+
"@swc/core": "1.2.106",
|
|
119
|
+
"@swc/jest": "0.2.5",
|
|
89
120
|
"@tsconfig/node12": "1.0.9",
|
|
90
121
|
"@types/jest": "27.0.2",
|
|
91
|
-
"@typescript-eslint/eslint-plugin": "5.
|
|
92
|
-
"@typescript-eslint/parser": "5.
|
|
93
|
-
"
|
|
122
|
+
"@typescript-eslint/eslint-plugin": "5.3.0",
|
|
123
|
+
"@typescript-eslint/parser": "5.3.0",
|
|
124
|
+
"concurrently": "6.3.0",
|
|
125
|
+
"eslint": "8.1.0",
|
|
94
126
|
"jest": "27.3.1",
|
|
95
|
-
"jest-date-mock": "1.0.8",
|
|
96
127
|
"prettier": "2.4.1",
|
|
97
128
|
"prettier-plugin-packagejson": "2.2.13",
|
|
98
129
|
"rimraf": "3.0.2",
|
|
99
|
-
"tsup": "5.
|
|
130
|
+
"tsup": "5.6.0",
|
|
100
131
|
"typescript": "4.4.4"
|
|
101
132
|
},
|
|
102
133
|
"peerDependencies": {
|
|
134
|
+
"express": ">=4",
|
|
103
135
|
"next": ">=10"
|
|
104
136
|
},
|
|
105
137
|
"peerDependenciesMeta": {
|
|
138
|
+
"express": {
|
|
139
|
+
"optional": true
|
|
140
|
+
},
|
|
106
141
|
"next": {
|
|
107
142
|
"optional": true
|
|
108
143
|
}
|
package/dist/index.cjs
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
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.cjs.map
|
package/dist/index.cjs.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
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/next/dist/index.cjs.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
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
|
-
}
|