Skip to content

Instantly share code, notes, and snippets.

@MichaelFedora
Created July 18, 2019 21:58
Show Gist options
  • Save MichaelFedora/9023bec9b34cb5bf57c9b7ba1126dcaa to your computer and use it in GitHub Desktop.
Save MichaelFedora/9023bec9b34cb5bf57c9b7ba1126dcaa to your computer and use it in GitHub Desktop.
An Express-Session store for use with rethinkdb-ts.
import { r, RTable } from 'rethinkdb-ts';
import { Store } from 'express-session';
import { getLogger, Logger } from '@log4js-node/log4js-api';
export class SessionEntry {
id: string;
expires: Date;
session: Express.SessionData;
}
/**
* May or may not work, but at least it's clean -- if anything, try to fix how it gets the table, make sure it exists,
* index it properly with the expires entry, and make sure the pool exists.
*/
export class RethinkSessionStore extends Store {
private logger: Logger;
private table: RTable<SessionEntry>;
constructor(private options?: { db?: string, logger?: string, table: string, browserSessionsMaxAge?: number, clearInterval?: number }) {
super(options); // v-- one day
options = Object.assign({ table: 'sessions', browserSessionsMaxAge: 86400000, clearInterval: 60000}, options);
if(options.db)
this.table = r.db(options.db).table(options.table);
else
this.table = r.table(options.table);
this.logger = getLogger('rdb-session');
setInterval(() => {
this.table.between(0, r.now(), { index: 'expires' }).delete().run().then(
res => res && res.deleted && this.logger.info('Deleted ' + res.deleted + ' expired sessions.'),
err => this.logger.error('Error clearing sessions: ' + err)
);
}, this.options.clearInterval).unref();
}
get = (sid: string, callback: (err?: any, session?: Express.SessionData) => void) => {
this.table.get(sid).run()
.then(data => data ? callback(null, data.session) : callback(null))
.catch(err => callback(err));
}
set = (sid: string, sess: Express.SessionData, callback: (err?: any, session?: any) => void) => {
this.table.insert({
id: sid,
expires: new Date(Date.now() + (sess.cookie.originalMaxAge || this.options.browserSessionsMaxAge)),
session: sess
}).run()
.then(() => callback())
.catch(err => callback(err));
}
destroy = (sid: string, callback: (err?: any) => void) => {
this.table.get(sid).delete().run()
.then(() => callback())
.catch(err => callback(err));
}
clear = (callback: (err?: any) => void) => {
this.table.delete().run().then(() => callback()).catch(err => callback(err));
}
length = (callback: (err?: any, count?: number) => void) => {
this.table.count().run().then(res => callback(null, res)).catch(err => callback(err));
}
all = (callback: (err: any, obj?: { [sid: string]: Express.SessionData; } | null) => void) => {
this.table.run().then(res => {
const obj = { };
for(const o of res)
obj[o.id] = o.session;
callback(null, obj);
}).catch(err => callback(err));
}
touch = (sid: string, sess: Express.SessionData, callback?: (err?: any) => void) => {
this.table.get(sid).update({
session: sess,
expires: new Date(Date.now() + (sess.cookie.originalMaxAge || this.options.browserSessionsMaxAge))
}).run()
.then(() => callback())
.catch(err => callback(err));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment