mirror of https://github.com/calzoneman/sync.git
Change login sessions
This commit is contained in:
parent
10aa7519da
commit
b579db5310
|
@ -64,6 +64,8 @@ http:
|
||||||
gzip: true
|
gzip: true
|
||||||
# Customize the threshold byte size for applying gzip
|
# Customize the threshold byte size for applying gzip
|
||||||
gzip-threshold: 1024
|
gzip-threshold: 1024
|
||||||
|
# Secret used for signed cookies. Can be anything, but make it unique and hard to guess
|
||||||
|
cookie-secret: 'change-me'
|
||||||
|
|
||||||
# HTTPS server details
|
# HTTPS server details
|
||||||
https:
|
https:
|
||||||
|
|
|
@ -33,7 +33,8 @@ var defaults = {
|
||||||
minify: false,
|
minify: false,
|
||||||
"max-age": "7d",
|
"max-age": "7d",
|
||||||
gzip: true,
|
gzip: true,
|
||||||
"gzip-threshold": 1024
|
"gzip-threshold": 1024,
|
||||||
|
"cookie-secret": "change-me"
|
||||||
},
|
},
|
||||||
https: {
|
https: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
//var db = require("../database");
|
|
||||||
var $util = require("../utilities");
|
var $util = require("../utilities");
|
||||||
var bcrypt = require("bcrypt");
|
var bcrypt = require("bcrypt");
|
||||||
var db = require("../database");
|
var db = require("../database");
|
||||||
|
@ -59,6 +58,25 @@ module.exports = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getUser: function (name, callback) {
|
||||||
|
if (typeof callback !== "function") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
db.query("SELECT * FROM `users` WHERE name = ?", [name], function (err, rows) {
|
||||||
|
if (err) {
|
||||||
|
callback(err, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rows.length !== 1) {
|
||||||
|
return callback("User does not exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(null, rows[0]);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a new user account
|
* Registers a new user account
|
||||||
*/
|
*/
|
||||||
|
@ -198,11 +216,7 @@ module.exports = {
|
||||||
} else if (!match) {
|
} else if (!match) {
|
||||||
callback("Invalid username/password combination", null);
|
callback("Invalid username/password combination", null);
|
||||||
} else {
|
} else {
|
||||||
callback(null, {
|
callback(null, rows[0]);
|
||||||
name: rows[0].name,
|
|
||||||
hash: rows[0].password,
|
|
||||||
global_rank: rows[0].global_rank
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,7 +6,8 @@ const TBL_USERS = "" +
|
||||||
"`global_rank` INT NOT NULL," +
|
"`global_rank` INT NOT NULL," +
|
||||||
"`email` VARCHAR(255) NOT NULL," +
|
"`email` VARCHAR(255) NOT NULL," +
|
||||||
"`profile` TEXT CHARACTER SET utf8mb4 NOT NULL," +
|
"`profile` TEXT CHARACTER SET utf8mb4 NOT NULL," +
|
||||||
"`ip` VARCHAR(39) NOT NULL," + "`time` BIGINT NOT NULL," +
|
"`ip` VARCHAR(39) NOT NULL," +
|
||||||
|
"`time` BIGINT NOT NULL," +
|
||||||
"PRIMARY KEY(`id`)," +
|
"PRIMARY KEY(`id`)," +
|
||||||
"UNIQUE(`name`)) " +
|
"UNIQUE(`name`)) " +
|
||||||
"CHARACTER SET utf8";
|
"CHARACTER SET utf8";
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
var dbAccounts = require("./database/accounts");
|
||||||
|
var util = require("./utilities");
|
||||||
|
var crypto = require("crypto");
|
||||||
|
|
||||||
|
function sha256(input) {
|
||||||
|
var hash = crypto.createHash("sha256");
|
||||||
|
hash.update(input);
|
||||||
|
return hash.digest("base64");
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.genSession = function (account, expiration, cb) {
|
||||||
|
if (expiration instanceof Date) {
|
||||||
|
expiration = Date.parse(expiration);
|
||||||
|
}
|
||||||
|
|
||||||
|
var salt = crypto.pseudoRandomBytes(24).toString("base64");
|
||||||
|
var hashInput = [account.name, account.password, expiration, salt].join(":");
|
||||||
|
var hash = sha256(hashInput);
|
||||||
|
|
||||||
|
cb(null, [account.name, expiration, salt, hash].join(":"));
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.verifySession = function (input, cb) {
|
||||||
|
var parts = input.split(":");
|
||||||
|
if (parts.length !== 4) {
|
||||||
|
return cb("Invalid auth string");
|
||||||
|
}
|
||||||
|
|
||||||
|
var name = parts[0];
|
||||||
|
var expiration = parts[1];
|
||||||
|
var salt = parts[2];
|
||||||
|
var hash = parts[3];
|
||||||
|
|
||||||
|
if (Date.now() > parseInt(expiration)) {
|
||||||
|
return cb("Session expired");
|
||||||
|
}
|
||||||
|
|
||||||
|
dbAccounts.getUser(name, function (err, account) {
|
||||||
|
if (err) {
|
||||||
|
return cb(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
var hashInput = [account.name, account.password, expiration, salt].join(":");
|
||||||
|
if (sha256(hashInput) !== hash) {
|
||||||
|
return cb("Invalid auth string");
|
||||||
|
}
|
||||||
|
|
||||||
|
cb(null, account);
|
||||||
|
});
|
||||||
|
};
|
|
@ -11,6 +11,7 @@ var db = require("../database");
|
||||||
var $util = require("../utilities");
|
var $util = require("../utilities");
|
||||||
var Config = require("../config");
|
var Config = require("../config");
|
||||||
var Server = require("../server");
|
var Server = require("../server");
|
||||||
|
var session = require("../session");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a GET request for /account/edit
|
* Handles a GET request for /account/edit
|
||||||
|
@ -20,23 +21,7 @@ function handleAccountEditPage(req, res) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var loginName = false;
|
sendJade(res, "account-edit", {});
|
||||||
if (req.cookies.auth) {
|
|
||||||
loginName = req.cookies.auth.split(":")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
db.users.verifyAuth(req.cookies.auth, function (err, user) {
|
|
||||||
if (err) {
|
|
||||||
return sendJade(res, "account-edit", {
|
|
||||||
loggedIn: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
sendJade(res, "account-edit", {
|
|
||||||
loggedIn: loginName !== false,
|
|
||||||
loginName: loginName
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,10 +49,6 @@ function handleChangePassword(req, res) {
|
||||||
var name = req.body.name;
|
var name = req.body.name;
|
||||||
var oldpassword = req.body.oldpassword;
|
var oldpassword = req.body.oldpassword;
|
||||||
var newpassword = req.body.newpassword;
|
var newpassword = req.body.newpassword;
|
||||||
var loginName = false;
|
|
||||||
if (req.cookies.auth) {
|
|
||||||
loginName = req.cookies.auth.split(":")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof name !== "string" ||
|
if (typeof name !== "string" ||
|
||||||
typeof oldpassword !== "string" ||
|
typeof oldpassword !== "string" ||
|
||||||
|
@ -78,20 +59,23 @@ function handleChangePassword(req, res) {
|
||||||
|
|
||||||
if (newpassword.length === 0) {
|
if (newpassword.length === 0) {
|
||||||
sendJade(res, "account-edit", {
|
sendJade(res, "account-edit", {
|
||||||
loggedIn: loginName !== false,
|
|
||||||
loginName: loginName,
|
|
||||||
errorMessage: "New password must not be empty"
|
errorMessage: "New password must not be empty"
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!req.user) {
|
||||||
|
sendJade(res, "account-edit", {
|
||||||
|
errorMessage: "You must be logged in to change your password"
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
newpassword = newpassword.substring(0, 100);
|
newpassword = newpassword.substring(0, 100);
|
||||||
|
|
||||||
db.users.verifyLogin(name, oldpassword, function (err, user) {
|
db.users.verifyLogin(name, oldpassword, function (err, user) {
|
||||||
if (err) {
|
if (err) {
|
||||||
sendJade(res, "account-edit", {
|
sendJade(res, "account-edit", {
|
||||||
loggedIn: loginName !== false,
|
|
||||||
loginName: loginName,
|
|
||||||
errorMessage: err
|
errorMessage: err
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
@ -100,18 +84,49 @@ function handleChangePassword(req, res) {
|
||||||
db.users.setPassword(name, newpassword, function (err, dbres) {
|
db.users.setPassword(name, newpassword, function (err, dbres) {
|
||||||
if (err) {
|
if (err) {
|
||||||
sendJade(res, "account-edit", {
|
sendJade(res, "account-edit", {
|
||||||
loggedIn: loginName !== false,
|
|
||||||
loginName: loginName,
|
|
||||||
errorMessage: err
|
errorMessage: err
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.eventlog.log("[account] " + webserver.ipForRequest(req) +
|
Logger.eventlog.log("[account] " + webserver.ipForRequest(req) +
|
||||||
" changed password for " + name);
|
" changed password for " + name);
|
||||||
sendJade(res, "account-edit", {
|
|
||||||
loggedIn: loginName !== false,
|
db.users.getUser(name, function (err, user) {
|
||||||
loginName: loginName,
|
if (err) {
|
||||||
successMessage: "Password changed."
|
return sendJade(res, "account-edit", {
|
||||||
|
errorMessage: err
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
res.user = user;
|
||||||
|
var expiration = new Date(parseInt(req.signedCookies.auth.split(":")[1]));
|
||||||
|
session.genSession(user, expiration, function (err, auth) {
|
||||||
|
if (err) {
|
||||||
|
return sendJade(res, "account-edit", {
|
||||||
|
errorMessage: err
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.hostname.indexOf(Config.get("http.root-domain")) >= 0) {
|
||||||
|
res.cookie("auth", auth, {
|
||||||
|
domain: Config.get("http.root-domain-dotted"),
|
||||||
|
expires: expiration,
|
||||||
|
httpOnly: true,
|
||||||
|
signed: true
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
res.cookie("auth", auth, {
|
||||||
|
expires: expiration,
|
||||||
|
httpOnly: true,
|
||||||
|
signed: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
sendJade(res, "account-edit", {
|
||||||
|
successMessage: "Password changed."
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -124,10 +139,6 @@ function handleChangeEmail(req, res) {
|
||||||
var name = req.body.name;
|
var name = req.body.name;
|
||||||
var password = req.body.password;
|
var password = req.body.password;
|
||||||
var email = req.body.email;
|
var email = req.body.email;
|
||||||
var loginName = false;
|
|
||||||
if (req.cookies.auth) {
|
|
||||||
loginName = req.cookies.auth.split(":")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof name !== "string" ||
|
if (typeof name !== "string" ||
|
||||||
typeof password !== "string" ||
|
typeof password !== "string" ||
|
||||||
|
@ -138,8 +149,6 @@ function handleChangeEmail(req, res) {
|
||||||
|
|
||||||
if (!$util.isValidEmail(email) && email !== "") {
|
if (!$util.isValidEmail(email) && email !== "") {
|
||||||
sendJade(res, "account-edit", {
|
sendJade(res, "account-edit", {
|
||||||
loggedIn: loginName !== false,
|
|
||||||
loginName: loginName,
|
|
||||||
errorMessage: "Invalid email address"
|
errorMessage: "Invalid email address"
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
@ -148,8 +157,6 @@ function handleChangeEmail(req, res) {
|
||||||
db.users.verifyLogin(name, password, function (err, user) {
|
db.users.verifyLogin(name, password, function (err, user) {
|
||||||
if (err) {
|
if (err) {
|
||||||
sendJade(res, "account-edit", {
|
sendJade(res, "account-edit", {
|
||||||
loggedIn: loginName !== false,
|
|
||||||
loginName: loginName,
|
|
||||||
errorMessage: err
|
errorMessage: err
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
@ -158,8 +165,6 @@ function handleChangeEmail(req, res) {
|
||||||
db.users.setEmail(name, email, function (err, dbres) {
|
db.users.setEmail(name, email, function (err, dbres) {
|
||||||
if (err) {
|
if (err) {
|
||||||
sendJade(res, "account-edit", {
|
sendJade(res, "account-edit", {
|
||||||
loggedIn: loginName !== false,
|
|
||||||
loginName: loginName,
|
|
||||||
errorMessage: err
|
errorMessage: err
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
@ -168,8 +173,6 @@ function handleChangeEmail(req, res) {
|
||||||
" changed email for " + name +
|
" changed email for " + name +
|
||||||
" to " + email);
|
" to " + email);
|
||||||
sendJade(res, "account-edit", {
|
sendJade(res, "account-edit", {
|
||||||
loggedIn: loginName !== false,
|
|
||||||
loginName: loginName,
|
|
||||||
successMessage: "Email address changed."
|
successMessage: "Email address changed."
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -184,33 +187,17 @@ function handleAccountChannelPage(req, res) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var loginName = false;
|
if (!req.user) {
|
||||||
if (req.cookies.auth) {
|
return sendJade(res, "account-channels", {
|
||||||
loginName = req.cookies.auth.split(":")[0];
|
channels: []
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loginName) {
|
db.channels.listUserChannels(req.user.name, function (err, channels) {
|
||||||
db.users.verifyAuth(req.cookies.auth, function (err, user) {
|
|
||||||
if (err) {
|
|
||||||
return sendJade(res, "account-channels", {
|
|
||||||
loggedIn: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
db.channels.listUserChannels(loginName, function (err, channels) {
|
|
||||||
sendJade(res, "account-channels", {
|
|
||||||
loggedIn: true,
|
|
||||||
loginName: loginName,
|
|
||||||
channels: channels
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
sendJade(res, "account-channels", {
|
sendJade(res, "account-channels", {
|
||||||
loggedIn: false,
|
channels: channels
|
||||||
channels: [],
|
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -242,87 +229,64 @@ function handleNewChannel(req, res) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var loginName = false;
|
if (!req.user) {
|
||||||
if (req.cookies.auth) {
|
return sendJade(res, "account-channels", {
|
||||||
loginName = req.cookies.auth.split(":")[0];
|
|
||||||
} else {
|
|
||||||
sendJade(res, "account-channels", {
|
|
||||||
loggedIn: false,
|
|
||||||
channels: []
|
channels: []
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
db.users.verifyAuth(req.cookies.auth, function (err, user) {
|
|
||||||
|
db.channels.listUserChannels(req.user.name, function (err, channels) {
|
||||||
if (err) {
|
if (err) {
|
||||||
sendJade(res, "account-channels", {
|
sendJade(res, "account-channels", {
|
||||||
loggedIn: false,
|
|
||||||
channels: [],
|
channels: [],
|
||||||
newChannelError: err
|
newChannelError: err
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
db.channels.listUserChannels(loginName, function (err, channels) {
|
if (name.match(Config.get("reserved-names.channels"))) {
|
||||||
if (err) {
|
sendJade(res, "account-channels", {
|
||||||
sendJade(res, "account-channels", {
|
channels: channels,
|
||||||
loggedIn: true,
|
newChannelError: "That channel name is reserved"
|
||||||
loginName: loginName,
|
});
|
||||||
channels: [],
|
return;
|
||||||
newChannelError: err
|
}
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name.match(Config.get("reserved-names.channels"))) {
|
if (channels.length >= Config.get("max-channels-per-user")) {
|
||||||
sendJade(res, "account-channels", {
|
sendJade(res, "account-channels", {
|
||||||
loggedIn: true,
|
channels: channels,
|
||||||
loginName: loginName,
|
newChannelError: "You are not allowed to register more than " +
|
||||||
channels: channels,
|
Config.get("max-channels-per-user") + " channels."
|
||||||
newChannelError: "That channel name is reserved"
|
});
|
||||||
});
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (channels.length >= Config.get("max-channels-per-user")) {
|
db.channels.register(name, req.user.name, function (err, channel) {
|
||||||
sendJade(res, "account-channels", {
|
if (!err) {
|
||||||
loggedIn: true,
|
Logger.eventlog.log("[channel] " + req.user.name + "@" +
|
||||||
loginName: loginName,
|
webserver.ipForRequest(req) +
|
||||||
channels: channels,
|
" registered channel " + name);
|
||||||
newChannelError: "You are not allowed to register more than " +
|
var sv = Server.getServer();
|
||||||
Config.get("max-channels-per-user") + " channels."
|
if (sv.isChannelLoaded(name)) {
|
||||||
});
|
var chan = sv.getChannel(name);
|
||||||
return;
|
var users = Array.prototype.slice.call(chan.users);
|
||||||
}
|
users.forEach(function (u) {
|
||||||
|
u.kick("Channel reloading");
|
||||||
db.channels.register(name, user.name, function (err, channel) {
|
|
||||||
if (!err) {
|
|
||||||
Logger.eventlog.log("[channel] " + user.name + "@" +
|
|
||||||
webserver.ipForRequest(req) +
|
|
||||||
" registered channel " + name);
|
|
||||||
var sv = Server.getServer();
|
|
||||||
if (sv.isChannelLoaded(name)) {
|
|
||||||
var chan = sv.getChannel(name);
|
|
||||||
var users = Array.prototype.slice.call(chan.users);
|
|
||||||
users.forEach(function (u) {
|
|
||||||
u.kick("Channel reloading");
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!chan.dead) {
|
|
||||||
chan.emit("empty");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
channels.push({
|
|
||||||
name: name
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!chan.dead) {
|
||||||
|
chan.emit("empty");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
channels.push({
|
||||||
|
name: name
|
||||||
sendJade(res, "account-channels", {
|
|
||||||
loggedIn: true,
|
|
||||||
loginName: loginName,
|
|
||||||
channels: channels,
|
|
||||||
newChannelError: err ? err : undefined
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sendJade(res, "account-channels", {
|
||||||
|
channels: channels,
|
||||||
|
newChannelError: err ? err : undefined
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -338,75 +302,55 @@ function handleDeleteChannel(req, res) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var loginName = false;
|
if (!req.user) {
|
||||||
if (req.cookies.auth) {
|
return sendJade(res, "account-channels", {
|
||||||
loginName = req.cookies.auth.split(":")[0];
|
|
||||||
} else {
|
|
||||||
sendJade(res, "account-channels", {
|
|
||||||
loggedIn: false,
|
|
||||||
channels: [],
|
channels: [],
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
db.users.verifyAuth(req.cookies.auth, function (err, user) {
|
|
||||||
|
|
||||||
|
db.channels.lookup(name, function (err, channel) {
|
||||||
if (err) {
|
if (err) {
|
||||||
sendJade(res, "account-channels", {
|
sendJade(res, "account-channels", {
|
||||||
loggedIn: false,
|
|
||||||
channels: [],
|
channels: [],
|
||||||
deleteChannelError: err
|
deleteChannelError: err
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
db.channels.lookup(name, function (err, channel) {
|
if (channel.owner !== req.user.name && req.user.global_rank < 255) {
|
||||||
if (err) {
|
db.channels.listUserChannels(req.user.name, function (err2, channels) {
|
||||||
sendJade(res, "account-channels", {
|
sendJade(res, "account-channels", {
|
||||||
loggedIn: true,
|
channels: err2 ? [] : channels,
|
||||||
loginName: loginName,
|
deleteChannelError: "You do not have permission to delete this channel"
|
||||||
channels: [],
|
|
||||||
deleteChannelError: err
|
|
||||||
});
|
});
|
||||||
return;
|
});
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (channel.owner !== user.name && user.global_rank < 255) {
|
db.channels.drop(name, function (err) {
|
||||||
db.channels.listUserChannels(loginName, function (err2, channels) {
|
if (!err) {
|
||||||
sendJade(res, "account-channels", {
|
Logger.eventlog.log("[channel] " + req.user.name + "@" +
|
||||||
loggedIn: true,
|
webserver.ipForRequest(req) + " deleted channel " +
|
||||||
loginName: loginName,
|
name);
|
||||||
channels: err2 ? [] : channels,
|
}
|
||||||
deleteChannelError: "You do not have permission to delete this channel"
|
var sv = Server.getServer();
|
||||||
});
|
if (sv.isChannelLoaded(name)) {
|
||||||
|
var chan = sv.getChannel(name);
|
||||||
|
chan.clearFlag(require("../flags").C_REGISTERED);
|
||||||
|
var users = Array.prototype.slice.call(chan.users);
|
||||||
|
users.forEach(function (u) {
|
||||||
|
u.kick("Channel reloading");
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
|
if (!chan.dead) {
|
||||||
|
chan.emit("empty");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
db.channels.listUserChannels(req.user.name, function (err2, channels) {
|
||||||
db.channels.drop(name, function (err) {
|
sendJade(res, "account-channels", {
|
||||||
if (!err) {
|
channels: err2 ? [] : channels,
|
||||||
Logger.eventlog.log("[channel] " + loginName + "@" +
|
deleteChannelError: err ? err : undefined
|
||||||
webserver.ipForRequest(req) + " deleted channel " +
|
|
||||||
name);
|
|
||||||
}
|
|
||||||
var sv = Server.getServer();
|
|
||||||
if (sv.isChannelLoaded(name)) {
|
|
||||||
var chan = sv.getChannel(name);
|
|
||||||
chan.clearFlag(require("../flags").C_REGISTERED);
|
|
||||||
var users = Array.prototype.slice.call(chan.users);
|
|
||||||
users.forEach(function (u) {
|
|
||||||
u.kick("Channel reloading");
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!chan.dead) {
|
|
||||||
chan.emit("empty");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
db.channels.listUserChannels(loginName, function (err2, channels) {
|
|
||||||
sendJade(res, "account-channels", {
|
|
||||||
loggedIn: true,
|
|
||||||
loginName: loginName,
|
|
||||||
channels: err2 ? [] : channels,
|
|
||||||
deleteChannelError: err ? err : undefined
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -421,70 +365,49 @@ function handleAccountProfilePage(req, res) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var loginName = false;
|
if (!req.user) {
|
||||||
if (!req.cookies.auth) {
|
|
||||||
return sendJade(res, "account-profile", {
|
return sendJade(res, "account-profile", {
|
||||||
loggedIn: false,
|
|
||||||
profileImage: "",
|
profileImage: "",
|
||||||
profileText: ""
|
profileText: ""
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
loginName = req.cookies.auth.split(":")[0];
|
|
||||||
db.users.verifyAuth(req.cookies.auth, function (err, user) {
|
|
||||||
if (err) {
|
|
||||||
return sendJade(res, "account-profile", {
|
|
||||||
loggedIn: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
db.users.getProfile(loginName, function (err, profile) {
|
|
||||||
if (err) {
|
|
||||||
sendJade(res, "account-profile", {
|
|
||||||
loggedIn: true,
|
|
||||||
loginName: loginName,
|
|
||||||
profileError: err,
|
|
||||||
profileImage: "",
|
|
||||||
profileText: ""
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sendJade(res, "account-profile", {
|
|
||||||
loggedIn: true,
|
|
||||||
loginName: loginName,
|
|
||||||
profileImage: profile.image,
|
|
||||||
profileText: profile.text,
|
|
||||||
profileError: false
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db.users.getProfile(req.user.name, function (err, profile) {
|
||||||
|
if (err) {
|
||||||
|
sendJade(res, "account-profile", {
|
||||||
|
profileError: err,
|
||||||
|
profileImage: "",
|
||||||
|
profileText: ""
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendJade(res, "account-profile", {
|
||||||
|
profileImage: profile.image,
|
||||||
|
profileText: profile.text,
|
||||||
|
profileError: false
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a POST request to edit a profile
|
* Handles a POST request to edit a profile
|
||||||
*/
|
*/
|
||||||
function handleAccountProfile(req, res) {
|
function handleAccountProfile(req, res) {
|
||||||
var loginName = false;
|
if (!req.user) {
|
||||||
if (req.cookies.auth) {
|
return sendJade(res, "account-profile", {
|
||||||
loginName = req.cookies.auth.split(":")[0];
|
|
||||||
} else {
|
|
||||||
sendJade(res, "account-profile", {
|
|
||||||
loggedIn: false,
|
|
||||||
profileImage: "",
|
profileImage: "",
|
||||||
profileText: "",
|
profileText: "",
|
||||||
profileError: "You must be logged in to edit your profile",
|
profileError: "You must be logged in to edit your profile",
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var image = req.body.image;
|
var image = req.body.image;
|
||||||
var text = req.body.text;
|
var text = req.body.text;
|
||||||
|
|
||||||
db.users.verifyAuth(req.cookies.auth, function (err, user) {
|
db.users.setProfile(req.user.name, { image: image, text: text }, function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
sendJade(res, "account-profile", {
|
sendJade(res, "account-profile", {
|
||||||
loggedIn: false,
|
|
||||||
profileImage: "",
|
profileImage: "",
|
||||||
profileText: "",
|
profileText: "",
|
||||||
profileError: err
|
profileError: err
|
||||||
|
@ -492,25 +415,10 @@ function handleAccountProfile(req, res) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
db.users.setProfile(user.name, { image: image, text: text }, function (err) {
|
sendJade(res, "account-profile", {
|
||||||
if (err) {
|
profileImage: image,
|
||||||
sendJade(res, "account-profile", {
|
profileText: text,
|
||||||
loggedIn: true,
|
profileError: false
|
||||||
loginName: user.name,
|
|
||||||
profileImage: "",
|
|
||||||
profileText: "",
|
|
||||||
profileError: err
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sendJade(res, "account-profile", {
|
|
||||||
loggedIn: true,
|
|
||||||
loginName: user.name,
|
|
||||||
profileImage: image,
|
|
||||||
profileText: text,
|
|
||||||
profileError: false
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -664,8 +572,7 @@ function handlePasswordRecover(req, res) {
|
||||||
if (err) {
|
if (err) {
|
||||||
sendJade(res, "account-passwordrecover", {
|
sendJade(res, "account-passwordrecover", {
|
||||||
recovered: false,
|
recovered: false,
|
||||||
recoverErr: err,
|
recoverErr: err
|
||||||
loginName: false
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -675,8 +582,7 @@ function handlePasswordRecover(req, res) {
|
||||||
recovered: false,
|
recovered: false,
|
||||||
recoverErr: "This password recovery link has expired. Password " +
|
recoverErr: "This password recovery link has expired. Password " +
|
||||||
"recovery links are valid only for 24 hours after " +
|
"recovery links are valid only for 24 hours after " +
|
||||||
"submission.",
|
"submission."
|
||||||
loginName: false
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -691,8 +597,8 @@ function handlePasswordRecover(req, res) {
|
||||||
sendJade(res, "account-passwordrecover", {
|
sendJade(res, "account-passwordrecover", {
|
||||||
recovered: false,
|
recovered: false,
|
||||||
recoverErr: "Database error. Please contact an administrator if " +
|
recoverErr: "Database error. Please contact an administrator if " +
|
||||||
"this persists.",
|
"this persists."
|
||||||
loginName: false
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -702,8 +608,7 @@ function handlePasswordRecover(req, res) {
|
||||||
|
|
||||||
sendJade(res, "account-passwordrecover", {
|
sendJade(res, "account-passwordrecover", {
|
||||||
recovered: true,
|
recovered: true,
|
||||||
recoverPw: newpw,
|
recoverPw: newpw
|
||||||
loginName: false
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,31 +8,18 @@ var Config = require("../config");
|
||||||
|
|
||||||
function checkAdmin(cb) {
|
function checkAdmin(cb) {
|
||||||
return function (req, res) {
|
return function (req, res) {
|
||||||
var auth = req.cookies.auth;
|
if (!req.user) {
|
||||||
if (!auth) {
|
return res.send(403);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.user.global_rank < 255) {
|
||||||
res.send(403);
|
res.send(403);
|
||||||
|
Logger.eventlog.log("[acp] Attempted GET "+req.path+" from non-admin " +
|
||||||
|
user.name + "@" + webserver.ipForRequest(req));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
db.users.verifyAuth(auth, function (err, user) {
|
|
||||||
if (err) {
|
|
||||||
if (err === "Invalid auth string" ||
|
|
||||||
err === "Auth string does not match an existing user") {
|
|
||||||
res.send(403);
|
|
||||||
} else {
|
|
||||||
res.send(500);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user.global_rank < 255) {
|
cb(req, res, req.user);
|
||||||
res.send(403);
|
|
||||||
Logger.eventlog.log("[acp] Attempted GET "+req.path+" from non-admin " +
|
|
||||||
user.name + "@" + webserver.ipForRequest(req));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cb(req, res, user);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,8 +36,6 @@ function handleAcp(req, res, user) {
|
||||||
sio += "/socket.io/socket.io.js";
|
sio += "/socket.io/socket.io.js";
|
||||||
|
|
||||||
sendJade(res, "acp", {
|
sendJade(res, "acp", {
|
||||||
loginName: user.name,
|
|
||||||
loggedIn: true,
|
|
||||||
sioSource: sio
|
sioSource: sio
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
219
lib/web/auth.js
219
lib/web/auth.js
|
@ -14,6 +14,7 @@ var $util = require("../utilities");
|
||||||
var db = require("../database");
|
var db = require("../database");
|
||||||
var Config = require("../config");
|
var Config = require("../config");
|
||||||
var url = require("url");
|
var url = require("url");
|
||||||
|
var session = require("../session");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes a login request. Sets a cookie upon successful authentication
|
* Processes a login request. Sets a cookie upon successful authentication
|
||||||
|
@ -22,12 +23,28 @@ function handleLogin(req, res) {
|
||||||
var name = req.body.name;
|
var name = req.body.name;
|
||||||
var password = req.body.password;
|
var password = req.body.password;
|
||||||
var rememberMe = req.body.remember;
|
var rememberMe = req.body.remember;
|
||||||
|
var dest = req.body.dest || req.header("referer") || null;
|
||||||
|
dest = dest.match(/login|logout/) ? null : dest;
|
||||||
|
|
||||||
if (typeof name !== "string" || typeof password !== "string") {
|
if (typeof name !== "string" || typeof password !== "string") {
|
||||||
res.send(400);
|
res.send(400);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var host = req.hostname;
|
||||||
|
if (host.indexOf(Config.get("http.root-domain")) === -1 &&
|
||||||
|
Config.get("http.alt-domains").indexOf(host) === -1) {
|
||||||
|
Logger.syslog.log("WARNING: Attempted login from non-approved domain " + host);
|
||||||
|
return res.send(403);
|
||||||
|
}
|
||||||
|
|
||||||
|
var expiration;
|
||||||
|
if (rememberMe) {
|
||||||
|
expiration = new Date("Fri, 31 Dec 9999 23:59:59 GMT");
|
||||||
|
} else {
|
||||||
|
expiration = new Date(Date.now() + 7*24*60*60*1000);
|
||||||
|
}
|
||||||
|
|
||||||
password = password.substring(0, 100);
|
password = password.substring(0, 100);
|
||||||
|
|
||||||
db.users.verifyLogin(name, password, function (err, user) {
|
db.users.verifyLogin(name, password, function (err, user) {
|
||||||
|
@ -40,126 +57,41 @@ function handleLogin(req, res) {
|
||||||
loggedIn: false,
|
loggedIn: false,
|
||||||
loginError: err
|
loginError: err
|
||||||
});
|
});
|
||||||
} else {
|
return;
|
||||||
var auth = user.name + ":" + user.hash;
|
}
|
||||||
var expiration;
|
|
||||||
if (rememberMe) {
|
|
||||||
expiration = new Date("Fri, 31 Dec 9999 23:59:59 GMT");
|
|
||||||
} else {
|
|
||||||
expiration = new Date(Date.now() + 7*24*60*60*1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
res.cookie("auth", auth, {
|
session.genSession(user, expiration, function (err, auth) {
|
||||||
expires: expiration,
|
if (err) {
|
||||||
httpOnly: true
|
|
||||||
});
|
|
||||||
|
|
||||||
res.cookie("auth", auth, {
|
|
||||||
domain: Config.get("http.root-domain-dotted"),
|
|
||||||
expires: expiration,
|
|
||||||
httpOnly: true
|
|
||||||
});
|
|
||||||
|
|
||||||
// Try to find an appropriate redirect
|
|
||||||
var ref = req.header("referrer");
|
|
||||||
if (!ref) {
|
|
||||||
ref = req.body.redirect;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof ref !== "string") {
|
|
||||||
ref = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Redirect to shim cookie layer if the host doesn't match
|
|
||||||
try {
|
|
||||||
var data = url.parse(ref);
|
|
||||||
if (data.host.indexOf(Config.get("http.root-domain")) === -1) {
|
|
||||||
var host = data.host.replace(/:\d+$/, "");
|
|
||||||
if (Config.get("http.alt-domains").indexOf(host) === -1) {
|
|
||||||
Logger.syslog.log("WARNING: Attempted login from non-approved "+
|
|
||||||
"domain " + host);
|
|
||||||
} else {
|
|
||||||
var dest = "/shimcookie?auth=" + encodeURIComponent(auth) +
|
|
||||||
"&rank=" + encodeURIComponent(user.global_rank) +
|
|
||||||
"&redirect=" + encodeURIComponent(ref);
|
|
||||||
res.redirect(data.protocol + "//" + data.host + dest);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ref.match(/login|logout/)) {
|
|
||||||
ref = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ref) {
|
|
||||||
res.redirect(ref);
|
|
||||||
} else {
|
|
||||||
sendJade(res, "login", {
|
sendJade(res, "login", {
|
||||||
loggedIn: true,
|
loggedIn: false,
|
||||||
loginName: user.name
|
loginError: err
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.hostname.indexOf(Config.get("http.root-domain")) >= 0) {
|
||||||
|
res.cookie("auth", auth, {
|
||||||
|
domain: Config.get("http.root-domain-dotted"),
|
||||||
|
expires: expiration,
|
||||||
|
httpOnly: true,
|
||||||
|
signed: true
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
res.cookie("auth", auth, {
|
||||||
|
expires: expiration,
|
||||||
|
httpOnly: true,
|
||||||
|
signed: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleShimCookie(req, res) {
|
if (dest) {
|
||||||
var auth = req.query.auth;
|
res.redirect(dest);
|
||||||
var rank = req.query.rank;
|
} else {
|
||||||
var redirect = req.query.redirect;
|
res.user = user;
|
||||||
if (typeof auth !== "string" || typeof redirect !== "string" ||
|
sendJade(res, "login", {});
|
||||||
typeof rank !== "string") {
|
}
|
||||||
res.send(400);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
res.cookie("auth", auth, {
|
|
||||||
expires: new Date(Date.now() + 7*24*60*60*1000),
|
|
||||||
httpOnly: true
|
|
||||||
});
|
|
||||||
|
|
||||||
res.cookie("rank", rank, {
|
|
||||||
expires: new Date(Date.now() + 7*24*60*60*1000),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (redirect.match(/login|logout/)) {
|
|
||||||
redirect = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (redirect) {
|
|
||||||
res.redirect(redirect);
|
|
||||||
} else {
|
|
||||||
sendJade(res, "login", {
|
|
||||||
loggedIn: true,
|
|
||||||
loginName: auth.split(":")[0]
|
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
|
||||||
function handleShimLogout(req, res) {
|
|
||||||
var redirect = req.query.redirect;
|
|
||||||
if (typeof redirect !== "string") {
|
|
||||||
res.send(400);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
res.clearCookie("auth");
|
|
||||||
res.clearCookie("rank");
|
|
||||||
res.clearCookie("auth", { domain: Config.get("http.root-domain-dotted") });
|
|
||||||
res.clearCookie("rank", { domain: Config.get("http.root-domain-dotted") });
|
|
||||||
|
|
||||||
|
|
||||||
if (redirect.match(/login|logout/)) {
|
|
||||||
redirect = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (redirect) {
|
|
||||||
res.redirect(redirect);
|
|
||||||
} else {
|
|
||||||
sendJade(res, "logout", {});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -170,20 +102,14 @@ function handleLoginPage(req, res) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req.cookies.auth) {
|
if (req.user) {
|
||||||
var split = req.cookies.auth.split(":");
|
return sendJade(res, "login", {
|
||||||
if (split.length === 2) {
|
wasAlreadyLoggedIn: true
|
||||||
sendJade(res, "login", {
|
});
|
||||||
wasAlreadyLoggedIn: true,
|
|
||||||
loggedIn: true,
|
|
||||||
loginName: split[0]
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sendJade(res, "login", {
|
sendJade(res, "login", {
|
||||||
loggedIn: false,
|
redirect: req.query.dest || req.header("referer")
|
||||||
redirect: req.header("Referrer")
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,34 +118,17 @@ function handleLoginPage(req, res) {
|
||||||
*/
|
*/
|
||||||
function handleLogout(req, res) {
|
function handleLogout(req, res) {
|
||||||
res.clearCookie("auth");
|
res.clearCookie("auth");
|
||||||
res.clearCookie("rank");
|
|
||||||
// Try to find an appropriate redirect
|
// Try to find an appropriate redirect
|
||||||
var ref = req.header("referrer");
|
var dest = req.query.dest || req.header("referer");
|
||||||
if (!ref) {
|
dest = dest.match(/login|logout|account/) ? null : dest;
|
||||||
ref = req.query.redirect;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof ref !== "string") {
|
|
||||||
ref = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
var host = req.hostname;
|
var host = req.hostname;
|
||||||
if (host.indexOf(Config.get("http.root-domain")) !== -1) {
|
if (host.indexOf(Config.get("http.root-domain")) !== -1) {
|
||||||
res.clearCookie("auth", { domain: Config.get("http.root-domain-dotted") });
|
res.clearCookie("auth", { domain: Config.get("http.root-domain-dotted") });
|
||||||
res.clearCookie("rank", { domain: Config.get("http.root-domain-dotted") });
|
}
|
||||||
} else {
|
|
||||||
var dest = Config.get("http.full-address") + "/shimlogout?redirect=" +
|
if (dest) {
|
||||||
encodeURIComponent(ref);
|
|
||||||
res.redirect(dest);
|
res.redirect(dest);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ref.match(/login|logout/)) {
|
|
||||||
ref = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ref) {
|
|
||||||
res.redirect(ref);
|
|
||||||
} else {
|
} else {
|
||||||
sendJade(res, "logout", {});
|
sendJade(res, "logout", {});
|
||||||
}
|
}
|
||||||
|
@ -233,15 +142,9 @@ function handleRegisterPage(req, res) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req.cookies.auth) {
|
if (req.user) {
|
||||||
var split = req.cookies.auth.split(":");
|
sendJade(res, "register", {});
|
||||||
if (split.length === 2) {
|
return;
|
||||||
sendJade(res, "register", {
|
|
||||||
loggedIn: true,
|
|
||||||
loginName: split[0]
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sendJade(res, "register", {
|
sendJade(res, "register", {
|
||||||
|
@ -324,7 +227,5 @@ module.exports = {
|
||||||
app.get("/logout", handleLogout);
|
app.get("/logout", handleLogout);
|
||||||
app.get("/register", handleRegisterPage);
|
app.get("/register", handleRegisterPage);
|
||||||
app.post("/register", handleRegister);
|
app.post("/register", handleRegister);
|
||||||
app.get("/shimcookie", handleShimCookie);
|
|
||||||
app.get("/shimlogout", handleShimLogout);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,13 +3,12 @@ var fs = require("fs");
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
var Config = require("../config");
|
var Config = require("../config");
|
||||||
var templates = path.join(__dirname, "..", "..", "templates");
|
var templates = path.join(__dirname, "..", "..", "templates");
|
||||||
|
|
||||||
var cache = {};
|
var cache = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merges locals with globals for jade rendering
|
* Merges locals with globals for jade rendering
|
||||||
*/
|
*/
|
||||||
function merge(locals) {
|
function merge(locals, res) {
|
||||||
var _locals = {
|
var _locals = {
|
||||||
siteTitle: Config.get("html-template.title"),
|
siteTitle: Config.get("html-template.title"),
|
||||||
siteDescription: Config.get("html-template.description"),
|
siteDescription: Config.get("html-template.description"),
|
||||||
|
@ -30,6 +29,8 @@ function merge(locals) {
|
||||||
* Renders and serves a jade template
|
* Renders and serves a jade template
|
||||||
*/
|
*/
|
||||||
function sendJade(res, view, locals) {
|
function sendJade(res, view, locals) {
|
||||||
|
locals.loggedIn = locals.loggedIn || !!res.user;
|
||||||
|
locals.loginName = locals.loginName || res.user ? res.user.name : false;
|
||||||
if (!(view in cache) || Config.get("debug")) {
|
if (!(view in cache) || Config.get("debug")) {
|
||||||
var file = path.join(templates, view + ".jade");
|
var file = path.join(templates, view + ".jade");
|
||||||
var fn = jade.compile(fs.readFileSync(file), {
|
var fn = jade.compile(fs.readFileSync(file), {
|
||||||
|
@ -38,7 +39,7 @@ function sendJade(res, view, locals) {
|
||||||
});
|
});
|
||||||
cache[view] = fn;
|
cache[view] = fn;
|
||||||
}
|
}
|
||||||
var html = cache[view](merge(locals));
|
var html = cache[view](merge(locals, res));
|
||||||
res.send(html);
|
res.send(html);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ var bodyParser = require("body-parser");
|
||||||
var cookieParser = require("cookie-parser");
|
var cookieParser = require("cookie-parser");
|
||||||
var static = require("serve-static");
|
var static = require("serve-static");
|
||||||
var morgan = require("morgan");
|
var morgan = require("morgan");
|
||||||
|
var session = require("../session");
|
||||||
|
|
||||||
const LOG_FORMAT = ':real-address - :remote-user [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"';
|
const LOG_FORMAT = ':real-address - :remote-user [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"';
|
||||||
morgan.token('real-address', function (req) { return req._ip; });
|
morgan.token('real-address', function (req) { return req._ip; });
|
||||||
|
@ -46,6 +47,10 @@ function ipForRequest(req) {
|
||||||
function redirectHttps(req, res) {
|
function redirectHttps(req, res) {
|
||||||
if (!req.secure && Config.get("https.enabled")) {
|
if (!req.secure && Config.get("https.enabled")) {
|
||||||
var ssldomain = Config.get("https.full-address");
|
var ssldomain = Config.get("https.full-address");
|
||||||
|
if (ssldomain.indexOf(req.hostname) < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
res.redirect(ssldomain + req.path);
|
res.redirect(ssldomain + req.path);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -74,11 +79,6 @@ function handleChannel(req, res) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var loginName = false;
|
|
||||||
if (req.cookies.auth) {
|
|
||||||
loginName = req.cookies.auth.split(":")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
var sio;
|
var sio;
|
||||||
if (net.isIPv6(ipForRequest(req))) {
|
if (net.isIPv6(ipForRequest(req))) {
|
||||||
sio = Config.get("io.ipv6-default");
|
sio = Config.get("io.ipv6-default");
|
||||||
|
@ -92,8 +92,6 @@ function handleChannel(req, res) {
|
||||||
|
|
||||||
sendJade(res, "channel", {
|
sendJade(res, "channel", {
|
||||||
channelName: req.params.channel,
|
channelName: req.params.channel,
|
||||||
loggedIn: loginName !== false,
|
|
||||||
loginName: loginName,
|
|
||||||
sioSource: sio
|
sioSource: sio
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -102,11 +100,6 @@ function handleChannel(req, res) {
|
||||||
* Handles a request for the index page
|
* Handles a request for the index page
|
||||||
*/
|
*/
|
||||||
function handleIndex(req, res) {
|
function handleIndex(req, res) {
|
||||||
var loginName = false;
|
|
||||||
if (req.cookies.auth) {
|
|
||||||
loginName = req.cookies.auth.split(":")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
var channels = Server.getServer().packChannelList(true);
|
var channels = Server.getServer().packChannelList(true);
|
||||||
channels.sort(function (a, b) {
|
channels.sort(function (a, b) {
|
||||||
if (a.usercount === b.usercount) {
|
if (a.usercount === b.usercount) {
|
||||||
|
@ -117,8 +110,6 @@ function handleIndex(req, res) {
|
||||||
});
|
});
|
||||||
|
|
||||||
sendJade(res, "index", {
|
sendJade(res, "index", {
|
||||||
loggedIn: loginName !== false,
|
|
||||||
loginName: loginName,
|
|
||||||
channels: channels
|
channels: channels
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -142,30 +133,19 @@ function handleSocketConfig(req, res) {
|
||||||
if (!iourl) {
|
if (!iourl) {
|
||||||
iourl = Config.get("io.ipv4-default");
|
iourl = Config.get("io.ipv4-default");
|
||||||
}
|
}
|
||||||
|
|
||||||
sioconfig += "var IO_URL='" + iourl + "';";
|
sioconfig += "var IO_URL='" + iourl + "';";
|
||||||
sioconfig += "var IO_V6=" + ipv6 + ";";
|
sioconfig += "var IO_V6=" + ipv6 + ";";
|
||||||
res.send(sioconfig);
|
res.send(sioconfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleUserAgreement(req, res) {
|
function handleUserAgreement(req, res) {
|
||||||
var loginName = false;
|
|
||||||
if (req.cookies.auth) {
|
|
||||||
loginName = req.cookies.auth.split(":")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
sendJade(res, "tos", {
|
sendJade(res, "tos", {
|
||||||
loggedIn: loginName !== false,
|
|
||||||
loginName: loginName,
|
|
||||||
domain: Config.get("http.domain")
|
domain: Config.get("http.domain")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleContactPage(req, res) {
|
function handleContactPage(req, res) {
|
||||||
var loginName = false;
|
|
||||||
if (req.cookies.auth) {
|
|
||||||
loginName = req.cookies.auth.split(":")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make a copy to prevent messing with the original
|
// Make a copy to prevent messing with the original
|
||||||
var contacts = Config.get("contacts").map(function (c) {
|
var contacts = Config.get("contacts").map(function (c) {
|
||||||
return {
|
return {
|
||||||
|
@ -189,8 +169,6 @@ function handleContactPage(req, res) {
|
||||||
});
|
});
|
||||||
|
|
||||||
sendJade(res, "contact", {
|
sendJade(res, "contact", {
|
||||||
loggedIn: loginName !== false,
|
|
||||||
loginName: loginName,
|
|
||||||
contacts: contacts
|
contacts: contacts
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -208,7 +186,10 @@ module.exports = {
|
||||||
extended: false,
|
extended: false,
|
||||||
limit: '1kb' // No POST data should ever exceed this size under normal usage
|
limit: '1kb' // No POST data should ever exceed this size under normal usage
|
||||||
}));
|
}));
|
||||||
app.use(cookieParser());
|
if (Config.get("http.cookie-secret") === "change-me") {
|
||||||
|
Logger.errlog.log("YOU SHOULD CHANGE THE VALUE OF cookie-secret IN config.yaml");
|
||||||
|
}
|
||||||
|
app.use(cookieParser(Config.get("http.cookie-secret")));
|
||||||
app.use(morgan(LOG_FORMAT, {
|
app.use(morgan(LOG_FORMAT, {
|
||||||
stream: require("fs").createWriteStream(path.join(__dirname, "..", "..",
|
stream: require("fs").createWriteStream(path.join(__dirname, "..", "..",
|
||||||
"http.log"), {
|
"http.log"), {
|
||||||
|
@ -217,6 +198,24 @@ module.exports = {
|
||||||
})
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
app.use(function (req, res, next) {
|
||||||
|
if (req.path.match(/^\/(css|js|img|boop).*$/)) {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!req.signedCookies || !req.signedCookies.auth) {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
|
||||||
|
session.verifySession(req.signedCookies.auth, function (err, account) {
|
||||||
|
if (!err) {
|
||||||
|
req.user = res.user = account;
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
if (Config.get("http.gzip")) {
|
if (Config.get("http.gzip")) {
|
||||||
app.use(require("compression")({ threshold: Config.get("http.gzip-threshold") }));
|
app.use(require("compression")({ threshold: Config.get("http.gzip-threshold") }));
|
||||||
Logger.syslog.log("Enabled gzip compression");
|
Logger.syslog.log("Enabled gzip compression");
|
||||||
|
@ -267,5 +266,5 @@ module.exports = {
|
||||||
|
|
||||||
redirectHttps: redirectHttps,
|
redirectHttps: redirectHttps,
|
||||||
|
|
||||||
redirectHttp: redirectHttp,
|
redirectHttp: redirectHttp
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,7 +12,7 @@ html(lang="en")
|
||||||
ul.nav.navbar-nav
|
ul.nav.navbar-nav
|
||||||
mixin navdefaultlinks("/login")
|
mixin navdefaultlinks("/login")
|
||||||
if loggedIn
|
if loggedIn
|
||||||
mixin navlogoutform()
|
mixin navlogoutform("/")
|
||||||
section#mainpage.container
|
section#mainpage.container
|
||||||
if wasAlreadyLoggedIn
|
if wasAlreadyLoggedIn
|
||||||
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
||||||
|
@ -27,7 +27,7 @@ html(lang="en")
|
||||||
h2 Login
|
h2 Login
|
||||||
form(role="form", action="/login", method="post")
|
form(role="form", action="/login", method="post")
|
||||||
if redirect
|
if redirect
|
||||||
input(type="hidden", name="redirect", value=redirect)
|
input(type="hidden", name="dest", value=redirect)
|
||||||
.form-group
|
.form-group
|
||||||
label(for="username") Username
|
label(for="username") Username
|
||||||
input#username.form-control(type="text", name="name")
|
input#username.form-control(type="text", name="name")
|
||||||
|
|
|
@ -11,7 +11,7 @@ html(lang="en")
|
||||||
#nav-collapsible.collapse.navbar-collapse
|
#nav-collapsible.collapse.navbar-collapse
|
||||||
ul.nav.navbar-nav
|
ul.nav.navbar-nav
|
||||||
mixin navdefaultlinks("/logout")
|
mixin navdefaultlinks("/logout")
|
||||||
mixin navloginform()
|
mixin navloginform("/")
|
||||||
section#mainpage.container
|
section#mainpage.container
|
||||||
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
||||||
.alert.alert-info.center.messagebox
|
.alert.alert-info.center.messagebox
|
||||||
|
|
|
@ -27,13 +27,13 @@ mixin navdefaultlinks(page)
|
||||||
b.caret
|
b.caret
|
||||||
ul.dropdown-menu
|
ul.dropdown-menu
|
||||||
if loggedIn
|
if loggedIn
|
||||||
li: a(href="/logout?redirect=#{page}") Logout
|
li: a(href="/logout?dest=#{page}") Logout
|
||||||
li.divider
|
li.divider
|
||||||
li: a(href="/account/channels") Channels
|
li: a(href="/account/channels") Channels
|
||||||
li: a(href="/account/profile") Profile
|
li: a(href="/account/profile") Profile
|
||||||
li: a(href="/account/edit") Change Password/Email
|
li: a(href="/account/edit") Change Password/Email
|
||||||
else
|
else
|
||||||
li: a(href="/login") Login
|
li: a(href="/login?dest=#{page}") Login
|
||||||
li: a(href="/register") Register
|
li: a(href="/register") Register
|
||||||
|
|
||||||
mixin navloginlogout(redirect)
|
mixin navloginlogout(redirect)
|
||||||
|
@ -47,7 +47,7 @@ mixin navloginform(redirect)
|
||||||
- loginDomain = ""
|
- loginDomain = ""
|
||||||
.visible-lg
|
.visible-lg
|
||||||
form#loginform.navbar-form.navbar-right(action="#{loginDomain}/login", method="post")
|
form#loginform.navbar-form.navbar-right(action="#{loginDomain}/login", method="post")
|
||||||
input(type="hidden", name="redirect", value=redirect)
|
input(type="hidden", name="dest", value=redirect)
|
||||||
.form-group
|
.form-group
|
||||||
input#username.form-control(type="text", name="name", placeholder="Username")
|
input#username.form-control(type="text", name="name", placeholder="Username")
|
||||||
.form-group
|
.form-group
|
||||||
|
@ -60,19 +60,13 @@ mixin navloginform(redirect)
|
||||||
button#login.btn.btn-default(type="submit") Login
|
button#login.btn.btn-default(type="submit") Login
|
||||||
.visible-md
|
.visible-md
|
||||||
p#loginform.navbar-text.pull-right
|
p#loginform.navbar-text.pull-right
|
||||||
a#login.navbar-link(href="#{loginDomain}/login?redirect=#{redirect}") Log in
|
a#login.navbar-link(href="#{loginDomain}/login?dest=#{redirect}") Log in
|
||||||
span ·
|
span ·
|
||||||
a#register.navbar-link(href="/register") Register
|
a#register.navbar-link(href="/register") Register
|
||||||
|
|
||||||
|
|
||||||
mixin navlogoutform(redirect)
|
mixin navlogoutform(redirect)
|
||||||
if loginDomain == null
|
|
||||||
- loginDomain = ""
|
|
||||||
if redirect
|
|
||||||
- url = "logout?redirect=" + redirect
|
|
||||||
else
|
|
||||||
- url = "logout"
|
|
||||||
p#logoutform.navbar-text.pull-right
|
p#logoutform.navbar-text.pull-right
|
||||||
span#welcome Welcome, #{loginName}
|
span#welcome Welcome, #{loginName}
|
||||||
span ·
|
span ·
|
||||||
a#logout.navbar-link(href="#{loginDomain}/#{url}") Logout
|
a#logout.navbar-link(href="/logout?dest=#{redirect}") Logout
|
||||||
|
|
Loading…
Reference in New Issue