All files express-session-cache-manager.js

82.14% Statements 46/56
55.17% Branches 16/29
91.67% Functions 11/12
82.14% Lines 46/56
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152          1x     1x 1x               6x   6x 6x 6x 6x 6x                 3x   3x 3x       3x 1x     2x   2x   2x   2x 2x         2x                     9x 9x 9x   9x 9x         9x 9x   9x         9x 9x       9x 9x         9x 9x                     3x   3x   3x               3x 3x       2x 2x       2x   2x                     1x   1x       1x      
// Code adapted from connect-redis (https://github.com/tj/connect-redis)
 
import { Store } from 'express-session'
import debugFactory from 'debug'
 
const debug = debugFactory('session-cache-manager')
 
// day in seconds
const oneDay = 86400
const noop = function () {}
 
export default class SessionCacheManager extends Store {
  /**
   * @param {CacheManager} cacheManager instance of node-cache-manager
   * @param {object} options
   */
  constructor (cacheManager, options = {}) {
    super(options)
 
    this.store = cacheManager
    this.prefix = options.prefix === null ? 'sess:' : options.prefix
    this.serializer = options.serializer || JSON
    this.ttl = options.ttl || oneDay
    this.disableTTL = options.disableTTL
  }
 
  /**
   * Get a session
   * @param {String} sid
   * @param {Function} cb (err, result)
   */
  get (sid, cb = noop) {
    const psid = this.prefix + sid
 
    this.store.get(psid, (err, data) => {
      Iif (err) {
        return cb(err)
      }
 
      if (!data) {
        return cb(err, null)
      }
 
      let result = null
 
      data = data.toString()
 
      debug('GOT %s', data)
 
      try {
        result = this.serializer.parse(data)
      } catch (er) {
        return cb(er)
      }
 
      return cb(null, result)
    })
  }
 
  /**
   * Set a session
   * @param {String} sid
   * @param {Session} sess
   * @param {Function} cb
   */
  set (sid, sess, cb = noop) {
    const resolvedSID = this.prefix + sid
    let serializedSess = null
    let ttl = null
 
    try {
      serializedSess = this.serializer.stringify(sess)
    } catch (er) {
      return cb(er)
    }
 
    Eif (!this.disableTTL) {
      ttl = this.getTTL(sess)
 
      debug('SET "%s" %s ttl:%s', sid, serializedSess, ttl)
    } else {
      debug('SET "%s" %s', sid, serializedSess)
    }
 
    this.store.set(resolvedSID, serializedSess, { ttl }, (err) => {
      Iif (err) {
        return cb(err)
      }
 
      debug('SET complete')
      cb(null, null)
    })
  }
 
  getTTL (sess) {
    let maxAge = sess.cookie.maxAge
    return this.ttl || (typeof maxAge === 'number'
        ? Math.floor(maxAge / 1000)
        : oneDay)
  }
 
  /**
   * Removes the session
   * @param {String|Array} sid
   * @param {Function} cb
   */
  destroy (sid, cb = noop) {
    debug('DEL "%s"', sid);
 
    const prefix = this.prefix
 
    Iif (Array.isArray(sid)) {
      sid.forEach((sessID) => {
        this.store.del(prefix + sessID)
      })
 
      return cb(null, null)
    }
 
    sid = this.prefix + sid
    this.store.del(sid, cb)
  }
 
  length (cb) {
    this.store.keys(this.prefix, (err, rslts) => {
      Iif (err) {
        return cb(err, null)
      }
 
      debug('LENGTH %s', rslts.length)
 
      cb(null, rslts.length)
    })
  }
 
  /**
   * Refresh the TTL for the session
   * @param {String} sid
   * @param {Session} sess
   * @param {Function} cb
   */
  touch (sid, sess, cb = noop) {
    debug('TOUCH "%s" %s', sid)
 
    Iif (this.disableTTL) {
      return cb(null, null)
    }
 
    this.set(sid, sess, cb)
  }
}