From bb59158bbc73b8d5a717ee9299f6e88e440f4fb8 Mon Sep 17 00:00:00 2001 From: Baris Soner Usakli Date: Tue, 11 Feb 2014 20:39:07 -0500 Subject: [PATCH] closes #721, admins can edit other users from their edit page --- public/src/forum/accountedit.js | 46 +++++---- public/src/forum/accountheader.js | 4 + public/templates/admin/users.tpl | 2 +- src/routes/user.js | 165 +++++++++++++++++++----------- src/socket.io/index.js | 16 +-- src/socket.io/user.js | 19 +++- src/user.js | 108 +++++++++---------- 7 files changed, 217 insertions(+), 143 deletions(-) diff --git a/public/src/forum/accountedit.js b/public/src/forum/accountedit.js index b9570fce7d..ce50d539ee 100644 --- a/public/src/forum/accountedit.js +++ b/public/src/forum/accountedit.js @@ -25,31 +25,35 @@ define(['forum/accountheader', 'uploader'], function(header, uploader) { }; socket.emit('user.updateProfile', userData, function(err, data) { - if (data.success) { - app.alertSuccess('Your profile has been updated successfully!'); - if (data.picture) { - $('#user-current-picture').attr('src', data.picture); - $('#user_label img').attr('src', data.picture); - } + if(err) { + return app.alertError(err.message); + } - if (data.gravatarpicture) { - $('#user-gravatar-picture').attr('src', data.gravatarpicture); - gravatarPicture = data.gravatarpicture; - } + if (!data || !data.success) { + return app.alertError('There was an error updating your profile! ' + err.message); + } - if(data.userslug) { - var oldslug = $('.account-username-box').attr('data-userslug'); - $('.account-username-box a').each(function(index) { - $(this).attr('href', $(this).attr('href').replace(oldslug, data.userslug)); - }); + app.alertSuccess('Your profile has been updated successfully!'); + if (data.picture) { + $('#user-current-picture').attr('src', data.picture); + $('#user_label img').attr('src', data.picture); + } - $('.account-username-box').attr('data-userslug', data.userslug); + if (data.gravatarpicture) { + $('#user-gravatar-picture').attr('src', data.gravatarpicture); + gravatarPicture = data.gravatarpicture; + } - $('#user-profile-link').attr('href', config.relative_path + '/user/' + data.userslug); - $('#user-profile-link span').html(' ' + userData.username); - } - } else { - app.alertError('There was an error updating your profile! ' + err.message); + if(data.userslug) { + var oldslug = $('.account-username-box').attr('data-userslug'); + $('.account-username-box a').each(function(index) { + $(this).attr('href', $(this).attr('href').replace(oldslug, data.userslug)); + }); + + $('.account-username-box').attr('data-userslug', data.userslug); + + $('#user-profile-link').attr('href', config.relative_path + '/user/' + data.userslug); + $('#user-profile-link span').html(' ' + userData.username); } }); return false; diff --git a/public/src/forum/accountheader.js b/public/src/forum/accountheader.js index ec9a6ac2e7..15c94f573e 100644 --- a/public/src/forum/accountheader.js +++ b/public/src/forum/accountheader.js @@ -45,6 +45,10 @@ define(function() { settingsLink.hide(); favouritesLink.hide(); } + + if(app.isAdmin) { + editLink.show(); + } } function selectActivePill() { diff --git a/public/templates/admin/users.tpl b/public/templates/admin/users.tpl index 4dcf4d0b85..dd178658a2 100644 --- a/public/templates/admin/users.tpl +++ b/public/templates/admin/users.tpl @@ -34,7 +34,7 @@ {users.postcount} -
+
Make Admin
diff --git a/src/routes/user.js b/src/routes/user.js index 0c8e66609c..c4dd3f573e 100644 --- a/src/routes/user.js +++ b/src/routes/user.js @@ -77,23 +77,41 @@ var fs = require('fs'), createRoute('/:userslug/favourites', '/favourites', 'favourites'); createRoute('/:userslug/posts', '/posts', 'accountposts'); - app.get('/:userslug/edit', function (req, res) { + app.get('/:userslug/edit', function (req, res, next) { if (!req.user) { return res.redirect('/403'); } - + console.log('epic fail', req.user); user.getUserField(req.user.uid, 'userslug', function (err, userslug) { - if (req.params.userslug && userslug === req.params.userslug) { + function done() { app.build_header({ req: req, res: res }, function (err, header) { res.send(header + app.create_route('user/' + req.params.userslug + '/edit', 'accountedit') + templates['footer']); }); - } else { - return res.redirect('/404'); } + + if(err || !userslug) { + return next(err); + } + + if (userslug === req.params.userslug) { + return done(); + } + + user.isAdministrator(req.user.uid, function(err, isAdmin) { + if(err) { + return next(err); + } + + if(!isAdmin) { + return res.redirect('/403'); + } + + done(); + }); }); }); @@ -221,10 +239,14 @@ var fs = require('fs'), } - app.get('/api/user/:userslug/following', function (req, res) { + app.get('/api/user/:userslug/following', function (req, res, next) { var callerUID = req.user ? req.user.uid : '0'; - getUserDataByUserSlug(req.params.userslug, callerUID, function (userData) { + getUserDataByUserSlug(req.params.userslug, callerUID, function (err, userData) { + if(err) { + return next(err); + } + if (userData) { user.getFollowing(userData.uid, function (followingData) { userData.following = followingData; @@ -240,10 +262,14 @@ var fs = require('fs'), }); }); - app.get('/api/user/:userslug/followers', function (req, res) { + app.get('/api/user/:userslug/followers', function (req, res, next) { var callerUID = req.user ? req.user.uid : '0'; - getUserDataByUserSlug(req.params.userslug, callerUID, function (userData) { + getUserDataByUserSlug(req.params.userslug, callerUID, function (err, userData) { + if(err) { + return next(err); + } + if (userData) { user.getFollowers(userData.uid, function (followersData) { userData.followers = followersData; @@ -258,10 +284,19 @@ var fs = require('fs'), }); }); - app.get('/api/user/:userslug/edit', function (req, res) { + app.get('/api/user/:userslug/edit', function (req, res, next) { var callerUID = req.user ? req.user.uid : '0'; - getUserDataByUserSlug(req.params.userslug, callerUID, function (userData) { + if(!parseInt(callerUID, 10)) { + return res.json(403, { + error: 'Not allowed!' + }); + } + + getUserDataByUserSlug(req.params.userslug, callerUID, function (err, userData) { + if(err) { + return next(err); + } res.json(userData); }); }); @@ -393,7 +428,11 @@ var fs = require('fs'), app.get('/api/user/:userslug', function (req, res, next) { var callerUID = req.user ? req.user.uid : '0'; - getUserDataByUserSlug(req.params.userslug, callerUID, function (userData) { + getUserDataByUserSlug(req.params.userslug, callerUID, function (err, userData) { + if(err) { + return next(err); + } + if(!userData) { return res.json(404, { error: 'User not found!' @@ -534,62 +573,74 @@ var fs = require('fs'), } function getUserDataByUserSlug(userslug, callerUID, callback) { - user.getUidByUserslug(userslug, function (err, uid) { + var userData; + + async.waterfall([ + function(next) { + user.getUidByUserslug(userslug, next); + }, + function(uid, next) { + if (!uid) { + return next(new Error('invalid-user')); + } - if (uid === null) { - callback(null); - return; + user.getUserData(uid, next); + }, + function(data, next) { + userData = data; + if (!userData) { + return callback(new Error('invalid-user')); + } + + user.isAdministrator(callerUID, next); + } + ], function(err, isAdmin) { + if(err) { + return callback(err); } - user.getUserData(uid, function (err, data) { - if (data) { - data.joindate = utils.toISOString(data.joindate); - if(data.lastonline) { - data.lastonline = utils.toISOString(data.lastonline); - } else { - data.lastonline = data.joindate; - } + userData.joindate = utils.toISOString(userData.joindate); + if(userData.lastonline) { + userData.lastonline = utils.toISOString(userData.lastonline); + } else { + userData.lastonline = userData.joindate; + } - if (!data.birthday) { - data.age = ''; - } else { - data.age = Math.floor((new Date().getTime() - new Date(data.birthday).getTime()) / 31536000000); - } + if (!userData.birthday) { + userData.age = ''; + } else { + userData.age = Math.floor((new Date().getTime() - new Date(userData.birthday).getTime()) / 31536000000); + } - function canSeeEmail() { - return callerUID == uid || (data.email && (data.showemail && parseInt(data.showemail, 10) === 1)); - } + function canSeeEmail() { + return isAdmin || callerUID == userData.uid || (userData.email && (userData.showemail && parseInt(userData.showemail, 10) === 1)); + } - if (!canSeeEmail()) { - data.email = ""; - } + if (!canSeeEmail()) { + userData.email = ""; + } - if (callerUID == uid && (!data.showemail || parseInt(data.showemail, 10) === 0)) { - data.emailClass = ""; - } else { - data.emailClass = "hide"; - } + if (callerUID == userData.uid && (!userData.showemail || parseInt(userData.showemail, 10) === 0)) { + userData.emailClass = ""; + } else { + userData.emailClass = "hide"; + } - data.websiteName = data.website.replace('http://', '').replace('https://', ''); - data.banned = parseInt(data.banned, 10) === 1; - data.uid = uid; - data.yourid = callerUID; - data.theirid = uid; + userData.websiteName = userData.website.replace('http://', '').replace('https://', ''); + userData.banned = parseInt(userData.banned, 10) === 1; + userData.uid = userData.uid; + userData.yourid = callerUID; + userData.theirid = userData.uid; - data.disableSignatures = meta.config.disableSignatures !== undefined && parseInt(meta.config.disableSignatures, 10) === 1; + userData.disableSignatures = meta.config.disableSignatures !== undefined && parseInt(meta.config.disableSignatures, 10) === 1; - user.getFollowingCount(uid, function (followingCount) { - user.getFollowerCount(uid, function (followerCount) { - data.followingCount = followingCount; - data.followerCount = followerCount; - callback(data); - }); - }); - } else { - callback(null); - } + user.getFollowingCount(userData.uid, function (followingCount) { + user.getFollowerCount(userData.uid, function (followerCount) { + userData.followingCount = followingCount; + userData.followerCount = followerCount; + callback(null, userData); + }); }); - }); } diff --git a/src/socket.io/index.js b/src/socket.io/index.js index fa7886b14a..6b8c7db45e 100644 --- a/src/socket.io/index.js +++ b/src/socket.io/index.js @@ -84,14 +84,10 @@ Sockets.init = function(server) { async.parallel({ username: function(next) { - user.getUserField(uid, 'username', function(err, username) { - next(err, username); - }); + user.getUserField(uid, 'username', next); }, isAdmin: function(next) { - user.isAdministrator(uid, function(err, isAdmin) { - next(err, isAdmin); - }); + user.isAdministrator(uid, next); } }, function(err, userData) { socket.emit('event:connect', { @@ -108,9 +104,13 @@ Sockets.init = function(server) { }); } else { socket.broadcast.emit('user.anonConnect'); + socket.emit('event:connect', { + status: 1, + username: 'Anonymous', + isAdmin: false, + uid: 0 + }); } - - }); }); diff --git a/src/socket.io/user.js b/src/socket.io/user.js index 92dfdfe0c5..f9e3ade0e9 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -80,9 +80,24 @@ SocketUser.changePassword = function(socket, data, callback) { }; SocketUser.updateProfile = function(socket, data, callback) { - if(data) { - user.updateProfile(socket.uid, data, callback); + if(!data || !data.uid) { + return callback(new Error('invalid-data')); + } + + if(socket.uid === parseInt(data.uid, 10)) { + return user.updateProfile(socket.uid, data, callback); } + + user.isAdministrator(socket.uid, function(err, isAdmin) { + if(err) { + return callback(err); + } + if(!isAdmin) { + return callback(new Error('not allowed!')) + } + + user.updateProfile(data.uid, data, callback); + }); }; SocketUser.changePicture = function(socket, data, callback) { diff --git a/src/user.js b/src/user.js index 41527b6ed9..232b73caf7 100644 --- a/src/user.js +++ b/src/user.js @@ -301,73 +301,73 @@ var bcrypt = require('bcryptjs'), }); function updateField(field, next) { - if (data[field] !== undefined && typeof data[field] === 'string') { - data[field] = data[field].trim(); - data[field] = sanitize(data[field]).escape(); - - if (field === 'email') { - User.getUserFields(uid, ['email', 'picture', 'uploadedpicture'], function(err, userData) { - if (err) { - return next(err); - } + if (!(data[field] !== undefined && typeof data[field] === 'string')) { + return next(); + } - if(userData.email === data.email) { - return next(); - } + data[field] = data[field].trim(); + data[field] = sanitize(data[field]).escape(); - var gravatarpicture = User.createGravatarURLFromEmail(data.email); - User.setUserField(uid, 'gravatarpicture', gravatarpicture); + if (field === 'email') { + User.getUserFields(uid, ['email', 'picture', 'uploadedpicture'], function(err, userData) { + if (err) { + return next(err); + } - db.deleteObjectField('email:uid', userData.email); - db.setObjectField('email:uid', data.email, uid); - User.setUserField(uid, 'email', data.email); - if (userData.picture !== userData.uploadedpicture) { - returnData.picture = gravatarpicture; - User.setUserField(uid, 'picture', gravatarpicture); - } - returnData.gravatarpicture = gravatarpicture; + if(userData.email === data.email) { + return next(); + } - events.logEmailChange(uid, userData.email, data.email); - next(); - }); - return; - } else if (field === 'username') { + var gravatarpicture = User.createGravatarURLFromEmail(data.email); + User.setUserField(uid, 'gravatarpicture', gravatarpicture); - User.getUserFields(uid, ['username', 'userslug'], function(err, userData) { - var userslug = utils.slugify(data.username); + db.deleteObjectField('email:uid', userData.email); + db.setObjectField('email:uid', data.email, uid); + User.setUserField(uid, 'email', data.email); + if (userData.picture !== userData.uploadedpicture) { + returnData.picture = gravatarpicture; + User.setUserField(uid, 'picture', gravatarpicture); + } + returnData.gravatarpicture = gravatarpicture; - if(data.username !== userData.username) { - User.setUserField(uid, 'username', data.username); - db.deleteObjectField('username:uid', userData.username); - db.setObjectField('username:uid', data.username, uid); - events.logUsernameChange(uid, userData.username, data.username); - } + events.logEmailChange(uid, userData.email, data.email); + next(); + }); + return; + } else if (field === 'username') { - if(userslug !== userData.userslug) { - User.setUserField(uid, 'userslug', userslug); - db.deleteObjectField('userslug:uid', userData.userslug); - db.setObjectField('userslug:uid', userslug, uid); - returnData.userslug = userslug; - } + User.getUserFields(uid, ['username', 'userslug'], function(err, userData) { + var userslug = utils.slugify(data.username); - next(); - }); + if(data.username !== userData.username) { + User.setUserField(uid, 'username', data.username); + db.deleteObjectField('username:uid', userData.username); + db.setObjectField('username:uid', data.username, uid); + events.logUsernameChange(uid, userData.username, data.username); + } - return; - } else if (field === 'signature') { - data[field] = S(data[field]).stripTags().s; - } else if (field === 'website') { - if(data[field].substr(0, 7) !== 'http://' && data[field].substr(0, 8) !== 'https://') { - data[field] = 'http://' + data[field]; + if(userslug !== userData.userslug) { + User.setUserField(uid, 'userslug', userslug); + db.deleteObjectField('userslug:uid', userData.userslug); + db.setObjectField('userslug:uid', userslug, uid); + returnData.userslug = userslug; } - } - User.setUserField(uid, field, data[field]); + next(); + }); - next(); - } else { - next(); + return; + } else if (field === 'signature') { + data[field] = S(data[field]).stripTags().s; + } else if (field === 'website') { + if(data[field].substr(0, 7) !== 'http://' && data[field].substr(0, 8) !== 'https://') { + data[field] = 'http://' + data[field]; + } } + + User.setUserField(uid, field, data[field]); + + next(); } };