diff --git a/client/js/lounge.js b/client/js/lounge.js index 1f5a5251..ef4e20a1 100644 --- a/client/js/lounge.js +++ b/client/js/lounge.js @@ -588,9 +588,6 @@ $(function() { } setTimeout(updateDateMarkers, msUntilNextDay()); - // Only start opening socket.io connection after all events have been registered - socket.open(); - window.addEventListener("popstate", (e) => { const {state} = e; if (!state) { @@ -604,4 +601,7 @@ $(function() { }); } }); + + // Only start opening socket.io connection after all events have been registered + socket.open(); }); diff --git a/client/js/socket-events/auth.js b/client/js/socket-events/auth.js index 08ce2ebd..6cdf923f 100644 --- a/client/js/socket-events/auth.js +++ b/client/js/socket-events/auth.js @@ -3,8 +3,19 @@ const $ = require("jquery"); const socket = require("../socket"); const storage = require("../localStorage"); +const utils = require("../utils"); socket.on("auth", function(data) { + // If we reconnected and serverHash differents, that means the server restarted + // And we will reload the page to grab the latest version + if (utils.serverHash > -1 && data.serverHash > -1 && data.serverHash !== utils.serverHash) { + socket.disconnect(); + location.reload(true); + return; + } + + utils.serverHash = data.serverHash; + const login = $("#sign-in"); let token; const user = storage.get("user"); @@ -12,6 +23,13 @@ socket.on("auth", function(data) { login.find(".btn").prop("disabled", false); if (!data.success) { + if (login.length === 0) { + socket.disconnect(); + $("#connection-error").text("Authentication failed, reloading…"); + location.reload(); + return; + } + storage.remove("token"); const error = login.find(".error"); @@ -20,9 +38,15 @@ socket.on("auth", function(data) { }); } else if (user) { token = storage.get("token"); + if (token) { $("#loading-page-message").text("Authorizing…"); - socket.emit("auth", {user: user, token: token}); + + socket.emit("auth", { + user: user, + token: token, + lastMessage: utils.lastMessageId, + }); } } diff --git a/client/js/socket.js b/client/js/socket.js index b7ba0e70..a646ad47 100644 --- a/client/js/socket.js +++ b/client/js/socket.js @@ -8,9 +8,11 @@ const socket = io({ transports: $(document.body).data("transports"), path: path, autoConnect: false, - reconnection: false + reconnection: !$(document.body).hasClass("public") }); +window.lounge_socket = socket; // TODO: Remove later, this is for debugging + [ "connect_error", "connect_failed", @@ -34,7 +36,7 @@ const socket = io({ } }); // Hides the "Send Message" button - $("#submit").remove(); + $("#submit").hide(); }); }); @@ -43,11 +45,16 @@ socket.on("connecting", function() { }); socket.on("connect", function() { - $("#loading-page-message").text("Finalizing connection…"); + // Clear send buffer when reconnecting, socket.io would emit these + // immediately upon connection and it will have no effect, so we ensure + // nothing is sent to the server that might have happened. + socket.sendBuffer = []; + + status.text("Finalizing connection…"); }); socket.on("authorized", function() { - $("#loading-page-message").text("Authorized, loading messages…"); + $("#loading-page-message").text("Loading messages…"); }); module.exports = socket; diff --git a/client/js/utils.js b/client/js/utils.js index 086a796e..07b1d328 100644 --- a/client/js/utils.js +++ b/client/js/utils.js @@ -3,7 +3,12 @@ const $ = require("jquery"); const input = $("#input"); +var serverHash = -1; +var lastMessageId = -1; + module.exports = { + serverHash, + lastMessageId, confirmExit, forceFocus, move, diff --git a/src/server.js b/src/server.js index aebc6bfb..7069a905 100644 --- a/src/server.js +++ b/src/server.js @@ -23,6 +23,9 @@ const authPlugins = [ require("./plugins/auth/local"), ]; +// A random number that will force clients to reload the page if it differs +const serverHash = Math.floor(Date.now() * Math.random()); + var manager = null; module.exports = function() { @@ -135,7 +138,10 @@ module.exports = function() { if (config.public) { performAuthentication.call(socket, {}); } else { - socket.emit("auth", {success: true}); + socket.emit("auth", { + serverHash: serverHash, + success: true, + }); socket.on("auth", performAuthentication); } });