@randajan/koa-io-session 0.1.0 → 2.1.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.
@@ -29,107 +29,451 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  // src/index.js
30
30
  var index_exports = {};
31
31
  __export(index_exports, {
32
+ SessionBridge: () => SessionBridge,
32
33
  SessionStore: () => SessionStore,
33
- attachSession: () => attachSession,
34
+ bridgeSession: () => bridgeSession,
34
35
  default: () => index_default,
35
36
  generateUid: () => generateUid
36
37
  });
37
38
  module.exports = __toCommonJS(index_exports);
38
39
 
39
- // src/attachSession.js
40
- var import_koa_session = __toESM(require("koa-session"), 1);
41
- var import_props2 = require("@randajan/props");
40
+ // src/class/SessionBridge.js
41
+ var import_events2 = require("events");
42
+ var import_http = require("http");
43
+ var import_props4 = require("@randajan/props");
42
44
 
43
- // src/uid.js
45
+ // src/tools.js
44
46
  var import_crypto = __toESM(require("crypto"), 1);
45
47
  var generateUid = (len = 16) => import_crypto.default.randomBytes(len).toString("base64url").slice(0, len);
48
+ var is = (type, any) => typeof any === type;
49
+ var valid = (type, any, req = false, msg = "argument") => {
50
+ if (any == null) {
51
+ if (!req) {
52
+ return;
53
+ }
54
+ throw new Error(`${msg} require typeof '${type}'`);
55
+ }
56
+ if (is(type, any)) {
57
+ return any;
58
+ }
59
+ throw new Error(`${msg} is not typeof '${type}'`);
60
+ };
61
+ var validRange = (min, max, any, req = false, msg = "argument") => {
62
+ const num = valid("number", any, req, msg);
63
+ if (num == null) {
64
+ return;
65
+ }
66
+ if (num < min) {
67
+ throw new Error(`${msg} must be greater than ${min}`);
68
+ }
69
+ if (num > max) {
70
+ throw new Error(`${msg} must be less than ${max}`);
71
+ }
72
+ return num;
73
+ };
74
+ var validInterval = (any, req = false, msg = "argument") => {
75
+ return validRange(10, 2147483647, any, req, msg);
76
+ };
77
+ var validObject = (any, req = false, msg = "argument") => {
78
+ const obj = valid("object", any, req, msg);
79
+ if (obj == null) {
80
+ return;
81
+ }
82
+ if (!Array.isArray(obj)) {
83
+ return obj;
84
+ }
85
+ throw new Error(`${msg} must be object, not array`);
86
+ };
87
+ var validStore = (store) => {
88
+ const missing = [];
89
+ if (!is("function", store?.get)) {
90
+ missing.push("get()");
91
+ }
92
+ if (!is("function", store?.set)) {
93
+ missing.push("set()");
94
+ }
95
+ if (!is("function", store?.destroy)) {
96
+ missing.push("destroy()");
97
+ }
98
+ if (!is("function", store?.on)) {
99
+ missing.push("on()");
100
+ }
101
+ if (missing.length) {
102
+ throw new TypeError(`store is missing required API: ${missing.join(", ")}`);
103
+ }
104
+ return store;
105
+ };
106
+
107
+ // src/httpSession.js
108
+ var import_koa_session = __toESM(require("koa-session"), 1);
109
+
110
+ // src/wrappers.js
111
+ var wrapStore = (store) => {
112
+ return {
113
+ get: store.get.bind(store),
114
+ set: store.set.bind(store),
115
+ destroy: store.destroy.bind(store)
116
+ };
117
+ };
118
+ var wrapExternalKey = (opt, onSet) => {
119
+ const { externalKey: base, key, signed } = opt;
120
+ const get = base?.get ? (ctx) => base.get(ctx) : (ctx) => ctx.cookies.get(key, { signed });
121
+ const setRaw = base?.set ? (ctx, sid) => base.set(ctx, sid) : (ctx, sid) => ctx.cookies.set(key, sid, opt);
122
+ const set = typeof onSet != "function" ? setRaw : (ctx, sid) => {
123
+ setRaw(ctx, sid);
124
+ onSet(ctx, sid);
125
+ };
126
+ return { get, set };
127
+ };
128
+
129
+ // src/httpSession.js
130
+ var createKoaSession = (opt, app, onSet) => {
131
+ const store = wrapStore(opt.store);
132
+ const externalKey = wrapExternalKey(opt, onSet);
133
+ const koaSession = (0, import_koa_session.default)({ ...opt, store, externalKey }, app);
134
+ return [koaSession, externalKey];
135
+ };
136
+ var createClientCookie = (opt) => {
137
+ const { key, maxAge, signed, path, secure, sameSite, httpOnly } = opt;
138
+ return wrapExternalKey({
139
+ key,
140
+ signed,
141
+ maxAge,
142
+ path: path ?? "/",
143
+ secure,
144
+ sameSite,
145
+ httpOnly: httpOnly ?? true,
146
+ overwrite: true
147
+ });
148
+ };
46
149
 
47
- // src/SessionStore.js
150
+ // src/socketSession.js
48
151
  var import_props = require("@randajan/props");
49
- var SessionStore = class {
50
- constructor(defaultTTL = 864e5) {
51
- (0, import_props.solid)(this, "_data", /* @__PURE__ */ new Map());
52
- (0, import_props.solid)(this, "_defaultTTL", defaultTTL);
152
+ var sidLocks = /* @__PURE__ */ new Map();
153
+ var createSessionCtx = (sessionId, session2, socket) => (0, import_props.solids)({ session: session2 }, { sessionId, socket });
154
+ var createSessionHash = (session2) => {
155
+ try {
156
+ return JSON.stringify(session2 ?? null);
157
+ } catch {
158
+ return null;
159
+ }
160
+ };
161
+ var isSessionHashChanged = (originalHash, session2) => {
162
+ const nextHash = createSessionHash(session2);
163
+ if (originalHash == null || nextHash == null) {
164
+ return true;
165
+ }
166
+ return originalHash !== nextHash;
167
+ };
168
+ var withLock = async (task, socket, ...args) => {
169
+ const sid = socket.sessionId;
170
+ const previous = sidLocks.get(sid);
171
+ let releaseCurrent;
172
+ const current = new Promise((resolve) => {
173
+ releaseCurrent = resolve;
174
+ });
175
+ sidLocks.set(sid, current);
176
+ if (previous) {
177
+ await previous;
178
+ }
179
+ try {
180
+ return await task(socket, ...args);
181
+ } finally {
182
+ releaseCurrent();
183
+ if (sidLocks.get(sid) === current) {
184
+ sidLocks.delete(sid);
185
+ }
186
+ }
187
+ };
188
+ var runSessionHandler = async (socket, handler, store) => {
189
+ const sid = socket.sessionId;
190
+ const current = await store.get(sid);
191
+ if (!current) {
192
+ throw new Error("Session not found");
193
+ }
194
+ const session2 = current;
195
+ const sessionCtx = createSessionCtx(sid, session2, socket);
196
+ const originalHash = createSessionHash(sessionCtx.session);
197
+ const result = await handler(sessionCtx, socket);
198
+ if (sessionCtx.session == null) {
199
+ await store.destroy(sid);
200
+ return result;
201
+ }
202
+ sessionCtx.session = validObject(sessionCtx.session, false, "session");
203
+ if (isSessionHashChanged(originalHash, sessionCtx.session)) {
204
+ await store.set(sid, sessionCtx.session);
205
+ }
206
+ return result;
207
+ };
208
+ var applySessionHandler = async (socket, handler, store) => {
209
+ if (typeof handler !== "function") {
210
+ throw new TypeError("socket.withSession(handler) requires a function");
211
+ }
212
+ if (!socket.sessionId) {
213
+ throw new Error("Missing session id");
214
+ }
215
+ return withLock(runSessionHandler, socket, handler, store);
216
+ };
217
+
218
+ // src/class/SessionStore.js
219
+ var import_props2 = require("@randajan/props");
220
+ var import_events = require("events");
221
+
222
+ // src/const.js
223
+ var ms = {
224
+ s: (v = 1) => v * 1e3,
225
+ m: (v = 1) => ms.s(v * 60),
226
+ h: (v = 1) => ms.m(v * 60),
227
+ d: (v = 1) => ms.h(v * 24),
228
+ w: (v = 1) => ms.d(v * 7),
229
+ M: (v = 1) => ms.d(v * 30),
230
+ y: (v = 1) => ms.d(v * 365)
231
+ };
232
+ var _customOptKeys = /* @__PURE__ */ new Set([
233
+ "store",
234
+ "autoCleanup",
235
+ "autoCleanupMs",
236
+ "clientKey",
237
+ "clientMaxAge",
238
+ "clientAlwaysRoll"
239
+ ]);
240
+
241
+ // src/class/SessionStore.js
242
+ var formatState = (session2, maxAge, prevTTL, maxAgeDefault) => {
243
+ const ttl = maxAge ?? prevTTL ?? maxAgeDefault;
244
+ const expiresAt = Date.now() + ttl;
245
+ return { session: session2, expiresAt, ttl };
246
+ };
247
+ var SessionStore = class extends Map {
248
+ constructor(opt = {}) {
249
+ super();
250
+ const maxAge = validRange(ms.s(), ms.y(), opt.maxAge, false, "maxAge") ?? ms.M();
251
+ const autoCleanup = valid("boolean", opt.autoCleanup, false, "autoCleanup") ?? true;
252
+ const autoCleanupMs = validInterval(opt.autoCleanupMs, false, "autoCleanupMs") ?? Math.max(ms.s(), Math.min(ms.h(), maxAge / 10));
253
+ (0, import_props2.solid)(this, "maxAge", maxAge);
254
+ (0, import_props2.solid)(this, "event", new import_events.EventEmitter());
255
+ if (!autoCleanup) {
256
+ return;
257
+ }
258
+ setInterval((_) => this.cleanup(), autoCleanupMs);
259
+ }
260
+ on(eventName, callback) {
261
+ return this.event.on(eventName, callback);
53
262
  }
54
263
  get(sid) {
55
- const d = this._data.get(sid);
56
- if (!d) return;
264
+ const d = super.get(sid);
265
+ if (!d) {
266
+ return;
267
+ }
57
268
  if (Date.now() < d.expiresAt) {
58
269
  return d.session;
59
270
  }
60
- this.destroy(sid);
61
- return {};
271
+ this.delete(sid);
62
272
  }
63
273
  set(sid, session2, maxAge) {
64
- const { _data, _defaultTTL } = this;
65
- const d = _data.get(sid);
66
- const ttl = maxAge ?? d?.ttl ?? _defaultTTL;
67
- const expiresAt = Date.now() + ttl;
68
- _data.set(sid, { session: session2, expiresAt, ttl });
274
+ const d = super.get(sid);
275
+ if (session2 == null) {
276
+ return !d || this.destroy(sid);
277
+ }
278
+ super.set(sid, formatState(session2, maxAge, d?.ttl, this.maxAge));
279
+ this.event.emit("set", this, sid, !d);
280
+ return true;
281
+ }
282
+ delete(sid) {
283
+ return this.destroy(sid);
69
284
  }
70
285
  destroy(sid) {
71
- this._data.delete(sid);
286
+ if (this.has(sid)) {
287
+ super.delete(sid);
288
+ this.event.emit("destroy", this, sid);
289
+ }
290
+ return true;
72
291
  }
73
292
  cleanup() {
74
- const { _data } = this;
75
293
  const now = Date.now();
76
294
  let cleared = 0;
77
- for (const [sid, d] of _data) {
295
+ for (const [sid, d] of this.entries()) {
78
296
  if (now < d.expiresAt) {
79
297
  continue;
80
298
  }
81
- _data.delete(sid);
82
- cleared++;
299
+ if (this.destroy(sid)) {
300
+ cleared++;
301
+ }
302
+ }
303
+ if (cleared) {
304
+ this.event.emit("cleanup", this, cleared);
83
305
  }
84
306
  return cleared;
85
307
  }
86
- autoCleanup(interval = 36e5, onCleanup = () => {
87
- }) {
88
- const tid = setInterval(() => {
89
- const cleared = this.cleanup();
90
- if (cleared) {
91
- onCleanup(cleared);
92
- }
93
- }, interval);
94
- return (_) => clearInterval(tid);
308
+ };
309
+
310
+ // src/formatOptions.js
311
+ var pickKoaOpt = (rawOpt) => {
312
+ const koaOpt = {};
313
+ for (const key in rawOpt) {
314
+ if (_customOptKeys.has(key)) {
315
+ continue;
316
+ }
317
+ koaOpt[key] = rawOpt[key];
95
318
  }
319
+ koaOpt.key = valid("string", koaOpt.key, false, "key") ?? generateUid(12);
320
+ koaOpt.maxAge = validRange(ms.s(), ms.y(), koaOpt.maxAge, false, "maxAge") ?? ms.M();
321
+ koaOpt.signed = valid("boolean", koaOpt.signed, false, "signed") ?? true;
322
+ koaOpt.store = validStore(rawOpt.store || new SessionStore(rawOpt));
323
+ return koaOpt;
324
+ };
325
+ var formatOptions = (opt = {}) => {
326
+ opt = validObject(opt, true, "options");
327
+ const koaOpt = pickKoaOpt(opt);
328
+ const clientKey = valid("string", opt.clientKey) ?? `${koaOpt.key}.cid`;
329
+ const clientMaxAge = validInterval(opt.clientMaxAge, false, "clientMaxAge") ?? ms.y();
330
+ const clientAlwaysRoll = valid("boolean", opt.clientAlwaysRoll, false, "clientAlwaysRoll") ?? true;
331
+ const clientOpt = { ...koaOpt, key: clientKey, maxAge: clientMaxAge };
332
+ return {
333
+ koaOpt,
334
+ clientOpt,
335
+ clientAlwaysRoll
336
+ };
96
337
  };
97
338
 
98
- // src/attachSession.js
99
- var attachSession = (app, io, opt = {}) => {
100
- const signed = "signed" in opt ? !!opt.signed : true;
101
- delete opt.signed;
102
- if (!app.keys) app.keys = Array(6).fill().map(() => generateUid(12));
103
- if (!opt.key) opt.key = generateUid(12);
104
- if (!opt.maxAge) {
105
- opt.maxAge = 864e5;
106
- }
107
- if (!opt.store) {
108
- opt.store = new SessionStore(opt.maxAge);
109
- }
110
- const { key, store } = opt;
111
- const koaSession = (0, import_koa_session.default)(opt, app);
112
- app.use(koaSession);
113
- app.use(async (ctx, next) => {
114
- ctx.session.active = true;
115
- (0, import_props2.solid)(ctx, "sessionId", ctx.cookies.get(key, { signed }));
116
- await next();
117
- });
118
- io.use(async (socket, next) => {
119
- if (!socket.request.headers.cookie) {
120
- return next(new Error("No cookie"));
339
+ // src/class/Bridge.js
340
+ var import_props3 = require("@randajan/props");
341
+ var Bridge = class {
342
+ constructor(opt = {}) {
343
+ const { onSet, onDelete } = opt;
344
+ (0, import_props3.solids)(this, {
345
+ onSet,
346
+ onDelete,
347
+ s2c: /* @__PURE__ */ new Map(),
348
+ c2s: /* @__PURE__ */ new Map()
349
+ });
350
+ }
351
+ set(cid, sid) {
352
+ if (!cid || !sid) {
353
+ return false;
354
+ }
355
+ const byCid = this.deleteByCid(cid, sid);
356
+ const bySid = this.deleteBySid(sid, cid);
357
+ if (!byCid && !bySid) {
358
+ return false;
359
+ }
360
+ this.c2s.set(cid, sid);
361
+ this.s2c.set(sid, cid);
362
+ this.onSet({ clientId: cid, sessionId: sid });
363
+ return true;
364
+ }
365
+ getByCid(cid) {
366
+ return this.c2s.get(cid);
367
+ }
368
+ getBySid(sid) {
369
+ return this.s2c.get(sid);
370
+ }
371
+ deleteBySid(sid, skipIf) {
372
+ const cid = this.getBySid(sid);
373
+ if (!cid) {
374
+ return true;
375
+ }
376
+ if (skipIf && cid == skipIf) {
377
+ return false;
378
+ }
379
+ this.s2c.delete(sid);
380
+ this.c2s.delete(cid);
381
+ this.onDelete({ clientId: cid, sessionId: sid });
382
+ return true;
383
+ }
384
+ deleteByCid(cid, skipIf) {
385
+ const sid = this.getByCid(cid);
386
+ if (!sid) {
387
+ return true;
121
388
  }
122
- const ctx = app.createContext(socket.request, socket.response);
123
- await koaSession(ctx, async () => {
389
+ if (skipIf && sid == skipIf) {
390
+ return false;
391
+ }
392
+ this.c2s.delete(cid);
393
+ this.s2c.delete(sid);
394
+ this.onDelete({ clientId: cid, sessionId: sid });
395
+ return true;
396
+ }
397
+ };
398
+
399
+ // src/class/SessionBridge.js
400
+ var SessionBridge = class extends import_events2.EventEmitter {
401
+ constructor(app, io, opt = {}) {
402
+ super();
403
+ if (!app.keys) {
404
+ app.keys = Array(6).fill().map(() => generateUid(12));
405
+ }
406
+ const o = formatOptions(opt);
407
+ const { store } = o.koaOpt;
408
+ const brg = new Bridge({
409
+ onSet: (pair) => this.emit("sessionStart", pair),
410
+ onDelete: (pair) => this.emit("sessionEnd", pair)
124
411
  });
125
- const sid = ctx.cookies.get(key, { signed });
126
- (0, import_props2.solid)(socket, "sessionId", sid);
127
- (0, import_props2.virtual)(socket, "session", (_) => store.get(sid));
128
- await next();
129
- });
130
- return koaSession.store;
412
+ const cc = createClientCookie(o.clientOpt);
413
+ const [koaSession, sc] = createKoaSession(o.koaOpt, app, (ctx, sid) => {
414
+ const cid = cc.get(ctx);
415
+ brg.set(cid, sid);
416
+ });
417
+ const regenerateSid = async (ctx, cid, reqSid) => {
418
+ if (cid == null || reqSid == null) {
419
+ return;
420
+ }
421
+ const brgSid = brg.getByCid(cid);
422
+ if (brgSid == reqSid) {
423
+ return;
424
+ } else if (brgSid) {
425
+ sc.set(ctx, brgSid);
426
+ return;
427
+ }
428
+ if (brg.getBySid(reqSid)) {
429
+ return;
430
+ }
431
+ if (!await store.get(reqSid)) {
432
+ return;
433
+ }
434
+ brg.set(cid, reqSid);
435
+ };
436
+ app.use(koaSession);
437
+ app.use(async (ctx, next) => {
438
+ let cid = cc.get(ctx);
439
+ const sid = sc.get(ctx);
440
+ if (!cid) {
441
+ cc.set(ctx, cid = generateUid(24));
442
+ } else if (o.clientAlwaysRoll) {
443
+ cc.set(ctx, cid);
444
+ }
445
+ await regenerateSid(ctx, cid, sid);
446
+ (0, import_props4.solid)(ctx, "clientId", cid);
447
+ (0, import_props4.virtual)(ctx, "sessionId", (_) => brg.getByCid(cid));
448
+ await next();
449
+ });
450
+ io.use(async (socket, next) => {
451
+ const req = socket.request;
452
+ const res = req.res ?? socket.response ?? new import_http.ServerResponse(req);
453
+ const ctx = app.createContext(req, res);
454
+ await koaSession(ctx, async () => {
455
+ });
456
+ const cid = cc.get(ctx);
457
+ const sid = sc.get(ctx);
458
+ await regenerateSid(ctx, cid, sid);
459
+ (0, import_props4.solid)(socket, "clientId", cid);
460
+ (0, import_props4.virtual)(socket, "sessionId", (_) => brg.getByCid(cid));
461
+ (0, import_props4.solid)(socket, "withSession", async (handler) => {
462
+ return applySessionHandler(socket, handler, store);
463
+ }, false);
464
+ await next();
465
+ });
466
+ store.on("destroy", (_store, sid) => {
467
+ if (!sid) {
468
+ return;
469
+ }
470
+ brg.deleteBySid(sid);
471
+ });
472
+ (0, import_props4.solid)(this, "store", store);
473
+ }
131
474
  };
132
475
 
133
476
  // src/index.js
134
- var index_default = attachSession;
477
+ var bridgeSession = (app, io, opt = {}) => new SessionBridge(app, io, opt);
478
+ var index_default = bridgeSession;
135
479
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/index.js", "../../src/attachSession.js", "../../src/uid.js", "../../src/SessionStore.js"],
4
- "sourcesContent": ["import { attachSession } from \"./attachSession\";\r\nimport { SessionStore } from \"./SessionStore\";\r\nimport { generateUid } from \"./uid\";\r\n\r\n\r\nexport default attachSession;\r\n\r\nexport {\r\n attachSession,\r\n generateUid,\r\n SessionStore\r\n}", "// attachSession.js \u2013 verze s auto-persist proxy\nimport session from \"koa-session\";\nimport { solid, virtual } from \"@randajan/props\";\nimport { generateUid } from \"./uid\";\nimport { SessionStore } from \"./SessionStore\";\n\n\nexport const attachSession = (app, io, opt = {}) => {\n const signed = \"signed\" in opt ? !!opt.signed : true;\n delete opt.signed;\n\n\n if (!app.keys) app.keys = Array(6).fill().map(() => generateUid(12));\n if (!opt.key) opt.key = generateUid(12);\n if (!opt.maxAge) { opt.maxAge = 86_400_000; }\n if (!opt.store) { opt.store = new SessionStore(opt.maxAge); }\n\n const { key, store } = opt;\n\n const koaSession = session(opt, app);\n app.use(koaSession);\n\n // pro HTTP jen sessionId, nic v\u00EDc nepot\u0159ebujeme\n app.use(async (ctx, next) => {\n ctx.session.active = true;\n solid(ctx, \"sessionId\", ctx.cookies.get(key, { signed }));\n await next();\n });\n\n /* ------------------ WebSocket ------------------------------------- */\n io.use(async (socket, next) => {\n\n if (!socket.request.headers.cookie) { return next(new Error(\"No cookie\")); }\n\n const ctx = app.createContext(socket.request, socket.response);\n await koaSession(ctx, async () => { }); // aktivuj koa-session\n\n const sid = ctx.cookies.get(key, { signed });\n\n solid(socket, \"sessionId\", sid);\n virtual(socket, \"session\", _=>store.get(sid)); // <-- u\u017E se ukl\u00E1d\u00E1 samo\n\n await next();\n });\n\n return koaSession.store; // kdyby ses k n\u011Bmu cht\u011Bl dostat jinde\n};", "import crypto from \"crypto\";\r\n\r\nexport const generateUid = (len = 16) => crypto.randomBytes(len).toString(\"base64url\").slice(0, len);", "import { solid } from \"@randajan/props\";\r\n\r\nexport class SessionStore {\r\n constructor(defaultTTL=86_400_000) {\r\n solid(this, \"_data\", new Map());\r\n solid(this, \"_defaultTTL\", defaultTTL);\r\n }\r\n\r\n get(sid) {\r\n const d = this._data.get(sid);\r\n if (!d) return;\r\n if (Date.now() < d.expiresAt) { return d.session; }\r\n this.destroy(sid);\r\n return {};\r\n }\r\n\r\n set(sid, session, maxAge) {\r\n const { _data, _defaultTTL } = this;\r\n const d = _data.get(sid);\r\n const ttl = maxAge ?? d?.ttl ?? _defaultTTL;\r\n const expiresAt = Date.now() + ttl;\r\n _data.set(sid, { session, expiresAt, ttl });\r\n }\r\n\r\n destroy(sid) { this._data.delete(sid); }\r\n\r\n cleanup() {\r\n const { _data } = this;\r\n\r\n const now = Date.now();\r\n let cleared = 0;\r\n\r\n for (const [sid, d] of _data) {\r\n if (now < d.expiresAt) { continue; }\r\n _data.delete(sid);\r\n cleared++;\r\n }\r\n\r\n return cleared;\r\n }\r\n\r\n autoCleanup(interval=3_600_000, onCleanup=()=>{}) {\r\n const tid = setInterval(() => {\r\n const cleared = this.cleanup();\r\n if (cleared) { onCleanup(cleared); }\r\n }, interval);\r\n return _ => clearInterval(tid);\r\n }\r\n}"],
5
- "mappings": "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",
6
- "names": ["import_props", "crypto", "session", "session"]
3
+ "sources": ["../../src/index.js", "../../src/class/SessionBridge.js", "../../src/tools.js", "../../src/httpSession.js", "../../src/wrappers.js", "../../src/socketSession.js", "../../src/class/SessionStore.js", "../../src/const.js", "../../src/formatOptions.js", "../../src/class/Bridge.js"],
4
+ "sourcesContent": ["import { SessionBridge } from \"./class/SessionBridge.js\";\r\nimport { SessionStore } from \"./class/SessionStore.js\";\r\nimport { generateUid } from \"./tools.js\";\r\n\r\n\r\nconst bridgeSession = (app, io, opt = {}) => new SessionBridge(app, io, opt);\r\n\r\nexport default bridgeSession;\r\n\r\nexport {\r\n bridgeSession,\r\n generateUid,\r\n SessionStore,\r\n SessionBridge\r\n}\r\n", "import { EventEmitter } from \"events\";\r\nimport { ServerResponse } from \"http\";\r\nimport { solid, virtual } from \"@randajan/props\";\r\n\r\nimport { generateUid } from \"../tools.js\";\r\nimport { createKoaSession, createClientCookie } from \"../httpSession.js\";\r\nimport { applySessionHandler } from \"../socketSession.js\";\r\n\r\nimport { formatOptions } from \"../formatOptions.js\";\r\nimport { Bridge } from \"./Bridge.js\";\r\n\r\n\r\nexport class SessionBridge extends EventEmitter {\r\n\r\n constructor(app, io, opt = {}) {\r\n super();\r\n\r\n if (!app.keys) { app.keys = Array(6).fill().map(() => generateUid(12)); }\r\n\r\n const o = formatOptions(opt);\r\n const { store } = o.koaOpt;\r\n\r\n const brg = new Bridge({\r\n onSet:pair=>this.emit(\"sessionStart\", pair),\r\n onDelete:pair=>this.emit(\"sessionEnd\", pair)\r\n });\r\n\r\n const cc = createClientCookie(o.clientOpt);\r\n const [koaSession, sc] = createKoaSession(o.koaOpt, app, (ctx, sid)=>{\r\n const cid = cc.get(ctx);\r\n brg.set(cid, sid);\r\n });\r\n\r\n const regenerateSid = async (ctx, cid, reqSid)=>{\r\n if (cid == null || reqSid == null) { return; } //empty cid or sid\r\n\r\n const brgSid = brg.getByCid(cid);\r\n if (brgSid == reqSid) { return; } //correct sid for this client\r\n else if (brgSid) { sc.set(ctx, brgSid); return; } //this client have different sid\r\n\r\n if (brg.getBySid(reqSid)) { return; } //sid is occupied by different client\r\n if (!await store.get(reqSid)) { return; } //there is no sesssion with that sid\r\n brg.set(cid, reqSid); //attach session to this client\r\n }\r\n \r\n app.use(koaSession);\r\n\r\n // pro HTTP jen sessionId, nic v\u00EDc nepot\u0159ebujeme\r\n app.use(async (ctx, next) => {\r\n let cid = cc.get(ctx);\r\n const sid = sc.get(ctx);\r\n\r\n if (!cid) { cc.set(ctx, cid = generateUid(24)); }\r\n else if (o.clientAlwaysRoll) { cc.set(ctx, cid); }\r\n \r\n await regenerateSid(ctx, cid, sid);\r\n \r\n solid(ctx, \"clientId\", cid);\r\n virtual(ctx, \"sessionId\", _=>brg.getByCid(cid));\r\n await next();\r\n });\r\n\r\n /* ------------------ WebSocket ------------------------------------- */\r\n io.use(async (socket, next) => {\r\n const req = socket.request;\r\n const res = req.res ?? socket.response ?? new ServerResponse(req);\r\n const ctx = app.createContext(req, res);\r\n\r\n await koaSession(ctx, async () => {});\r\n const cid = cc.get(ctx);\r\n const sid = sc.get(ctx);\r\n\r\n await regenerateSid(ctx, cid, sid);\r\n\r\n solid(socket, \"clientId\", cid);\r\n virtual(socket, \"sessionId\", _=>brg.getByCid(cid));\r\n solid(socket, \"withSession\", async (handler)=>{\r\n return applySessionHandler(socket, handler, store);\r\n }, false);\r\n\r\n await next();\r\n });\r\n\r\n store.on(\"destroy\", (_store, sid)=>{\r\n if (!sid) { return; }\r\n brg.deleteBySid(sid);\r\n });\r\n \r\n\r\n solid(this, \"store\", store);\r\n }\r\n\r\n\r\n}\r\n\r\n", "import crypto from \"crypto\";\r\n\r\nexport const generateUid = (len = 16) => crypto.randomBytes(len).toString(\"base64url\").slice(0, len);\r\n\r\nexport const is = (type, any)=>typeof any === type;\r\n\r\nexport const valid = (type, any, req=false, msg=\"argument\")=>{\r\n if (any == null) {\r\n if (!req) { return; }\r\n throw new Error(`${msg} require typeof '${type}'`);\r\n }\r\n if (is(type, any)) { return any; }\r\n throw new Error(`${msg} is not typeof '${type}'`);\r\n}\r\n\r\nexport const validRange = (min, max, any, req=false, msg=\"argument\")=>{\r\n const num = valid(\"number\", any, req, msg);\r\n if (num == null) { return; }\r\n if (num < min) { throw new Error(`${msg} must be greater than ${min}`); }\r\n if (num > max) { throw new Error(`${msg} must be less than ${max}`); }\r\n return num;\r\n}\r\n\r\nexport const validInterval = (any, req=false, msg=\"argument\")=>{\r\n return validRange(10, 2_147_483_647, any, req, msg);\r\n}\r\n\r\nexport const validObject = (any, req=false, msg=\"argument\")=>{\r\n const obj = valid(\"object\", any, req, msg);\r\n if (obj == null) { return; }\r\n if (!Array.isArray(obj)) { return obj; }\r\n throw new Error(`${msg} must be object, not array`);\r\n}\r\n\r\n\r\nexport const validStore = (store) => {\n const missing = [];\n if (!is(\"function\", store?.get)) { missing.push(\"get()\"); }\n if (!is(\"function\", store?.set)) { missing.push(\"set()\"); }\n if (!is(\"function\", store?.destroy)) { missing.push(\"destroy()\"); }\n if (!is(\"function\", store?.on)) { missing.push(\"on()\"); }\n\r\n if (missing.length) {\r\n throw new TypeError(`store is missing required API: ${missing.join(\", \")}`);\r\n }\r\n \r\n return store;\r\n};\n", "import session from \"koa-session\";\r\nimport { wrapExternalKey, wrapStore } from \"./wrappers.js\";\r\n\r\nexport const createKoaSession = (opt, app, onSet)=>{\r\n const store = wrapStore(opt.store);\r\n const externalKey = wrapExternalKey(opt, onSet);\r\n const koaSession = session({...opt, store, externalKey}, app);\r\n return [koaSession, externalKey];\r\n}\r\n\r\nexport const createClientCookie = opt => {\r\n const { key, maxAge, signed, path, secure, sameSite, httpOnly } = opt;\r\n return wrapExternalKey({\r\n key,\r\n signed,\r\n maxAge,\r\n path: path ?? \"/\",\r\n secure,\r\n sameSite,\r\n httpOnly: httpOnly ?? true,\r\n overwrite: true\r\n });\r\n}", "\r\n\r\nexport const wrapStore = (store)=>{\n return {\n get:store.get.bind(store),\n set:store.set.bind(store),\n destroy:store.destroy.bind(store)\n }\n}\n\r\nexport const wrapExternalKey = (opt, onSet) => {\r\n const { externalKey: base, key, signed } = opt;\r\n\r\n const get = base?.get\r\n ? (ctx) => base.get(ctx)\r\n : (ctx) => ctx.cookies.get(key, { signed });\r\n\r\n const setRaw = base?.set\r\n ? (ctx, sid) => base.set(ctx, sid)\r\n : (ctx, sid) => ctx.cookies.set(key, sid, opt);\r\n\r\n const set = typeof onSet != \"function\"\r\n ? setRaw\r\n : (ctx, sid) => {\r\n setRaw(ctx, sid); // re\u00E1ln\u00FD z\u00E1pis SID\r\n onSet(ctx, sid); // tv\u016Fj hook\r\n };\r\n\r\n return { get, set };\r\n};\r\n", "import { solids } from \"@randajan/props\";\r\nimport { validObject } from \"./tools.js\";\r\n\r\n\r\nconst sidLocks = new Map();\r\n\r\nconst createSessionCtx = (sessionId, session, socket) =>solids({ session }, { sessionId, socket });\r\n\r\nconst createSessionHash = (session) => {\r\n try { return JSON.stringify(session ?? null); }\r\n catch { return null; }\r\n};\r\n\r\nconst isSessionHashChanged = (originalHash, session) => {\r\n const nextHash = createSessionHash(session);\r\n if (originalHash == null || nextHash == null) { return true; }\r\n return originalHash !== nextHash;\r\n};\r\n\r\nconst withLock = async (task, socket, ...args) => {\r\n const sid = socket.sessionId;\r\n const previous = sidLocks.get(sid);\r\n let releaseCurrent;\r\n const current = new Promise((resolve) => { releaseCurrent = resolve; });\r\n sidLocks.set(sid, current);\r\n\r\n if (previous) { await previous; }\r\n\r\n try {\r\n return await task(socket, ...args);\r\n } finally {\r\n releaseCurrent();\r\n if (sidLocks.get(sid) === current) { sidLocks.delete(sid); }\r\n }\r\n};\r\n\r\nconst runSessionHandler = async (socket, handler, store) => {\r\n const sid = socket.sessionId;\r\n\r\n const current = await store.get(sid);\r\n\r\n if (!current) { throw new Error(\"Session not found\"); }\r\n\r\n const session = current;\r\n const sessionCtx = createSessionCtx(sid, session, socket);\r\n\r\n const originalHash = createSessionHash(sessionCtx.session);\r\n const result = await handler(sessionCtx, socket);\r\n\r\n if (sessionCtx.session == null) {\r\n await store.destroy(sid);\r\n return result;\r\n }\r\n\r\n sessionCtx.session = validObject(sessionCtx.session, false, \"session\");\r\n\r\n if (isSessionHashChanged(originalHash, sessionCtx.session)) {\r\n await store.set(sid, sessionCtx.session);\r\n }\r\n\r\n return result;\r\n};\r\n\r\nexport const applySessionHandler = async (socket, handler, store) => {\r\n\r\n if (typeof handler !== \"function\") {\r\n throw new TypeError(\"socket.withSession(handler) requires a function\");\r\n }\r\n if (!socket.sessionId) {\r\n throw new Error(\"Missing session id\");\r\n }\r\n\r\n return withLock(runSessionHandler, socket, handler, store);\r\n};\r\n", "import { solid } from \"@randajan/props\";\r\nimport { EventEmitter } from \"events\";\r\nimport { valid, validInterval, validRange } from \"../tools.js\";\r\nimport { ms } from \"../const.js\";\r\n\r\n\r\nconst formatState = (session, maxAge, prevTTL, maxAgeDefault)=>{\r\n const ttl = maxAge ?? prevTTL ?? maxAgeDefault;\r\n const expiresAt = Date.now() + ttl;\r\n return { session, expiresAt, ttl };\r\n}\r\n\r\nexport class SessionStore extends Map {\r\n\r\n constructor(opt={}) {\r\n super();\r\n\r\n const maxAge = validRange(ms.s(), ms.y(), opt.maxAge, false, \"maxAge\") ?? ms.M();\r\n const autoCleanup = valid(\"boolean\", opt.autoCleanup, false, \"autoCleanup\") ?? true;\r\n const autoCleanupMs = validInterval(opt.autoCleanupMs, false, \"autoCleanupMs\") ?? Math.max(ms.s(), Math.min(ms.h(), maxAge/10));\r\n \r\n solid(this, \"maxAge\", maxAge);\r\n solid(this, \"event\", new EventEmitter());\r\n\r\n if (!autoCleanup) { return; }\r\n\r\n setInterval(_=>this.cleanup(), autoCleanupMs);\r\n }\r\n\r\n on(eventName, callback) {\r\n return this.event.on(eventName, callback);\r\n }\r\n\r\n get(sid) {\r\n const d = super.get(sid);\r\n if (!d) { return; }\r\n if (Date.now() < d.expiresAt) { return d.session; }\r\n this.delete(sid);\r\n }\r\n\r\n set(sid, session, maxAge) {\r\n const d = super.get(sid);\r\n if (session == null) { return !d || this.destroy(sid); }\r\n super.set(sid, formatState(session, maxAge, d?.ttl, this.maxAge));\r\n this.event.emit(\"set\", this, sid, !d);\r\n return true;\r\n }\r\n\r\n delete(sid) {\r\n return this.destroy(sid);\r\n }\r\n\r\n destroy(sid) {\r\n if (this.has(sid)) {\r\n super.delete(sid);\r\n this.event.emit(\"destroy\", this, sid);\r\n }\r\n return true;\r\n }\r\n\r\n cleanup() {\r\n const now = Date.now();\r\n let cleared = 0;\r\n\r\n for (const [sid, d] of this.entries()) {\r\n if (now < d.expiresAt) { continue; }\r\n if (this.destroy(sid)) { cleared++; }\r\n }\r\n\r\n if (cleared) { this.event.emit(\"cleanup\", this, cleared); }\r\n\r\n return cleared;\r\n }\r\n\r\n}\r\n", "export const ms = {\r\n s:(v=1)=>v*1000,\r\n m:(v=1)=>ms.s(v*60),\r\n h:(v=1)=>ms.m(v*60),\r\n d:(v=1)=>ms.h(v*24),\r\n w:(v=1)=>ms.d(v*7),\r\n M:(v=1)=>ms.d(v*30),\r\n y:(v=1)=>ms.d(v*365)\r\n}\r\n\r\nexport const _customOptKeys = new Set([\n \"store\",\n \"autoCleanup\",\n \"autoCleanupMs\",\n \"clientKey\",\n \"clientMaxAge\",\n \"clientAlwaysRoll\"\n]);\n", "import { SessionStore } from \"./class/SessionStore.js\";\r\nimport { _customOptKeys, ms } from \"./const.js\";\r\nimport { generateUid, valid, validRange, validInterval, validObject, validStore } from \"./tools.js\";\r\n\r\nconst pickKoaOpt = (rawOpt) => {\r\n const koaOpt = {}\r\n for (const key in rawOpt) {\r\n if (_customOptKeys.has(key)) { continue; }\r\n koaOpt[key] = rawOpt[key];\r\n }\r\n\r\n koaOpt.key = valid(\"string\", koaOpt.key, false, \"key\") ?? generateUid(12);\r\n koaOpt.maxAge = validRange(ms.s(), ms.y(), koaOpt.maxAge, false, \"maxAge\") ?? ms.M();\r\n koaOpt.signed = valid(\"boolean\", koaOpt.signed, false, \"signed\") ?? true;\r\n koaOpt.store = validStore(rawOpt.store || new SessionStore(rawOpt));\r\n\r\n return koaOpt;\r\n};\r\n\r\n/**\r\n * Validate and normalize attachSession options.\r\n * Returns split options for internal parts and koa-session pass-through options.\r\n */\r\nexport const formatOptions = (opt = {}) => {\r\n opt = validObject(opt, true, \"options\");\r\n\r\n const koaOpt = pickKoaOpt(opt);\r\n \r\n const clientKey = valid(\"string\", opt.clientKey) ?? `${koaOpt.key}.cid`;\r\n const clientMaxAge = validInterval(opt.clientMaxAge, false, \"clientMaxAge\") ?? ms.y();\r\n const clientAlwaysRoll = valid(\"boolean\", opt.clientAlwaysRoll, false, \"clientAlwaysRoll\") ?? true;\r\n\r\n const clientOpt = { ...koaOpt, key:clientKey, maxAge:clientMaxAge }\r\n\r\n return {\r\n koaOpt,\r\n clientOpt,\r\n clientAlwaysRoll,\r\n };\r\n};\r\n\r\n", "import { solids } from \"@randajan/props\";\r\n\r\nexport class Bridge {\r\n constructor(opt={}) {\r\n const { onSet, onDelete } = opt;\r\n\r\n solids(this, {\r\n onSet,\r\n onDelete,\r\n s2c:new Map(),\r\n c2s:new Map()\r\n });\r\n\r\n }\r\n\r\n set(cid, sid) {\n if (!cid || !sid) { return false; }\n\n const byCid = this.deleteByCid(cid, sid);\n const bySid = this.deleteBySid(sid, cid);\n if (!byCid && !bySid) { return false; }\n\n this.c2s.set(cid, sid);\n this.s2c.set(sid, cid);\n\n this.onSet({clientId:cid, sessionId:sid});\n return true;\n }\n \r\n getByCid(cid) {return this.c2s.get(cid); }\r\n getBySid(sid) { return this.s2c.get(sid); }\r\n\r\n deleteBySid(sid, skipIf) {\r\n const cid = this.getBySid(sid);\r\n if (!cid) { return true; }\r\n if (skipIf && cid == skipIf) { return false; }\r\n this.s2c.delete(sid);\r\n this.c2s.delete(cid);\r\n this.onDelete({clientId:cid, sessionId:sid});\r\n return true;\r\n }\r\n\r\n deleteByCid(cid, skipIf) {\r\n const sid = this.getByCid(cid);\r\n if (!sid) { return true; }\r\n if (skipIf && sid == skipIf) { return false; }\r\n this.c2s.delete(cid);\r\n this.s2c.delete(sid);\r\n this.onDelete({clientId:cid, sessionId:sid});\r\n return true;\r\n }\r\n}\r\n"],
5
+ "mappings": "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",
6
+ "names": ["import_events", "import_props", "crypto", "session", "session", "import_props", "session", "import_props"]
7
7
  }