iron-session 9.0.0-beta.1 → 9.0.0
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/MIGRATION.md +7 -2
- package/README.md +70 -1
- package/package.json +1 -1
package/MIGRATION.md
CHANGED
|
@@ -2,15 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
## v8 to v9
|
|
4
4
|
|
|
5
|
+
```sh
|
|
6
|
+
pnpm add iron-session # latest
|
|
7
|
+
pnpm add iron-session@beta # prereleases
|
|
8
|
+
```
|
|
9
|
+
|
|
5
10
|
Most apps need two changes: Node 22 and one line if you store a `Date` in the
|
|
6
11
|
session. Everything else below is either a type error TypeScript will point at,
|
|
7
12
|
or a bug fix you want.
|
|
8
13
|
|
|
9
14
|
### Requirements
|
|
10
15
|
|
|
11
|
-
- **Node 22.
|
|
16
|
+
- **Node 22.13 or later.** Node 20 reached end of life in April 2026.
|
|
12
17
|
- **The package is ESM-only.** There is no CommonJS build. `require()` still
|
|
13
|
-
works on Node 22.
|
|
18
|
+
works on Node 22.13+, which supports `require()` of an ES module, so most CJS
|
|
14
19
|
code keeps working. If you are bundling for an older target, keep v8.
|
|
15
20
|
|
|
16
21
|
### Do this
|
package/README.md
CHANGED
|
@@ -14,6 +14,7 @@ The session data is stored in signed and encrypted cookies which are decoded by
|
|
|
14
14
|
|
|
15
15
|
- [Table of Contents](#table-of-contents)
|
|
16
16
|
- [Installation](#installation)
|
|
17
|
+
- [Upgrading to v9](#upgrading-to-v9)
|
|
17
18
|
- [Usage](#usage)
|
|
18
19
|
- [Examples](#examples)
|
|
19
20
|
- [Runtimes](#runtimes)
|
|
@@ -25,6 +26,7 @@ The session data is stored in signed and encrypted cookies which are decoded by
|
|
|
25
26
|
- [API](#api)
|
|
26
27
|
- [`getIronSession<T>(req, res, sessionOptions): Promise<IronSession<T>>`](#getironsessiontreq-res-sessionoptions-promiseironsessiont)
|
|
27
28
|
- [`getIronSession<T>(cookieStore, sessionOptions): Promise<IronSession<T>>`](#getironsessiontcookiestore-sessionoptions-promiseironsessiont)
|
|
29
|
+
- [`nodeCookies`, `webCookies`, `nextProxyCookies`](#nodecookiesreq-res-webcookiesrequest-responseorheaders-nextproxycookiesrequest-response)
|
|
28
30
|
- [`session.save(): Promise<void>`](#sessionsave-promisevoid)
|
|
29
31
|
- [`session.destroy(): void`](#sessiondestroy-void)
|
|
30
32
|
- [`session.updateConfig(sessionOptions: SessionOptions): void`](#sessionupdateconfigsessionoptions-sessionoptions-void)
|
|
@@ -44,6 +46,57 @@ The session data is stored in signed and encrypted cookies which are decoded by
|
|
|
44
46
|
pnpm add iron-session
|
|
45
47
|
```
|
|
46
48
|
|
|
49
|
+
Prereleases are published under the `beta` tag:
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
pnpm add iron-session@beta
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
v9 needs **Node 22.13 or later** and is **ESM-only**. `require()` still works on
|
|
56
|
+
Node 22.13+, which supports `require()` of an ES module. If you are stuck on an
|
|
57
|
+
older Node, stay on v8: `pnpm add iron-session@8`.
|
|
58
|
+
|
|
59
|
+
## Upgrading to v9
|
|
60
|
+
|
|
61
|
+
Most apps change two things. Both are things v8 got wrong quietly.
|
|
62
|
+
|
|
63
|
+
**1. Store timestamps, not `Date` objects.**
|
|
64
|
+
|
|
65
|
+
```diff
|
|
66
|
+
- session.lastSeen = new Date();
|
|
67
|
+
+ session.lastSeen = Date.now();
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
v8 turned a `Date` into a string when sealing, so the type you wrote was not the
|
|
71
|
+
type you read back. v9 throws and names the field.
|
|
72
|
+
|
|
73
|
+
**2. Handle a session that does not exist yet.**
|
|
74
|
+
|
|
75
|
+
```diff
|
|
76
|
+
- const userId = session.user.id;
|
|
77
|
+
+ const userId = session.user?.id;
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Reads are typed as `Partial<T>` now. A first visit, an expired cookie and a
|
|
81
|
+
`destroy()` all leave you an empty object, so the old type let this compile and
|
|
82
|
+
then throw at runtime.
|
|
83
|
+
|
|
84
|
+
Nothing else is required. `getIronSession(req, res, options)` and
|
|
85
|
+
`getIronSession(await cookies(), options)` both still work, v9 reads v8 cookies
|
|
86
|
+
and v8 reads v9 cookies, so you can roll a deploy back without signing everyone
|
|
87
|
+
out. If you had `as any` on `await cookies()`, delete it.
|
|
88
|
+
|
|
89
|
+
Worth adopting while you are here:
|
|
90
|
+
|
|
91
|
+
- [`nextProxyCookies`](#runtimes) if you ever tried to save a session in Next.js
|
|
92
|
+
middleware and it did not stick.
|
|
93
|
+
- [`onUnsealError`](#watching-for-unreadable-cookies) to see why cookies get
|
|
94
|
+
rejected instead of guessing.
|
|
95
|
+
- [`chunk: true`](#session-size) if your session outgrew one cookie.
|
|
96
|
+
|
|
97
|
+
The full guide, including the removed APIs and the security fix that signs pre-v8
|
|
98
|
+
cookies out once, is in [MIGRATION.md](./MIGRATION.md).
|
|
99
|
+
|
|
47
100
|
## Usage
|
|
48
101
|
|
|
49
102
|
_We have extensive examples here too: https://get-iron-session.vercel.app/._
|
|
@@ -258,7 +311,21 @@ type SessionData = {
|
|
|
258
311
|
// Your data
|
|
259
312
|
};
|
|
260
313
|
|
|
261
|
-
const session = await getIronSession<SessionData>(cookies(), sessionOptions);
|
|
314
|
+
const session = await getIronSession<SessionData>(await cookies(), sessionOptions);
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Reads are typed as `Partial<T>`, because a session that does not exist yet is an
|
|
318
|
+
empty object. Use optional chaining, or narrow once and pass the result around.
|
|
319
|
+
|
|
320
|
+
### `nodeCookies(req, res)`, `webCookies(request, responseOrHeaders)`, `nextProxyCookies(request, response)`
|
|
321
|
+
|
|
322
|
+
Cookie jars you pass in place of `req, res`, for when the shorthand cannot tell
|
|
323
|
+
what your framework wants. See [Runtimes](#runtimes).
|
|
324
|
+
|
|
325
|
+
```ts
|
|
326
|
+
import { getIronSession, nextProxyCookies } from "iron-session";
|
|
327
|
+
|
|
328
|
+
const session = await getIronSession(nextProxyCookies(request, response), sessionOptions);
|
|
262
329
|
```
|
|
263
330
|
|
|
264
331
|
### `session.save(): Promise<void>`
|
|
@@ -283,6 +350,8 @@ session.destroy();
|
|
|
283
350
|
|
|
284
351
|
Updates the configuration of the session with new session options. You still need to call save() if you want them to be applied.
|
|
285
352
|
|
|
353
|
+
It rebuilds the whole configuration, including the password, so this is what you use to rotate a password mid-request. In v8 a new password passed here was ignored.
|
|
354
|
+
|
|
286
355
|
### `sealData(data: unknown, { password, ttl }): Promise<string>`
|
|
287
356
|
|
|
288
357
|
This is the underlying method and seal mechanism that powers `iron-session`. You can use it to seal any `data` you want and pass it around. One usecase are magic links: you generate a seal that contains a user id to login and send it to a route on your website (like `/magic-login`). Once received, you can safely decode the seal with `unsealData` and log the user in.
|