Last active
February 3, 2019 17:15
-
-
Save adamelliotfields/e2dd1b62d02d1a813d54e4d4b46faa42 to your computer and use it in GitHub Desktop.
Express Session Memory Store
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { BaseMemoryStore, Store } from 'express-session'; | |
export class MemoryStore extends Store implements BaseMemoryStore { | |
/** | |
* A key/value mapping of session IDs to serialized (stringified) sessions. | |
*/ | |
private readonly sessions: Map<string, string>; | |
public constructor() { | |
super(); | |
this.sessions = new Map(); | |
} | |
/** | |
* Get all active sessions. | |
*/ | |
public all: Store['all'] = (callback) => { | |
// NOTE: The docs indicate that this should be an array of sessions; however, the signature in | |
// the TypeScript definition indicates this should be an object. | |
const sessions: { [sid: string]: Express.SessionData } = {}; | |
try { | |
this.sessions.forEach((value, key) => { | |
sessions[key] = JSON.parse(value); | |
}); | |
callback && setImmediate(callback, null, sessions); | |
} catch (err) { | |
callback && setImmediate(callback, err) | |
} | |
} | |
/** | |
* Destroy the session associated with the given session ID. | |
*/ | |
public destroy: Store['destroy'] = (id, callback) => { | |
this.sessions.delete(id); | |
callback && setImmediate(callback, null); | |
} | |
/** | |
* Clear all sessions. | |
*/ | |
public clear: Store['clear'] = (callback) => { | |
this.sessions.clear(); | |
callback && setImmediate(callback, null); | |
} | |
/** | |
* Get number of active sessions. | |
*/ | |
public length: Store['length'] = (callback) => { | |
const { size } = this.sessions; | |
callback && setImmediate(callback, null, size); | |
} | |
/** | |
* Fetch session by the given session ID. | |
*/ | |
public get: Store['get'] = (id, callback) => { | |
try { | |
const session = this.sessions.has(id) | |
? JSON.parse(this.sessions.get(id) as string) | |
: undefined; | |
if (typeof session !== 'undefined' && typeof session.cookie === 'object') { | |
const expires = typeof session.cookie.expires === 'string' | |
? new Date(session.cookie.expires) | |
: session.cookie.expires; | |
// Destroy expired session | |
// NOTE: if expires === true, then expires <= new Date() === true | |
if (expires && expires <= new Date()) { | |
this.sessions.delete(id); | |
callback && setImmediate(callback, null, undefined); | |
return; | |
} | |
} | |
callback && setImmediate(callback, null, session); | |
} catch (err) { | |
callback && setImmediate(callback, err); | |
} | |
} | |
/** | |
* Commit the given session associated with the given sessionId to the store. | |
*/ | |
public set: Store['set'] = (id, session, callback) => { | |
try { | |
this.sessions.set(id, JSON.stringify(session)); | |
callback && setImmediate(callback, null); | |
} catch (err) { | |
callback && setImmediate(callback, err); | |
} | |
} | |
/** | |
* Touch the given session object associated with the given session ID. | |
*/ | |
public touch: Store['touch'] = (id, session, callback) => { | |
if (this.sessions.has(id)) { | |
try { | |
const oldSession: Express.SessionData = JSON.parse(this.sessions.get(id) as string); | |
const newSession: Express.SessionData = { ...oldSession, ...session }; | |
this.sessions.set(id, JSON.stringify(newSession)); | |
} catch (err) { | |
callback && setImmediate(callback, err); | |
return; | |
} | |
} | |
callback && setImmediate(callback, null); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment