Added 'Remember' login option

This commit is contained in:
Mattias Erming 2014-09-15 14:13:03 -07:00
parent f95a74bb2a
commit 78d36d6750
6 changed files with 68 additions and 18 deletions

View File

@ -595,6 +595,15 @@ button {
#sign-in .title { #sign-in .title {
margin-bottom: 10px; 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 { #sign-in .btn {
margin-top: 25px; margin-top: 25px;
} }

View File

@ -58,6 +58,12 @@
<input class="input" type="password" name="password"> <input class="input" type="password" name="password">
</label> </label>
</div> </div>
<div class="col-xs-12">
<label class="remember">
<input type="checkbox" name="remember" checked="checked">
Stay signed in
</label>
</div>
<div class="col-xs-12 error" style="display: none;"> <div class="col-xs-12 error" style="display: none;">
Authentication failed. Authentication failed.
</div> </div>

View File

@ -72,6 +72,11 @@ $(function() {
refresh(); refresh();
return; return;
} }
var token = $.cookie("token");
if (token) {
$.removeCookie("token");
socket.emit("auth", {token: token});
}
if (body.hasClass("signed-out")) { if (body.hasClass("signed-out")) {
var error = login.find(".error"); var error = login.find(".error");
error.show().closest("form").one("submit", function() { error.show().closest("form").one("submit", function() {
@ -83,13 +88,18 @@ $(function() {
if (input.val() === "") { if (input.val() === "") {
input.val($.cookie("user") || ""); input.val($.cookie("user") || "");
} }
sidebar.find(".sign-in") setTimeout(function() {
.click() if (!body.hasClass("signed-out")) {
.end() return;
.find(".networks") }
.html("") sidebar.find(".sign-in")
.next() .click()
.show(); .end()
.find(".networks")
.html("")
.next()
.show();
}, token ? 200 : 0);
}); });
socket.on("init", function(data) { socket.on("init", function(data) {
@ -113,6 +123,10 @@ $(function() {
confirmExit(); confirmExit();
} }
if (data.token) {
$.cookie("token", data.token);
}
$("body").removeClass("signed-out"); $("body").removeClass("signed-out");
$("#sign-in").detach(); $("#sign-in").detach();
@ -230,7 +244,7 @@ $(function() {
}); });
socket.on("users", function(data) { socket.on("users", function(data) {
chat.find("#chan-" + data.chan) var users = chat.find("#chan-" + data.chan)
.find(".users") .find(".users")
.html(render("user", data)); .html(render("user", data));
}); });
@ -276,7 +290,7 @@ $(function() {
$("#badge").on("change", function() { $("#badge").on("change", function() {
var self = $(this); var self = $(this);
if (self.prop("checked")) { if (self.prop("checked")) {
if (Notification.permission !== "granted") { if (Notification.permission != "granted") {
Notification.requestPermission(); Notification.requestPermission();
} }
} }
@ -353,6 +367,7 @@ $(function() {
}); });
sidebar.on("click", "#sign-out", function() { sidebar.on("click", "#sign-out", function() {
$.removeCookie("token");
location.reload(); location.reload();
}); });
@ -416,9 +431,12 @@ $(function() {
var highlight = type.contains("highlight"); var highlight = type.contains("highlight");
if (highlight || isQuery) { if (highlight || isQuery) {
if (!document.hasFocus() || !$(target).hasClass("active")) { if (!document.hasFocus() || !$(target).hasClass("active")) {
pop.play(); var settings = $.cookie("settings") || {};
if (settings.notification) {
pop.play();
}
favico.badge("!"); favico.badge("!");
if (Notification.permission === "granted") { if (settings.badge && Notification.permission == "granted") {
var n = new Notification(msg.from + " says:", { var n = new Notification(msg.from + " says:", {
body: msg.text.trim(), body: msg.text.trim(),
icon: "/img/logo-64.png" icon: "/img/logo-64.png"

View File

@ -1,7 +1,7 @@
{ {
"name": "shout", "name": "shout",
"description": "A web IRC client", "description": "A web IRC client",
"version": "0.29.1", "version": "0.30.0",
"author": "Mattias Erming", "author": "Mattias Erming",
"preferGlobal": true, "preferGlobal": true,
"bin": { "bin": {

View File

@ -1,5 +1,6 @@
var _ = require("lodash"); var _ = require("lodash");
var config = require("../config"); var config = require("../config");
var crypto = require("crypto");
var net = require("net"); var net = require("net");
var Msg = require("./models/msg"); var Msg = require("./models/msg");
var Network = require("./models/network"); var Network = require("./models/network");
@ -52,8 +53,11 @@ function Client(sockets, config) {
networks: [], networks: [],
sockets: sockets sockets: sockets
}); });
var client = this;
crypto.randomBytes(48, function(err, buf) {
client.token = buf.toString("hex");
});
if (config) { if (config) {
var client = this;
var delay = 0; var delay = 0;
(config.networks || []).forEach(function(n) { (config.networks || []).forEach(function(n) {
setTimeout(function() { setTimeout(function() {

View File

@ -57,7 +57,7 @@ function index(req, res, next) {
}); });
} }
function init(socket, client) { function init(socket, client, token) {
if (!client) { if (!client) {
socket.emit("auth"); socket.emit("auth");
socket.on("auth", auth); socket.on("auth", auth);
@ -82,7 +82,8 @@ function init(socket, client) {
); );
socket.join(client.id); socket.join(client.id);
socket.emit("init", { socket.emit("init", {
networks: client.networks networks: client.networks,
token: token || ""
}); });
} }
} }
@ -100,15 +101,27 @@ function auth(data) {
} else { } else {
var success = false; var success = false;
_.each(manager.clients, function(client) { _.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)) { if (bcrypt.compareSync(data.password || "", client.config.password)) {
init(socket, client);
success = true; success = true;
} }
} }
if (success) {
var token;
if (data.remember || data.token) {
token = client.token;
}
init(socket, client, token);
}
}); });
if (!success) { if (!success) {
socket.emit("auth"); if (!data.token) {
socket.emit("auth");
}
} }
} }
} }