mirror of https://github.com/calzoneman/sync.git
Continue work on account management and password reset
This commit is contained in:
parent
f3da02566c
commit
74203ad223
52
api.js
52
api.js
|
@ -26,10 +26,12 @@ var jsonHandlers = {
|
|||
"login" : handleLogin,
|
||||
"register" : handleRegister,
|
||||
"changepass" : handlePasswordChange,
|
||||
"resetpass" : handlePasswordReset,
|
||||
"recoverpw" : handlePasswordRecover,
|
||||
"setemail" : handleEmailChange,
|
||||
"globalbans" : handleGlobalBans,
|
||||
"admreports" : handleAdmReports,
|
||||
"pwreset" : handlePasswordReset
|
||||
"acppwreset" : handleAcpPasswordReset
|
||||
};
|
||||
|
||||
function handle(path, req, res) {
|
||||
|
@ -229,6 +231,50 @@ function handlePasswordChange(params, req, res) {
|
|||
}
|
||||
}
|
||||
|
||||
function handlePasswordReset(params, req, res) {
|
||||
var name = params.name || "";
|
||||
var email = unescape(params.email || "");
|
||||
var ip = req.socket.address().address;
|
||||
|
||||
try {
|
||||
Database.generatePasswordReset(ip, name, email);
|
||||
}
|
||||
catch(e) {
|
||||
sendJSON(res, {
|
||||
success: false,
|
||||
error: e
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
sendJSON(res, {
|
||||
success: true
|
||||
});
|
||||
}
|
||||
|
||||
function handlePasswordRecover(params, req, res) {
|
||||
var hash = params.hash || "";
|
||||
var ip = req.socket.address().address;
|
||||
|
||||
try {
|
||||
var info = Database.recoverPassword(hash);
|
||||
sendJSON(res, {
|
||||
success: true,
|
||||
name: info[0],
|
||||
pw: info[1]
|
||||
});
|
||||
Logger.syslog.log(ip + " recovered password for " + name);
|
||||
return;
|
||||
}
|
||||
catch(e) {
|
||||
sendJSON(res, {
|
||||
success: false,
|
||||
error: e
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function handleEmailChange(params, req, res) {
|
||||
var name = params.name || "";
|
||||
var pw = params.pw || "";
|
||||
|
@ -309,7 +355,7 @@ function handleRegister(params, req, res) {
|
|||
else {
|
||||
sendJSON(res, {
|
||||
success: false,
|
||||
error: "I dunno what went wrong"
|
||||
error: "Registration error. Contact an admin for assistance."
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -373,7 +419,7 @@ function handleAdmReports(params, req, res) {
|
|||
});
|
||||
}
|
||||
|
||||
function handlePasswordReset(params, req, res) {
|
||||
function handleAcpPasswordReset(params, req, res) {
|
||||
var name = params.name || "";
|
||||
var pw = params.pw || "";
|
||||
var session = params.session || "";
|
||||
|
|
2
auth.js
2
auth.js
|
@ -58,7 +58,7 @@ exports.register = function(name, pw) {
|
|||
var hash = bcrypt.hashSync(pw, 10);
|
||||
var query = Database.createQuery(
|
||||
["INSERT INTO `registrations` VALUES ",
|
||||
"(NULL, ?, ?, 1, '', 0, '', '')"].join(""),
|
||||
"(NULL, ?, ?, 1, '', 0, '', '', '')"].join(""),
|
||||
[name, hash]
|
||||
);
|
||||
var results = db.querySync(query);
|
||||
|
|
48
database.js
48
database.js
|
@ -2,6 +2,7 @@ var mysql = require("mysql-libmysqlclient");
|
|||
var Logger = require("./logger");
|
||||
var Media = require("./media").Media;
|
||||
var bcrypt = require("bcrypt");
|
||||
var hashlib = require("node_hash");
|
||||
|
||||
var db = false;
|
||||
var SERVER = "";
|
||||
|
@ -620,13 +621,14 @@ function generatePasswordReset(ip, name, email) {
|
|||
|
||||
// Validation complete, now time to reset it
|
||||
var hash = hashlib.sha256(Date.now() + name);
|
||||
var exp = Date.now() + 24*60*60*1000;
|
||||
query = createQuery(
|
||||
["INSERT INTO `password_reset` (",
|
||||
"`ip`, `name`, `hash`, `email`, `expire",
|
||||
"`ip`, `name`, `hash`, `email`, `expire`",
|
||||
") VALUES (",
|
||||
"?, ?, ?, ?, ?",
|
||||
")"].join(""),
|
||||
[ip, name, hash, email, Date.now() + 24*60*60]
|
||||
") ON DUPLICATE KEY UPDATE `expire`=?"].join(""),
|
||||
[ip, name, hash, email, exp, exp]
|
||||
);
|
||||
|
||||
results = db.querySync(query);
|
||||
|
@ -638,6 +640,45 @@ function generatePasswordReset(ip, name, email) {
|
|||
return true;
|
||||
}
|
||||
|
||||
function recoverPassword(hash) {
|
||||
var db = getConnection();
|
||||
if(!db) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var query = createQuery(
|
||||
"SELECT * FROM password_reset WHERE hash=?",
|
||||
[hash]
|
||||
);
|
||||
|
||||
var results = db.querySync(query);
|
||||
if(!results) {
|
||||
Logger.errlog.log("! Failed to retrieve from password_reset");
|
||||
throw "Database error. Contact an administrator";
|
||||
}
|
||||
|
||||
var rows = results.fetchAllSync();
|
||||
if(rows.length == 0) {
|
||||
throw "Invalid password reset link";
|
||||
}
|
||||
|
||||
db.querySync(createQuery(
|
||||
"DELETE FROM password_reset WHERE hash=?",
|
||||
[hash]
|
||||
));
|
||||
|
||||
if(Date.now() > rows[0].expire) {
|
||||
throw "Link expired. Password resets are valid for 24 hours";
|
||||
}
|
||||
|
||||
var pw;
|
||||
if(!(pw = resetPassword(rows[0].name))) {
|
||||
throw "Operation failed. Contact an administrator.";
|
||||
}
|
||||
|
||||
return [rows[0].name, pw];
|
||||
}
|
||||
|
||||
function resetPassword(name) {
|
||||
var db = getConnection();
|
||||
if(!db) {
|
||||
|
@ -684,4 +725,5 @@ exports.channelUnbanName = channelUnbanName;
|
|||
exports.setProfile = setProfile;
|
||||
exports.setUserEmail = setUserEmail;
|
||||
exports.generatePasswordReset = generatePasswordReset;
|
||||
exports.recoverPassword = recoverPassword;
|
||||
exports.resetPassword = resetPassword;
|
||||
|
|
|
@ -160,6 +160,28 @@
|
|||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="span7" id="pwresetpane" style="display: none">
|
||||
<h3>Reset Password</h3>
|
||||
<form class="form-horizontal" action="javascript:void(0)">
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="rpusername">Username</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="rpusername">
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="rpemail">Email</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="rpemail">
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<button class="btn btn-primary" id="rpbtn">Send Reset</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- /container -->
|
||||
<div class="push"></div>
|
||||
|
|
|
@ -40,17 +40,18 @@ function makeTabCallback(tabid, paneid) {
|
|||
|
||||
$("#register").click(makeTabCallback("#register", "#registerpane"));
|
||||
$("#pwchange").click(makeTabCallback("#pwchange", "#changepwpane"));
|
||||
$("#pwreset").click(makeTabCallback("#pwreset", "#pwresetpane"));
|
||||
$("#email").click(makeTabCallback("#email", "#changeemailpane"));
|
||||
|
||||
$("#registerbtn").click(function() {
|
||||
$("#registerpane").find(".alert-error").remove();
|
||||
$("#registerpane").find(".error").removeClass("error");
|
||||
var uname = $("#regusername").val();
|
||||
var name = $("#regusername").val();
|
||||
var pw = $("#regpw").val();
|
||||
var pwc = $("#regpwconfirm").val();
|
||||
|
||||
var err = false;
|
||||
if(!uname.match(/^[a-z0-9_]{1,20}$/i)) {
|
||||
if(!name.match(/^[a-z0-9_]{1,20}$/i)) {
|
||||
$("<div/>").addClass("alert alert-error")
|
||||
.text("Usernames must be 1-20 characters long and contain only a-z, 0-9, and underscores")
|
||||
.insertAfter($("#regusername").parent().parent());
|
||||
|
@ -78,6 +79,28 @@ $("#registerbtn").click(function() {
|
|||
}
|
||||
|
||||
// Input valid, try registering
|
||||
var url = api + "register?" + [
|
||||
"name=" + name,
|
||||
"pw=" + pw
|
||||
].join("&") + "&callback=?";
|
||||
|
||||
$.getJSON(url, function(data) {
|
||||
if(data.success) {
|
||||
uname = name;
|
||||
session = data.session;
|
||||
onLogin();
|
||||
$("<div/>").addClass("alert alert-success")
|
||||
.text("Registration successful")
|
||||
.insertBefore($("#registerpane form"));
|
||||
$("#regpw").val("");
|
||||
$("#regusername").val("");
|
||||
}
|
||||
else {
|
||||
$("<div/>").addClass("alert alert-error")
|
||||
.text(data.error)
|
||||
.insertBefore($("#registerpane form"));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$("#loginbtn").click(function() {
|
||||
|
@ -227,6 +250,32 @@ $("#cebtn").click(function() {
|
|||
|
||||
});
|
||||
|
||||
$("#rpbtn").click(function() {
|
||||
$("#pwresetpane").find(".alert-error").remove();
|
||||
$("#pwresetpane").find(".alert-success").remove();
|
||||
var name = $("#rpusername").val();
|
||||
var email = $("#rpemail").val();
|
||||
|
||||
email = escape(email);
|
||||
var url = api + "resetpass?" + [
|
||||
"name=" + name,
|
||||
"email=" + email
|
||||
].join("&") + "&callback=?";
|
||||
$.getJSON(url, function(data) {
|
||||
if(data.success) {
|
||||
$("<div/>").addClass("alert alert-success")
|
||||
.text("Password reset link issued. Check your email.")
|
||||
.insertBefore($("#pwresetpane form"));
|
||||
}
|
||||
else {
|
||||
$("<div/>").addClass("alert alert-error")
|
||||
.text(data.error)
|
||||
.insertBefore($("#pwresetpane form"));
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$("#login").click(function() {
|
||||
if(!loggedin) {
|
||||
makeTabCallback("#login", "#loginpane")();
|
||||
|
|
Loading…
Reference in New Issue