diff --git a/api.js b/api.js
index 1bae1ba5..eb0fb3f9 100644
--- a/api.js
+++ b/api.js
@@ -26,6 +26,7 @@ var jsonHandlers = {
"login" : handleLogin,
"register" : handleRegister,
"changepass" : handlePasswordChange,
+ "setemail" : handleEmailChange,
"globalbans" : handleGlobalBans,
"admreports" : handleAdmReports,
"pwreset" : handlePasswordReset
@@ -194,7 +195,7 @@ function handleLogin(params, req, res) {
}
else {
sendJSON(res, {
- error: "Invalid session",
+ error: "Invalid username/password",
success: false
});
}
@@ -216,13 +217,58 @@ function handlePasswordChange(params, req, res) {
var success = Auth.setUserPassword(name, newpw);
sendJSON(res, {
success: success,
- error: success ? "" : "Change password failed"
+ error: success ? "" : "Change password failed",
+ session: row.session_hash
});
}
else {
sendJSON(res, {
success: false,
- error: "Invalid username or password"
+ error: "Invalid username/password"
+ });
+ }
+}
+
+function handleEmailChange(params, req, res) {
+ var name = params.name || "";
+ var pw = params.pw || "";
+ var email = unescape(params.email) || "";
+ if(!email.match(/^[a-z0-9_\.]+@[a-z0-9_\.]+[a-z]+$/)) {
+ sendJSON(res, {
+ success: false,
+ error: "Invalid email"
+ });
+ return;
+ }
+
+ if(email.match(/.*@(localhost|127\.0\.0\.1)/i)) {
+ sendJSON(res, {
+ success: false,
+ error: "Nice try, but no."
+ });
+ return;
+ }
+
+ if(pw == "") {
+ sendJSON(res, {
+ success: false,
+ error: "Password cannot be empty"
+ });
+ return;
+ }
+ var row = Auth.login(name, pw);
+ if(row) {
+ var success = Database.setUserEmail(name, email);
+ sendJSON(res, {
+ success: success,
+ error: success ? "" : "Email update failed",
+ session: row.session_hash
+ });
+ }
+ else {
+ sendJSON(res, {
+ success: false,
+ error: "Invalid username/password"
});
}
}
diff --git a/database.js b/database.js
index d4dffeae..9eafcb52 100644
--- a/database.js
+++ b/database.js
@@ -574,6 +574,25 @@ function setProfile(name, data) {
return db.querySync(query);
}
+function setUserEmail(name, email) {
+ var db = getConnection();
+ if(!db) {
+ return false;
+ }
+
+ var query = createQuery(
+ "UPDATE `registrations` SET `email`=? WHERE `uname`=?",
+ [email, name]
+ );
+
+ var results = db.querySync(query);
+ if(!results) {
+ Logger.errlog.log("! Failed to set user email");
+ return false;
+ }
+ return true;
+}
+
function generatePasswordReset(ip, name, email) {
var db = getConnection();
if(!db) {
@@ -663,5 +682,6 @@ exports.channelBan = channelBan;
exports.channelUnbanIP = channelUnbanIP;
exports.channelUnbanName = channelUnbanName;
exports.setProfile = setProfile;
+exports.setUserEmail = setUserEmail;
exports.generatePasswordReset = generatePasswordReset;
exports.resetPassword = resetPassword;
diff --git a/www/account.html b/www/account.html
new file mode 100644
index 00000000..c170d69a
--- /dev/null
+++ b/www/account.html
@@ -0,0 +1,187 @@
+
+
+
+
+ CyTube
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Register New Account
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/www/assets/js/account.js b/www/assets/js/account.js
new file mode 100644
index 00000000..e56f13d3
--- /dev/null
+++ b/www/assets/js/account.js
@@ -0,0 +1,269 @@
+var uname = readCookie("sync_uname") || "";
+var session = readCookie("sync_session") || "";
+var api = WEB_URL + "/api/json/";
+var loggedin = false;
+
+if(uname && session) {
+ var loginstr = "name=" + uname + "&session=" + session;
+ var url = api + "login?" + loginstr + "&callback=?";
+ $.getJSON(url, function(data) {
+ if(data.success) {
+ onLogin();
+ }
+ });
+}
+
+function onLogin() {
+ $("#cpwusername").val(uname);
+ $("#ceusername").val(uname);
+ $("#accountnav li")[0].innerHTML = "Logged in as " + uname;
+ $("#register").hide();
+ loggedin = true;
+ $("#login").text("Logout");
+ createCookie("sync_uname", uname, 7);
+ createCookie("sync_session", session, 7);
+}
+
+function makeTabCallback(tabid, paneid) {
+ return function() {
+ $("#accountnav li").each(function() {
+ $(this).removeClass("active");
+ });
+
+ $(tabid).parent().addClass("active");
+ $(".span7").each(function() {
+ $(this).css("display", "none");
+ });
+ $(paneid).css("display", "");
+ };
+}
+
+$("#register").click(makeTabCallback("#register", "#registerpane"));
+$("#pwchange").click(makeTabCallback("#pwchange", "#changepwpane"));
+$("#email").click(makeTabCallback("#email", "#changeemailpane"));
+
+$("#registerbtn").click(function() {
+ $("#registerpane").find(".alert-error").remove();
+ $("#registerpane").find(".error").removeClass("error");
+ var uname = $("#regusername").val();
+ var pw = $("#regpw").val();
+ var pwc = $("#regpwconfirm").val();
+
+ var err = false;
+ if(!uname.match(/^[a-z0-9_]{1,20}$/i)) {
+ $("").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());
+ err = true;
+ }
+
+ if(pw == "") {
+ $("").addClass("alert alert-error")
+ .text("Password must not be blank")
+ .insertAfter($("#regpw").parent().parent());
+ $("#regpw").parent().parent().addClass("error");
+ err = true;
+ }
+
+ if(pw != pwc) {
+ $("").addClass("alert alert-error")
+ .text("Passwords do not match")
+ .insertAfter($("#regpwconfirm").parent().parent());
+ $("#regpwconfirm").parent().parent().addClass("error");
+ err = true;
+ }
+
+ if(err) {
+ return;
+ }
+
+ // Input valid, try registering
+});
+
+$("#loginbtn").click(function() {
+ $("#loginpane").find(".alert-error").remove();
+ $("#loginpane").find(".alert-success").remove();
+
+ if($("#loginpw").val() == "") {
+ $("").addClass("alert alert-error")
+ .text("Please provide a password")
+ .insertAfter($("#loginpw").parent().parent());
+ $("#loginpw").parent().parent().addClass("error");
+ return;
+ }
+ uname = $("#loginusername").val();
+ var loginstr = "name=" + uname + "&pw=" + $("#loginpw").val();
+ var url = api + "login?" + loginstr + "&callback=?";
+ $.getJSON(url, function(data) {
+ if(data.success) {
+ session = data.session;
+ onLogin();
+ $("").addClass("alert alert-success")
+ .text("Login successful")
+ .insertBefore($("#loginpane form"));
+ $("#loginpw").val("");
+ $("#loginusername").val("");
+ }
+ else {
+ $("").addClass("alert alert-error")
+ .text(data.error)
+ .insertBefore($("#loginpane form"));
+ }
+ });
+});
+
+$("#cpwbtn").click(function() {
+ $("#changepwpane").find(".alert-error").remove();
+ $("#changepwpane").find(".alert-success").remove();
+ $("#changepwpane").find(".error").removeClass("error");
+ var name = $("#cpwusername").val();
+ var oldpw = $("#cpwoldpw").val();
+ var newpw = $("#cpwnewpw").val();
+ var newpwc = $("#cpwconfirm").val();
+
+ var err = false;
+ if(oldpw == "") {
+ $("").addClass("alert alert-error")
+ .text("Password must not be empty")
+ .insertAfter($("#cpwoldpw").parent().parent());
+ $("#cpwoldpw").parent().parent().addClass("error");
+ err = true;
+ }
+
+ if(newpw == "") {
+ $("").addClass("alert alert-error")
+ .text("Password must not be empty")
+ .insertAfter($("#cpwnewpw").parent().parent());
+ $("#cpwnewpw").parent().parent().addClass("error");
+ err = true;
+ }
+
+ if(newpw != newpwc) {
+ $("").addClass("alert alert-error")
+ .text("Passwords do not match")
+ .insertAfter($("#cpwconfirm").parent().parent());
+ $("#cpwconfirm").parent().parent().addClass("error");
+ err = true;
+ }
+
+ if(err) {
+ return;
+ }
+
+ // Input valid, try changing password
+ var url = api + "changepass?" + [
+ "name=" + name,
+ "oldpw=" + oldpw,
+ "newpw=" + newpw
+ ].join("&") + "&callback=?";
+ $.getJSON(url, function(data) {
+ if(data.success) {
+ $("").addClass("alert alert-success")
+ .text("Password changed.")
+ .insertBefore($("#changepwpane form"));
+ uname = name;
+ session = data.session;
+ onLogin();
+ }
+ else {
+ $("").addClass("alert alert-error")
+ .text(data.error)
+ .insertBefore($("#changepwpane form"));
+ }
+ });
+});
+
+$("#cebtn").click(function() {
+ $("#changeemailpane").find(".alert-error").remove();
+ $("#changeemailpane").find(".alert-success").remove();
+ var name = $("#ceusername").val();
+ var pw = $("#cepw").val();
+ var email = $("#ceemail").val();
+ if(pw == "") {
+ $("").addClass("alert alert-error")
+ .text("Please provide a password")
+ .insertAfter($("#cepw").parent().parent());
+ $("#cepw").parent().parent().addClass("error");
+ return;
+ }
+
+ if(!email.match(/^[a-z0-9_\.]+@[a-z0-9_\.]+[a-z]+$/)) {
+ $("").addClass("alert alert-error")
+ .text("Invalid email")
+ .insertAfter($("#ceemail").parent().parent());
+ $("#ceemail").parent().parent().addClass("error");
+ return;
+ }
+
+ if(email.match(/.*@(localhost|127\.0\.0\.1)/i)) {
+ $("").addClass("alert alert-error")
+ .text("Nice try, but no.")
+ .insertAfter($("#ceemail").parent().parent());
+ $("#ceemail").parent().parent().addClass("error");
+ return;
+ }
+
+ email = escape(email);
+ var url = api + "setemail?" + [
+ "name=" + name,
+ "pw=" + pw,
+ "email=" + email
+ ].join("&") + "&callback=?";
+ $.getJSON(url, function(data) {
+ if(data.success) {
+ $("").addClass("alert alert-success")
+ .text("Email updated")
+ .insertBefore($("#changeemailpane form"));
+ uname = name;
+ session = data.session;
+ onLogin();
+ }
+ else {
+ $("").addClass("alert alert-error")
+ .text(data.error)
+ .insertBefore($("#changeemailpane form"));
+ }
+ });
+
+});
+
+$("#login").click(function() {
+ if(!loggedin) {
+ makeTabCallback("#login", "#loginpane")();
+ }
+ else {
+ uname = "";
+ session = "";
+ eraseCookie("sync_uname");
+ eraseCookie("sync_session");
+ $("#accountnav li")[0].innerHTML = "Not Logged In";
+ $("#register").show();
+ $("#login").text("Login");
+ loggedin = false;
+ }
+});
+
+function createCookie(name,value,days) {
+ if (days) {
+ var date = new Date();
+ date.setTime(date.getTime()+(days*24*60*60*1000));
+ var expires = "; expires="+date.toGMTString();
+ }
+ else var expires = "";
+ document.cookie = name+"="+value+expires+"; path=/";
+}
+
+function readCookie(name) {
+ var nameEQ = name + "=";
+ var ca = document.cookie.split(";");
+ for(var i=0;i < ca.length;i++) {
+ var c = ca[i];
+ while (c.charAt(0)==" ") c = c.substring(1,c.length);
+ if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
+ }
+ return null;
+}
+
+function eraseCookie(name) {
+ createCookie(name,"",-1);
+}