2

I'm writing a policy checkSession which basically destroy session after some time.

checkSession.js (policies/checksession.js)

var moment = require('moment');

function checkLastActivity(req) {
    if (!req.session.lastActivity) {
        return false; // no session.
    } else {
        return true;
    }
}

function setActivity(req) {
    req.session.lastActivity = moment(new Date()).format();
    return true;
}

function updateActivity(req, res, updated) {
    req.session.lastActivity = moment(new Date()).format();
    updated(null, {
        isdestroted: 0
    });
}

function checkIdleTime(req, idleTime) {
    try {
        var lastActivityTime = moment(req.session.lastActivity).format();
        var currentActivityTime = moment(new Date()).format();
        timeIdle = moment.utc(moment(currentActivityTime).diff(moment(lastActivityTime))).format("HH:mm:ss");
        minutestimeIdle = moment.duration(timeIdle).asMinutes().toFixed(2);
        idleTime(null, minutestimeIdle);
    } catch (e) {
        idleTime(e, null);
    }
}

function destroyActivity(req, res, destroyed) {
  try {
    req.session.destroy();
    sails.log.info("***********************session is expired for user *****************");
    destroyed(null, {
        isdestroted: 1,
        redirectCode: 200,
        redirectView: '/login/'
    });
  } catch(e) {
    destroyed(e, null);
  }
}

module.exports = function isSession(req, res, next) {
    cleanParamsService.cleanPrm(req);
    async.waterfall([
        function(callback) {
            callback(null, checkLastActivity(req));
        },
        function(isLastActivity, callback) {
            if (isLastActivity) {
                checkIdleTime(req, function(err, timeIdle) {
                    if (minutestimeIdle > sails.config.session_timeout) { /*if user is being idle*/
                        destroyActivity(req, res, function(err, destroyed) {
                            sails.log.warn('User was idle since' + minutestimeIdle + ', sessions are destroyed');
                            callback(null, destroyed);
                        })
                    } else {
                        updateActivity(req, res, function(err, updated) {
                            callback(null, updated);
                        });
                    }
                })
            } else {
                updateActivity(req, res, function(err, updated) {
                    callback(null, updated);
                });
            }
        }
    ], function(err, result) {
        if (result) {
            if (result.isdestroted == 0) {
                return next();
            } else {
                return res.redirect(result.redirectCode, result.redirectView);
            }
        } else {
            sails.log.error('err:', err);
            return res.badRequest();
        }
    });
};

now if i change it to

var moment = require('moment');

function checkLastActivity(req) {
    if (!req.session.lastActivity) {
        return false; // no session.
    } else {
        return true;
    }
}

function setActivity(req) {
    req.session.lastActivity = moment(new Date()).format();
    return true;
}

function updateActivity(req, res, updated) {
    req.session.lastActivity = moment(new Date()).format();
    updated(null, {
        isdestroted: 0
    });
}

function checkIdleTime(req, idleTime) {
    try {
        var lastActivityTime = moment(req.session.lastActivity).format();
        var currentActivityTime = moment(new Date()).format();
        timeIdle = moment.utc(moment(currentActivityTime).diff(moment(lastActivityTime))).format("HH:mm:ss");
        minutestimeIdle = moment.duration(timeIdle).asMinutes().toFixed(2);
        idleTime(null, minutestimeIdle);
    } catch (e) {
        idleTime(e, null);
    }
}

function destroyActivity(req, res, destroyed) {
    try {
        req.session.destroy();
        sails.log.info("***********************session is expired for user *****************");
        destroyed(null, {
            isdestroted: 1,
            redirectCode: 200,
            redirectView: '/login/'
        });
    } catch (e) {
        destroyed(e, null);
    }
}

module.exports = function isSession(req, res, next) {
    cleanParamsService.cleanPrm(req);
    async.waterfall([
        function(callback) {
            callback(null, checkLastActivity(req));
        },
        function(isLastActivity, callback) {
            if (isLastActivity) {
                checkIdleTime(req, function(err, timeIdle) {
                    if (minutestimeIdle > sails.config.session_timeout) { /*if user is being idle*/
                        destroyActivity(req, res, function(err, destroyed) {
                            sails.log.warn('User was idle since' + minutestimeIdle + ', sessions are destroyed');
                            callback(null, destroyed);
                        })
                    } else {
                        updateActivity(req, res, function(err, updated) {
                            callback(null, updated);
                        });
                    }
                })
            } else {
                updateActivity(req, res, function(err, updated) {
                    callback(null, updated);
                });
            }
        },
        function(resp, callback) {
            if (resp.isdestroted == 0) {
                req.fresh;
                req.session.isdestroted = false;
                callback(null, resp);
            } else {
                req.fresh;
                req.session.isdestroted = true;
                callback(null, resp);
            }
        }
    ], function(err, result) {
        if (result) {
            if (result.isdestroted == 0) {
                return next();
            } else {
                return res.redirect(result.redirectCode, result.redirectView);
            }
        } else {
            sails.log.error('err:', err);
            return res.badRequest();
        }
    });
};

The application trigger error where i'm setting req.session.isdestroted = true/false and the error is

warn: User was idle since0.38, sessions are destroyed
debug: Lowering sails...
C:\Users\Vbase002\Desktop\CC\Website\api\policies\checkSession.js:83
                req.session.isdestroted = true;
                                        ^
TypeError: Cannot set property 'isdestroted' of undefined
    at C:\Users\Vbase002\Desktop\CC\Website\api\policies\checkSession.js:83:41
    at fn (C:\Users\Vbase002\Desktop\CC\Website\node_modules\sails\node_modules\
async\lib\async.js:579:34)
    at Immediate._onImmediate (C:\Users\Vbase002\Desktop\CC\Website\node_modules
\sails\node_modules\async\lib\async.js:495:34)
    at processImmediate [as _immediateCallback] (timers.js:367:17)

i'm setting this session to show some message on login page to user, but i don't know why sails is behaving like this.

is there any way to handle this scenario and also please let me know the reason why this is happening.

Thanks

Ahsan Hussain
  • 952
  • 4
  • 21
  • 42

1 Answers1

2

This is a behavior from express.

Session.destroy()

Destroys the session, removing req.session, will be re-generated next request.

As your warn log indicates, req.session.destroy(); has been called before the error.

You could use req.session.regenerate() to have the expected behavior.

Session.regenerate()

To regenerate the session simply invoke the method, once complete a new SID and Session instance will be initialized at req.session.

Alexis N-o
  • 3,954
  • 26
  • 34