Skip to content

Commit c9d4bca

Browse files
committed
feat: Add expiresIn option
This allows users to override the default expiry behavior when using DynamoDB TTL to expire sessions from the table. This would be useful, for example, if they wanted to use a browser session scoped cookie as the session cookie (with no maxAge attribute) but needed a shorter TTL than the default '1 day from now'. If this parameter is not provided then there will be no change to the current behaviour.
1 parent eeeb8d3 commit c9d4bca

File tree

4 files changed

+53
-1
lines changed

4 files changed

+53
-1
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ unless the `client` options is provided to override them.
2121
☣️ Legacy reap behaviors use DynamoDB [`scan`](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-dynamodb/classes/scancommand.html)
2222
functionality that can incur significant costs. Should instead enable [DynamoDB TTL](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html)
2323
and select the `expires` field. TODO should we just remove it since we're already making a breaking change?
24+
- `expiresIn` Optional set the number of seconds for DynamoDB TTL. Defaults to the cookie's maxAge.
2425

2526
## Usage
2627

@@ -42,6 +43,8 @@ var options = {
4243
],
4344
// Optional skip throw missing special keys in session, if set true
4445
skipThrowMissingSpecialKeys: true,
46+
// Optional set the number of seconds for DynamoDB TTL
47+
expiresIn: 3600,
4548
};
4649
```
4750

index.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ declare namespace ConnectDynamoDB {
3737
* Useful if the table already exists or if you want to skip existence checks in a serverless environment such as AWS Lambda.
3838
*/
3939
initialized?: boolean;
40+
/**
41+
* Set the number of seconds added to the item expiry time.
42+
*
43+
* Setting this to 0 will use the `maxAge` value from the session cookie.
44+
* @default 0
45+
*/
46+
expiresIn?: number;
4047
}
4148

4249
interface DynamoDBStoreOptionsSpecialKey {

lib/connect-dynamodb.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ module.exports = function (connect) {
6868
if (this.reapInterval > 0) {
6969
this._reap = setInterval(this.reap.bind(this), this.reapInterval);
7070
}
71+
this.expiresIn = null == options.expiresIn ? 0 : options.expiresIn
7172
}
7273

7374
/*
@@ -344,11 +345,17 @@ module.exports = function (connect) {
344345
*/
345346
DynamoDBStore.prototype.getExpiresValue = function (sess) {
346347
const now = Math.floor(Date.now() / 1000);
347-
const expires =
348+
349+
if (this.expiresIn != 0) {
350+
return now + this.expiresIn;
351+
}
352+
else {
353+
const expires =
348354
typeof sess.cookie.maxAge === "number"
349355
? now + (sess.cookie.maxAge / 1000)
350356
: now + oneDayInSeconds;
351357
return expires;
358+
}
352359
};
353360

354361
/**

test/test.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const {
55
DynamoDBClient,
66
CreateTableCommand,
77
DeleteTableCommand,
8+
GetItemCommand,
89
ScalarAttributeType,
910
} = require("@aws-sdk/client-dynamodb");
1011
const ConnectDynamoDB = require(__dirname + "/../lib/connect-dynamodb.js");
@@ -231,6 +232,40 @@ describe("DynamoDBStore", () => {
231232
});
232233
});
233234
});
235+
236+
it("should set correct expiry when expiresIn option is set", async () => {
237+
const storeWithExpiry = new DynamoDBStore({
238+
client: client,
239+
table: tableName,
240+
expiresIn: 1000
241+
});
242+
const beforeTime = Math.floor(Date.now() / 1000);
243+
244+
await new Promise((resolve, reject) => {
245+
storeWithExpiry.set(
246+
sessionId,
247+
{
248+
cookie: { maxAge: 2000 },
249+
name: "test"
250+
},
251+
(err) => {
252+
if (err) return reject(err);
253+
resolve();
254+
}
255+
);
256+
});
257+
258+
const result = await client.send(
259+
new GetItemCommand({
260+
TableName: tableName,
261+
Key: { id: { S: "sess:" + sessionId } }
262+
})
263+
);
264+
265+
const expiryValue = parseInt(result.Item.expires.N);
266+
const expectedExpiry = beforeTime + 1000;
267+
expiryValue.should.be.approximately(expectedExpiry, 2);
268+
});
234269
});
235270

236271
describe("Getting", () => {

0 commit comments

Comments
 (0)