Continue work on password reset/recovery
This commit is contained in:
parent
65ef082a64
commit
63ed9c7883
|
@ -235,6 +235,27 @@ module.exports.globalUnbanIP = function (ip, callback) {
|
||||||
|
|
||||||
/* password recovery */
|
/* password recovery */
|
||||||
|
|
||||||
|
module.exports.addPasswordReset = function (data, cb) {
|
||||||
|
if (typeof cb !== "function") {
|
||||||
|
cb = blackHole;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ip = data.ip || "";
|
||||||
|
var name = data.name;
|
||||||
|
var email = data.email;
|
||||||
|
var hash = data.hash;
|
||||||
|
var expire = data.expire;
|
||||||
|
|
||||||
|
if (!name || !hash) {
|
||||||
|
cb("Internal error: Must provide name and hash to insert a new password reset", null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.query("INSERT INTO `password_reset` (`ip`, `name`, `email`, `hash`, `expire`) " +
|
||||||
|
"VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE ip=?, hash=?, email=?, expire=?",
|
||||||
|
[ip, name, email, hash, expire, ip, hash, email, expire], cb);
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
module.exports.genPasswordReset = function (ip, name, email, callback) {
|
module.exports.genPasswordReset = function (ip, name, email, callback) {
|
||||||
if(typeof callback !== "function")
|
if(typeof callback !== "function")
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
var crypto = require("crypto");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Set prototype- simple wrapper around JS objects to
|
Set prototype- simple wrapper around JS objects to
|
||||||
manipulate them like a set
|
manipulate them like a set
|
||||||
|
@ -194,5 +196,11 @@ module.exports = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
Set: Set
|
Set: Set,
|
||||||
|
|
||||||
|
sha1: function (data) {
|
||||||
|
var shasum = crypto.createHash("sha1");
|
||||||
|
shasum.update(data);
|
||||||
|
return shasum.digest("hex");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,12 +4,13 @@
|
||||||
* @author Calvin Montgomery <cyzon@cyzon.us>
|
* @author Calvin Montgomery <cyzon@cyzon.us>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var webserver = require('./webserver');
|
var webserver = require("./webserver");
|
||||||
var logRequest = webserver.logRequest;
|
var logRequest = webserver.logRequest;
|
||||||
var sendJade = require('./jade').sendJade;
|
var sendJade = require("./jade").sendJade;
|
||||||
var Logger = require('../logger');
|
var Logger = require("../logger");
|
||||||
var db = require('../database');
|
var db = require("../database");
|
||||||
var $util = require('../utilities');
|
var $util = require("../utilities");
|
||||||
|
var Config = require("../config");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a GET request for /account/edit
|
* Handles a GET request for /account/edit
|
||||||
|
@ -22,25 +23,25 @@ function handleAccountEditPage(req, res) {
|
||||||
logRequest(req);
|
logRequest(req);
|
||||||
var loginName = false;
|
var loginName = false;
|
||||||
if (req.cookies.auth) {
|
if (req.cookies.auth) {
|
||||||
loginName = req.cookies.auth.split(':')[0];
|
loginName = req.cookies.auth.split(":")[0];
|
||||||
}
|
}
|
||||||
sendJade(res, 'account-edit', {
|
sendJade(res, "account-edit", {
|
||||||
loggedIn: loginName !== false,
|
loggedIn: loginName !== false,
|
||||||
loginName: loginName
|
loginName: loginName
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a POST request to edit a user's account
|
* Handles a POST request to edit a user"s account
|
||||||
*/
|
*/
|
||||||
function handleAccountEdit(req, res) {
|
function handleAccountEdit(req, res) {
|
||||||
logRequest(req);
|
logRequest(req);
|
||||||
var action = req.body.action;
|
var action = req.body.action;
|
||||||
switch(action) {
|
switch(action) {
|
||||||
case 'change_password':
|
case "change_password":
|
||||||
handleChangePassword(req, res);
|
handleChangePassword(req, res);
|
||||||
break;
|
break;
|
||||||
case 'change_email':
|
case "change_email":
|
||||||
handleChangeEmail(req, res);
|
handleChangeEmail(req, res);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -50,7 +51,7 @@ function handleAccountEdit(req, res) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a request to change the user's password
|
* Handles a request to change the user"s password
|
||||||
*/
|
*/
|
||||||
function handleChangePassword(req, res) {
|
function handleChangePassword(req, res) {
|
||||||
var name = req.body.name;
|
var name = req.body.name;
|
||||||
|
@ -58,21 +59,21 @@ function handleChangePassword(req, res) {
|
||||||
var newpassword = req.body.newpassword;
|
var newpassword = req.body.newpassword;
|
||||||
var loginName = false;
|
var loginName = false;
|
||||||
if (req.cookies.auth) {
|
if (req.cookies.auth) {
|
||||||
loginName = req.cookies.auth.split(':')[0];
|
loginName = req.cookies.auth.split(":")[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof name !== 'string' ||
|
if (typeof name !== "string" ||
|
||||||
typeof oldpassword !== 'string' ||
|
typeof oldpassword !== "string" ||
|
||||||
typeof newpassword !== 'string') {
|
typeof newpassword !== "string") {
|
||||||
res.send(400);
|
res.send(400);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newpassword.length === 0) {
|
if (newpassword.length === 0) {
|
||||||
sendJade(res, 'account-edit', {
|
sendJade(res, "account-edit", {
|
||||||
loggedIn: loginName !== false,
|
loggedIn: loginName !== false,
|
||||||
loginName: loginName,
|
loginName: loginName,
|
||||||
errorMessage: 'New password must not be empty'
|
errorMessage: "New password must not be empty"
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -81,7 +82,7 @@ function handleChangePassword(req, res) {
|
||||||
|
|
||||||
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,
|
loggedIn: loginName !== false,
|
||||||
loginName: loginName,
|
loginName: loginName,
|
||||||
errorMessage: err
|
errorMessage: err
|
||||||
|
@ -91,25 +92,25 @@ 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,
|
loggedIn: loginName !== false,
|
||||||
loginName: loginName,
|
loginName: loginName,
|
||||||
errorMessage: err
|
errorMessage: err
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Logger.eventlog(webserver.ipForRequest(req) + ' changed password for ' + name);
|
Logger.eventlog(webserver.ipForRequest(req) + " changed password for " + name);
|
||||||
sendJade(res, 'account-edit', {
|
sendJade(res, "account-edit", {
|
||||||
loggedIn: loginName !== false,
|
loggedIn: loginName !== false,
|
||||||
loginName: loginName,
|
loginName: loginName,
|
||||||
successMessage: 'Password changed.'
|
successMessage: "Password changed."
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a request to change the user's email
|
* Handles a request to change the user"s email
|
||||||
*/
|
*/
|
||||||
function handleChangeEmail(req, res) {
|
function handleChangeEmail(req, res) {
|
||||||
var name = req.body.name;
|
var name = req.body.name;
|
||||||
|
@ -117,28 +118,28 @@ function handleChangeEmail(req, res) {
|
||||||
var email = req.body.email;
|
var email = req.body.email;
|
||||||
var loginName = false;
|
var loginName = false;
|
||||||
if (req.cookies.auth) {
|
if (req.cookies.auth) {
|
||||||
loginName = req.cookies.auth.split(':')[0];
|
loginName = req.cookies.auth.split(":")[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof name !== 'string' ||
|
if (typeof name !== "string" ||
|
||||||
typeof password !== 'string' ||
|
typeof password !== "string" ||
|
||||||
typeof email !== 'string') {
|
typeof email !== "string") {
|
||||||
res.send(400);
|
res.send(400);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$util.isValidEmail(email)) {
|
if (!$util.isValidEmail(email)) {
|
||||||
sendJade(res, 'account-edit', {
|
sendJade(res, "account-edit", {
|
||||||
loggedIn: loginName !== false,
|
loggedIn: loginName !== false,
|
||||||
loginName: loginName,
|
loginName: loginName,
|
||||||
errorMessage: 'Invalid email address'
|
errorMessage: "Invalid email address"
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
loggedIn: loginName !== false,
|
||||||
loginName: loginName,
|
loginName: loginName,
|
||||||
errorMessage: err
|
errorMessage: err
|
||||||
|
@ -148,19 +149,20 @@ 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,
|
loggedIn: loginName !== false,
|
||||||
loginName: loginName,
|
loginName: loginName,
|
||||||
errorMessage: err
|
errorMessage: err
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Logger.eventlog(webserver.ipForRequest(req) + ' changed email for ' + name +
|
// TODO event log
|
||||||
' to ' + email);
|
Logger.syslog.log(webserver.ipForRequest(req) + " changed email for " + name +
|
||||||
sendJade(res, 'account-edit', {
|
" to " + email);
|
||||||
|
sendJade(res, "account-edit", {
|
||||||
loggedIn: loginName !== false,
|
loggedIn: loginName !== false,
|
||||||
loginName: loginName,
|
loginName: loginName,
|
||||||
successMessage: 'Email address changed.'
|
successMessage: "Email address changed."
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -177,19 +179,19 @@ function handleAccountChannelPage(req, res) {
|
||||||
logRequest(req);
|
logRequest(req);
|
||||||
var loginName = false;
|
var loginName = false;
|
||||||
if (req.cookies.auth) {
|
if (req.cookies.auth) {
|
||||||
loginName = req.cookies.auth.split(':')[0];
|
loginName = req.cookies.auth.split(":")[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loginName) {
|
if (loginName) {
|
||||||
db.channels.listUserChannels(loginName, function (err, channels) {
|
db.channels.listUserChannels(loginName, function (err, channels) {
|
||||||
sendJade(res, 'account-channels', {
|
sendJade(res, "account-channels", {
|
||||||
loggedIn: true,
|
loggedIn: true,
|
||||||
loginName: loginName,
|
loginName: loginName,
|
||||||
channels: channels
|
channels: channels
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
sendJade(res, 'account-channels', {
|
sendJade(res, "account-channels", {
|
||||||
loggedIn: false,
|
loggedIn: false,
|
||||||
channels: [],
|
channels: [],
|
||||||
});
|
});
|
||||||
|
@ -197,16 +199,16 @@ function handleAccountChannelPage(req, res) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a POST request to modify a user's channels
|
* Handles a POST request to modify a user"s channels
|
||||||
*/
|
*/
|
||||||
function handleAccountChannel(req, res) {
|
function handleAccountChannel(req, res) {
|
||||||
logRequest(req);
|
logRequest(req);
|
||||||
var action = req.body.action;
|
var action = req.body.action;
|
||||||
switch(action) {
|
switch(action) {
|
||||||
case 'new_channel':
|
case "new_channel":
|
||||||
handleNewChannel(req, res);
|
handleNewChannel(req, res);
|
||||||
break;
|
break;
|
||||||
case 'delete_channel':
|
case "delete_channel":
|
||||||
handleDeleteChannel(req, res);
|
handleDeleteChannel(req, res);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -222,16 +224,16 @@ function handleNewChannel(req, res) {
|
||||||
logRequest(req);
|
logRequest(req);
|
||||||
|
|
||||||
var name = req.body.name;
|
var name = req.body.name;
|
||||||
if (typeof name !== 'string') {
|
if (typeof name !== "string") {
|
||||||
res.send(400);
|
res.send(400);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var loginName = false;
|
var loginName = false;
|
||||||
if (req.cookies.auth) {
|
if (req.cookies.auth) {
|
||||||
loginName = req.cookies.auth.split(':')[0];
|
loginName = req.cookies.auth.split(":")[0];
|
||||||
} else {
|
} else {
|
||||||
sendJade(res, 'account-channels', {
|
sendJade(res, "account-channels", {
|
||||||
loggedIn: false,
|
loggedIn: false,
|
||||||
channels: []
|
channels: []
|
||||||
});
|
});
|
||||||
|
@ -239,7 +241,7 @@ function handleNewChannel(req, res) {
|
||||||
}
|
}
|
||||||
db.users.verifyAuth(req.cookies.auth, function (err, user) {
|
db.users.verifyAuth(req.cookies.auth, function (err, user) {
|
||||||
if (err) {
|
if (err) {
|
||||||
sendJade(res, 'account-channels', {
|
sendJade(res, "account-channels", {
|
||||||
loggedIn: false,
|
loggedIn: false,
|
||||||
channels: [],
|
channels: [],
|
||||||
newChannelError: err
|
newChannelError: err
|
||||||
|
@ -249,7 +251,7 @@ function handleNewChannel(req, res) {
|
||||||
|
|
||||||
db.channels.register(name, user.name, function (err, channel) {
|
db.channels.register(name, user.name, function (err, channel) {
|
||||||
db.channels.listUserChannels(loginName, function (err2, channels) {
|
db.channels.listUserChannels(loginName, function (err2, channels) {
|
||||||
sendJade(res, 'account-channels', {
|
sendJade(res, "account-channels", {
|
||||||
loggedIn: true,
|
loggedIn: true,
|
||||||
loginName: loginName,
|
loginName: loginName,
|
||||||
channels: err2 ? [] : channels,
|
channels: err2 ? [] : channels,
|
||||||
|
@ -267,16 +269,16 @@ function handleDeleteChannel(req, res) {
|
||||||
logRequest(req);
|
logRequest(req);
|
||||||
|
|
||||||
var name = req.body.name;
|
var name = req.body.name;
|
||||||
if (typeof name !== 'string') {
|
if (typeof name !== "string") {
|
||||||
res.send(400);
|
res.send(400);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var loginName = false;
|
var loginName = false;
|
||||||
if (req.cookies.auth) {
|
if (req.cookies.auth) {
|
||||||
loginName = req.cookies.auth.split(':')[0];
|
loginName = req.cookies.auth.split(":")[0];
|
||||||
} else {
|
} else {
|
||||||
sendJade(res, 'account-channels', {
|
sendJade(res, "account-channels", {
|
||||||
loggedIn: false,
|
loggedIn: false,
|
||||||
channels: [],
|
channels: [],
|
||||||
});
|
});
|
||||||
|
@ -284,7 +286,7 @@ function handleDeleteChannel(req, res) {
|
||||||
}
|
}
|
||||||
db.users.verifyAuth(req.cookies.auth, function (err, user) {
|
db.users.verifyAuth(req.cookies.auth, function (err, user) {
|
||||||
if (err) {
|
if (err) {
|
||||||
sendJade(res, 'account-channels', {
|
sendJade(res, "account-channels", {
|
||||||
loggedIn: false,
|
loggedIn: false,
|
||||||
channels: [],
|
channels: [],
|
||||||
deleteChannelError: err
|
deleteChannelError: err
|
||||||
|
@ -295,18 +297,18 @@ function handleDeleteChannel(req, res) {
|
||||||
db.channels.lookup(name, function (err, channel) {
|
db.channels.lookup(name, function (err, channel) {
|
||||||
if (channel.owner !== user.name && user.global_rank < 255) {
|
if (channel.owner !== user.name && user.global_rank < 255) {
|
||||||
db.channels.listUserChannels(loginName, function (err2, channels) {
|
db.channels.listUserChannels(loginName, function (err2, channels) {
|
||||||
sendJade(res, 'account-channels', {
|
sendJade(res, "account-channels", {
|
||||||
loggedIn: true,
|
loggedIn: true,
|
||||||
loginName: loginName,
|
loginName: loginName,
|
||||||
channels: err2 ? [] : channels,
|
channels: err2 ? [] : channels,
|
||||||
deleteChannelError: 'You do not have permission to delete this channel'
|
deleteChannelError: "You do not have permission to delete this channel"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
db.channels.drop(name, function (err) {
|
db.channels.drop(name, function (err) {
|
||||||
db.channels.listUserChannels(loginName, function (err2, channels) {
|
db.channels.listUserChannels(loginName, function (err2, channels) {
|
||||||
sendJade(res, 'account-channels', {
|
sendJade(res, "account-channels", {
|
||||||
loggedIn: true,
|
loggedIn: true,
|
||||||
loginName: loginName,
|
loginName: loginName,
|
||||||
channels: err2 ? [] : channels,
|
channels: err2 ? [] : channels,
|
||||||
|
@ -330,29 +332,29 @@ function handleAccountProfilePage(req, res) {
|
||||||
|
|
||||||
var loginName = false;
|
var loginName = false;
|
||||||
if (req.cookies.auth) {
|
if (req.cookies.auth) {
|
||||||
loginName = req.cookies.auth.split(':')[0];
|
loginName = req.cookies.auth.split(":")[0];
|
||||||
} else {
|
} else {
|
||||||
sendJade(res, 'account-profile', {
|
sendJade(res, "account-profile", {
|
||||||
loggedIn: false,
|
loggedIn: false,
|
||||||
profileImage: '',
|
profileImage: "",
|
||||||
profileText: ''
|
profileText: ""
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
db.users.getProfile(loginName, function (err, profile) {
|
db.users.getProfile(loginName, function (err, profile) {
|
||||||
if (err) {
|
if (err) {
|
||||||
sendJade(res, 'account-profile', {
|
sendJade(res, "account-profile", {
|
||||||
loggedIn: true,
|
loggedIn: true,
|
||||||
loginName: loginName,
|
loginName: loginName,
|
||||||
profileError: err,
|
profileError: err,
|
||||||
profileImage: '',
|
profileImage: "",
|
||||||
profileText: ''
|
profileText: ""
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendJade(res, 'account-profile', {
|
sendJade(res, "account-profile", {
|
||||||
loggedIn: true,
|
loggedIn: true,
|
||||||
loginName: loginName,
|
loginName: loginName,
|
||||||
profileImage: profile.image,
|
profileImage: profile.image,
|
||||||
|
@ -370,9 +372,9 @@ function handleAccountProfile(req, res) {
|
||||||
|
|
||||||
var loginName = false;
|
var loginName = false;
|
||||||
if (req.cookies.auth) {
|
if (req.cookies.auth) {
|
||||||
loginName = req.cookies.auth.split(':')[0];
|
loginName = req.cookies.auth.split(":")[0];
|
||||||
} else {
|
} else {
|
||||||
sendJade(res, 'account-profile', {
|
sendJade(res, "account-profile", {
|
||||||
loggedIn: false,
|
loggedIn: false,
|
||||||
profileImage: "",
|
profileImage: "",
|
||||||
profileText: "",
|
profileText: "",
|
||||||
|
@ -386,7 +388,7 @@ function handleAccountProfile(req, res) {
|
||||||
|
|
||||||
db.users.verifyAuth(req.cookies.auth, function (err, user) {
|
db.users.verifyAuth(req.cookies.auth, function (err, user) {
|
||||||
if (err) {
|
if (err) {
|
||||||
sendJade(res, 'account-profile', {
|
sendJade(res, "account-profile", {
|
||||||
loggedIn: false,
|
loggedIn: false,
|
||||||
profileImage: "",
|
profileImage: "",
|
||||||
profileText: "",
|
profileText: "",
|
||||||
|
@ -397,7 +399,7 @@ function handleAccountProfile(req, res) {
|
||||||
|
|
||||||
db.users.setProfile(user.name, { image: image, text: text }, function (err) {
|
db.users.setProfile(user.name, { image: image, text: text }, function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
sendJade(res, 'account-profile', {
|
sendJade(res, "account-profile", {
|
||||||
loggedIn: true,
|
loggedIn: true,
|
||||||
loginName: user.name,
|
loginName: user.name,
|
||||||
profileImage: "",
|
profileImage: "",
|
||||||
|
@ -407,7 +409,7 @@ function handleAccountProfile(req, res) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendJade(res, 'account-profile', {
|
sendJade(res, "account-profile", {
|
||||||
loggedIn: true,
|
loggedIn: true,
|
||||||
loginName: user.name,
|
loginName: user.name,
|
||||||
profileImage: image,
|
profileImage: image,
|
||||||
|
@ -436,7 +438,7 @@ function handlePasswordResetPage(req, res) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a POST request to reset a user's password
|
* Handles a POST request to reset a user"s password
|
||||||
*/
|
*/
|
||||||
function handlePasswordReset(req, res) {
|
function handlePasswordReset(req, res) {
|
||||||
logRequest(req);
|
logRequest(req);
|
||||||
|
@ -485,11 +487,119 @@ function handlePasswordReset(req, res) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hash = $util.sha1($util.randomSalt(64));
|
||||||
|
// 24-hour expiration
|
||||||
|
var expire = Date.now() + 86400000;
|
||||||
|
var ip = webserver.ipForRequest(req);
|
||||||
|
|
||||||
|
db.addPasswordReset({
|
||||||
|
ip: ip,
|
||||||
|
name: name,
|
||||||
|
email: email,
|
||||||
|
hash: hash,
|
||||||
|
expire: expire
|
||||||
|
}, function (err, dbres) {
|
||||||
|
if (err) {
|
||||||
|
sendJade(res, "account-passwordreset", {
|
||||||
|
reset: false,
|
||||||
|
resetEmail: "",
|
||||||
|
resetErr: err
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Config.get("mail.enabled")) {
|
||||||
|
sendJade(res, "account-passwordreset", {
|
||||||
|
reset: false,
|
||||||
|
resetEmail: email,
|
||||||
|
resetErr: "This server does not have mail support enabled. Please " +
|
||||||
|
"contact an administrator for assistance."
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var msg = "A password reset request was issued for your " +
|
||||||
|
"account `"+ name + "` on " + Config.get("http.domain") +
|
||||||
|
". This request is valid for 24 hours. If you did "+
|
||||||
|
"not initiate this, there is no need to take action."+
|
||||||
|
" To reset your password, copy and paste the " +
|
||||||
|
"following link into your browser: " +
|
||||||
|
Config.get("http.domain") + "/passwordrecover/"+hash;
|
||||||
|
|
||||||
|
var mail = {
|
||||||
|
from: "CyTube Services <" + Config.get("mail.from") + ">",
|
||||||
|
to: email,
|
||||||
|
subject: "Password reset request",
|
||||||
|
text: msg
|
||||||
|
};
|
||||||
|
|
||||||
|
Config.get("nodemailer").sendMail(mail, function (err, response) {
|
||||||
|
if (err) {
|
||||||
|
Logger.errlog.log("mail fail: " + err);
|
||||||
|
sendJade(res, "account-passwordreset", {
|
||||||
|
reset: false,
|
||||||
|
resetEmail: user.email,
|
||||||
|
resetErr: "Sending reset email failed. Please contact an " +
|
||||||
|
"administrator for assistance."
|
||||||
|
});
|
||||||
|
} else {
|
||||||
sendJade(res, "account-passwordreset", {
|
sendJade(res, "account-passwordreset", {
|
||||||
reset: true,
|
reset: true,
|
||||||
resetEmail: user.email,
|
resetEmail: user.email,
|
||||||
resetErr: false
|
resetErr: false
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a request for /passwordreceover/<hash>
|
||||||
|
*/
|
||||||
|
function handlePasswordRecover(req, res) {
|
||||||
|
var hash = req.query.hash;
|
||||||
|
if (typeof hash !== "string") {
|
||||||
|
res.send(400);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ip = webserver.ipForRequest(req);
|
||||||
|
|
||||||
|
db.lookupPasswordReset(hash, function (err, row) {
|
||||||
|
if (err) {
|
||||||
|
sendJade(req, "account-passwordrecover", {
|
||||||
|
recovered: false,
|
||||||
|
recoverErr: err,
|
||||||
|
loginName: false
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (row.ip && row.ip !== ip) {
|
||||||
|
sendJade(req, "account-passwordrecover", {
|
||||||
|
recovered: false,
|
||||||
|
recoverErr: "Your IP address does not match the address " +
|
||||||
|
"used to submit the reset request. For your " +
|
||||||
|
"security, only the IP which initiates the reset " +
|
||||||
|
"may reclaim an account.",
|
||||||
|
loginName: false
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Date.now() >= row.expire) {
|
||||||
|
sendJade(req, "account-passwordrecover", {
|
||||||
|
recovered: false,
|
||||||
|
recoverErr: "This password recovery link has expired. Password " +
|
||||||
|
"recovery links are valid only for 24 hours after " +
|
||||||
|
"submission.",
|
||||||
|
loginName: false
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO actual reset
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,12 +608,12 @@ module.exports = {
|
||||||
* Initialize the module
|
* Initialize the module
|
||||||
*/
|
*/
|
||||||
init: function (app) {
|
init: function (app) {
|
||||||
app.get('/account/edit', handleAccountEditPage);
|
app.get("/account/edit", handleAccountEditPage);
|
||||||
app.post('/account/edit', handleAccountEdit);
|
app.post("/account/edit", handleAccountEdit);
|
||||||
app.get('/account/channels', handleAccountChannelPage);
|
app.get("/account/channels", handleAccountChannelPage);
|
||||||
app.post('/account/channels', handleAccountChannel);
|
app.post("/account/channels", handleAccountChannel);
|
||||||
app.get('/account/profile', handleAccountProfilePage);
|
app.get("/account/profile", handleAccountProfilePage);
|
||||||
app.post('/account/profile', handleAccountProfile);
|
app.post("/account/profile", handleAccountProfile);
|
||||||
app.get("/account/passwordreset", handlePasswordResetPage);
|
app.get("/account/passwordreset", handlePasswordResetPage);
|
||||||
app.post("/account/passwordreset", handlePasswordReset);
|
app.post("/account/passwordreset", handlePasswordReset);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue