From d7e6db92b594a179fd2184e859d69011b0871dc6 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Tue, 15 Aug 2017 12:44:29 +0300 Subject: [PATCH 1/3] Implement session list --- client/css/style.css | 9 +++++ client/index.html | 19 +++++++--- client/js/lounge.js | 8 ++++- client/js/socket-events/index.js | 1 + client/js/socket-events/sessions_list.js | 31 +++++++++++++++++ client/views/index.js | 1 + client/views/session.tpl | 17 +++++++++ src/server.js | 44 ++++++++++++++++++++++-- 8 files changed, 122 insertions(+), 8 deletions(-) create mode 100644 client/js/socket-events/sessions_list.js create mode 100644 client/views/session.tpl diff --git a/client/css/style.css b/client/css/style.css index aaed0a37..807aae85 100644 --- a/client/css/style.css +++ b/client/css/style.css @@ -252,6 +252,14 @@ kbd { color: #7f8c8d; } +.session-list strong { + display: block; +} + +.session-list p { + margin-bottom: 10px; +} + #chat .invite .from::before { content: "\f003"; /* http://fontawesome.io/icon/envelope-o/ */ color: #2ecc40; @@ -668,6 +676,7 @@ kbd { width: 100%; } +#windows p, #windows label, #settings .error { font-size: 14px; diff --git a/client/index.html b/client/index.html index 5b170e63..26f4c4f4 100644 --- a/client/index.html +++ b/client/index.html @@ -198,15 +198,14 @@ -
+
+

Settings

+
-
-

Settings

-

Messages

@@ -380,6 +379,18 @@
+ + {{#unless public}} +
+

Sessions

+ +

Current session

+
+ +

Other sessions

+
+
+ {{/unless}}
diff --git a/client/js/lounge.js b/client/js/lounge.js index 009871bb..9daad56b 100644 --- a/client/js/lounge.js +++ b/client/js/lounge.js @@ -383,8 +383,9 @@ $(function() { } document.title = title; + const type = chan.data("type"); var placeholder = ""; - if (chan.data("type") === "channel" || chan.data("type") === "query") { + if (type === "channel" || type === "query") { placeholder = `Write to ${chan.data("title")}`; } input.attr("placeholder", placeholder); @@ -404,6 +405,11 @@ $(function() { socket.emit("names", {target: self.data("id")}); } + if (type === "settings") { + $("#session-list").html("

Loading…

"); + socket.emit("sessions:get"); + } + focus(); }); diff --git a/client/js/socket-events/index.js b/client/js/socket-events/index.js index 23a5e961..b0064665 100644 --- a/client/js/socket-events/index.js +++ b/client/js/socket-events/index.js @@ -17,3 +17,4 @@ require("./sync_sort"); require("./topic"); require("./users"); require("./sign_out"); +require("./sessions_list"); diff --git a/client/js/socket-events/sessions_list.js b/client/js/socket-events/sessions_list.js new file mode 100644 index 00000000..9d77df46 --- /dev/null +++ b/client/js/socket-events/sessions_list.js @@ -0,0 +1,31 @@ +"use strict"; + +const $ = require("jquery"); +const socket = require("../socket"); +const templates = require("../../views"); + +socket.on("sessions:list", function(data) { + data.sort((a, b) => b.lastUse - a.lastUse); + + let html = ""; + data.forEach((connection) => { + if (connection.current) { + $("#session-current").html(templates.session(connection)); + return; + } + + html += templates.session(connection); + }); + + if (html.length === 0) { + html = "

You are not currently logged in to any other device.

"; + } + + $("#session-list").html(html); +}); + +$("#settings").on("click", ".remove-session", function() { + socket.emit("sign-out", $(this).data("token")); + + return false; +}); diff --git a/client/views/index.js b/client/views/index.js index 50f6a93f..118fa60c 100644 --- a/client/views/index.js +++ b/client/views/index.js @@ -34,6 +34,7 @@ module.exports = { msg_unhandled: require("./msg_unhandled.tpl"), network: require("./network.tpl"), image_viewer: require("./image_viewer.tpl"), + session: require("./session.tpl"), unread_marker: require("./unread_marker.tpl"), user: require("./user.tpl"), user_filtered: require("./user_filtered.tpl"), diff --git a/client/views/session.tpl b/client/views/session.tpl new file mode 100644 index 00000000..d3d5cbd8 --- /dev/null +++ b/client/views/session.tpl @@ -0,0 +1,17 @@ +

+{{#if current}} + {{agent}} + {{ip}} +{{else}} + + + {{agent}} + {{ip}} +
+ {{#if active}} + Currently active + {{else}} + Last used on + {{/if}} +{{/if}} +

diff --git a/src/server.js b/src/server.js index e43cc70b..a5f58d3a 100644 --- a/src/server.js +++ b/src/server.js @@ -378,8 +378,32 @@ function initializeClient(socket, client, token, lastMessage) { client.unregisterPushSubscription(token); }); - socket.on("sign-out", () => { - delete client.config.sessions[token]; + const sendSessionList = () => { + const sessions = _.map(client.config.sessions, (session, sessionToken) => ({ + current: sessionToken === token, + active: _.find(client.attachedClients, (u) => u.token === sessionToken) !== undefined, + lastUse: session.lastUse, + ip: session.ip, + agent: session.agent, + token: sessionToken, // TODO: Ideally don't expose actual tokens to the client + })); + + socket.emit("sessions:list", sessions); + }; + + socket.on("sessions:get", sendSessionList); + + socket.on("sign-out", (tokenToSignOut) => { + // If no token provided, sign same client out + if (!tokenToSignOut) { + tokenToSignOut = token; + } + + if (!(tokenToSignOut in client.config.sessions)) { + return; + } + + delete client.config.sessions[tokenToSignOut]; client.manager.updateUser(client.name, { sessions: client.config.sessions @@ -389,7 +413,21 @@ function initializeClient(socket, client, token, lastMessage) { } }); - socket.emit("sign-out"); + _.map(client.attachedClients, (attachedClient, socketId) => { + if (attachedClient.token !== tokenToSignOut) { + return; + } + + const socketToRemove = manager.sockets.of("/").connected[socketId]; + + socketToRemove.emit("sign-out"); + socketToRemove.disconnect(); + }); + + // Do not send updated session list if user simply logs out + if (tokenToSignOut !== token) { + sendSessionList(); + } }); socket.join(client.id); From 833bdfa2aac6ac7519ce1a7e597ee9c8eaf31811 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Sun, 17 Sep 2017 11:09:19 +0300 Subject: [PATCH 2/3] Fix session data not updating correctly --- src/client.js | 9 ++++++--- src/clientManager.js | 2 +- src/server.js | 12 ------------ 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/client.js b/src/client.js index d4cd3ccc..a70b9472 100644 --- a/src/client.js +++ b/src/client.js @@ -304,11 +304,15 @@ Client.prototype.updateSession = function(token, ip, request) { friendlyAgent += ` on ${agent.os.name} ${agent.os.version}`; } - client.config.sessions[token] = _.assign({ + client.config.sessions[token] = _.assign(client.config.sessions[token], { lastUse: Date.now(), ip: ip, agent: friendlyAgent, - }, client.config.sessions[token]); + }); + + client.manager.updateUser(client.name, { + sessions: client.config.sessions + }); }; Client.prototype.setPassword = function(hash, callback) { @@ -318,7 +322,6 @@ Client.prototype.setPassword = function(hash, callback) { password: hash }, function(err) { if (err) { - log.error("Failed to update password of", client.name, err); return callback(false); } diff --git a/src/clientManager.js b/src/clientManager.js index f8425182..da7f663d 100644 --- a/src/clientManager.js +++ b/src/clientManager.js @@ -153,7 +153,7 @@ ClientManager.prototype.updateUser = function(name, opts, callback) { fs.writeFile(Helper.getUserConfigPath(name), newUser, (err) => { if (err) { - log.error("Failed to update user", err); + log.error(`Failed to update user ${colors.green(name)} (${err})`); } if (callback) { diff --git a/src/server.js b/src/server.js index a5f58d3a..76e6ac2b 100644 --- a/src/server.js +++ b/src/server.js @@ -407,10 +407,6 @@ function initializeClient(socket, client, token, lastMessage) { client.manager.updateUser(client.name, { sessions: client.config.sessions - }, (err) => { - if (err) { - log.error("Failed to update sessions for", client.name, err); - } }); _.map(client.attachedClients, (attachedClient, socketId) => { @@ -461,14 +457,6 @@ function initializeClient(socket, client, token, lastMessage) { client.updateSession(token, getClientIp(socket.request), socket.request); - client.manager.updateUser(client.name, { - sessions: client.config.sessions - }, (err) => { - if (err) { - log.error("Failed to update sessions for", client.name, err); - } - }); - sendInitEvent(token); }); } else { From 2f15ab3999dedd3e0c0a35fd7aa57a08efab197a Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Sun, 17 Sep 2017 11:33:16 +0300 Subject: [PATCH 3/3] Fix attached client not having token on login --- src/server.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/server.js b/src/server.js index 76e6ac2b..de8c90e5 100644 --- a/src/server.js +++ b/src/server.js @@ -237,7 +237,6 @@ function initializeClient(socket, client, token, lastMessage) { socket.on("disconnect", function() { client.clientDetach(socket.id); }); - client.clientAttach(socket.id, token); socket.on( "input", @@ -429,6 +428,8 @@ function initializeClient(socket, client, token, lastMessage) { socket.join(client.id); const sendInitEvent = (tokenToSend) => { + client.clientAttach(socket.id, token); + let networks = client.networks; if (lastMessage > -1) {