@spinajs/session-provider-db 2.0.481 → 2.0.484

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.
@@ -1,17 +1,38 @@
1
- import { SessionProvider, ISession, User } from '@spinajs/rbac';
1
+ import { SessionProvider, ISession } from '@spinajs/rbac';
2
2
  import { Log } from '@spinajs/log';
3
3
  export * from './models/DbSession.js';
4
4
  export * from './migrations/UserSessionDBSqlMigration_2022_06_28_01_01_01.js';
5
+ /**
6
+ * Relational-db backed session store. Conforms to the `@spinajs/rbac`
7
+ * `SessionProvider` contract: ownership is the numeric `UserId`, expiration is
8
+ * owned by the injected strategy (`this.Expiration`) and persisted verbatim, and
9
+ * `Data` is (de)serialized with the shared session codec.
10
+ */
5
11
  export declare class DbSessionStore extends SessionProvider {
6
12
  protected Log: Log;
7
- protected CleanupInterval: any;
8
- protected DefaultExpirationTime: number;
13
+ /**
14
+ * How often expired rows are swept, in milliseconds. Reads the correctly
15
+ * spelled `rbac.session.db.cleanupInterval` key (fixes B2 — the historic typo
16
+ * `cleanupInteval` meant the configured value was ignored).
17
+ */
18
+ protected CleanupInterval: number;
9
19
  resolve(): Promise<void>;
20
+ /**
21
+ * Removes every session whose expiration has passed.
22
+ *
23
+ * Extracted from the cleanup timer so it can be exercised directly.
24
+ *
25
+ * @returns how many sessions were removed
26
+ */
27
+ cleanupExpired(): Promise<number>;
10
28
  restore(sessionId: string): Promise<ISession | null>;
29
+ save(session: ISession): Promise<void>;
30
+ touch(session: ISession): Promise<boolean>;
11
31
  delete(sessionId: string): Promise<void>;
12
- save(sessionOrId: string | ISession, data?: object): Promise<void>;
13
- touch(session: ISession): Promise<void>;
14
- logsOut(user: User): Promise<void>;
32
+ deleteByUser(userId: number): Promise<void>;
33
+ listByUser(userId: number): Promise<ISession[]>;
15
34
  truncate(): Promise<void>;
35
+ private toSession;
36
+ private expirationEquals;
16
37
  }
17
38
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAe,IAAI,EAAE,MAAM,eAAe,CAAC;AAE7E,OAAO,EAAU,GAAG,EAAE,MAAM,cAAc,CAAC;AAQ3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,+DAA+D,CAAC;AAE9E,qBACa,cAAe,SAAQ,eAAe;IAEjD,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAKnB,SAAS,CAAC,eAAe,EAAE,GAAG,CAAC;IAG/B,SAAS,CAAC,qBAAqB,EAAE,MAAM,CAAC;IAE3B,OAAO;IAQP,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAuBpD,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,QAAQ,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBlE,KAAK,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvC,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAQlC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAGvC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAqD,MAAM,eAAe,CAAC;AAE7G,OAAO,EAAU,GAAG,EAAE,MAAM,cAAc,CAAC;AAM3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,+DAA+D,CAAC;AAE9E;;;;;GAKG;AACH,qBACa,cAAe,SAAQ,eAAe;IAEjD,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAEnB;;;;OAIG;IAIH,SAAS,CAAC,eAAe,EAAE,MAAM,CAAC;IAErB,OAAO;IAWpB;;;;;;OAMG;IACU,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAgBjC,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAmBpD,IAAI,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBtC,KAAK,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAiB1C,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc3C,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAM/C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAItC,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,gBAAgB;CAMzB"}
package/lib/cjs/index.js CHANGED
@@ -22,9 +22,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
22
22
  var __metadata = (this && this.__metadata) || function (k, v) {
23
23
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
24
24
  };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
25
  Object.defineProperty(exports, "__esModule", { value: true });
29
26
  exports.DbSessionStore = void 0;
30
27
  const rbac_1 = require("@spinajs/rbac");
@@ -34,67 +31,122 @@ const DbSession_js_1 = require("./models/DbSession.js");
34
31
  const orm_1 = require("@spinajs/orm");
35
32
  const configuration_1 = require("@spinajs/configuration");
36
33
  const luxon_1 = require("luxon");
37
- const lodash_1 = __importDefault(require("lodash"));
38
- const util_1 = require("@spinajs/util");
39
34
  __exportStar(require("./models/DbSession.js"), exports);
40
35
  __exportStar(require("./migrations/UserSessionDBSqlMigration_2022_06_28_01_01_01.js"), exports);
36
+ /**
37
+ * Relational-db backed session store. Conforms to the `@spinajs/rbac`
38
+ * `SessionProvider` contract: ownership is the numeric `UserId`, expiration is
39
+ * owned by the injected strategy (`this.Expiration`) and persisted verbatim, and
40
+ * `Data` is (de)serialized with the shared session codec.
41
+ */
41
42
  let DbSessionStore = class DbSessionStore extends rbac_1.SessionProvider {
42
43
  async resolve() {
43
- setInterval(async () => {
44
- const c = await DbSession_js_1.DbSession.destroy().where('Expiration', '<=', luxon_1.DateTime.now());
45
- this.Log.info(`Cleaned up expired session, count: ${c.RowsAffected}`);
44
+ const timer = setInterval(async () => {
45
+ const count = await this.cleanupExpired();
46
+ this.Log.info(`Cleaned up expired session, count: ${count}`);
46
47
  }, this.CleanupInterval);
48
+ // do not keep the process alive solely for the cleanup timer
49
+ timer.unref?.();
50
+ }
51
+ /**
52
+ * Removes every session whose expiration has passed.
53
+ *
54
+ * Extracted from the cleanup timer so it can be exercised directly.
55
+ *
56
+ * @returns how many sessions were removed
57
+ */
58
+ async cleanupExpired() {
59
+ // NOTE: same reason as in deleteByUser — destroy() only builds a DELETE
60
+ // bounded by primary keys, so the expired rows are looked up first.
61
+ // `destroy().where(...)` threw on every tick and no session was ever
62
+ // cleaned up.
63
+ const expired = await DbSession_js_1.DbSession.where('Expiration', '<=', luxon_1.DateTime.now());
64
+ if (expired.length === 0) {
65
+ return 0;
66
+ }
67
+ await DbSession_js_1.DbSession.destroy(expired.map((s) => s.SessionId));
68
+ return expired.length;
47
69
  }
48
70
  async restore(sessionId) {
49
- const session = await DbSession_js_1.DbSession.where({
71
+ const row = await DbSession_js_1.DbSession.where({
50
72
  SessionId: sessionId,
51
73
  }).first();
52
- if (!session) {
74
+ if (!row) {
53
75
  return null;
54
76
  }
55
- if (session.Expiration < luxon_1.DateTime.now()) {
77
+ const session = this.toSession(row);
78
+ // an expired row is treated as absent
79
+ if (this.isExpired(session)) {
56
80
  return null;
57
81
  }
58
- const sData = JSON.parse(session.Data);
59
- return new rbac_1.UserSession({
60
- SessionId: session.SessionId,
61
- Creation: session.CreatedAt,
62
- Data: new Map(Object.entries(sData)),
63
- Expiration: session.Expiration,
64
- });
82
+ return session;
65
83
  }
66
- async delete(sessionId) {
67
- await DbSession_js_1.DbSession.destroy(sessionId);
68
- }
69
- async save(sessionOrId, data) {
70
- const sessionId = lodash_1.default.isString(sessionOrId) ? sessionOrId : sessionOrId.SessionId;
71
- const userId = lodash_1.default.isString(sessionOrId) ? null : sessionOrId.UserId;
72
- const sData = lodash_1.default.isString(sessionOrId) ? data : sessionOrId.Data;
73
- let sCreationTime = luxon_1.DateTime.now();
74
- let sExpirationTime = luxon_1.DateTime.now().plus({ minutes: this.DefaultExpirationTime });
84
+ async save(session) {
85
+ // Persist `Expiration` verbatim (fixes B3). Only a brand-new session with no
86
+ // scheduled expiration is given its initial expiry via the strategy.
87
+ if (session.Expiration === undefined) {
88
+ this.applyInitialExpiration(session);
89
+ }
75
90
  const s = await DbSession_js_1.DbSession.getOrNew({
76
- SessionId: sessionId,
77
- CreatedAt: sCreationTime,
78
- Expiration: sExpirationTime,
79
- UserId: userId
91
+ SessionId: session.SessionId,
80
92
  });
81
- s.Data = JSON.stringify(Object.fromEntries(sData), util_1.replacer);
93
+ s.SessionId = session.SessionId;
94
+ s.CreatedAt = session.Creation;
95
+ // column is nullable; a never-expiring session persists a NULL Expiration
96
+ s.Expiration = (session.Expiration ?? null);
97
+ s.UserId = session.UserId;
98
+ s.Data = (0, rbac_1.encodeSessionData)(session.Data);
82
99
  await s.insert(orm_1.InsertBehaviour.InsertOrUpdate);
83
100
  }
84
101
  async touch(session) {
102
+ const current = session.Expiration;
103
+ const renewed = this.Expiration.renew(session);
104
+ // unchanged (e.g. AbsoluteExpiration) — skip the write, report false
105
+ if (this.expirationEquals(current, renewed)) {
106
+ return false;
107
+ }
108
+ session.Expiration = renewed;
85
109
  await DbSession_js_1.DbSession.update({
86
- Expiration: session.Expiration,
110
+ Expiration: renewed,
87
111
  }).where('SessionId', session.SessionId);
112
+ return true;
88
113
  }
89
- async logsOut(user) {
90
- const sessionsToDelete = await DbSession_js_1.DbSession.where('UserId', user.Id);
91
- if (sessionsToDelete.length > 0) {
92
- await DbSession_js_1.DbSession.destroy(sessionsToDelete.map((x) => x.SessionId));
114
+ async delete(sessionId) {
115
+ await DbSession_js_1.DbSession.destroy(sessionId);
116
+ }
117
+ async deleteByUser(userId) {
118
+ // NOTE: destroy() refuses to build an unbounded DELETE, so the sessions of
119
+ // the user are resolved to their primary keys first. `destroy().where(...)`
120
+ // threw "Cannot destroy without primary keys", which broke every forced
121
+ // logout ( admin "log out user" route included ).
122
+ const sessions = await DbSession_js_1.DbSession.where('UserId', userId);
123
+ if (sessions.length === 0) {
124
+ return;
93
125
  }
126
+ await DbSession_js_1.DbSession.destroy(sessions.map((s) => s.SessionId));
127
+ }
128
+ async listByUser(userId) {
129
+ const rows = await DbSession_js_1.DbSession.where('UserId', userId);
130
+ return rows.map((r) => this.toSession(r)).filter((s) => !this.isExpired(s));
94
131
  }
95
132
  async truncate() {
96
133
  await DbSession_js_1.DbSession.truncate();
97
134
  }
135
+ toSession(row) {
136
+ return new rbac_1.UserSession({
137
+ SessionId: row.SessionId,
138
+ UserId: row.UserId,
139
+ Creation: row.CreatedAt,
140
+ Expiration: row.Expiration ?? undefined,
141
+ Data: (0, rbac_1.decodeSessionData)(row.Data),
142
+ });
143
+ }
144
+ expirationEquals(a, b) {
145
+ if (a === undefined || b === undefined) {
146
+ return a === b;
147
+ }
148
+ return a.toMillis() === b.toMillis();
149
+ }
98
150
  };
99
151
  exports.DbSessionStore = DbSessionStore;
100
152
  __decorate([
@@ -102,15 +154,11 @@ __decorate([
102
154
  __metadata("design:type", log_1.Log)
103
155
  ], DbSessionStore.prototype, "Log", void 0);
104
156
  __decorate([
105
- (0, configuration_1.Config)('rbac.session.db.cleanupInteval', {
157
+ (0, configuration_1.Config)('rbac.session.db.cleanupInterval', {
106
158
  defaultValue: 100000,
107
159
  }),
108
- __metadata("design:type", Object)
109
- ], DbSessionStore.prototype, "CleanupInterval", void 0);
110
- __decorate([
111
- (0, configuration_1.Config)('rbac.session.expiration'),
112
160
  __metadata("design:type", Number)
113
- ], DbSessionStore.prototype, "DefaultExpirationTime", void 0);
161
+ ], DbSessionStore.prototype, "CleanupInterval", void 0);
114
162
  exports.DbSessionStore = DbSessionStore = __decorate([
115
163
  (0, di_1.Injectable)(rbac_1.SessionProvider)
116
164
  ], DbSessionStore);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wCAA6G;AAC7G,oCAAyC;AACzC,sCAA2C;AAC3C,wDAAkD;AAClD,sCAA+C;AAC/C,0DAAgD;AAChD,iCAAiC;AAEjC,wDAAsC;AACtC,gGAA8E;AAE9E;;;;;GAKG;AAEI,IAAM,cAAc,GAApB,MAAM,cAAe,SAAQ,sBAAe;IAc1C,KAAK,CAAC,OAAO;QAClB,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;YACnC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;YAE1C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,sCAAsC,KAAK,EAAE,CAAC,CAAC;QAC/D,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAEzB,6DAA6D;QAC7D,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IAClB,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,cAAc;QACzB,wEAAwE;QACxE,oEAAoE;QACpE,qEAAqE;QACrE,cAAc;QACd,MAAM,OAAO,GAAG,MAAM,wBAAS,CAAC,KAAK,CAAC,YAAY,EAAE,IAAI,EAAE,gBAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;QAE1E,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,CAAC;QACX,CAAC;QAED,MAAM,wBAAS,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QAEzD,OAAO,OAAO,CAAC,MAAM,CAAC;IACxB,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,SAAiB;QACpC,MAAM,GAAG,GAAG,MAAM,wBAAS,CAAC,KAAK,CAAC;YAChC,SAAS,EAAE,SAAS;SACrB,CAAC,CAAC,KAAK,EAAE,CAAC;QAEX,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAEpC,sCAAsC;QACtC,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,OAAiB;QACjC,6EAA6E;QAC7E,qEAAqE;QACrE,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACrC,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,CAAC,GAAG,MAAM,wBAAS,CAAC,QAAQ,CAAC;YACjC,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC,CAAC;QAEH,CAAC,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QAChC,CAAC,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC;QAC/B,0EAA0E;QAC1E,CAAC,CAAC,UAAU,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,IAAI,CAAa,CAAC;QACxD,CAAC,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC1B,CAAC,CAAC,IAAI,GAAG,IAAA,wBAAiB,EAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAEzC,MAAM,CAAC,CAAC,MAAM,CAAC,qBAAe,CAAC,cAAc,CAAC,CAAC;IACjD,CAAC;IAEM,KAAK,CAAC,KAAK,CAAC,OAAiB;QAClC,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAE/C,qEAAqE;QACrE,IAAI,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC;YAC5C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC;QAC7B,MAAM,wBAAS,CAAC,MAAM,CAAC;YACrB,UAAU,EAAE,OAAO;SACpB,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QAEzC,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,SAAiB;QACnC,MAAM,wBAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC;IAEM,KAAK,CAAC,YAAY,CAAC,MAAc;QACtC,2EAA2E;QAC3E,4EAA4E;QAC5E,wEAAwE;QACxE,kDAAkD;QAClD,MAAM,QAAQ,GAAG,MAAM,wBAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAEzD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO;QACT,CAAC;QAED,MAAM,wBAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5D,CAAC;IAEM,KAAK,CAAC,UAAU,CAAC,MAAc;QACpC,MAAM,IAAI,GAAG,MAAM,wBAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAErD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,CAAC;IAEM,KAAK,CAAC,QAAQ;QACnB,MAAM,wBAAS,CAAC,QAAQ,EAAE,CAAC;IAC7B,CAAC;IAEO,SAAS,CAAC,GAAc;QAC9B,OAAO,IAAI,kBAAW,CAAC;YACrB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,QAAQ,EAAE,GAAG,CAAC,SAAS;YACvB,UAAU,EAAE,GAAG,CAAC,UAAU,IAAI,SAAS;YACvC,IAAI,EAAE,IAAA,wBAAiB,EAAC,GAAG,CAAC,IAAI,CAAC;SAClC,CAAC,CAAC;IACL,CAAC;IAEO,gBAAgB,CAAC,CAAuB,EAAE,CAAuB;QACvE,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YACvC,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC;QACD,OAAO,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;IACvC,CAAC;CACF,CAAA;AArJY,wCAAc;AAEf;IADT,IAAA,YAAM,EAAC,kBAAkB,CAAC;8BACZ,SAAG;2CAAC;AAUT;IAHT,IAAA,sBAAM,EAAC,iCAAiC,EAAE;QACzC,YAAY,EAAE,MAAM;KACrB,CAAC;;uDACgC;yBAZvB,cAAc;IAD1B,IAAA,eAAU,EAAC,sBAAe,CAAC;GACf,cAAc,CAqJ1B"}
@@ -1,17 +1,38 @@
1
- import { SessionProvider, ISession, User } from '@spinajs/rbac';
1
+ import { SessionProvider, ISession } from '@spinajs/rbac';
2
2
  import { Log } from '@spinajs/log';
3
3
  export * from './models/DbSession.js';
4
4
  export * from './migrations/UserSessionDBSqlMigration_2022_06_28_01_01_01.js';
5
+ /**
6
+ * Relational-db backed session store. Conforms to the `@spinajs/rbac`
7
+ * `SessionProvider` contract: ownership is the numeric `UserId`, expiration is
8
+ * owned by the injected strategy (`this.Expiration`) and persisted verbatim, and
9
+ * `Data` is (de)serialized with the shared session codec.
10
+ */
5
11
  export declare class DbSessionStore extends SessionProvider {
6
12
  protected Log: Log;
7
- protected CleanupInterval: any;
8
- protected DefaultExpirationTime: number;
13
+ /**
14
+ * How often expired rows are swept, in milliseconds. Reads the correctly
15
+ * spelled `rbac.session.db.cleanupInterval` key (fixes B2 — the historic typo
16
+ * `cleanupInteval` meant the configured value was ignored).
17
+ */
18
+ protected CleanupInterval: number;
9
19
  resolve(): Promise<void>;
20
+ /**
21
+ * Removes every session whose expiration has passed.
22
+ *
23
+ * Extracted from the cleanup timer so it can be exercised directly.
24
+ *
25
+ * @returns how many sessions were removed
26
+ */
27
+ cleanupExpired(): Promise<number>;
10
28
  restore(sessionId: string): Promise<ISession | null>;
29
+ save(session: ISession): Promise<void>;
30
+ touch(session: ISession): Promise<boolean>;
11
31
  delete(sessionId: string): Promise<void>;
12
- save(sessionOrId: string | ISession, data?: object): Promise<void>;
13
- touch(session: ISession): Promise<void>;
14
- logsOut(user: User): Promise<void>;
32
+ deleteByUser(userId: number): Promise<void>;
33
+ listByUser(userId: number): Promise<ISession[]>;
15
34
  truncate(): Promise<void>;
35
+ private toSession;
36
+ private expirationEquals;
16
37
  }
17
38
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAe,IAAI,EAAE,MAAM,eAAe,CAAC;AAE7E,OAAO,EAAU,GAAG,EAAE,MAAM,cAAc,CAAC;AAQ3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,+DAA+D,CAAC;AAE9E,qBACa,cAAe,SAAQ,eAAe;IAEjD,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAKnB,SAAS,CAAC,eAAe,EAAE,GAAG,CAAC;IAG/B,SAAS,CAAC,qBAAqB,EAAE,MAAM,CAAC;IAE3B,OAAO;IAQP,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAuBpD,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,QAAQ,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBlE,KAAK,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvC,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAQlC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAGvC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAqD,MAAM,eAAe,CAAC;AAE7G,OAAO,EAAU,GAAG,EAAE,MAAM,cAAc,CAAC;AAM3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,+DAA+D,CAAC;AAE9E;;;;;GAKG;AACH,qBACa,cAAe,SAAQ,eAAe;IAEjD,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAEnB;;;;OAIG;IAIH,SAAS,CAAC,eAAe,EAAE,MAAM,CAAC;IAErB,OAAO;IAWpB;;;;;;OAMG;IACU,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAgBjC,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAmBpD,IAAI,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBtC,KAAK,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAiB1C,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc3C,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAM/C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAItC,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,gBAAgB;CAMzB"}
package/lib/mjs/index.js CHANGED
@@ -7,89 +7,140 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  var __metadata = (this && this.__metadata) || function (k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
- import { SessionProvider, UserSession } from '@spinajs/rbac';
10
+ import { SessionProvider, UserSession, encodeSessionData, decodeSessionData } from '@spinajs/rbac';
11
11
  import { Injectable } from '@spinajs/di';
12
12
  import { Logger, Log } from '@spinajs/log';
13
13
  import { DbSession } from './models/DbSession.js';
14
14
  import { InsertBehaviour } from '@spinajs/orm';
15
15
  import { Config } from '@spinajs/configuration';
16
16
  import { DateTime } from 'luxon';
17
- import _ from 'lodash';
18
- import { replacer } from '@spinajs/util';
19
17
  export * from './models/DbSession.js';
20
18
  export * from './migrations/UserSessionDBSqlMigration_2022_06_28_01_01_01.js';
19
+ /**
20
+ * Relational-db backed session store. Conforms to the `@spinajs/rbac`
21
+ * `SessionProvider` contract: ownership is the numeric `UserId`, expiration is
22
+ * owned by the injected strategy (`this.Expiration`) and persisted verbatim, and
23
+ * `Data` is (de)serialized with the shared session codec.
24
+ */
21
25
  let DbSessionStore = class DbSessionStore extends SessionProvider {
22
26
  async resolve() {
23
- setInterval(async () => {
24
- const c = await DbSession.destroy().where('Expiration', '<=', DateTime.now());
25
- this.Log.info(`Cleaned up expired session, count: ${c.RowsAffected}`);
27
+ const timer = setInterval(async () => {
28
+ const count = await this.cleanupExpired();
29
+ this.Log.info(`Cleaned up expired session, count: ${count}`);
26
30
  }, this.CleanupInterval);
31
+ // do not keep the process alive solely for the cleanup timer
32
+ timer.unref?.();
33
+ }
34
+ /**
35
+ * Removes every session whose expiration has passed.
36
+ *
37
+ * Extracted from the cleanup timer so it can be exercised directly.
38
+ *
39
+ * @returns how many sessions were removed
40
+ */
41
+ async cleanupExpired() {
42
+ // NOTE: same reason as in deleteByUser — destroy() only builds a DELETE
43
+ // bounded by primary keys, so the expired rows are looked up first.
44
+ // `destroy().where(...)` threw on every tick and no session was ever
45
+ // cleaned up.
46
+ const expired = await DbSession.where('Expiration', '<=', DateTime.now());
47
+ if (expired.length === 0) {
48
+ return 0;
49
+ }
50
+ await DbSession.destroy(expired.map((s) => s.SessionId));
51
+ return expired.length;
27
52
  }
28
53
  async restore(sessionId) {
29
- const session = await DbSession.where({
54
+ const row = await DbSession.where({
30
55
  SessionId: sessionId,
31
56
  }).first();
32
- if (!session) {
57
+ if (!row) {
33
58
  return null;
34
59
  }
35
- if (session.Expiration < DateTime.now()) {
60
+ const session = this.toSession(row);
61
+ // an expired row is treated as absent
62
+ if (this.isExpired(session)) {
36
63
  return null;
37
64
  }
38
- const sData = JSON.parse(session.Data);
39
- return new UserSession({
40
- SessionId: session.SessionId,
41
- Creation: session.CreatedAt,
42
- Data: new Map(Object.entries(sData)),
43
- Expiration: session.Expiration,
44
- });
45
- }
46
- async delete(sessionId) {
47
- await DbSession.destroy(sessionId);
65
+ return session;
48
66
  }
49
- async save(sessionOrId, data) {
50
- const sessionId = _.isString(sessionOrId) ? sessionOrId : sessionOrId.SessionId;
51
- const userId = _.isString(sessionOrId) ? null : sessionOrId.UserId;
52
- const sData = _.isString(sessionOrId) ? data : sessionOrId.Data;
53
- let sCreationTime = DateTime.now();
54
- let sExpirationTime = DateTime.now().plus({ minutes: this.DefaultExpirationTime });
67
+ async save(session) {
68
+ // Persist `Expiration` verbatim (fixes B3). Only a brand-new session with no
69
+ // scheduled expiration is given its initial expiry via the strategy.
70
+ if (session.Expiration === undefined) {
71
+ this.applyInitialExpiration(session);
72
+ }
55
73
  const s = await DbSession.getOrNew({
56
- SessionId: sessionId,
57
- CreatedAt: sCreationTime,
58
- Expiration: sExpirationTime,
59
- UserId: userId
74
+ SessionId: session.SessionId,
60
75
  });
61
- s.Data = JSON.stringify(Object.fromEntries(sData), replacer);
76
+ s.SessionId = session.SessionId;
77
+ s.CreatedAt = session.Creation;
78
+ // column is nullable; a never-expiring session persists a NULL Expiration
79
+ s.Expiration = (session.Expiration ?? null);
80
+ s.UserId = session.UserId;
81
+ s.Data = encodeSessionData(session.Data);
62
82
  await s.insert(InsertBehaviour.InsertOrUpdate);
63
83
  }
64
84
  async touch(session) {
85
+ const current = session.Expiration;
86
+ const renewed = this.Expiration.renew(session);
87
+ // unchanged (e.g. AbsoluteExpiration) — skip the write, report false
88
+ if (this.expirationEquals(current, renewed)) {
89
+ return false;
90
+ }
91
+ session.Expiration = renewed;
65
92
  await DbSession.update({
66
- Expiration: session.Expiration,
93
+ Expiration: renewed,
67
94
  }).where('SessionId', session.SessionId);
95
+ return true;
68
96
  }
69
- async logsOut(user) {
70
- const sessionsToDelete = await DbSession.where('UserId', user.Id);
71
- if (sessionsToDelete.length > 0) {
72
- await DbSession.destroy(sessionsToDelete.map((x) => x.SessionId));
97
+ async delete(sessionId) {
98
+ await DbSession.destroy(sessionId);
99
+ }
100
+ async deleteByUser(userId) {
101
+ // NOTE: destroy() refuses to build an unbounded DELETE, so the sessions of
102
+ // the user are resolved to their primary keys first. `destroy().where(...)`
103
+ // threw "Cannot destroy without primary keys", which broke every forced
104
+ // logout ( admin "log out user" route included ).
105
+ const sessions = await DbSession.where('UserId', userId);
106
+ if (sessions.length === 0) {
107
+ return;
73
108
  }
109
+ await DbSession.destroy(sessions.map((s) => s.SessionId));
110
+ }
111
+ async listByUser(userId) {
112
+ const rows = await DbSession.where('UserId', userId);
113
+ return rows.map((r) => this.toSession(r)).filter((s) => !this.isExpired(s));
74
114
  }
75
115
  async truncate() {
76
116
  await DbSession.truncate();
77
117
  }
118
+ toSession(row) {
119
+ return new UserSession({
120
+ SessionId: row.SessionId,
121
+ UserId: row.UserId,
122
+ Creation: row.CreatedAt,
123
+ Expiration: row.Expiration ?? undefined,
124
+ Data: decodeSessionData(row.Data),
125
+ });
126
+ }
127
+ expirationEquals(a, b) {
128
+ if (a === undefined || b === undefined) {
129
+ return a === b;
130
+ }
131
+ return a.toMillis() === b.toMillis();
132
+ }
78
133
  };
79
134
  __decorate([
80
135
  Logger('db-session-store'),
81
136
  __metadata("design:type", Log)
82
137
  ], DbSessionStore.prototype, "Log", void 0);
83
138
  __decorate([
84
- Config('rbac.session.db.cleanupInteval', {
139
+ Config('rbac.session.db.cleanupInterval', {
85
140
  defaultValue: 100000,
86
141
  }),
87
- __metadata("design:type", Object)
88
- ], DbSessionStore.prototype, "CleanupInterval", void 0);
89
- __decorate([
90
- Config('rbac.session.expiration'),
91
142
  __metadata("design:type", Number)
92
- ], DbSessionStore.prototype, "DefaultExpirationTime", void 0);
143
+ ], DbSessionStore.prototype, "CleanupInterval", void 0);
93
144
  DbSessionStore = __decorate([
94
145
  Injectable(SessionProvider)
95
146
  ], DbSessionStore);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,eAAe,EAAY,WAAW,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC7G,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,+DAA+D,CAAC;AAE9E;;;;;GAKG;AAEI,IAAM,cAAc,GAApB,MAAM,cAAe,SAAQ,eAAe;IAc1C,KAAK,CAAC,OAAO;QAClB,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;YACnC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;YAE1C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,sCAAsC,KAAK,EAAE,CAAC,CAAC;QAC/D,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAEzB,6DAA6D;QAC7D,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IAClB,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,cAAc;QACzB,wEAAwE;QACxE,oEAAoE;QACpE,qEAAqE;QACrE,cAAc;QACd,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,YAAY,EAAE,IAAI,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;QAE1E,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,CAAC;QACX,CAAC;QAED,MAAM,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QAEzD,OAAO,OAAO,CAAC,MAAM,CAAC;IACxB,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,SAAiB;QACpC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC;YAChC,SAAS,EAAE,SAAS;SACrB,CAAC,CAAC,KAAK,EAAE,CAAC;QAEX,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAEpC,sCAAsC;QACtC,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,OAAiB;QACjC,6EAA6E;QAC7E,qEAAqE;QACrE,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACrC,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC;YACjC,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC,CAAC;QAEH,CAAC,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QAChC,CAAC,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC;QAC/B,0EAA0E;QAC1E,CAAC,CAAC,UAAU,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,IAAI,CAAa,CAAC;QACxD,CAAC,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC1B,CAAC,CAAC,IAAI,GAAG,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAEzC,MAAM,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;IACjD,CAAC;IAEM,KAAK,CAAC,KAAK,CAAC,OAAiB;QAClC,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAE/C,qEAAqE;QACrE,IAAI,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC;YAC5C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC;QAC7B,MAAM,SAAS,CAAC,MAAM,CAAC;YACrB,UAAU,EAAE,OAAO;SACpB,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QAEzC,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,SAAiB;QACnC,MAAM,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC;IAEM,KAAK,CAAC,YAAY,CAAC,MAAc;QACtC,2EAA2E;QAC3E,4EAA4E;QAC5E,wEAAwE;QACxE,kDAAkD;QAClD,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAEzD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO;QACT,CAAC;QAED,MAAM,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5D,CAAC;IAEM,KAAK,CAAC,UAAU,CAAC,MAAc;QACpC,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAErD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,CAAC;IAEM,KAAK,CAAC,QAAQ;QACnB,MAAM,SAAS,CAAC,QAAQ,EAAE,CAAC;IAC7B,CAAC;IAEO,SAAS,CAAC,GAAc;QAC9B,OAAO,IAAI,WAAW,CAAC;YACrB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,QAAQ,EAAE,GAAG,CAAC,SAAS;YACvB,UAAU,EAAE,GAAG,CAAC,UAAU,IAAI,SAAS;YACvC,IAAI,EAAE,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC;SAClC,CAAC,CAAC;IACL,CAAC;IAEO,gBAAgB,CAAC,CAAuB,EAAE,CAAuB;QACvE,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YACvC,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC;QACD,OAAO,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;IACvC,CAAC;CACF,CAAA;AAnJW;IADT,MAAM,CAAC,kBAAkB,CAAC;8BACZ,GAAG;2CAAC;AAUT;IAHT,MAAM,CAAC,iCAAiC,EAAE;QACzC,YAAY,EAAE,MAAM;KACrB,CAAC;;uDACgC;AAZvB,cAAc;IAD1B,UAAU,CAAC,eAAe,CAAC;GACf,cAAc,CAqJ1B"}