@spinajs/session-provider-dynamodb 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.
- package/lib/cjs/index.d.ts +25 -11
- package/lib/cjs/index.d.ts.map +1 -1
- package/lib/cjs/index.js +131 -127
- package/lib/cjs/index.js.map +1 -1
- package/lib/mjs/index.d.ts +25 -11
- package/lib/mjs/index.d.ts.map +1 -1
- package/lib/mjs/index.js +132 -125
- 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 +15 -16
package/lib/mjs/index.js
CHANGED
|
@@ -7,42 +7,154 @@ 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
|
|
10
|
+
import { readFileSync } from 'fs';
|
|
11
|
+
import { DynamoDBClient, GetItemCommand, PutItemCommand, DeleteItemCommand, ScanCommand, DescribeTableCommand, CreateTableCommand, UpdateTimeToLiveCommand, DeleteTableCommand, } from '@aws-sdk/client-dynamodb';
|
|
11
12
|
import { DateTime } from 'luxon';
|
|
12
|
-
import { SessionProvider, UserSession } from '@spinajs/rbac';
|
|
13
|
+
import { SessionProvider, UserSession, encodeSessionData, decodeSessionData } from '@spinajs/rbac';
|
|
13
14
|
import { Injectable } from '@spinajs/di';
|
|
14
15
|
import { Config } from '@spinajs/configuration';
|
|
15
16
|
import { Logger, Log } from '@spinajs/log';
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
/**
|
|
18
|
+
* DynamoDB-backed session store. Conforms to the `@spinajs/rbac`
|
|
19
|
+
* `SessionProvider` contract: ownership is the numeric `UserId` (persisted as
|
|
20
|
+
* its own top-level attribute), expiration is owned by the injected strategy
|
|
21
|
+
* (`this.Expiration`) and persisted verbatim, and `Data` is (de)serialized with
|
|
22
|
+
* the shared session codec. Uses the AWS SDK for JavaScript v3
|
|
23
|
+
* (`new DynamoDBClient(...)` + command objects dispatched through `.send()`).
|
|
24
|
+
*/
|
|
18
25
|
let DynamoDbSessionProvider = class DynamoDbSessionProvider extends SessionProvider {
|
|
19
|
-
// tslint:disable-next-line: no-empty
|
|
20
26
|
async resolve() {
|
|
21
|
-
AWS.config
|
|
27
|
+
// v3 has no global `AWS.config` / `loadFromPath` — the whole configuration
|
|
28
|
+
// (region, endpoint, credentials) is passed straight into the client
|
|
29
|
+
// constructor. `configPath` is read here and merged in ourselves.
|
|
30
|
+
let cfg = {};
|
|
22
31
|
if (this.ConfigPath) {
|
|
23
|
-
|
|
32
|
+
cfg = { ...cfg, ...JSON.parse(readFileSync(this.ConfigPath, 'utf-8')) };
|
|
24
33
|
}
|
|
25
34
|
else if (this.AwsConfig) {
|
|
26
|
-
|
|
35
|
+
cfg = { ...cfg, ...this.AwsConfig };
|
|
27
36
|
}
|
|
28
|
-
this.DynamoDb = new
|
|
37
|
+
this.DynamoDb = new DynamoDBClient(cfg);
|
|
29
38
|
const table = await this.checkSessionTable();
|
|
30
39
|
if (!table) {
|
|
31
40
|
await this.createSessionTable();
|
|
32
41
|
await this.updateTimeToLive();
|
|
33
42
|
}
|
|
34
43
|
}
|
|
44
|
+
async restore(sessionId) {
|
|
45
|
+
const result = await this.DynamoDb.send(new GetItemCommand({
|
|
46
|
+
TableName: this.Table,
|
|
47
|
+
Key: {
|
|
48
|
+
SessionId: { S: sessionId },
|
|
49
|
+
},
|
|
50
|
+
}));
|
|
51
|
+
if (!result.Item) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
const session = this.toSession(result.Item);
|
|
55
|
+
// DynamoDB TTL deletion is eventual — an expired item may still be present.
|
|
56
|
+
// Treat an expired session as absent, matching the contract.
|
|
57
|
+
if (this.isExpired(session)) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
return session;
|
|
61
|
+
}
|
|
62
|
+
async save(session) {
|
|
63
|
+
// Persist `Expiration` verbatim. Only a brand-new session with no scheduled
|
|
64
|
+
// expiration is given its initial expiry via the strategy (fixes B3).
|
|
65
|
+
if (session.Expiration === undefined) {
|
|
66
|
+
this.applyInitialExpiration(session);
|
|
67
|
+
}
|
|
68
|
+
const item = {
|
|
69
|
+
SessionId: { S: session.SessionId },
|
|
70
|
+
// ownership source of truth — a top-level numeric attribute (fixes B4).
|
|
71
|
+
UserId: { N: `${session.UserId}` },
|
|
72
|
+
Creation: { S: session.Creation.toISO() },
|
|
73
|
+
Data: { S: encodeSessionData(session.Data) },
|
|
74
|
+
};
|
|
75
|
+
// DynamoDB TTL attribute (epoch millis), driven by `session.Expiration`.
|
|
76
|
+
// A never-expiring session simply omits it.
|
|
77
|
+
if (session.Expiration !== undefined) {
|
|
78
|
+
item.Expiration = { N: `${session.Expiration.toMillis()}` };
|
|
79
|
+
}
|
|
80
|
+
await this.DynamoDb.send(new PutItemCommand({
|
|
81
|
+
TableName: this.Table,
|
|
82
|
+
Item: item,
|
|
83
|
+
}));
|
|
84
|
+
}
|
|
85
|
+
async touch(session) {
|
|
86
|
+
const current = session.Expiration;
|
|
87
|
+
const renewed = this.Expiration.renew(session);
|
|
88
|
+
// unchanged (e.g. AbsoluteExpiration) — skip the write, report false
|
|
89
|
+
if (this.expirationEquals(current, renewed)) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
session.Expiration = renewed;
|
|
93
|
+
await this.save(session);
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
async delete(sessionId) {
|
|
97
|
+
await this.DynamoDb.send(new DeleteItemCommand({
|
|
98
|
+
TableName: this.Table,
|
|
99
|
+
Key: {
|
|
100
|
+
SessionId: { S: sessionId },
|
|
101
|
+
},
|
|
102
|
+
}));
|
|
103
|
+
}
|
|
104
|
+
async deleteByUser(userId) {
|
|
105
|
+
// DynamoDB has no filtered batch delete — scan by the top-level numeric
|
|
106
|
+
// UserId attribute and delete each match (fixes B4; the old `logsOut`
|
|
107
|
+
// filtered `Data.User` inside a scalar JSON string and matched nothing).
|
|
108
|
+
const items = await this.scanByUser(userId);
|
|
109
|
+
for (const item of items) {
|
|
110
|
+
await this.delete(item.SessionId.S);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async listByUser(userId) {
|
|
114
|
+
const items = await this.scanByUser(userId);
|
|
115
|
+
return items.map((item) => this.toSession(item)).filter((s) => !this.isExpired(s));
|
|
116
|
+
}
|
|
117
|
+
async truncate() {
|
|
118
|
+
await this.deleteSessionTable();
|
|
119
|
+
await this.createSessionTable();
|
|
120
|
+
await this.updateTimeToLive();
|
|
121
|
+
}
|
|
122
|
+
async scanByUser(userId) {
|
|
123
|
+
const result = await this.DynamoDb.send(new ScanCommand({
|
|
124
|
+
TableName: this.Table,
|
|
125
|
+
FilterExpression: 'UserId = :uid',
|
|
126
|
+
ExpressionAttributeValues: {
|
|
127
|
+
':uid': { N: `${userId}` },
|
|
128
|
+
},
|
|
129
|
+
}));
|
|
130
|
+
return result.Items ?? [];
|
|
131
|
+
}
|
|
132
|
+
toSession(item) {
|
|
133
|
+
return new UserSession({
|
|
134
|
+
SessionId: item.SessionId.S,
|
|
135
|
+
UserId: item.UserId ? parseInt(item.UserId.N, 10) : 0,
|
|
136
|
+
Creation: DateTime.fromISO(item.Creation.S),
|
|
137
|
+
Expiration: item.Expiration ? DateTime.fromMillis(parseInt(item.Expiration.N, 10)) : undefined,
|
|
138
|
+
Data: decodeSessionData(item.Data.S),
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
expirationEquals(a, b) {
|
|
142
|
+
if (a === undefined || b === undefined) {
|
|
143
|
+
return a === b;
|
|
144
|
+
}
|
|
145
|
+
return a.toMillis() === b.toMillis();
|
|
146
|
+
}
|
|
35
147
|
updateTimeToLive() {
|
|
36
|
-
return this.DynamoDb.
|
|
148
|
+
return this.DynamoDb.send(new UpdateTimeToLiveCommand({
|
|
37
149
|
TableName: this.Table,
|
|
38
150
|
TimeToLiveSpecification: {
|
|
39
151
|
AttributeName: 'Expiration',
|
|
40
152
|
Enabled: true,
|
|
41
153
|
},
|
|
42
|
-
})
|
|
154
|
+
}));
|
|
43
155
|
}
|
|
44
156
|
createSessionTable() {
|
|
45
|
-
return this.DynamoDb.
|
|
157
|
+
return this.DynamoDb.send(new CreateTableCommand({
|
|
46
158
|
TableName: this.Table,
|
|
47
159
|
AttributeDefinitions: [
|
|
48
160
|
{
|
|
@@ -60,127 +172,26 @@ let DynamoDbSessionProvider = class DynamoDbSessionProvider extends SessionProvi
|
|
|
60
172
|
ReadCapacityUnits: this.ReadCapacityUnits,
|
|
61
173
|
WriteCapacityUnits: this.WriteCapacityUnits,
|
|
62
174
|
},
|
|
63
|
-
})
|
|
175
|
+
}));
|
|
64
176
|
}
|
|
65
177
|
async checkSessionTable() {
|
|
66
178
|
try {
|
|
67
|
-
return await this.DynamoDb.
|
|
179
|
+
return await this.DynamoDb.send(new DescribeTableCommand({
|
|
68
180
|
TableName: this.Table,
|
|
69
|
-
})
|
|
181
|
+
}));
|
|
70
182
|
}
|
|
71
183
|
catch (err) {
|
|
72
|
-
|
|
184
|
+
// v3 surfaces the error class name via `err.name` (v2 used `err.code`).
|
|
185
|
+
if (err.name === 'ResourceNotFoundException') {
|
|
73
186
|
return null;
|
|
74
187
|
}
|
|
188
|
+
throw err;
|
|
75
189
|
}
|
|
76
190
|
}
|
|
77
|
-
async restore(sessionId) {
|
|
78
|
-
const params = {
|
|
79
|
-
TableName: this.Table,
|
|
80
|
-
Key: {
|
|
81
|
-
SessionId: { S: sessionId },
|
|
82
|
-
},
|
|
83
|
-
};
|
|
84
|
-
const result = await this.DynamoDb.getItem(params).promise();
|
|
85
|
-
if (!result.Item) {
|
|
86
|
-
return null;
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
// DynamoDB ttl takes time, sometimes
|
|
90
|
-
// we receive session before ttl mark result as expired
|
|
91
|
-
// and deletes it
|
|
92
|
-
const ttl = parseInt(result.Item.Expiration.N);
|
|
93
|
-
if (ttl < DateTime.now().toMillis()) {
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
const data = JSON.parse(result.Item.Data.S);
|
|
97
|
-
return new UserSession({
|
|
98
|
-
Creation: DateTime.fromISO(result.Item.Creation.S),
|
|
99
|
-
Expiration: DateTime.fromMillis(ttl),
|
|
100
|
-
SessionId: result.Item.SessionId.S,
|
|
101
|
-
Data: new Map(Object.entries(data)),
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
async delete(sessionId) {
|
|
106
|
-
const params = {
|
|
107
|
-
TableName: this.Table,
|
|
108
|
-
Key: {
|
|
109
|
-
SessionId: { S: sessionId },
|
|
110
|
-
},
|
|
111
|
-
};
|
|
112
|
-
await this.DynamoDb.deleteItem(params).promise();
|
|
113
|
-
}
|
|
114
|
-
async touch(session) {
|
|
115
|
-
const params = {
|
|
116
|
-
TableName: this.Table,
|
|
117
|
-
Key: {
|
|
118
|
-
SessionId: { S: session.SessionId },
|
|
119
|
-
},
|
|
120
|
-
UpdateExpression: 'set Expiration = :e',
|
|
121
|
-
ExpressionAttributeValues: {
|
|
122
|
-
':e': {
|
|
123
|
-
N: `${session.Expiration.toMillis()}`,
|
|
124
|
-
},
|
|
125
|
-
},
|
|
126
|
-
ReturnValues: 'UPDATED_NEW',
|
|
127
|
-
};
|
|
128
|
-
await this.DynamoDb.updateItem(params).promise();
|
|
129
|
-
}
|
|
130
|
-
async truncate() {
|
|
131
|
-
await this.deleteSessionTable();
|
|
132
|
-
await this.createSessionTable();
|
|
133
|
-
await this.updateTimeToLive();
|
|
134
|
-
}
|
|
135
191
|
async deleteSessionTable() {
|
|
136
|
-
await this.DynamoDb.
|
|
137
|
-
TableName: this.Table,
|
|
138
|
-
}).promise();
|
|
139
|
-
}
|
|
140
|
-
async logsOut(user) {
|
|
141
|
-
// DynamoDB does not support batch delete
|
|
142
|
-
// so we need to load all sessions and delete them one by one
|
|
143
|
-
const params = {
|
|
144
|
-
TableName: this.Table,
|
|
145
|
-
FilterExpression: 'Data.User = :userId',
|
|
146
|
-
ExpressionAttributeValues: {
|
|
147
|
-
':userId': { S: user.Uuid },
|
|
148
|
-
},
|
|
149
|
-
};
|
|
150
|
-
const sessions = await this.DynamoDb.scan(params).promise();
|
|
151
|
-
if (sessions.Items && sessions.Items.length > 0) {
|
|
152
|
-
for (const item of sessions.Items) {
|
|
153
|
-
await this.delete(item.SessionId.S);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
async save(sessionOrId, data) {
|
|
158
|
-
let sId = '';
|
|
159
|
-
let sData = null;
|
|
160
|
-
let sCreationTime = DateTime.now();
|
|
161
|
-
let sExpirationTime = DateTime.now().plus({ minutes: this.DefaultExpirationTime });
|
|
162
|
-
if (_.isString(sessionOrId)) {
|
|
163
|
-
sId = sessionOrId;
|
|
164
|
-
sData = JSON.stringify(data);
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
sId = sessionOrId.SessionId;
|
|
168
|
-
sData = JSON.stringify(Object.fromEntries(sessionOrId.Data), replacer);
|
|
169
|
-
sCreationTime = sessionOrId.Creation;
|
|
170
|
-
sExpirationTime = sessionOrId.Expiration;
|
|
171
|
-
}
|
|
172
|
-
const params = {
|
|
192
|
+
await this.DynamoDb.send(new DeleteTableCommand({
|
|
173
193
|
TableName: this.Table,
|
|
174
|
-
|
|
175
|
-
SessionId: { S: sId },
|
|
176
|
-
Data: {
|
|
177
|
-
S: sData,
|
|
178
|
-
},
|
|
179
|
-
Creation: { S: sCreationTime.toISO() },
|
|
180
|
-
Expiration: { N: `${sExpirationTime.toMillis()}` },
|
|
181
|
-
},
|
|
182
|
-
};
|
|
183
|
-
await this.DynamoDb.putItem(params).promise();
|
|
194
|
+
}));
|
|
184
195
|
}
|
|
185
196
|
};
|
|
186
197
|
__decorate([
|
|
@@ -195,10 +206,6 @@ __decorate([
|
|
|
195
206
|
Config('rbac.session.aws.config'),
|
|
196
207
|
__metadata("design:type", Object)
|
|
197
208
|
], DynamoDbSessionProvider.prototype, "AwsConfig", void 0);
|
|
198
|
-
__decorate([
|
|
199
|
-
Config('rbac.session.expiration'),
|
|
200
|
-
__metadata("design:type", Number)
|
|
201
|
-
], DynamoDbSessionProvider.prototype, "DefaultExpirationTime", void 0);
|
|
202
209
|
__decorate([
|
|
203
210
|
Config('rbac.session.aws.configPath'),
|
|
204
211
|
__metadata("design:type", Object)
|
package/lib/mjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|