diff --git a/client/css/style.css b/client/css/style.css
index 1d0b65d..fffab5a 100644
--- a/client/css/style.css
+++ b/client/css/style.css
@@ -595,6 +595,15 @@ button {
#sign-in .title {
margin-bottom: 10px;
}
+#sign-in .remember {
+ float: left;
+ font-size: 14px;
+ margin-top: 12px;
+}
+#sign-in .remember input {
+ float: left;
+ margin: 3px 10px 0 0;
+}
#sign-in .btn {
margin-top: 25px;
}
diff --git a/client/index.html b/client/index.html
index 56b4a3e..dcfcf6e 100644
--- a/client/index.html
+++ b/client/index.html
@@ -58,6 +58,12 @@
+
+
+
Authentication failed.
diff --git a/client/js/shout.js b/client/js/shout.js
index 84d61f8..91bae5b 100644
--- a/client/js/shout.js
+++ b/client/js/shout.js
@@ -72,6 +72,11 @@ $(function() {
refresh();
return;
}
+ var token = $.cookie("token");
+ if (token) {
+ $.removeCookie("token");
+ socket.emit("auth", {token: token});
+ }
if (body.hasClass("signed-out")) {
var error = login.find(".error");
error.show().closest("form").one("submit", function() {
@@ -83,13 +88,18 @@ $(function() {
if (input.val() === "") {
input.val($.cookie("user") || "");
}
- sidebar.find(".sign-in")
- .click()
- .end()
- .find(".networks")
- .html("")
- .next()
- .show();
+ setTimeout(function() {
+ if (!body.hasClass("signed-out")) {
+ return;
+ }
+ sidebar.find(".sign-in")
+ .click()
+ .end()
+ .find(".networks")
+ .html("")
+ .next()
+ .show();
+ }, token ? 200 : 0);
});
socket.on("init", function(data) {
@@ -113,6 +123,10 @@ $(function() {
confirmExit();
}
+ if (data.token) {
+ $.cookie("token", data.token);
+ }
+
$("body").removeClass("signed-out");
$("#sign-in").detach();
@@ -230,7 +244,7 @@ $(function() {
});
socket.on("users", function(data) {
- chat.find("#chan-" + data.chan)
+ var users = chat.find("#chan-" + data.chan)
.find(".users")
.html(render("user", data));
});
@@ -276,7 +290,7 @@ $(function() {
$("#badge").on("change", function() {
var self = $(this);
if (self.prop("checked")) {
- if (Notification.permission !== "granted") {
+ if (Notification.permission != "granted") {
Notification.requestPermission();
}
}
@@ -353,6 +367,7 @@ $(function() {
});
sidebar.on("click", "#sign-out", function() {
+ $.removeCookie("token");
location.reload();
});
@@ -416,9 +431,12 @@ $(function() {
var highlight = type.contains("highlight");
if (highlight || isQuery) {
if (!document.hasFocus() || !$(target).hasClass("active")) {
- pop.play();
+ var settings = $.cookie("settings") || {};
+ if (settings.notification) {
+ pop.play();
+ }
favico.badge("!");
- if (Notification.permission === "granted") {
+ if (settings.badge && Notification.permission == "granted") {
var n = new Notification(msg.from + " says:", {
body: msg.text.trim(),
icon: "/img/logo-64.png"
diff --git a/package.json b/package.json
index 72a4871..7b3734f 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "shout",
"description": "A web IRC client",
- "version": "0.29.1",
+ "version": "0.30.0",
"author": "Mattias Erming",
"preferGlobal": true,
"bin": {
diff --git a/src/client.js b/src/client.js
index 5a63bd8..c8e998e 100644
--- a/src/client.js
+++ b/src/client.js
@@ -1,5 +1,6 @@
var _ = require("lodash");
var config = require("../config");
+var crypto = require("crypto");
var net = require("net");
var Msg = require("./models/msg");
var Network = require("./models/network");
@@ -52,8 +53,11 @@ function Client(sockets, config) {
networks: [],
sockets: sockets
});
+ var client = this;
+ crypto.randomBytes(48, function(err, buf) {
+ client.token = buf.toString("hex");
+ });
if (config) {
- var client = this;
var delay = 0;
(config.networks || []).forEach(function(n) {
setTimeout(function() {
diff --git a/src/server.js b/src/server.js
index 514bc0d..a382509 100644
--- a/src/server.js
+++ b/src/server.js
@@ -57,7 +57,7 @@ function index(req, res, next) {
});
}
-function init(socket, client) {
+function init(socket, client, token) {
if (!client) {
socket.emit("auth");
socket.on("auth", auth);
@@ -82,7 +82,8 @@ function init(socket, client) {
);
socket.join(client.id);
socket.emit("init", {
- networks: client.networks
+ networks: client.networks,
+ token: token || ""
});
}
}
@@ -100,15 +101,27 @@ function auth(data) {
} else {
var success = false;
_.each(manager.clients, function(client) {
- if (client.config.user == data.user) {
+ if (data.token) {
+ if (data.token == client.token) {
+ success = true;
+ }
+ } else if (client.config.user == data.user) {
if (bcrypt.compareSync(data.password || "", client.config.password)) {
- init(socket, client);
success = true;
}
}
+ if (success) {
+ var token;
+ if (data.remember || data.token) {
+ token = client.token;
+ }
+ init(socket, client, token);
+ }
});
if (!success) {
- socket.emit("auth");
+ if (!data.token) {
+ socket.emit("auth");
+ }
}
}
}