@regraf/session-redis
Version:
Redis powered session middleware for Regraf
85 lines (77 loc) • 2.25 kB
JavaScript
const debug = require('debug')('regraf:session-redis')
const redis = require('redis')
class RedisSession {
constructor (options) {
this.options = Object.assign({
property: 'session',
getSessionKey: (ctx) => ctx.from && ctx.chat && `${ctx.from.id}:${ctx.chat.id}`,
store: {}
}, options)
this.client = redis.createClient(this.options.store)
}
getSession (key) {
return new Promise((resolve, reject) => {
this.client.get(key, (err, json) => {
if (err) {
return reject(err)
}
if (json) {
try {
const session = JSON.parse(json)
debug('session state', key, session)
resolve(session)
} catch (error) {
debug('Parse session state failed', error)
}
}
resolve({})
})
})
}
clearSession (key) {
debug('clear session', key)
return new Promise((resolve, reject) => {
this.client.del(key, (err, json) => {
if (err) {
return reject(err)
}
resolve()
})
})
}
saveSession (key, session) {
if (!session || Object.keys(session).length === 0) {
return this.clearSession(key)
}
debug('save session', key, session)
return new Promise((resolve, reject) => {
this.client.set(key, JSON.stringify(session), (err, json) => {
if (err) {
return reject(err)
}
if (this.options.ttl) {
debug('session ttl', session)
this.client.expire(key, this.options.ttl)
}
resolve({})
})
})
}
middleware () {
return (ctx, next) => {
const key = this.options.getSessionKey(ctx)
if (!key) {
return next()
}
return this.getSession(key).then((session) => {
debug('session snapshot', key, session)
Object.defineProperty(ctx, this.options.property, {
get: function () { return session },
set: function (newValue) { session = Object.assign({}, newValue) }
})
return next().then(() => this.saveSession(key, session))
})
}
}
}
module.exports = RedisSession