65 lines
2 KiB
JavaScript
Executable file
65 lines
2 KiB
JavaScript
Executable file
'use strict';
|
|
// Custom session store backed by the same better-sqlite3 instance.
|
|
// Avoids pulling in a second SQLite driver (connect-sqlite3 / sqlite3).
|
|
|
|
const session = require('express-session');
|
|
|
|
const TTL_SECONDS = 8 * 60 * 60; // 8 hours — matches cookie maxAge
|
|
|
|
function createSessionStore(db) {
|
|
class SQLiteStore extends session.Store {
|
|
constructor() {
|
|
super();
|
|
// Purge expired sessions every 15 minutes
|
|
setInterval(() => {
|
|
db.prepare('DELETE FROM sessions WHERE expired < ?').run(Math.floor(Date.now() / 1000));
|
|
}, 15 * 60 * 1000).unref();
|
|
}
|
|
|
|
get(sid, cb) {
|
|
try {
|
|
const row = db.prepare('SELECT sess, expired FROM sessions WHERE sid = ?').get(sid);
|
|
if (!row) return cb(null, null);
|
|
if (row.expired < Math.floor(Date.now() / 1000)) {
|
|
db.prepare('DELETE FROM sessions WHERE sid = ?').run(sid);
|
|
return cb(null, null);
|
|
}
|
|
cb(null, JSON.parse(row.sess));
|
|
} catch (e) { cb(e); }
|
|
}
|
|
|
|
set(sid, sessionData, cb) {
|
|
try {
|
|
const ttl = sessionData.cookie?.maxAge
|
|
? Math.floor(sessionData.cookie.maxAge / 1000)
|
|
: TTL_SECONDS;
|
|
const expired = Math.floor(Date.now() / 1000) + ttl;
|
|
db.prepare('INSERT OR REPLACE INTO sessions (sid, sess, expired) VALUES (?, ?, ?)')
|
|
.run(sid, JSON.stringify(sessionData), expired);
|
|
cb(null);
|
|
} catch (e) { cb(e); }
|
|
}
|
|
|
|
destroy(sid, cb) {
|
|
try {
|
|
db.prepare('DELETE FROM sessions WHERE sid = ?').run(sid);
|
|
cb(null);
|
|
} catch (e) { cb(e); }
|
|
}
|
|
|
|
touch(sid, sessionData, cb) {
|
|
try {
|
|
const ttl = sessionData.cookie?.maxAge
|
|
? Math.floor(sessionData.cookie.maxAge / 1000)
|
|
: TTL_SECONDS;
|
|
const expired = Math.floor(Date.now() / 1000) + ttl;
|
|
db.prepare('UPDATE sessions SET expired = ? WHERE sid = ?').run(expired, sid);
|
|
cb(null);
|
|
} catch (e) { cb(e); }
|
|
}
|
|
}
|
|
|
|
return new SQLiteStore();
|
|
}
|
|
|
|
module.exports = { createSessionStore };
|