begin working on password reset

This commit is contained in:
calzoneman 2013-05-28 11:40:06 -04:00
parent 0c0fc843d6
commit a882f598d6
3 changed files with 150 additions and 2 deletions

42
api.js
View File

@ -27,7 +27,8 @@ var jsonHandlers = {
"register" : handleRegister, "register" : handleRegister,
"changepass" : handlePasswordChange, "changepass" : handlePasswordChange,
"globalbans" : handleGlobalBans, "globalbans" : handleGlobalBans,
"admreports" : handleAdmReports "admreports" : handleAdmReports,
"pwreset" : handlePasswordReset
}; };
function handle(path, req, res) { function handle(path, req, res) {
@ -326,6 +327,45 @@ function handleAdmReports(params, req, res) {
}); });
} }
function handlePasswordReset(params, req, res) {
var name = params.name || "";
var pw = params.pw || "";
var session = params.session || "";
var row = Auth.login(name, pw, session);
if(!row || row.global_rank < 255) {
res.send(403);
return;
}
var action = params.action || "";
if(action == "reset") {
var uname = params.reset_name;
if(Auth.getGlobalRank(uname) > row.global_rank) {
sendJSON(res, {
success: false
});
return;
}
var new_pw = Database.resetPassword(uname);
if(new_pw) {
sendJSON(res, {
success: true,
pw: new_pw
});
}
else {
sendJSON(res, {
success: false
});
}
}
else {
sendJSON(res, {
success: false
});
}
}
// Helper function // Helper function
function pipeLast(res, file, len) { function pipeLast(res, file, len) {
fs.stat(file, function(err, data) { fs.stat(file, function(err, data) {

View File

@ -1,6 +1,7 @@
var mysql = require("mysql-libmysqlclient"); var mysql = require("mysql-libmysqlclient");
var Logger = require("./logger"); var Logger = require("./logger");
var Media = require("./media").Media; var Media = require("./media").Media;
var bcrypt = require("bcrypt");
var db = false; var db = false;
var SERVER = ""; var SERVER = "";
@ -106,6 +107,21 @@ function init() {
} }
refreshGlobalBans(); refreshGlobalBans();
// Create password reset table
query = ["CREATE TABLE IF NOT EXISTS `password_reset` (",
"`ip` VARCHAR(15) NOT NULL,",
"`name` VARCHAR(20) NOT NULL,",
"`hash` VARCHAR(64) NOT NULL,",
"`email` VARCHAR(255) NOT NULL,",
"`expire` BIGINT NOT NULL,",
"PRIMARY KEY (`name`))",
"ENGINE = MyISAM;"].join("");
results = db.querySync(query);
if(!results) {
Logger.errlog.log("! Failed to create password reset table");
}
} }
/* REGION Global Bans */ /* REGION Global Bans */
@ -558,6 +574,75 @@ function setProfile(name, data) {
return db.querySync(query); return db.querySync(query);
} }
function generatePasswordReset(ip, name, email) {
var db = getConnection();
if(!db) {
return false;
}
var query = createQuery(
"SELECT `email` FROM `registrations` WHERE `uname`=?",
[name]
);
var results = db.querySync(query);
if(!results) {
Logger.errlog.log("! Failed to retrieve user email");
return false;
}
var rows = results.fetchAllSync();
if(rows.length == 0) {
throw "Provided username does not exist";
}
if(rows[0].email != email) {
throw "Provided email does not match user's email";
}
// Validation complete, now time to reset it
var hash = hashlib.sha256(Date.now() + name);
query = createQuery(
["INSERT INTO `password_reset` (",
"`ip`, `name`, `hash`, `email`, `expire",
") VALUES (",
"?, ?, ?, ?, ?",
")"].join(""),
[ip, name, hash, email, Date.now() + 24*60*60]
);
results = db.querySync(query);
if(!results) {
Logger.errlog.log("! Failed to insert password reset");
return false;
}
return true;
}
function resetPassword(name) {
var db = getConnection();
if(!db) {
return false;
}
var pw = "";
for(var i = 0; i < 10; i++) {
pw += "abcdefghijklmnopqrstuvwxyz"[parseInt(Math.random() * 25)];
}
var hash = bcrypt.hashSync(pw, 10);
var query = createQuery(
"UPDATE `registrations` SET `pw`=? WHERE `uname`=?",
[hash, name]
);
var results = db.querySync(query);
if(!results) {
return false;
}
return pw;
}
exports.setup = setup; exports.setup = setup;
exports.getConnection = getConnection; exports.getConnection = getConnection;
exports.createQuery = createQuery; exports.createQuery = createQuery;
@ -578,3 +663,5 @@ exports.channelBan = channelBan;
exports.channelUnbanIP = channelUnbanIP; exports.channelUnbanIP = channelUnbanIP;
exports.channelUnbanName = channelUnbanName; exports.channelUnbanName = channelUnbanName;
exports.setProfile = setProfile; exports.setProfile = setProfile;
exports.generatePasswordReset = generatePasswordReset;
exports.resetPassword = resetPassword;

View File

@ -75,6 +75,15 @@
</form> </form>
<pre id="log"></pre> <pre id="log"></pre>
</div> </div>
<div class="span4">
<h3>Password Reset</h3>
<form class="form-inline" action="javascript:void(0)">
<div class="input-append">
<input type="text" id="reset_uname" placeholder="Username">
<button class="btn" id="reset_pw">Reset</button>
</div>
</form>
</div>
</div> </div>
<div class="row"> <div class="row">
<div class="span8"> <div class="span8">
@ -171,7 +180,19 @@
getChanlog(); getChanlog();
} }
}); });
$("#reset_pw").click(function() {
$.getJSON(WEB_URL+"/api/json/pwreset?action=reset&reset_name="+$("#reset_uname").val()+"&"+p+"&callback=?", function(data) {
if(data.success) {
alert("Success. New password: " + data.pw);
}
else {
alert("Failure.");
}
});
});
function loadBanlist() { function loadBanlist() {
$.getJSON(WEB_URL+"/api/json/globalbans?action=list&"+p+"&callback=?", function(data) { $.getJSON(WEB_URL+"/api/json/globalbans?action=list&"+p+"&callback=?", function(data) {
handleBanlist(data); handleBanlist(data);