Work on account channels interface; Start work on /account/profile

This commit is contained in:
calzoneman 2013-12-26 23:38:35 -05:00
parent 5fe5dd440e
commit ead38a9d35
5 changed files with 231 additions and 41 deletions

View File

@ -81,20 +81,20 @@ module.exports = {
} }
if (typeof name !== "string" || typeof pw !== "string") { if (typeof name !== "string" || typeof pw !== "string") {
callback(new Error("You must provide a nonempty username and password"), null); callback("You must provide a nonempty username and password", null);
return; return;
} }
var lname = name.toLowerCase(); var lname = name.toLowerCase();
if (registrationLock[lname]) { if (registrationLock[lname]) {
callback(new Error("There is already a registration in progress for "+name), callback("There is already a registration in progress for "+name,
null); null);
return; return;
} }
if (!$util.isValidUserName(name)) { if (!$util.isValidUserName(name)) {
callback(new Error("Invalid username. Usernames may consist of 1-20 " + callback("Invalid username. Usernames may consist of 1-20 " +
"characters a-z, A-Z, 0-9, -, _, and accented letters."), "characters a-z, A-Z, 0-9, -, _, and accented letters.",
null); null);
return; return;
} }
@ -121,7 +121,7 @@ module.exports = {
if (taken) { if (taken) {
delete registrationLock[lname]; delete registrationLock[lname];
callback(new Error("Username is already registered"), null); callback("Username is already registered", null);
return; return;
} }
@ -161,7 +161,7 @@ module.exports = {
} }
if (typeof name !== "string" || typeof pw !== "string") { if (typeof name !== "string" || typeof pw !== "string") {
callback(new Error("Invalid username/password combination"), null); callback("Invalid username/password combination", null);
return; return;
} }
@ -185,7 +185,7 @@ module.exports = {
} }
if (rows.length === 0) { if (rows.length === 0) {
callback(new Error("User does not exist"), null); callback("User does not exist", null);
return; return;
} }
@ -193,7 +193,7 @@ module.exports = {
if (err) { if (err) {
callback(err, null); callback(err, null);
} else if (!match) { } else if (!match) {
callback(new Error("Invalid username/password combination"), null); callback("Invalid username/password combination", null);
} else { } else {
callback(null, { callback(null, {
name: rows[0].name, name: rows[0].name,
@ -212,15 +212,15 @@ module.exports = {
if (typeof callback !== "function") { if (typeof callback !== "function") {
return; return;
} }
if (typeof auth !== "string") { if (typeof auth !== "string") {
callback(new Error("Invalid auth string"), null); callback("Invalid auth string", null);
return; return;
} }
var split = auth.split(":"); var split = auth.split(":");
if (split.length !== 2) { if (split.length !== 2) {
callback(new Error("Invalid auth string"), null); callback("Invalid auth string", null);
return; return;
} }
@ -235,7 +235,7 @@ module.exports = {
} }
if (rows.length === 0) { if (rows.length === 0) {
callback(new Error("Auth string does not match an existing user"), null); callback("Auth string does not match an existing user", null);
return; return;
} }
@ -256,7 +256,7 @@ module.exports = {
} }
if (typeof name !== "string" || typeof pw !== "string") { if (typeof name !== "string" || typeof pw !== "string") {
callback(new Error("Invalid username/password combination"), null); callback("Invalid username/password combination", null);
return; return;
} }
@ -289,7 +289,7 @@ module.exports = {
} }
if (typeof name !== "string") { if (typeof name !== "string") {
callback(new Error("Invalid username"), null); callback("Invalid username", null);
return; return;
} }
@ -298,7 +298,7 @@ module.exports = {
if (err) { if (err) {
callback(err, null); callback(err, null);
} else if (rows.length === 0) { } else if (rows.length === 0) {
callback(new Error("User does not exist"), null); callback("User does not exist", null);
} else { } else {
callback(null, rows[0].global_rank); callback(null, rows[0].global_rank);
} }
@ -314,12 +314,12 @@ module.exports = {
} }
if (typeof name !== "string") { if (typeof name !== "string") {
callback(new Error("Invalid username"), null); callback("Invalid username", null);
return; return;
} }
if (typeof rank !== "number") { if (typeof rank !== "number") {
callback(new Error("Invalid rank"), null); callback("Invalid rank", null);
return; return;
} }
@ -338,7 +338,7 @@ module.exports = {
} }
if (!(names instanceof Array)) { if (!(names instanceof Array)) {
callback(new Error("Expected array of names, got " + typeof names), null); callback("Expected array of names, got " + typeof names, null);
return; return;
} }
@ -365,7 +365,7 @@ module.exports = {
} }
if (typeof name !== "string") { if (typeof name !== "string") {
callback(new Error("Invalid username"), null); callback("Invalid username", null);
return; return;
} }
@ -374,7 +374,7 @@ module.exports = {
if (err) { if (err) {
callback(err, null); callback(err, null);
} else if (rows.length === 0) { } else if (rows.length === 0) {
callback(new Error("User does not exist"), null); callback("User does not exist", null);
} else { } else {
callback(null, rows[0].email); callback(null, rows[0].email);
} }
@ -390,12 +390,12 @@ module.exports = {
} }
if (typeof name !== "string") { if (typeof name !== "string") {
callback(new Error("Invalid username"), null); callback("Invalid username", null);
return; return;
} }
if (typeof email !== "string") { if (typeof email !== "string") {
callback(new Error("Invalid email"), null); callback("Invalid email", null);
return; return;
} }
@ -414,7 +414,7 @@ module.exports = {
} }
if (typeof name !== "string") { if (typeof name !== "string") {
callback(new Error("Invalid username"), null); callback("Invalid username", null);
return; return;
} }
@ -423,12 +423,18 @@ module.exports = {
if (err) { if (err) {
callback(err, null); callback(err, null);
} else if (rows.length === 0) { } else if (rows.length === 0) {
callback(new Error("User does not exist"), null); callback("User does not exist", null);
} else { } else {
var userprof = { var userprof = {
image: "", image: "",
text: "" text: ""
}; };
if (rows[0].profile === "") {
callback(null, userprof);
return;
}
try { try {
var profile = JSON.parse(rows[0].profile); var profile = JSON.parse(rows[0].profile);
userprof.image = profile.image || ""; userprof.image = profile.image || "";
@ -450,12 +456,12 @@ module.exports = {
} }
if (typeof name !== "string") { if (typeof name !== "string") {
callback(new Error("Invalid username"), null); callback("Invalid username", null);
return; return;
} }
if (typeof profile !== "object") { if (typeof profile !== "object") {
callback(new Error("Invalid profile"), null); callback("Invalid profile", null);
return; return;
} }
@ -484,7 +490,7 @@ module.exports = {
return; return;
} }
callback(new Error("generatePasswordReset is not implemented"), null); callback("generatePasswordReset is not implemented", null);
}, },
recoverPassword: function (hash, callback) { recoverPassword: function (hash, callback) {
@ -492,7 +498,7 @@ module.exports = {
return; return;
} }
callback(new Error("recoverPassword is not implemented"), null); callback("recoverPassword is not implemented", null);
}, },
/** /**

View File

@ -4,7 +4,7 @@ var valid = require("../utilities").isValidChannelName;
var blackHole = function () { }; var blackHole = function () { };
function dropTable(name, callback) { function dropTable(name, callback) {
db.query("DROP TABLE `" + name + "`"); db.query("DROP TABLE `" + name + "`", callback);
} }
function createRanksTable(name, callback) { function createRanksTable(name, callback) {
@ -116,7 +116,7 @@ module.exports = {
return; return;
} }
if (!valid(chan)) { if (!valid(name)) {
callback("Invalid channel name", null); callback("Invalid channel name", null);
return; return;
} }
@ -128,7 +128,12 @@ module.exports = {
callback(err, null); callback(err, null);
return; return;
} }
callback(null, rows);
if (rows.length === 0) {
callback("No such channel", null);
} else {
callback(null, rows[0]);
}
}); });
}, },
@ -212,7 +217,7 @@ module.exports = {
callback = blackHole; callback = blackHole;
} }
if (!valid(chan)) { if (!valid(name)) {
callback("Invalid channel name", null); callback("Invalid channel name", null);
return; return;
} }

View File

@ -167,15 +167,14 @@ function handleChangeEmail(req, res) {
* Handles a GET request for /account/channels * Handles a GET request for /account/channels
*/ */
function handleAccountChannelPage(req, res) { function handleAccountChannelPage(req, res) {
res.send(500);
return;
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) {
dbchannels.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,
@ -194,8 +193,6 @@ 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) {
res.send(500);
return;
logRequest(req); logRequest(req);
var action = req.body.action; var action = req.body.action;
switch(action) { switch(action) {
@ -215,26 +212,162 @@ function handleAccountChannel(req, res) {
* Handles a request to register a new channel * Handles a request to register a new channel
*/ */
function handleNewChannel(req, res) { function handleNewChannel(req, res) {
res.send(500); logRequest(req);
var name = req.body.name;
if (typeof name !== 'string') {
res.send(400);
return;
}
var loginName = false;
if (req.cookies.auth) {
loginName = req.cookies.auth.split(':')[0];
} else {
sendJade(res, 'account-channels', {
loggedIn: false,
channels: []
});
return;
}
db.users.verifyAuth(req.cookies.auth, function (err, user) {
if (err) {
sendJade(res, 'account-channels', {
loggedIn: false,
channels: [],
newChannelError: err
});
return;
}
db.channels.register(name, user.name, function (err, channel) {
db.channels.listUserChannels(loginName, function (err2, channels) {
sendJade(res, 'account-channels', {
loggedIn: true,
loginName: loginName,
channels: err2 ? [] : channels,
newChannelError: err ? err : undefined
});
});
});
});
} }
/** /**
* Handles a request to delete a new channel * Handles a request to delete a new channel
*/ */
function handleDeleteChannel(req, res) { function handleDeleteChannel(req, res) {
logRequest(req);
var name = req.body.name;
if (typeof name !== 'string') {
res.send(400);
return;
}
var loginName = false;
if (req.cookies.auth) {
loginName = req.cookies.auth.split(':')[0];
} else {
sendJade(res, 'account-channels', {
loggedIn: false,
channels: [],
});
return;
}
db.users.verifyAuth(req.cookies.auth, function (err, user) {
if (err) {
sendJade(res, 'account-channels', {
loggedIn: false,
channels: [],
deleteChannelError: err
});
return;
}
db.channels.lookup(name, function (err, channel) {
if (channel.owner !== user.name && user.global_rank < 255) {
db.channels.listUserChannels(loginName, function (err2, channels) {
sendJade(res, 'account-channels', {
loggedIn: true,
loginName: loginName,
channels: err2 ? [] : channels,
deleteChannelError: 'You do not have permission to delete this channel'
});
});
return;
}
db.channels.drop(name, function (err) {
db.channels.listUserChannels(loginName, function (err2, channels) {
sendJade(res, 'account-channels', {
loggedIn: true,
loginName: loginName,
channels: err2 ? [] : channels,
deleteChannelError: err ? err : undefined
});
});
});
});
});
}
/**
* Handles a GET request for /account/profile
*/
function handleAccountProfilePage(req, res) {
logRequest(req);
var loginName = false;
if (req.cookies.auth) {
loginName = req.cookies.auth.split(':')[0];
} else {
sendJade(res, 'account-profile', {
loggedIn: false,
profileImage: '',
profileText: ''
});
return;
}
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
});
});
}
/**
* Handles a POST request to edit a profile
*/
function handleAccountProfile(req, res) {
res.send(500); res.send(500);
} }
module.exports = { module.exports = {
/** /**
* Initializes the module * Initialize the module
*
* @param app - The Express server to initialize
*/ */
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.post('/account/profile', handleAccountProfile);
} }
}; };

View File

@ -40,6 +40,7 @@ html(lang="en")
th th
form.form-inline.pull-right(action="/account/channels", method="post", onsubmit="return confirm('Are you sure you want to delete #{c.name}? This cannot be undone');") form.form-inline.pull-right(action="/account/channels", method="post", onsubmit="return confirm('Are you sure you want to delete #{c.name}? This cannot be undone');")
input(type="hidden", name="action", value="delete_channel") input(type="hidden", name="action", value="delete_channel")
input(type="hidden", name="name", value="#{c.name}")
button.btn.btn-xs.btn-danger(type="submit") Delete button.btn.btn-xs.btn-danger(type="submit") Delete
span.glyphicon.glyphicon-trash span.glyphicon.glyphicon-trash
a(href="/r/#{c.name}", style="margin-left: 5px")= c.name a(href="/r/#{c.name}", style="margin-left: 5px")= c.name

View File

@ -0,0 +1,45 @@
doctype html
html(lang="en")
head
include head
mixin head()
body
#wrap
nav.navbar.navbar-inverse.navbar-fixed-top(role="navigation")
include nav
mixin navheader()
#nav-collapsible.collapse.navbar-collapse
ul.nav.navbar-nav
mixin navdefaultlinks("/account/profile")
mixin navloginlogout("/account/profile")
section#mainpage
.container
if !loggedIn
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
.alert.alert-danger.messagebox.center
strong Authorization Required
p You must be <a href="/login">logged in</a> to view this page.
else
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
h3 Profile
if profileError
.alert.alert-danger.center.messagebox
strong Profile Error
p= profileError
.media
a.pull-left(href="#")
img.media-object(src=profileImage, alt="Profile Image")
.media-body
= profileText
h3 Edit Profile
form(action="/account/profile", method="post", role="form")
.form-group
label.control-label(for="profileimage") Image
input#profileimage.form-control(type="text", name="image")
.form-group
label.control-label(for="profiletext") Text
textarea#profiletext.form-control(cols="10")
button.btn.btn-primary.btn-block(type="submit") Save
include footer
mixin footer()