@spinajs/session-provider-db 2.0.480 → 2.0.482
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/lib/cjs/index.d.ts +19 -6
- package/lib/cjs/index.d.ts.map +1 -1
- package/lib/cjs/index.js +63 -42
- package/lib/cjs/index.js.map +1 -1
- package/lib/mjs/index.d.ts +19 -6
- package/lib/mjs/index.d.ts.map +1 -1
- package/lib/mjs/index.js +64 -40
- package/lib/mjs/index.js.map +1 -1
- package/lib/tsconfig.cjs.tsbuildinfo +1 -1
- package/lib/tsconfig.mjs.tsbuildinfo +1 -1
- package/package.json +18 -19
package/lib/cjs/index.d.ts
CHANGED
|
@@ -1,17 +1,30 @@
|
|
|
1
|
-
import { SessionProvider, ISession
|
|
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
|
-
|
|
8
|
-
|
|
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>;
|
|
10
20
|
restore(sessionId: string): Promise<ISession | null>;
|
|
21
|
+
save(session: ISession): Promise<void>;
|
|
22
|
+
touch(session: ISession): Promise<boolean>;
|
|
11
23
|
delete(sessionId: string): Promise<void>;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
logsOut(user: User): Promise<void>;
|
|
24
|
+
deleteByUser(userId: number): Promise<void>;
|
|
25
|
+
listByUser(userId: number): Promise<ISession[]>;
|
|
15
26
|
truncate(): Promise<void>;
|
|
27
|
+
private toSession;
|
|
28
|
+
private expirationEquals;
|
|
16
29
|
}
|
|
17
30
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/cjs/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,QAAQ,
|
|
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;IAWP,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;IAI3C,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,95 @@ 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 timer = setInterval(async () => {
|
|
44
45
|
const c = await DbSession_js_1.DbSession.destroy().where('Expiration', '<=', luxon_1.DateTime.now());
|
|
45
46
|
this.Log.info(`Cleaned up expired session, count: ${c.RowsAffected}`);
|
|
46
47
|
}, this.CleanupInterval);
|
|
48
|
+
// do not keep the process alive solely for the cleanup timer
|
|
49
|
+
timer.unref?.();
|
|
47
50
|
}
|
|
48
51
|
async restore(sessionId) {
|
|
49
|
-
const
|
|
52
|
+
const row = await DbSession_js_1.DbSession.where({
|
|
50
53
|
SessionId: sessionId,
|
|
51
54
|
}).first();
|
|
52
|
-
if (!
|
|
55
|
+
if (!row) {
|
|
53
56
|
return null;
|
|
54
57
|
}
|
|
55
|
-
|
|
58
|
+
const session = this.toSession(row);
|
|
59
|
+
// an expired row is treated as absent
|
|
60
|
+
if (this.isExpired(session)) {
|
|
56
61
|
return null;
|
|
57
62
|
}
|
|
58
|
-
|
|
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
|
-
});
|
|
65
|
-
}
|
|
66
|
-
async delete(sessionId) {
|
|
67
|
-
await DbSession_js_1.DbSession.destroy(sessionId);
|
|
63
|
+
return session;
|
|
68
64
|
}
|
|
69
|
-
async save(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
65
|
+
async save(session) {
|
|
66
|
+
// Persist `Expiration` verbatim (fixes B3). Only a brand-new session with no
|
|
67
|
+
// scheduled expiration is given its initial expiry via the strategy.
|
|
68
|
+
if (session.Expiration === undefined) {
|
|
69
|
+
this.applyInitialExpiration(session);
|
|
70
|
+
}
|
|
75
71
|
const s = await DbSession_js_1.DbSession.getOrNew({
|
|
76
|
-
SessionId:
|
|
77
|
-
CreatedAt: sCreationTime,
|
|
78
|
-
Expiration: sExpirationTime,
|
|
79
|
-
UserId: userId
|
|
72
|
+
SessionId: session.SessionId,
|
|
80
73
|
});
|
|
81
|
-
s.
|
|
74
|
+
s.SessionId = session.SessionId;
|
|
75
|
+
s.CreatedAt = session.Creation;
|
|
76
|
+
// column is nullable; a never-expiring session persists a NULL Expiration
|
|
77
|
+
s.Expiration = (session.Expiration ?? null);
|
|
78
|
+
s.UserId = session.UserId;
|
|
79
|
+
s.Data = (0, rbac_1.encodeSessionData)(session.Data);
|
|
82
80
|
await s.insert(orm_1.InsertBehaviour.InsertOrUpdate);
|
|
83
81
|
}
|
|
84
82
|
async touch(session) {
|
|
83
|
+
const current = session.Expiration;
|
|
84
|
+
const renewed = this.Expiration.renew(session);
|
|
85
|
+
// unchanged (e.g. AbsoluteExpiration) — skip the write, report false
|
|
86
|
+
if (this.expirationEquals(current, renewed)) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
session.Expiration = renewed;
|
|
85
90
|
await DbSession_js_1.DbSession.update({
|
|
86
|
-
Expiration:
|
|
91
|
+
Expiration: renewed,
|
|
87
92
|
}).where('SessionId', session.SessionId);
|
|
93
|
+
return true;
|
|
88
94
|
}
|
|
89
|
-
async
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
95
|
+
async delete(sessionId) {
|
|
96
|
+
await DbSession_js_1.DbSession.destroy(sessionId);
|
|
97
|
+
}
|
|
98
|
+
async deleteByUser(userId) {
|
|
99
|
+
await DbSession_js_1.DbSession.destroy().where('UserId', userId);
|
|
100
|
+
}
|
|
101
|
+
async listByUser(userId) {
|
|
102
|
+
const rows = await DbSession_js_1.DbSession.where('UserId', userId);
|
|
103
|
+
return rows.map((r) => this.toSession(r)).filter((s) => !this.isExpired(s));
|
|
94
104
|
}
|
|
95
105
|
async truncate() {
|
|
96
106
|
await DbSession_js_1.DbSession.truncate();
|
|
97
107
|
}
|
|
108
|
+
toSession(row) {
|
|
109
|
+
return new rbac_1.UserSession({
|
|
110
|
+
SessionId: row.SessionId,
|
|
111
|
+
UserId: row.UserId,
|
|
112
|
+
Creation: row.CreatedAt,
|
|
113
|
+
Expiration: row.Expiration ?? undefined,
|
|
114
|
+
Data: (0, rbac_1.decodeSessionData)(row.Data),
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
expirationEquals(a, b) {
|
|
118
|
+
if (a === undefined || b === undefined) {
|
|
119
|
+
return a === b;
|
|
120
|
+
}
|
|
121
|
+
return a.toMillis() === b.toMillis();
|
|
122
|
+
}
|
|
98
123
|
};
|
|
99
124
|
exports.DbSessionStore = DbSessionStore;
|
|
100
125
|
__decorate([
|
|
@@ -102,15 +127,11 @@ __decorate([
|
|
|
102
127
|
__metadata("design:type", log_1.Log)
|
|
103
128
|
], DbSessionStore.prototype, "Log", void 0);
|
|
104
129
|
__decorate([
|
|
105
|
-
(0, configuration_1.Config)('rbac.session.db.
|
|
130
|
+
(0, configuration_1.Config)('rbac.session.db.cleanupInterval', {
|
|
106
131
|
defaultValue: 100000,
|
|
107
132
|
}),
|
|
108
|
-
__metadata("design:type", Object)
|
|
109
|
-
], DbSessionStore.prototype, "CleanupInterval", void 0);
|
|
110
|
-
__decorate([
|
|
111
|
-
(0, configuration_1.Config)('rbac.session.expiration'),
|
|
112
133
|
__metadata("design:type", Number)
|
|
113
|
-
], DbSessionStore.prototype, "
|
|
134
|
+
], DbSessionStore.prototype, "CleanupInterval", void 0);
|
|
114
135
|
exports.DbSessionStore = DbSessionStore = __decorate([
|
|
115
136
|
(0, di_1.Injectable)(rbac_1.SessionProvider)
|
|
116
137
|
], DbSessionStore);
|
package/lib/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/lib/mjs/index.d.ts
CHANGED
|
@@ -1,17 +1,30 @@
|
|
|
1
|
-
import { SessionProvider, ISession
|
|
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
|
-
|
|
8
|
-
|
|
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>;
|
|
10
20
|
restore(sessionId: string): Promise<ISession | null>;
|
|
21
|
+
save(session: ISession): Promise<void>;
|
|
22
|
+
touch(session: ISession): Promise<boolean>;
|
|
11
23
|
delete(sessionId: string): Promise<void>;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
logsOut(user: User): Promise<void>;
|
|
24
|
+
deleteByUser(userId: number): Promise<void>;
|
|
25
|
+
listByUser(userId: number): Promise<ISession[]>;
|
|
15
26
|
truncate(): Promise<void>;
|
|
27
|
+
private toSession;
|
|
28
|
+
private expirationEquals;
|
|
16
29
|
}
|
|
17
30
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/mjs/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,QAAQ,
|
|
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;IAWP,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;IAI3C,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,113 @@ 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 () => {
|
|
27
|
+
const timer = setInterval(async () => {
|
|
24
28
|
const c = await DbSession.destroy().where('Expiration', '<=', DateTime.now());
|
|
25
29
|
this.Log.info(`Cleaned up expired session, count: ${c.RowsAffected}`);
|
|
26
30
|
}, this.CleanupInterval);
|
|
31
|
+
// do not keep the process alive solely for the cleanup timer
|
|
32
|
+
timer.unref?.();
|
|
27
33
|
}
|
|
28
34
|
async restore(sessionId) {
|
|
29
|
-
const
|
|
35
|
+
const row = await DbSession.where({
|
|
30
36
|
SessionId: sessionId,
|
|
31
37
|
}).first();
|
|
32
|
-
if (!
|
|
38
|
+
if (!row) {
|
|
33
39
|
return null;
|
|
34
40
|
}
|
|
35
|
-
|
|
41
|
+
const session = this.toSession(row);
|
|
42
|
+
// an expired row is treated as absent
|
|
43
|
+
if (this.isExpired(session)) {
|
|
36
44
|
return null;
|
|
37
45
|
}
|
|
38
|
-
|
|
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);
|
|
46
|
+
return session;
|
|
48
47
|
}
|
|
49
|
-
async save(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
async save(session) {
|
|
49
|
+
// Persist `Expiration` verbatim (fixes B3). Only a brand-new session with no
|
|
50
|
+
// scheduled expiration is given its initial expiry via the strategy.
|
|
51
|
+
if (session.Expiration === undefined) {
|
|
52
|
+
this.applyInitialExpiration(session);
|
|
53
|
+
}
|
|
55
54
|
const s = await DbSession.getOrNew({
|
|
56
|
-
SessionId:
|
|
57
|
-
CreatedAt: sCreationTime,
|
|
58
|
-
Expiration: sExpirationTime,
|
|
59
|
-
UserId: userId
|
|
55
|
+
SessionId: session.SessionId,
|
|
60
56
|
});
|
|
61
|
-
s.
|
|
57
|
+
s.SessionId = session.SessionId;
|
|
58
|
+
s.CreatedAt = session.Creation;
|
|
59
|
+
// column is nullable; a never-expiring session persists a NULL Expiration
|
|
60
|
+
s.Expiration = (session.Expiration ?? null);
|
|
61
|
+
s.UserId = session.UserId;
|
|
62
|
+
s.Data = encodeSessionData(session.Data);
|
|
62
63
|
await s.insert(InsertBehaviour.InsertOrUpdate);
|
|
63
64
|
}
|
|
64
65
|
async touch(session) {
|
|
66
|
+
const current = session.Expiration;
|
|
67
|
+
const renewed = this.Expiration.renew(session);
|
|
68
|
+
// unchanged (e.g. AbsoluteExpiration) — skip the write, report false
|
|
69
|
+
if (this.expirationEquals(current, renewed)) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
session.Expiration = renewed;
|
|
65
73
|
await DbSession.update({
|
|
66
|
-
Expiration:
|
|
74
|
+
Expiration: renewed,
|
|
67
75
|
}).where('SessionId', session.SessionId);
|
|
76
|
+
return true;
|
|
68
77
|
}
|
|
69
|
-
async
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
78
|
+
async delete(sessionId) {
|
|
79
|
+
await DbSession.destroy(sessionId);
|
|
80
|
+
}
|
|
81
|
+
async deleteByUser(userId) {
|
|
82
|
+
await DbSession.destroy().where('UserId', userId);
|
|
83
|
+
}
|
|
84
|
+
async listByUser(userId) {
|
|
85
|
+
const rows = await DbSession.where('UserId', userId);
|
|
86
|
+
return rows.map((r) => this.toSession(r)).filter((s) => !this.isExpired(s));
|
|
74
87
|
}
|
|
75
88
|
async truncate() {
|
|
76
89
|
await DbSession.truncate();
|
|
77
90
|
}
|
|
91
|
+
toSession(row) {
|
|
92
|
+
return new UserSession({
|
|
93
|
+
SessionId: row.SessionId,
|
|
94
|
+
UserId: row.UserId,
|
|
95
|
+
Creation: row.CreatedAt,
|
|
96
|
+
Expiration: row.Expiration ?? undefined,
|
|
97
|
+
Data: decodeSessionData(row.Data),
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
expirationEquals(a, b) {
|
|
101
|
+
if (a === undefined || b === undefined) {
|
|
102
|
+
return a === b;
|
|
103
|
+
}
|
|
104
|
+
return a.toMillis() === b.toMillis();
|
|
105
|
+
}
|
|
78
106
|
};
|
|
79
107
|
__decorate([
|
|
80
108
|
Logger('db-session-store'),
|
|
81
109
|
__metadata("design:type", Log)
|
|
82
110
|
], DbSessionStore.prototype, "Log", void 0);
|
|
83
111
|
__decorate([
|
|
84
|
-
Config('rbac.session.db.
|
|
112
|
+
Config('rbac.session.db.cleanupInterval', {
|
|
85
113
|
defaultValue: 100000,
|
|
86
114
|
}),
|
|
87
|
-
__metadata("design:type", Object)
|
|
88
|
-
], DbSessionStore.prototype, "CleanupInterval", void 0);
|
|
89
|
-
__decorate([
|
|
90
|
-
Config('rbac.session.expiration'),
|
|
91
115
|
__metadata("design:type", Number)
|
|
92
|
-
], DbSessionStore.prototype, "
|
|
116
|
+
], DbSessionStore.prototype, "CleanupInterval", void 0);
|
|
93
117
|
DbSessionStore = __decorate([
|
|
94
118
|
Injectable(SessionProvider)
|
|
95
119
|
], DbSessionStore);
|
package/lib/mjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,eAAe,EAAY,WAAW,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|