On socket.io connection, all clients join a room pertaining to
their express session id. We use this room to keep track of any
sessions in different browser windows (but the same cookie jar),
so if a login/logout occurs, we can throw a session mismatch
modal.

This room can also be used to emit messages across windows/tabs...
v1.18.x
Julian Lam 8 years ago
parent 38f11f8c28
commit ede7a71db7

@ -88,6 +88,14 @@ app.cacheBuster = null;
app.logout = function () { app.logout = function () {
$(window).trigger('action:app.logout'); $(window).trigger('action:app.logout');
/*
Set session refresh flag (otherwise the session check will trip and throw invalid session modal)
We know the session is/will be invalid (uid mismatch) because the user is logging out
*/
app.flags = app.flags || {};
app.flags._sessionRefresh = true;
$.ajax(config.relative_path + '/logout', { $.ajax(config.relative_path + '/logout', {
type: 'POST', type: 'POST',
headers: { headers: {

@ -23,6 +23,14 @@ define('forum/login', ['translator'], function (translator) {
} }
submitEl.addClass('disabled'); submitEl.addClass('disabled');
/*
Set session refresh flag (otherwise the session check will trip and throw invalid session modal)
We know the session is/will be invalid (uid mismatch) because the user is attempting a login
*/
app.flags = app.flags || {};
app.flags._sessionRefresh = true;
formEl.ajaxSubmit({ formEl.ajaxSubmit({
headers: { headers: {
'x-csrf-token': config.csrf_token 'x-csrf-token': config.csrf_token
@ -37,6 +45,7 @@ define('forum/login', ['translator'], function (translator) {
errorEl.find('p').translateText(data.responseText); errorEl.find('p').translateText(data.responseText);
errorEl.show(); errorEl.show();
submitEl.removeClass('disabled'); submitEl.removeClass('disabled');
app.flags._sessionRefresh = false;
// Select the entire password if that field has focus // Select the entire password if that field has focus
if ($('#password:focus').size()) { if ($('#password:focus').size()) {

@ -15,6 +15,8 @@ var plugins = require('../plugins');
var utils = require('../../public/src/utils'); var utils = require('../../public/src/utils');
var Password = require('../password'); var Password = require('../password');
var sockets = require('../socket.io');
var authenticationController = {}; var authenticationController = {};
authenticationController.register = function (req, res, next) { authenticationController.register = function (req, res, next) {
@ -326,6 +328,10 @@ authenticationController.onSuccessfulLogin = function (req, uid, callback) {
if (err) { if (err) {
return callback(err); return callback(err);
} }
// Force session check for all connected socket.io clients with the same session id
sockets.in('sess_' + req.sessionID).emit('checkSession', uid);
plugins.fireHook('action:user.loggedIn', uid); plugins.fireHook('action:user.loggedIn', uid);
callback(); callback();
}); });
@ -405,7 +411,9 @@ authenticationController.localLogin = function (req, username, password, next) {
authenticationController.logout = function (req, res, next) { authenticationController.logout = function (req, res, next) {
if (req.user && parseInt(req.user.uid, 10) > 0 && req.sessionID) { if (req.user && parseInt(req.user.uid, 10) > 0 && req.sessionID) {
var uid = parseInt(req.user.uid, 10); var uid = parseInt(req.user.uid, 10);
user.auth.revokeSession(req.sessionID, uid, function (err) { var sessionID = req.sessionID;
user.auth.revokeSession(sessionID, uid, function (err) {
if (err) { if (err) {
return next(err); return next(err);
} }
@ -416,6 +424,9 @@ authenticationController.logout = function (req, res, next) {
plugins.fireHook('static:user.loggedOut', {req: req, res: res, uid: uid}, function () { plugins.fireHook('static:user.loggedOut', {req: req, res: res, uid: uid}, function () {
res.status(200).send(''); res.status(200).send('');
// Force session check for all connected socket.io clients with the same session id
sockets.in('sess_' + sessionID).emit('checkSession', 0);
}); });
}); });
} else { } else {

@ -57,6 +57,7 @@ var ratelimit = require('../middleware/ratelimit');
socket.join('online_guests'); socket.join('online_guests');
} }
socket.join('sess_' + socket.request.signedCookies[nconf.get('sessionKey')]);
io.sockets.sockets[socket.id].emit('checkSession', socket.uid); io.sockets.sockets[socket.id].emit('checkSession', socket.uid);
} }

Loading…
Cancel
Save