@c9up/ream 0.2.27 → 0.2.29
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 +1 -0
- package/dist/Codemods.d.ts +16 -0
- package/dist/Codemods.d.ts.map +1 -1
- package/dist/Codemods.js +182 -0
- package/dist/Codemods.js.map +1 -1
- package/dist/Ignitor.d.ts +11 -1
- package/dist/Ignitor.d.ts.map +1 -1
- package/dist/Ignitor.js +27 -21
- package/dist/Ignitor.js.map +1 -1
- package/dist/bodyparser/BodyParserMiddleware.d.ts.map +1 -1
- package/dist/bodyparser/BodyParserMiddleware.js +3 -0
- package/dist/bodyparser/BodyParserMiddleware.js.map +1 -1
- package/dist/bodyparser/qsParse.d.ts +10 -1
- package/dist/bodyparser/qsParse.d.ts.map +1 -1
- package/dist/bodyparser/qsParse.js +53 -15
- package/dist/bodyparser/qsParse.js.map +1 -1
- package/dist/codemods/source.d.ts +57 -0
- package/dist/codemods/source.d.ts.map +1 -0
- package/dist/codemods/source.js +282 -0
- package/dist/codemods/source.js.map +1 -0
- package/dist/graphql/GraphQLEngine.d.ts.map +1 -1
- package/dist/graphql/GraphQLEngine.js +3 -2
- package/dist/graphql/GraphQLEngine.js.map +1 -1
- package/dist/http/Exception.d.ts +14 -1
- package/dist/http/Exception.d.ts.map +1 -1
- package/dist/http/Exception.js +10 -2
- package/dist/http/Exception.js.map +1 -1
- package/dist/http/HttpContext.d.ts +11 -0
- package/dist/http/HttpContext.d.ts.map +1 -1
- package/dist/http/HttpContext.js +2 -1
- package/dist/http/HttpContext.js.map +1 -1
- package/dist/http/RedirectBuilder.d.ts +9 -3
- package/dist/http/RedirectBuilder.d.ts.map +1 -1
- package/dist/http/RedirectBuilder.js +39 -37
- package/dist/http/RedirectBuilder.js.map +1 -1
- package/dist/http/Request.d.ts +42 -17
- package/dist/http/Request.d.ts.map +1 -1
- package/dist/http/Request.js +65 -29
- package/dist/http/Request.js.map +1 -1
- package/dist/http/SseStream.js +6 -7
- package/dist/http/SseStream.js.map +1 -1
- package/dist/http/permissions.d.ts +19 -0
- package/dist/http/permissions.d.ts.map +1 -0
- package/dist/http/permissions.js +28 -0
- package/dist/http/permissions.js.map +1 -0
- package/dist/http-client/HttpClient.d.ts +111 -0
- package/dist/http-client/HttpClient.d.ts.map +1 -0
- package/dist/http-client/HttpClient.js +386 -0
- package/dist/http-client/HttpClient.js.map +1 -0
- package/dist/http-client/addresses.d.ts +14 -0
- package/dist/http-client/addresses.d.ts.map +1 -0
- package/dist/http-client/addresses.js +57 -0
- package/dist/http-client/addresses.js.map +1 -0
- package/dist/http-client/fake.d.ts +50 -0
- package/dist/http-client/fake.d.ts.map +1 -0
- package/dist/http-client/fake.js +95 -0
- package/dist/http-client/fake.js.map +1 -0
- package/dist/http-client/index.d.ts +7 -0
- package/dist/http-client/index.d.ts.map +1 -0
- package/dist/http-client/index.js +7 -0
- package/dist/http-client/index.js.map +1 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/middleware/Pipeline.d.ts.map +1 -1
- package/dist/middleware/Pipeline.js +6 -3
- package/dist/middleware/Pipeline.js.map +1 -1
- package/dist/native/generated.d.ts +108 -3
- package/dist/native/generated.d.ts.map +1 -1
- package/dist/rpc/RpcProvider.d.ts +6 -0
- package/dist/rpc/RpcProvider.d.ts.map +1 -1
- package/dist/rpc/RpcProvider.js +4 -1
- package/dist/rpc/RpcProvider.js.map +1 -1
- package/dist/rpc/RpcRouter.d.ts +27 -14
- package/dist/rpc/RpcRouter.d.ts.map +1 -1
- package/dist/rpc/RpcRouter.js +95 -38
- package/dist/rpc/RpcRouter.js.map +1 -1
- package/dist/scheduler/locks/RedisLockBackend.d.ts.map +1 -1
- package/dist/scheduler/locks/RedisLockBackend.js +13 -2
- package/dist/scheduler/locks/RedisLockBackend.js.map +1 -1
- package/dist/security/CookieSigner.d.ts.map +1 -1
- package/dist/security/CookieSigner.js +17 -3
- package/dist/security/CookieSigner.js.map +1 -1
- package/dist/security/SignedUrl.d.ts.map +1 -1
- package/dist/security/SignedUrl.js +6 -1
- package/dist/security/SignedUrl.js.map +1 -1
- package/dist/server/Server.d.ts +75 -9
- package/dist/server/Server.d.ts.map +1 -1
- package/dist/server/Server.js +60 -9
- package/dist/server/Server.js.map +1 -1
- package/dist/server/nativeGrpc.d.ts +27 -0
- package/dist/server/nativeGrpc.d.ts.map +1 -0
- package/dist/server/nativeGrpc.js +47 -0
- package/dist/server/nativeGrpc.js.map +1 -0
- package/dist/server/nativeLimits.d.ts +49 -0
- package/dist/server/nativeLimits.d.ts.map +1 -0
- package/dist/server/nativeLimits.js +67 -0
- package/dist/server/nativeLimits.js.map +1 -0
- package/dist/session/Session.d.ts +45 -0
- package/dist/session/Session.d.ts.map +1 -1
- package/dist/session/Session.js +31 -2
- package/dist/session/Session.js.map +1 -1
- package/dist/session/SessionMiddleware.d.ts.map +1 -1
- package/dist/session/SessionMiddleware.js +52 -13
- package/dist/session/SessionMiddleware.js.map +1 -1
- package/dist/session/config.d.ts +5 -0
- package/dist/session/config.d.ts.map +1 -1
- package/dist/session/config.js +8 -0
- package/dist/session/config.js.map +1 -1
- package/dist/session/drivers/CookieDriver.d.ts +12 -3
- package/dist/session/drivers/CookieDriver.d.ts.map +1 -1
- package/dist/session/drivers/CookieDriver.js +20 -6
- package/dist/session/drivers/CookieDriver.js.map +1 -1
- package/dist/session/drivers/DatabaseDriver.d.ts +2 -0
- package/dist/session/drivers/DatabaseDriver.d.ts.map +1 -1
- package/dist/session/drivers/DatabaseDriver.js +6 -0
- package/dist/session/drivers/DatabaseDriver.js.map +1 -1
- package/dist/session/drivers/FileDriver.d.ts +8 -0
- package/dist/session/drivers/FileDriver.d.ts.map +1 -1
- package/dist/session/drivers/FileDriver.js +85 -11
- package/dist/session/drivers/FileDriver.js.map +1 -1
- package/dist/session/drivers/MemoryDriver.d.ts +2 -0
- package/dist/session/drivers/MemoryDriver.d.ts.map +1 -1
- package/dist/session/drivers/MemoryDriver.js +21 -5
- package/dist/session/drivers/MemoryDriver.js.map +1 -1
- package/dist/session/drivers/RedisDriver.d.ts +2 -0
- package/dist/session/drivers/RedisDriver.d.ts.map +1 -1
- package/dist/session/drivers/RedisDriver.js +6 -0
- package/dist/session/drivers/RedisDriver.js.map +1 -1
- package/dist/session/errors.d.ts +27 -0
- package/dist/session/errors.d.ts.map +1 -1
- package/dist/session/errors.js +33 -0
- package/dist/session/errors.js.map +1 -1
- package/dist/session/templateTags.d.ts +14 -0
- package/dist/session/templateTags.d.ts.map +1 -1
- package/dist/session/templateTags.js +45 -17
- package/dist/session/templateTags.js.map +1 -1
- package/dist/storage/StaticMiddleware.d.ts.map +1 -1
- package/dist/storage/StaticMiddleware.js +29 -18
- package/dist/storage/StaticMiddleware.js.map +1 -1
- package/events.darwin-arm64.node +0 -0
- package/events.darwin-x64.node +0 -0
- package/events.linux-arm64-gnu.node +0 -0
- package/events.linux-x64-gnu.node +0 -0
- package/events.win32-x64-msvc.node +0 -0
- package/index.darwin-arm64.node +0 -0
- package/index.darwin-x64.node +0 -0
- package/index.linux-arm64-gnu.node +0 -0
- package/index.linux-x64-gnu.node +0 -0
- package/index.win32-x64-msvc.node +0 -0
- package/package.json +11 -2
- package/scheduler.darwin-arm64.node +0 -0
- package/scheduler.darwin-x64.node +0 -0
- package/scheduler.linux-arm64-gnu.node +0 -0
- package/scheduler.linux-x64-gnu.node +0 -0
- package/scheduler.win32-x64-msvc.node +0 -0
- package/src/Codemods.ts +265 -0
- package/src/Ignitor.ts +48 -20
- package/src/bodyparser/BodyParserMiddleware.ts +3 -0
- package/src/bodyparser/qsParse.ts +69 -14
- package/src/codemods/source.ts +303 -0
- package/src/graphql/GraphQLEngine.ts +3 -2
- package/src/http/Exception.ts +17 -2
- package/src/http/HttpContext.ts +14 -1
- package/src/http/RedirectBuilder.ts +48 -37
- package/src/http/Request.ts +87 -29
- package/src/http/SseStream.ts +6 -7
- package/src/http/permissions.ts +31 -0
- package/src/http-client/HttpClient.ts +505 -0
- package/src/http-client/addresses.ts +58 -0
- package/src/http-client/fake.ts +141 -0
- package/src/http-client/index.ts +21 -0
- package/src/index.ts +9 -1
- package/src/middleware/Pipeline.ts +7 -3
- package/src/native/generated.ts +123 -3
- package/src/rpc/RpcProvider.ts +10 -1
- package/src/rpc/RpcRouter.ts +126 -42
- package/src/scheduler/locks/RedisLockBackend.ts +12 -4
- package/src/security/CookieSigner.ts +17 -3
- package/src/security/SignedUrl.ts +6 -1
- package/src/server/Server.ts +103 -9
- package/src/server/nativeGrpc.ts +59 -0
- package/src/server/nativeLimits.ts +94 -0
- package/src/session/Session.ts +72 -2
- package/src/session/SessionMiddleware.ts +53 -14
- package/src/session/config.ts +7 -0
- package/src/session/drivers/CookieDriver.ts +21 -6
- package/src/session/drivers/DatabaseDriver.ts +10 -0
- package/src/session/drivers/FileDriver.ts +91 -11
- package/src/session/drivers/MemoryDriver.ts +20 -5
- package/src/session/drivers/RedisDriver.ts +7 -0
- package/src/session/errors.ts +48 -0
- package/src/session/templateTags.ts +57 -0
- package/src/storage/StaticMiddleware.ts +28 -18
|
@@ -13,6 +13,7 @@ import { DatabaseDriver } from './drivers/DatabaseDriver.js';
|
|
|
13
13
|
import { FileDriver } from './drivers/FileDriver.js';
|
|
14
14
|
import { MemoryDriver } from './drivers/MemoryDriver.js';
|
|
15
15
|
import { RedisDriver } from './drivers/RedisDriver.js';
|
|
16
|
+
import { E_SESSION_COOKIE_NOT_HTTP_ONLY, E_SESSION_STORE_NOT_CONFIGURED } from './errors.js';
|
|
16
17
|
import { quasarConnection } from './quasar.js';
|
|
17
18
|
import { ReadOnlyValuesStore } from './ReadOnlyValuesStore.js';
|
|
18
19
|
import { Session } from './Session.js';
|
|
@@ -44,8 +45,17 @@ export default class SessionMiddleware {
|
|
|
44
45
|
// `{ store: 'redis', stores: { redis: { driver: 'redis' } } }` works.
|
|
45
46
|
const selected = config?.store ?? config?.driver;
|
|
46
47
|
const named = selected ? config?.stores?.[selected] : undefined;
|
|
48
|
+
// No implicit store, in any environment — AdonisJS' session config
|
|
49
|
+
// refuses one without `store` too. The memory store lives in one process
|
|
50
|
+
// and is bounded: a restart, a second replica, or enough anonymous
|
|
51
|
+
// requests signs every user out, so it is used only when it is chosen
|
|
52
|
+
// (`store: 'memory'`).
|
|
53
|
+
if (!selected)
|
|
54
|
+
throw new E_SESSION_STORE_NOT_CONFIGURED();
|
|
55
|
+
if (config?.cookie?.httpOnly === false)
|
|
56
|
+
throw new E_SESSION_COOKIE_NOT_HTTP_ONLY();
|
|
47
57
|
this.#config = {
|
|
48
|
-
driver: named?.driver ?? selected
|
|
58
|
+
driver: named?.driver ?? selected,
|
|
49
59
|
cookieName: config?.cookieName ?? 'ream_session',
|
|
50
60
|
// `age` is the AdonisJS key and accepts a duration string.
|
|
51
61
|
maxAge: config?.age !== undefined
|
|
@@ -53,12 +63,13 @@ export default class SessionMiddleware {
|
|
|
53
63
|
: (config?.maxAge ?? 7200),
|
|
54
64
|
clearWithBrowser: config?.clearWithBrowser ?? false,
|
|
55
65
|
rolling: config?.rolling ?? false,
|
|
66
|
+
cookie: { ...config?.cookie },
|
|
56
67
|
};
|
|
57
68
|
if (this.#config.driver === 'cookie') {
|
|
58
69
|
if (!config?.secret) {
|
|
59
70
|
throw new Error('Cookie session driver requires a secret. Set session.secret in your config.');
|
|
60
71
|
}
|
|
61
|
-
this.#cookieDriver = new CookieDriver(config.secret);
|
|
72
|
+
this.#cookieDriver = new CookieDriver(config.secret, this.#config.cookieName);
|
|
62
73
|
this.#driver = this.#cookieDriver;
|
|
63
74
|
}
|
|
64
75
|
else if (this.#config.driver === 'memory') {
|
|
@@ -113,6 +124,9 @@ export default class SessionMiddleware {
|
|
|
113
124
|
const hadIncomingCookie = sessionId !== null;
|
|
114
125
|
// Cookie driver: the cookie value IS the session data (encrypted)
|
|
115
126
|
if (this.#cookieDriver) {
|
|
127
|
+
// When the data this request carries was last vouched for. See the
|
|
128
|
+
// re-emission below.
|
|
129
|
+
const readAt = Date.now();
|
|
116
130
|
const data = await this.#driver.read(sessionId ?? '');
|
|
117
131
|
sessionId = sessionId ?? generateSessionId();
|
|
118
132
|
// `null` means the cookie carried nothing readable — an empty session,
|
|
@@ -137,8 +151,20 @@ export default class SessionMiddleware {
|
|
|
137
151
|
// the cookie maxAge window slides forward (active users don't time out
|
|
138
152
|
// mid-session). Caller opts in via SessionConfig.rolling.
|
|
139
153
|
const shouldEmit = session.isDirty() || (rolling && hadIncomingCookie);
|
|
140
|
-
|
|
141
|
-
|
|
154
|
+
// The re-emitted cookie lives `maxAge` from when this request READ the
|
|
155
|
+
// session, not from its response. Counted from the response, a request
|
|
156
|
+
// that outlasted a logout re-issued the signed-in data with a full new
|
|
157
|
+
// lifetime — past the window a revocation is kept for, after which the
|
|
158
|
+
// sign-in it carried was accepted again. Counted from the read, no cookie
|
|
159
|
+
// carrying a sign-in outlives the logout by more than `maxAge`. A session
|
|
160
|
+
// regenerated during the request (a login) is new data, so it counts from
|
|
161
|
+
// now; so does a session that came in with no cookie.
|
|
162
|
+
const issuedAt = hadIncomingCookie && !session.wasRegenerated() ? readAt : Date.now();
|
|
163
|
+
const remaining = issuedAt + maxAge * 1000 - Date.now();
|
|
164
|
+
// Expired while the request ran: nothing to hand back, and the browser
|
|
165
|
+
// keeps whatever cookie it was given since.
|
|
166
|
+
if (shouldEmit && remaining > 0) {
|
|
167
|
+
const encoded = this.#cookieDriver.encode(session.toJSON(), remaining / 1000);
|
|
142
168
|
if (encoded.length > 4096) {
|
|
143
169
|
process.stderr.write(`[session] Cookie session exceeds 4096 bytes (${encoded.length}). ` +
|
|
144
170
|
'Switch to a server-side driver (memory/redis) or reduce session data.\n');
|
|
@@ -147,11 +173,8 @@ export default class SessionMiddleware {
|
|
|
147
173
|
// Already encrypted by the cookie driver; packing it again would
|
|
148
174
|
// only make the cookie bigger and change nothing.
|
|
149
175
|
encode: false,
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
httpOnly: true,
|
|
153
|
-
sameSite: 'lax',
|
|
154
|
-
secure: isProduction,
|
|
176
|
+
...this.#cookieAttributes(isProduction),
|
|
177
|
+
maxAge: this.#config.clearWithBrowser ? undefined : Math.ceil(remaining / 1000),
|
|
155
178
|
});
|
|
156
179
|
}
|
|
157
180
|
return;
|
|
@@ -184,6 +207,11 @@ export default class SessionMiddleware {
|
|
|
184
207
|
// no server-side row (touch() is a no-op without a backing entry),
|
|
185
208
|
// defeats HTTP caching, and leaks a Set-Cookie to CDNs. This mirrors
|
|
186
209
|
// the cookie-driver path above (which already omits `isNew`).
|
|
210
|
+
// A session logged out or rotated by another request while this one ran
|
|
211
|
+
// was not written back (see `Session.wasLost`); handing the browser its id
|
|
212
|
+
// again would only point it at nothing, over the cookie it got since.
|
|
213
|
+
if (session.wasLost())
|
|
214
|
+
return;
|
|
187
215
|
if (session.isDirty() || regenerated || (rolling && hadIncomingCookie)) {
|
|
188
216
|
// SIGNED, as AdonisJS signs it (`response.cookie(cookieName, id, …)`).
|
|
189
217
|
// The id is 192 bits of entropy, so it was never guessable — what the
|
|
@@ -191,14 +219,25 @@ export default class SessionMiddleware {
|
|
|
191
219
|
// read, before any store lookup, and that an id from another deployment
|
|
192
220
|
// (a different APP_KEY) cannot be presented here.
|
|
193
221
|
ctx.response.cookie(cookieName, session.sessionId, {
|
|
222
|
+
...this.#cookieAttributes(isProduction),
|
|
194
223
|
maxAge: this.#config.clearWithBrowser ? undefined : maxAge,
|
|
195
|
-
path: '/',
|
|
196
|
-
httpOnly: true,
|
|
197
|
-
sameSite: 'lax',
|
|
198
|
-
secure: isProduction,
|
|
199
224
|
});
|
|
200
225
|
}
|
|
201
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* The session cookie's attributes: the configured `cookie` over the
|
|
229
|
+
* defaults. `secure` follows the environment unless the config sets it.
|
|
230
|
+
*/
|
|
231
|
+
#cookieAttributes(isProduction) {
|
|
232
|
+
const configured = this.#config.cookie;
|
|
233
|
+
return {
|
|
234
|
+
path: '/',
|
|
235
|
+
sameSite: 'lax',
|
|
236
|
+
...configured,
|
|
237
|
+
httpOnly: true,
|
|
238
|
+
secure: configured.secure ?? isProduction,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
202
241
|
}
|
|
203
242
|
function generateSessionId() {
|
|
204
243
|
return randomBytes(24).toString('base64url');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionMiddleware.js","sourceRoot":"","sources":["../../src/session/SessionMiddleware.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"SessionMiddleware.js","sourceRoot":"","sources":["../../src/session/SessionMiddleware.ts"],"names":[],"mappings":"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"}
|
package/dist/session/config.d.ts
CHANGED
|
@@ -21,5 +21,10 @@ export type SessionConfigInput = SessionConfig & {
|
|
|
21
21
|
*/
|
|
22
22
|
secret?: string;
|
|
23
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* Validate and return a session config. A config without `store` (or its
|
|
26
|
+
* older spelling `driver`) is refused here, at load time, as AdonisJS'
|
|
27
|
+
* `defineConfig` refuses it: there is no implicit store.
|
|
28
|
+
*/
|
|
24
29
|
export declare function defineConfig(config: SessionConfigInput): SessionConfigInput;
|
|
25
30
|
//# sourceMappingURL=config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/session/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/session/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAEjD,8CAA8C;AAC9C,MAAM,MAAM,kBAAkB,GAAG,aAAa,GAAG;IAC/C;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,kBAAkB,CAG3E"}
|
package/dist/session/config.js
CHANGED
|
@@ -12,7 +12,15 @@
|
|
|
12
12
|
* secret: env.get('APP_KEY'),
|
|
13
13
|
* })
|
|
14
14
|
*/
|
|
15
|
+
import { E_SESSION_STORE_NOT_CONFIGURED } from './errors.js';
|
|
16
|
+
/**
|
|
17
|
+
* Validate and return a session config. A config without `store` (or its
|
|
18
|
+
* older spelling `driver`) is refused here, at load time, as AdonisJS'
|
|
19
|
+
* `defineConfig` refuses it: there is no implicit store.
|
|
20
|
+
*/
|
|
15
21
|
export function defineConfig(config) {
|
|
22
|
+
if (!config.store && !config.driver)
|
|
23
|
+
throw new E_SESSION_STORE_NOT_CONFIGURED();
|
|
16
24
|
return config;
|
|
17
25
|
}
|
|
18
26
|
//# sourceMappingURL=config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/session/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/session/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,8BAA8B,EAAE,MAAM,aAAa,CAAA;AAY5D;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,MAA0B;IACrD,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,MAAM,IAAI,8BAA8B,EAAE,CAAA;IAC/E,OAAO,MAAM,CAAA;AACf,CAAC"}
|
|
@@ -3,15 +3,24 @@ import type { SessionDriver } from '../Session.js';
|
|
|
3
3
|
* Cookie session driver — stores session data in an encrypted cookie (AES-256-GCM).
|
|
4
4
|
* Stateless on the server. Limited by cookie size (~4KB).
|
|
5
5
|
* Requires a secret for encryption.
|
|
6
|
+
*
|
|
7
|
+
* Sealed for the cookie's name, as upstream seals every encrypted cookie, so a
|
|
8
|
+
* value encrypted for another cookie under the same key cannot be presented as
|
|
9
|
+
* the session. And sealed with its expiry — the named deviation: upstream
|
|
10
|
+
* leaves expiry to the browser's `maxAge`, which a copied cookie does not
|
|
11
|
+
* obey, so a session lifted from a browser stayed valid for as long as the key
|
|
12
|
+
* did. Here a value older than the session's lifetime opens as nothing.
|
|
6
13
|
*/
|
|
7
14
|
export declare class CookieDriver implements SessionDriver {
|
|
8
15
|
#private;
|
|
9
|
-
|
|
16
|
+
readonly stateless = true;
|
|
17
|
+
constructor(secret: string, cookieName?: string);
|
|
10
18
|
read(sessionId: string): Promise<Record<string, unknown> | null>;
|
|
11
19
|
write(_sessionId: string, _data: Record<string, unknown>, _ttl: number): Promise<void>;
|
|
20
|
+
update(_sessionId: string, _data: Record<string, unknown>, _ttl: number): Promise<boolean>;
|
|
12
21
|
destroy(_sessionId: string): Promise<void>;
|
|
13
22
|
touch(_sessionId: string, _ttl: number): Promise<void>;
|
|
14
|
-
/** Encode session data for cookie storage (encrypted). */
|
|
15
|
-
encode(data: Record<string, unknown
|
|
23
|
+
/** Encode session data for cookie storage (encrypted), valid for `ttl` seconds. */
|
|
24
|
+
encode(data: Record<string, unknown>, ttl: number): string;
|
|
16
25
|
}
|
|
17
26
|
//# sourceMappingURL=CookieDriver.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CookieDriver.d.ts","sourceRoot":"","sources":["../../../src/session/drivers/CookieDriver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAElD
|
|
1
|
+
{"version":3,"file":"CookieDriver.d.ts","sourceRoot":"","sources":["../../../src/session/drivers/CookieDriver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAElD;;;;;;;;;;;GAWG;AACH,qBAAa,YAAa,YAAW,aAAa;;IAGhD,QAAQ,CAAC,SAAS,QAAO;gBAEb,MAAM,EAAE,MAAM,EAAE,UAAU,SAAiB;IAUjD,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAWhE,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAItF,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK1F,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5D,mFAAmF;IACnF,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;CAG3D"}
|
|
@@ -3,20 +3,30 @@ import { CookieSigner } from '../../security/CookieSigner.js';
|
|
|
3
3
|
* Cookie session driver — stores session data in an encrypted cookie (AES-256-GCM).
|
|
4
4
|
* Stateless on the server. Limited by cookie size (~4KB).
|
|
5
5
|
* Requires a secret for encryption.
|
|
6
|
+
*
|
|
7
|
+
* Sealed for the cookie's name, as upstream seals every encrypted cookie, so a
|
|
8
|
+
* value encrypted for another cookie under the same key cannot be presented as
|
|
9
|
+
* the session. And sealed with its expiry — the named deviation: upstream
|
|
10
|
+
* leaves expiry to the browser's `maxAge`, which a copied cookie does not
|
|
11
|
+
* obey, so a session lifted from a browser stayed valid for as long as the key
|
|
12
|
+
* did. Here a value older than the session's lifetime opens as nothing.
|
|
6
13
|
*/
|
|
7
14
|
export class CookieDriver {
|
|
8
15
|
#signer;
|
|
9
|
-
|
|
16
|
+
#purpose;
|
|
17
|
+
stateless = true;
|
|
18
|
+
constructor(secret, cookieName = 'ream_session') {
|
|
10
19
|
if (!secret) {
|
|
11
20
|
throw new Error('CookieDriver requires a secret for session encryption. Set session.secret in your config.');
|
|
12
21
|
}
|
|
13
22
|
this.#signer = new CookieSigner(secret);
|
|
23
|
+
this.#purpose = cookieName;
|
|
14
24
|
}
|
|
15
25
|
async read(sessionId) {
|
|
16
26
|
if (!sessionId)
|
|
17
27
|
return null;
|
|
18
|
-
const decrypted = this.#signer.decrypt(sessionId);
|
|
19
|
-
if (
|
|
28
|
+
const decrypted = this.#signer.decrypt(sessionId, this.#purpose);
|
|
29
|
+
if (typeof decrypted !== 'string')
|
|
20
30
|
return null;
|
|
21
31
|
try {
|
|
22
32
|
return JSON.parse(decrypted);
|
|
@@ -28,15 +38,19 @@ export class CookieDriver {
|
|
|
28
38
|
async write(_sessionId, _data, _ttl) {
|
|
29
39
|
// Cookie driver writes via the response cookie — handled by middleware
|
|
30
40
|
}
|
|
41
|
+
async update(_sessionId, _data, _ttl) {
|
|
42
|
+
// Cookie driver writes via the response cookie — handled by middleware
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
31
45
|
async destroy(_sessionId) {
|
|
32
46
|
// Cookie deletion handled by middleware setting maxAge=0
|
|
33
47
|
}
|
|
34
48
|
async touch(_sessionId, _ttl) {
|
|
35
49
|
// Cookie renewal handled by middleware
|
|
36
50
|
}
|
|
37
|
-
/** Encode session data for cookie storage (encrypted). */
|
|
38
|
-
encode(data) {
|
|
39
|
-
return this.#signer.encrypt(JSON.stringify(data));
|
|
51
|
+
/** Encode session data for cookie storage (encrypted), valid for `ttl` seconds. */
|
|
52
|
+
encode(data, ttl) {
|
|
53
|
+
return this.#signer.encrypt(JSON.stringify(data), ttl * 1000, this.#purpose);
|
|
40
54
|
}
|
|
41
55
|
}
|
|
42
56
|
//# sourceMappingURL=CookieDriver.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CookieDriver.js","sourceRoot":"","sources":["../../../src/session/drivers/CookieDriver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAG7D
|
|
1
|
+
{"version":3,"file":"CookieDriver.js","sourceRoot":"","sources":["../../../src/session/drivers/CookieDriver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAG7D;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,YAAY;IACvB,OAAO,CAAc;IACZ,QAAQ,CAAQ;IAChB,SAAS,GAAG,IAAI,CAAA;IAEzB,YAAY,MAAc,EAAE,UAAU,GAAG,cAAc;QACrD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,2FAA2F,CAC5F,CAAA;QACH,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAA;QACvC,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAiB;QAC1B,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAA;QAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAA;QAChE,IAAI,OAAO,SAAS,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAA;QAC9C,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,UAAkB,EAAE,KAA8B,EAAE,IAAY;QAC1E,uEAAuE;IACzE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,UAAkB,EAAE,KAA8B,EAAE,IAAY;QAC3E,uEAAuE;QACvE,OAAO,IAAI,CAAA;IACb,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,UAAkB;QAC9B,yDAAyD;IAC3D,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,UAAkB,EAAE,IAAY;QAC1C,uCAAuC;IACzC,CAAC;IAED,mFAAmF;IACnF,MAAM,CAAC,IAA6B,EAAE,GAAW;QAC/C,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAA;IAC9E,CAAC;CACF"}
|
|
@@ -58,6 +58,8 @@ export declare class DatabaseDriver implements SessionDriverWithTagging {
|
|
|
58
58
|
constructor(options: DatabaseDriverOptions);
|
|
59
59
|
read(sessionId: string): Promise<Record<string, unknown> | null>;
|
|
60
60
|
write(sessionId: string, data: Record<string, unknown>, ttl: number): Promise<void>;
|
|
61
|
+
/** One UPDATE: a row deleted or expired meanwhile matches nothing. */
|
|
62
|
+
update(sessionId: string, data: Record<string, unknown>, ttl: number): Promise<boolean>;
|
|
61
63
|
destroy(sessionId: string): Promise<void>;
|
|
62
64
|
touch(sessionId: string, ttl: number): Promise<void>;
|
|
63
65
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatabaseDriver.d.ts","sourceRoot":"","sources":["../../../src/session/drivers/DatabaseDriver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAE5E;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;IAC/E,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC5E;AAQD,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,mBAAmB,CAAA;IAC/B,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAKD;;;;;;;;;;;;;GAaG;AACH,qBAAa,cAAe,YAAW,wBAAwB;;gBAKjD,OAAO,EAAE,qBAAqB;IAoBpC,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAiBhE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"DatabaseDriver.d.ts","sourceRoot":"","sources":["../../../src/session/drivers/DatabaseDriver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAE5E;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;IAC/E,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC5E;AAQD,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,mBAAmB,CAAA;IAC/B,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAKD;;;;;;;;;;;;;GAaG;AACH,qBAAa,cAAe,YAAW,wBAAwB;;gBAKjD,OAAO,EAAE,qBAAqB;IAoBpC,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAiBhE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsCzF,sEAAsE;IAChE,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IASvF,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO1D;;;OAGG;IACG,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOpE;;;OAGG;IACG,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOtE,wEAAwE;IAClE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAe/D,+EAA+E;IACzE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
|
|
@@ -92,6 +92,12 @@ export class DatabaseDriver {
|
|
|
92
92
|
// See above — the session was written, which is what the request needed.
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
+
/** One UPDATE: a row deleted or expired meanwhile matches nothing. */
|
|
96
|
+
async update(sessionId, data, ttl) {
|
|
97
|
+
const now = Date.now();
|
|
98
|
+
const updated = await this.#db.execute(`UPDATE ${this.#table} SET data = ?, expires_at = ? WHERE id = ? AND expires_at >= ?`, [JSON.stringify(data), now + ttl * 1000, sessionId, now]);
|
|
99
|
+
return updated.rowsAffected > 0;
|
|
100
|
+
}
|
|
95
101
|
async destroy(sessionId) {
|
|
96
102
|
await this.#db.execute(`DELETE FROM ${this.#table} WHERE id = ?`, [sessionId]);
|
|
97
103
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatabaseDriver.js","sourceRoot":"","sources":["../../../src/session/drivers/DatabaseDriver.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DatabaseDriver.js","sourceRoot":"","sources":["../../../src/session/drivers/DatabaseDriver.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,14 @@ export declare class FileDriver implements SessionDriver {
|
|
|
16
16
|
constructor(options: FileDriverOptions);
|
|
17
17
|
read(sessionId: string): Promise<Record<string, unknown> | null>;
|
|
18
18
|
write(sessionId: string, data: Record<string, unknown>, ttl: number): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Written only while the file is still there. A filesystem has no
|
|
21
|
+
* conditional write, so every change to a session's file — this, `write`,
|
|
22
|
+
* `destroy` and `touch` — runs under that session's lock: a `destroy` from a
|
|
23
|
+
* logout cannot land between the check and the write, in this process or in
|
|
24
|
+
* another one sharing the directory.
|
|
25
|
+
*/
|
|
26
|
+
update(sessionId: string, data: Record<string, unknown>, ttl: number): Promise<boolean>;
|
|
19
27
|
destroy(sessionId: string): Promise<void>;
|
|
20
28
|
touch(sessionId: string, ttl: number): Promise<void>;
|
|
21
29
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileDriver.d.ts","sourceRoot":"","sources":["../../../src/session/drivers/FileDriver.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAElD;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAA;CACjB;
|
|
1
|
+
{"version":3,"file":"FileDriver.d.ts","sourceRoot":"","sources":["../../../src/session/drivers/FileDriver.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAElD;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAA;CACjB;AAcD,qBAAa,UAAW,YAAW,aAAa;;gBAGlC,OAAO,EAAE,iBAAiB;IAiBhC,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAkChE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzF;;;;;;OAMG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQvF,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQzC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAoD3D"}
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import * as fs from 'node:fs';
|
|
3
3
|
import * as path from 'node:path';
|
|
4
|
+
/** How long a writer waits for a session's lock before giving up. */
|
|
5
|
+
const LOCK_WAIT_MS = 2000;
|
|
6
|
+
/**
|
|
7
|
+
* A lock older than this was left by a process that died holding it. Every
|
|
8
|
+
* operation under the lock is one small file read or write, far below it.
|
|
9
|
+
*/
|
|
10
|
+
const LOCK_STALE_MS = 10_000;
|
|
11
|
+
function hasCode(error, code) {
|
|
12
|
+
return error instanceof Error && Reflect.get(error, 'code') === code;
|
|
13
|
+
}
|
|
4
14
|
export class FileDriver {
|
|
5
15
|
#location;
|
|
6
16
|
constructor(options) {
|
|
@@ -19,6 +29,13 @@ export class FileDriver {
|
|
|
19
29
|
return path.join(this.#location, `${name}.json`);
|
|
20
30
|
}
|
|
21
31
|
async read(sessionId) {
|
|
32
|
+
return this.#read(sessionId, () => this.destroy(sessionId));
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Read, dropping an expired file through `drop`: `destroy()` from outside,
|
|
36
|
+
* a bare removal from inside the lock, which is already held there.
|
|
37
|
+
*/
|
|
38
|
+
async #read(sessionId, drop) {
|
|
22
39
|
let raw;
|
|
23
40
|
try {
|
|
24
41
|
raw = await fs.promises.readFile(this.#pathFor(sessionId), 'utf8');
|
|
@@ -32,7 +49,7 @@ export class FileDriver {
|
|
|
32
49
|
return null;
|
|
33
50
|
const entry = parsed;
|
|
34
51
|
if (typeof entry.expiresAt === 'number' && entry.expiresAt < Date.now()) {
|
|
35
|
-
await
|
|
52
|
+
await drop();
|
|
36
53
|
return null;
|
|
37
54
|
}
|
|
38
55
|
return entry.data ?? {};
|
|
@@ -44,6 +61,40 @@ export class FileDriver {
|
|
|
44
61
|
}
|
|
45
62
|
}
|
|
46
63
|
async write(sessionId, data, ttl) {
|
|
64
|
+
await this.#locked(sessionId, () => this.#replace(sessionId, data, ttl));
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Written only while the file is still there. A filesystem has no
|
|
68
|
+
* conditional write, so every change to a session's file — this, `write`,
|
|
69
|
+
* `destroy` and `touch` — runs under that session's lock: a `destroy` from a
|
|
70
|
+
* logout cannot land between the check and the write, in this process or in
|
|
71
|
+
* another one sharing the directory.
|
|
72
|
+
*/
|
|
73
|
+
async update(sessionId, data, ttl) {
|
|
74
|
+
return this.#locked(sessionId, async () => {
|
|
75
|
+
if ((await this.#read(sessionId, () => this.#remove(sessionId))) === null)
|
|
76
|
+
return false;
|
|
77
|
+
await this.#replace(sessionId, data, ttl);
|
|
78
|
+
return true;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
async destroy(sessionId) {
|
|
82
|
+
await this.#locked(sessionId, () => this.#remove(sessionId));
|
|
83
|
+
}
|
|
84
|
+
async #remove(sessionId) {
|
|
85
|
+
await fs.promises.rm(this.#pathFor(sessionId), { force: true });
|
|
86
|
+
}
|
|
87
|
+
async touch(sessionId, ttl) {
|
|
88
|
+
await this.#locked(sessionId, async () => {
|
|
89
|
+
const data = await this.#read(sessionId, () => this.#remove(sessionId));
|
|
90
|
+
// Nothing stored: there is no expiry to slide, and writing here would
|
|
91
|
+
// create the very session that was not there.
|
|
92
|
+
if (data === null || Object.keys(data).length === 0)
|
|
93
|
+
return;
|
|
94
|
+
await this.#replace(sessionId, data, ttl);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
async #replace(sessionId, data, ttl) {
|
|
47
98
|
const file = this.#pathFor(sessionId);
|
|
48
99
|
const payload = JSON.stringify({ expiresAt: Date.now() + ttl * 1000, data });
|
|
49
100
|
// Written to a temporary neighbour then renamed: a crash mid-write would
|
|
@@ -53,16 +104,39 @@ export class FileDriver {
|
|
|
53
104
|
await fs.promises.writeFile(temp, payload, { encoding: 'utf8', mode: 0o600 });
|
|
54
105
|
await fs.promises.rename(temp, file);
|
|
55
106
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
107
|
+
/**
|
|
108
|
+
* Run `fn` holding the session's lock: a directory beside its file, which
|
|
109
|
+
* `mkdir` creates atomically or refuses — the one exclusive primitive every
|
|
110
|
+
* filesystem gives, across processes too.
|
|
111
|
+
*/
|
|
112
|
+
async #locked(sessionId, fn) {
|
|
113
|
+
const lock = `${this.#pathFor(sessionId)}.lock`;
|
|
114
|
+
const deadline = Date.now() + LOCK_WAIT_MS;
|
|
115
|
+
for (;;) {
|
|
116
|
+
try {
|
|
117
|
+
await fs.promises.mkdir(lock);
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
if (!hasCode(error, 'EEXIST'))
|
|
122
|
+
throw error;
|
|
123
|
+
const held = await fs.promises.stat(lock).catch(() => null);
|
|
124
|
+
if (held !== null && Date.now() - held.mtimeMs > LOCK_STALE_MS) {
|
|
125
|
+
await fs.promises.rm(lock, { recursive: true, force: true });
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (Date.now() > deadline) {
|
|
129
|
+
throw new Error(`Session file is locked: ${lock}`);
|
|
130
|
+
}
|
|
131
|
+
await new Promise((resolve) => setTimeout(resolve, 5));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
return await fn();
|
|
136
|
+
}
|
|
137
|
+
finally {
|
|
138
|
+
await fs.promises.rmdir(lock).catch(() => { });
|
|
139
|
+
}
|
|
66
140
|
}
|
|
67
141
|
}
|
|
68
142
|
//# sourceMappingURL=FileDriver.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileDriver.js","sourceRoot":"","sources":["../../../src/session/drivers/FileDriver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AAgBjC,MAAM,OAAO,UAAU;IACZ,SAAS,CAAQ;IAE1B,YAAY,OAA0B;QACpC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;QAC/C,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACnD,CAAC;IAED;;;;;;OAMG;IACH,QAAQ,CAAC,SAAiB;QACxB,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACjE,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,OAAO,CAAC,CAAA;IAClD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAiB;QAC1B,IAAI,GAAW,CAAA;QACf,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAA;QACpE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAA;QACb,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YACvC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAA;YAC9D,MAAM,KAAK,GAAG,MAAgE,CAAA;YAC9E,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,IAAI,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;gBACxE,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"FileDriver.js","sourceRoot":"","sources":["../../../src/session/drivers/FileDriver.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,8 @@ export declare class MemoryDriver implements SessionDriverWithTagging {
|
|
|
8
8
|
constructor(options?: MemoryDriverOptions);
|
|
9
9
|
read(sessionId: string): Promise<Record<string, unknown> | null>;
|
|
10
10
|
write(sessionId: string, data: Record<string, unknown>, ttl: number): Promise<void>;
|
|
11
|
+
/** Atomic by construction: nothing else runs between the check and the set. */
|
|
12
|
+
update(sessionId: string, data: Record<string, unknown>, ttl: number): Promise<boolean>;
|
|
11
13
|
destroy(sessionId: string): Promise<void>;
|
|
12
14
|
touch(sessionId: string, ttl: number): Promise<void>;
|
|
13
15
|
tag(sessionId: string, userId: string | number): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MemoryDriver.d.ts","sourceRoot":"","sources":["../../../src/session/drivers/MemoryDriver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"MemoryDriver.d.ts","sourceRoot":"","sources":["../../../src/session/drivers/MemoryDriver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAiB5E,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,qBAAa,YAAa,YAAW,wBAAwB;;gBAM/C,OAAO,GAAE,mBAAwB;IAIvC,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAShE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBzF,+EAA+E;IACzE,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQvF,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUzC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYpD,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO9D,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQhE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;CAkBhE"}
|
|
@@ -6,8 +6,9 @@ const SWEEP_THRESHOLD = 1000;
|
|
|
6
6
|
* The sweep alone only removes EXPIRED entries, so within the TTL window
|
|
7
7
|
* nothing bounded growth: anyone able to request a page could mint sessions
|
|
8
8
|
* until the process ran out of memory, without ever logging in. Past the cap
|
|
9
|
-
* the
|
|
10
|
-
*
|
|
9
|
+
* the least recently used sessions are dropped (a write, an update or a
|
|
10
|
+
* touch moves a session to the back of the line) — a bounded store that
|
|
11
|
+
* forgets is strictly better than an unbounded one that dies.
|
|
11
12
|
*/
|
|
12
13
|
const DEFAULT_MAX_ENTRIES = 10_000;
|
|
13
14
|
export class MemoryDriver {
|
|
@@ -46,6 +47,15 @@ export class MemoryDriver {
|
|
|
46
47
|
this.#store.delete(oldest.value);
|
|
47
48
|
}
|
|
48
49
|
}
|
|
50
|
+
/** Atomic by construction: nothing else runs between the check and the set. */
|
|
51
|
+
async update(sessionId, data, ttl) {
|
|
52
|
+
const entry = this.#store.get(sessionId);
|
|
53
|
+
if (!entry || entry.expiresAt < Date.now())
|
|
54
|
+
return false;
|
|
55
|
+
this.#store.delete(sessionId);
|
|
56
|
+
this.#store.set(sessionId, { data, expiresAt: Date.now() + ttl * 1000 });
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
49
59
|
async destroy(sessionId) {
|
|
50
60
|
this.#store.delete(sessionId);
|
|
51
61
|
// Drop the tags too: a destroyed session left in the index would be
|
|
@@ -59,9 +69,15 @@ export class MemoryDriver {
|
|
|
59
69
|
}
|
|
60
70
|
async touch(sessionId, ttl) {
|
|
61
71
|
const entry = this.#store.get(sessionId);
|
|
62
|
-
if (entry)
|
|
63
|
-
|
|
64
|
-
|
|
72
|
+
if (!entry || entry.expiresAt < Date.now())
|
|
73
|
+
return;
|
|
74
|
+
// Re-inserted, not updated in place: eviction drops the head of the map,
|
|
75
|
+
// so a session in use has to move to the tail. Updated in place, a
|
|
76
|
+
// signed-in user who keeps browsing stayed first in line, and ten
|
|
77
|
+
// thousand anonymous requests evicted them.
|
|
78
|
+
entry.expiresAt = Date.now() + ttl * 1000;
|
|
79
|
+
this.#store.delete(sessionId);
|
|
80
|
+
this.#store.set(sessionId, entry);
|
|
65
81
|
}
|
|
66
82
|
async tag(sessionId, userId) {
|
|
67
83
|
const key = String(userId);
|