diff --git a/src/index.js b/src/index.js index 0917205..08353a8 100644 --- a/src/index.js +++ b/src/index.js @@ -67,17 +67,23 @@ module.exports = ({ Store }) => { } set(sid, sess, cb = noop) { - let age; // NOTE: Express's temporal unit of choice is milliseconds: // http://expressjs.com/en/resources/middleware/session.html#:~:text=cookie.maxAge + const now = new Date().getTime(); + let expire; + + // MaxAge takes precedence over Expires if (sess.cookie && sess.cookie.maxAge) { - age = sess.cookie.maxAge; + expire = new Date(now + sess.cookie.maxAge).toISOString(); + } else if (sess.cookie && sess.cookie.expires) { + expire = + typeof sess.cookie.expires === "object" + ? sess.cookie.expires.toISOString() + : new Date(sess.cookie.expires).toISOString(); } else { - age = oneDay; + expire = new Date(now + oneDay).toISOString(); } - const now = new Date().getTime(); - const expire = new Date(now + age).toISOString(); const entry = { sid, sess: JSON.stringify(sess), expire }; let res; diff --git a/test/index_test.js b/test/index_test.js index 00f8fc0..d373dc3 100644 --- a/test/index_test.js +++ b/test/index_test.js @@ -146,6 +146,84 @@ test("if it saves a session with a missing maxAge too", (t) => { ); }); +test("if it saves a session with expires value (as Date object) set instead of maxAge", (t) => { + const db = new sqlite(dbName, dbOptions); + const s = new SqliteStore({ + client: db, + }); + + const sid = "123"; + const ttlSeconds = 5; + const expires = new Date(); + expires.setSeconds(expires.getSeconds() + ttlSeconds); + const sess = { cookie: { expires }, name: "sample name" }; + s.set(sid, sess, (err, rows) => { + t.assert(!err); + t.assert(rows); + }); + + const dbSess = db.prepare("SELECT * FROM sessions WHERE sid = ?").get(sid); + t.assert(dbSess.sess === JSON.stringify(sess)); + t.assert(dbSess.sid === sid); + + const diff = differenceInSeconds(new Date(dbSess.expire), new Date()); + t.assert(diff >= ttlSeconds - 1 && diff <= ttlSeconds); +}); + +test("if it saves a session with expires value (as date string) set instead of maxAge", (t) => { + const db = new sqlite(dbName, dbOptions); + const s = new SqliteStore({ + client: db, + }); + + const sid = "123"; + const ttlSeconds = 5; + const expires = new Date(); + expires.setSeconds(expires.getSeconds() + ttlSeconds); + const sess = { + cookie: { expires: expires.toISOString() }, + name: "sample name", + }; + s.set(sid, sess, (err, rows) => { + t.assert(!err); + t.assert(rows); + }); + + const dbSess = db.prepare("SELECT * FROM sessions WHERE sid = ?").get(sid); + t.assert(dbSess.sess === JSON.stringify(sess)); + t.assert(dbSess.sid === sid); + + const diff = differenceInSeconds(new Date(dbSess.expire), new Date()); + t.assert(diff >= ttlSeconds - 1 && diff <= ttlSeconds); +}); + +test("if the maxAge value takes precedence over the expires value", (t) => { + const db = new sqlite(dbName, dbOptions); + const s = new SqliteStore({ + client: db, + }); + + const sid = "123"; + const ttlSeconds = 5; + const expires = new Date(); + expires.setSeconds(expires.getSeconds() + ttlSeconds); + const sess = { + cookie: { expires, maxAge: ttlSeconds * 1000 * 2 }, + name: "sample name", + }; + s.set(sid, sess, (err, rows) => { + t.assert(!err); + t.assert(rows); + }); + + const dbSess = db.prepare("SELECT * FROM sessions WHERE sid = ?").get(sid); + t.assert(dbSess.sess === JSON.stringify(sess)); + t.assert(dbSess.sid === sid); + + const diff = differenceInSeconds(new Date(dbSess.expire), new Date()); + t.assert(diff >= 2 * ttlSeconds - 1 && diff <= 2 * ttlSeconds); +}); + test("if get method returns null when no session was found", (t) => { const db = new sqlite(dbName, dbOptions); const s = new SqliteStore({