mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-01 19:46:01 +01:00
Do not require a full refresh on login/logout (#6841)
* no-refresh login as well, plus lots of fixes for missing config on login * replace config with new set on logout as well * passing new payload data into new action:app.loggedIn hook, and old action:app.loggedOut hook * fixed issues with socket.io not properly representing uid on server * some light refactoring and cleanup * minor cleanup, fixed spa logout not working after login * have reconnection handler for socket.io wait 2s to confirm disconnection before reporting -- stops flicker if reconnecting immediately * Dynamically replace chat and slideout menu on updateHeader() ... instead of just the menu items. * more efficient calls to Benchpress and translator /cc @pitaj * fix: chats and notification handlers not working after login * fix: accidentally calling cb multiple times
This commit is contained in:
@@ -56,9 +56,7 @@ app.cacheBuster = null;
|
|||||||
app.newTopic();
|
app.newTopic();
|
||||||
});
|
});
|
||||||
|
|
||||||
require(['components'], function (components) {
|
$('#header-menu .container').on('click', '[component="user/logout"]', app.logout);
|
||||||
components.get('user/logout').on('click', app.logout);
|
|
||||||
});
|
|
||||||
|
|
||||||
Visibility.change(function (event, state) {
|
Visibility.change(function (event, state) {
|
||||||
if (state === 'visible') {
|
if (state === 'visible') {
|
||||||
@@ -106,6 +104,45 @@ app.cacheBuster = null;
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
app.updateHeader = function (data, callback) {
|
||||||
|
/**
|
||||||
|
* data:
|
||||||
|
* header (obj)
|
||||||
|
* config (obj)
|
||||||
|
* next (string)
|
||||||
|
*/
|
||||||
|
require(['benchpress', 'translator', 'notifications', 'chat'], function (Benchpress, translator, Notifications, Chat) {
|
||||||
|
app.user = data.header.user;
|
||||||
|
data.header.config = data.config;
|
||||||
|
config = data.config;
|
||||||
|
Benchpress.setGlobal('config', config);
|
||||||
|
|
||||||
|
// Manually reconnect socket.io
|
||||||
|
socket.close();
|
||||||
|
socket.open();
|
||||||
|
|
||||||
|
// Re-render top bar menu
|
||||||
|
var toRender = {
|
||||||
|
menu: $('#header-menu .container'),
|
||||||
|
'chats-menu': $('#chats-menu'),
|
||||||
|
'slideout-menu': $('.slideout-menu'),
|
||||||
|
};
|
||||||
|
Promise.all(Object.keys(toRender).map(function (tpl) {
|
||||||
|
return Benchpress.render('partials/' + tpl, data.header).then(function (render) {
|
||||||
|
return translator.Translator.create().translate(render);
|
||||||
|
});
|
||||||
|
})).then(function (html) {
|
||||||
|
Object.values(toRender).forEach(function (element, idx) {
|
||||||
|
element.html(html[idx]);
|
||||||
|
});
|
||||||
|
|
||||||
|
Notifications.prepareDOM();
|
||||||
|
Chat.prepareDOM();
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
app.logout = function (e) {
|
app.logout = function (e) {
|
||||||
if (e) {
|
if (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -124,13 +161,18 @@ app.cacheBuster = null;
|
|||||||
headers: {
|
headers: {
|
||||||
'x-csrf-token': config.csrf_token,
|
'x-csrf-token': config.csrf_token,
|
||||||
},
|
},
|
||||||
success: function () {
|
success: function (data) {
|
||||||
var payload = {
|
app.updateHeader(data, function () {
|
||||||
next: config.relative_path + '/',
|
// Overwrite in hook (below) to redirect elsewhere
|
||||||
};
|
data.next = data.next || undefined;
|
||||||
|
|
||||||
$(window).trigger('action:app.loggedOut', payload);
|
$(window).trigger('action:app.loggedOut', data);
|
||||||
window.location.href = payload.next;
|
if (data.next) {
|
||||||
|
ajaxify.go(data.next);
|
||||||
|
} else {
|
||||||
|
ajaxify.refresh();
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -35,14 +35,14 @@ define('forum/login', [], function () {
|
|||||||
headers: {
|
headers: {
|
||||||
'x-csrf-token': config.csrf_token,
|
'x-csrf-token': config.csrf_token,
|
||||||
},
|
},
|
||||||
success: function (returnTo) {
|
success: function (data) {
|
||||||
var pathname = utils.urlToLocation(returnTo).pathname;
|
var params = utils.params({ url: data.next });
|
||||||
|
|
||||||
var params = utils.params({ url: returnTo });
|
|
||||||
params.loggedin = true;
|
params.loggedin = true;
|
||||||
var qs = decodeURIComponent($.param(params));
|
|
||||||
|
|
||||||
window.location.href = pathname + '?' + qs;
|
app.updateHeader(data, function () {
|
||||||
|
ajaxify.go(data.next);
|
||||||
|
$(window).trigger('action:app.loggedIn', data);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
error: function (data) {
|
error: function (data) {
|
||||||
if (data.status === 403 && data.responseText === 'Forbidden') {
|
if (data.status === 403 && data.responseText === 'Forbidden') {
|
||||||
|
|||||||
@@ -24,7 +24,14 @@ app.isConnected = false;
|
|||||||
function addHandlers() {
|
function addHandlers() {
|
||||||
socket.on('connect', onConnect);
|
socket.on('connect', onConnect);
|
||||||
|
|
||||||
socket.on('reconnecting', onReconnecting);
|
socket.on('reconnecting', function () {
|
||||||
|
// Wait 2s before firing
|
||||||
|
setTimeout(function () {
|
||||||
|
if (socket.disconnected) {
|
||||||
|
onReconnecting();
|
||||||
|
}
|
||||||
|
}, 2000);
|
||||||
|
});
|
||||||
|
|
||||||
socket.on('disconnect', onDisconnect);
|
socket.on('disconnect', onDisconnect);
|
||||||
|
|
||||||
|
|||||||
@@ -14,10 +14,12 @@ var plugins = require('../plugins');
|
|||||||
var utils = require('../utils');
|
var utils = require('../utils');
|
||||||
var translator = require('../translator');
|
var translator = require('../translator');
|
||||||
var helpers = require('./helpers');
|
var helpers = require('./helpers');
|
||||||
|
var middleware = require('../middleware');
|
||||||
var privileges = require('../privileges');
|
var privileges = require('../privileges');
|
||||||
var sockets = require('../socket.io');
|
var sockets = require('../socket.io');
|
||||||
|
|
||||||
var authenticationController = module.exports;
|
var authenticationController = module.exports;
|
||||||
|
var apiController = require('./api');
|
||||||
|
|
||||||
authenticationController.register = function (req, res) {
|
authenticationController.register = function (req, res) {
|
||||||
var registrationType = meta.config.registrationType || 'normal';
|
var registrationType = meta.config.registrationType || 'normal';
|
||||||
@@ -277,10 +279,16 @@ function continueLogin(req, res, next) {
|
|||||||
return helpers.noScriptErrors(req, res, err.message, 403);
|
return helpers.noScriptErrors(req, res, err.message, 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(200).send(nconf.get('relative_path') + '/reset/' + code);
|
res.status(200).send({
|
||||||
|
next: nconf.get('relative_path') + '/reset/' + code,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
authenticationController.doLogin(req, userData.uid, function (err) {
|
async.parallel({
|
||||||
|
doLogin: async.apply(authenticationController.doLogin, req, userData.uid),
|
||||||
|
header: async.apply(middleware.generateHeader, req, res, {}),
|
||||||
|
config: async.apply(apiController.loadConfig, req),
|
||||||
|
}, function (err, payload) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return helpers.noScriptErrors(req, res, err.message, 403);
|
return helpers.noScriptErrors(req, res, err.message, 403);
|
||||||
}
|
}
|
||||||
@@ -296,7 +304,11 @@ function continueLogin(req, res, next) {
|
|||||||
if (req.body.noscript === 'true') {
|
if (req.body.noscript === 'true') {
|
||||||
res.redirect(destination + '?loggedin');
|
res.redirect(destination + '?loggedin');
|
||||||
} else {
|
} else {
|
||||||
res.status(200).send(destination);
|
res.status(200).send({
|
||||||
|
next: destination,
|
||||||
|
header: payload.header,
|
||||||
|
config: payload.config,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -320,6 +332,9 @@ authenticationController.doLogin = function (req, uid, callback) {
|
|||||||
authenticationController.onSuccessfulLogin = function (req, uid, callback) {
|
authenticationController.onSuccessfulLogin = function (req, uid, callback) {
|
||||||
var uuid = utils.generateUUID();
|
var uuid = utils.generateUUID();
|
||||||
|
|
||||||
|
req.uid = uid;
|
||||||
|
req.loggedIn = true;
|
||||||
|
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function (next) {
|
function (next) {
|
||||||
meta.blacklist.test(req.ip, next);
|
meta.blacklist.test(req.ip, next);
|
||||||
@@ -451,7 +466,8 @@ authenticationController.logout = function (req, res, next) {
|
|||||||
},
|
},
|
||||||
function (next) {
|
function (next) {
|
||||||
req.logout();
|
req.logout();
|
||||||
req.session.destroy(function (err) {
|
req.session.regenerate(function (err) {
|
||||||
|
req.uid = 0;
|
||||||
next(err);
|
next(err);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -467,7 +483,19 @@ authenticationController.logout = function (req, res, next) {
|
|||||||
if (req.body.noscript === 'true') {
|
if (req.body.noscript === 'true') {
|
||||||
res.redirect(nconf.get('relative_path') + '/');
|
res.redirect(nconf.get('relative_path') + '/');
|
||||||
} else {
|
} else {
|
||||||
res.status(200).send('');
|
async.parallel({
|
||||||
|
header: async.apply(middleware.generateHeader, req, res, {}),
|
||||||
|
config: async.apply(apiController.loadConfig, req),
|
||||||
|
}, function (err, payload) {
|
||||||
|
if (err) {
|
||||||
|
return res.status(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).send({
|
||||||
|
header: payload.header,
|
||||||
|
config: payload.config,
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
], next);
|
], next);
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ module.exports = function (middleware) {
|
|||||||
], next);
|
], next);
|
||||||
};
|
};
|
||||||
|
|
||||||
middleware.renderHeader = function (req, res, data, callback) {
|
middleware.generateHeader = function (req, res, data, callback) {
|
||||||
var registrationType = meta.config.registrationType || 'normal';
|
var registrationType = meta.config.registrationType || 'normal';
|
||||||
res.locals.config = res.locals.config || {};
|
res.locals.config = res.locals.config || {};
|
||||||
var templateValues = {
|
var templateValues = {
|
||||||
@@ -209,8 +209,16 @@ module.exports = function (middleware) {
|
|||||||
templateValues: templateValues,
|
templateValues: templateValues,
|
||||||
}, next);
|
}, next);
|
||||||
},
|
},
|
||||||
function (data, next) {
|
], function (err, data) {
|
||||||
req.app.render('header', data.templateValues, next);
|
callback(err, data.templateValues);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
middleware.renderHeader = function (req, res, data, callback) {
|
||||||
|
async.waterfall([
|
||||||
|
async.apply(middleware.generateHeader, req, res, data),
|
||||||
|
function (templateValues, next) {
|
||||||
|
req.app.render('header', templateValues, next);
|
||||||
},
|
},
|
||||||
], callback);
|
], callback);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user