mweibel / connect-session-sequelize

Sequelize SessionStore for Express/Connect

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

TypeError: this.startExpiringSessions is not a function

LMADoneur opened this issue · comments

I making a api using sequelize and express, i need to use connect-session-sequelize.

const app = express(),
  httpserver = require('http').Server(app).listen(80),
  io = require('socket.io').listen(httpserver),
  session = require('express-session'),
  dbsession = require('connect-session-sequelize')(session.Store),
  dbsession_store = dbsession({
    db: db.sequelize,
    table: 'express_session',
    checkExpirationInterval: 15 * 60 * 1000,
    expiration: 24 * 60 * 60 * 60 * 1000
  })

app.use(compression())
  .use(cookieparser())
  .use(bodyparser.json())
  .use(bodyparser.urlencoded({
    extended: false
  }))
  .use(session({
    secret: 'mysecret',
    store: dbsession_store,
    resave: false,
    saveUninitialized: false,
    proxy: true
  }))

dbsession_store.sync();

The error i get while running my script.

/usr/src/api/node_modules/connect-session-sequelize/lib/connect-session-sequelize.js:41,
    this.startExpiringSessions(),
         ^,
,
TypeError: this.startExpiringSessions is not a function,
    at SequelizeStore (/usr/src/api/node_modules/connect-session-sequelize/lib/connect-session-sequelize.js:41:10),
    at Object.<anonymous> (/usr/src/api/api.js:15:21),
    at Module._compile (internal/modules/cjs/loader.js:734:30),
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:745:10),
    at Module.load (internal/modules/cjs/loader.js:626:32),
    at tryModuleLoad (internal/modules/cjs/loader.js:566:12),
    at Function.Module._load (internal/modules/cjs/loader.js:558:3),
    at Function.Module.runMain (internal/modules/cjs/loader.js:797:12),
    at executeUserCode (internal/bootstrap/node.js:526:15),
    at startMainThreadExecution (internal/bootstrap/node.js:439:3)

I already tried making a model in sequelize for the table with the same table name ect..

I believe you are not importing the model before setting up the session handler.

Here is my working code doing a similar setup.

First the model

/**
 * Exporting the model
 * @param {object} sequelize
 * @param {object} DataTypes
 * @return {object}
 */
module.exports = function(sequelize,DataTypes) {
  return sequelize.define('StaffSession',{
      sid: {
        type: DataTypes.STRING,
        primaryKey: true
      },
      expires: {
        type: DataTypes.DATE
      },
      data: {
        type: DataTypes.TEXT
      }
    },
    {
      indexes: [
        {
          name: 'expires_index',
          method: 'BTREE',
          fields: ['expires']
        },
        {
          name: 'createdAt_index',
          method: 'BTREE',
          fields: ['createdAt']
        },
        {
          name: 'updatedAt_index',
          method: 'BTREE',
          fields: ['updatedAt']
        }
      ]
    })
}

Which is loaded through sequelize.import('./StaffSession')

Then finally the connect setup

//session setup
      app.use(expressSession({
        cookie: {
          maxAge: 2592000000
        },
        resave: true,
        saveUninitialized: true,
        store: new SequelizeStore({
          db: sequelize,
          table: 'StaffSession'
        }),
        secret: 'something secret'
      }))

@nullivex I already have a model for the session table.

module.exports = (sequelize, DataTypes) => {
  var express_session = sequelize.define('express_session', {
    sid: {
      type: DataTypes.STRING,
      primaryKey: true
    },
    expires: {
      type: DataTypes.DATE
    },
    data: {
      type: DataTypes.TEXT
    }
  }, {
    freezeTableName: true,
    tableName: 'express_session',
    indexes: [{
        name: 'expires_index',
        method: 'BTREE',
        fields: ['expires']
      },
      {
        name: 'createdAt_index',
        method: 'BTREE',
        fields: ['createdAt']
      },
      {
        name: 'updatedAt_index',
        method: 'BTREE',
        fields: ['updatedAt']
      }
    ]
  });
  return express_session;
};

@LMADoneur the provided code does indicate how you setup your sequelize prior to instantiating your session handler. Are you importing the model?/

I dont see anything obviously wrong, however the error tells me that the system could not find your model object. Just for curiosity try using TitleCase and see if the plugin is having an issue with snake_case.

db.sequelize.sync()
  .then(() => {
    /*=============================================>>>>>
    = Express Initialization & Routing / Sequelize Sync =
    ===============================================>>>>>*/
    const app = express(),
      httpserver = require('http').Server(app).listen(80),
      io = require('socket.io').listen(httpserver),
      session = require('express-session'),
      dbsession = require('connect-session-sequelize')(session.Store),
      dbsession_store = dbsession({
        db: db.sequelize,
        table: 'express_session',
        checkExpirationInterval: 15 * 60 * 1000,
        expiration: 24 * 60 * 60 * 60 * 1000
      })


    app.engine('handlebars', exphbs())
      .set('view engine', 'handlebars')
      .use(compression())
      .use(cookieparser())
      .use(bodyparser.json())
      .use(bodyparser.urlencoded({
        extended: false
      }))
      .use(session({
        secret: '*SECRET KEY*',
        store: dbsession_store,
        resave: false,
        saveUninitialized: false,
        proxy: true
      }))

    const routes_index = require('./routes/index');

    app.use('/', routes_index);
    console.log('Table & Express have been established successfully.');
  }).catch(error => console.log('This error occured: ', error));

I still get

This error occured:  TypeError: this.startExpiringSessions is not a function
    at SequelizeStore (/usr/src/api/node_modules/connect-session-sequelize/lib/connect-session-sequelize.js:41:10)
    at db.sequelize.sync.then (/usr/src/api/api.js:18:25)
    at tryCatcher (/usr/src/api/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/usr/src/api/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/usr/src/api/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/usr/src/api/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/usr/src/api/node_modules/bluebird/js/release/promise.js:694:18)
    at _drainQueueStep (/usr/src/api/node_modules/bluebird/js/release/async.js:138:12)
    at _drainQueue (/usr/src/api/node_modules/bluebird/js/release/async.js:131:9)
    at Async._drainQueues (/usr/src/api/node_modules/bluebird/js/release/async.js:147:5)
    at Immediate.Async.drainQueues [as _onImmediate] (/usr/src/api/node_modules/bluebird/js/release/async.js:17:14)
    at processImmediate (timers.js:637:19)

@mweibel any thoughts?

On first sight I see two issues where you didn't follow the docs exactly (one related to this package, one not):

// first case
httpserver = require('http').Server(app).listen(80),

// second case
dbsession = require('connect-session-sequelize')(session.Store),
dbsession_store = dbsession({

In case one: Server is a class, you need to use createServer(). Docs are here: https://nodejs.org/api/http.html#http_event_clienterror

In case two, which is related to connect-session-sequelize: What you get from require('connect-session-sequelize')(session.Store) is a class. You need to instantiate it.
This is documented in the README, please follow it exactly and don't take shortcuts:

var connect = require('connect')
	// for express, just call it with 'require('connect-session-sequelize')(session.Store)'
	, SequelizeStore = require('connect-session-sequelize')(connect.session.Store);

connect().use(connect.session({
	store: new SequelizeStore(options)
	, secret: 'CHANGEME'
}));

Let me know if your issue still persists. I'll close this ticket meanwhile but will reopen if necessary.