From e0c6acd163350122aa4d36a1899a18fe4b3537db Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 25 Sep 2015 15:56:58 -0400 Subject: [PATCH] socket.io/user.js refactor --- src/socket.io/user.js | 271 ++-------------------------------- src/socket.io/user/picture.js | 84 +++++++++++ src/socket.io/user/profile.js | 94 ++++++++++++ src/socket.io/user/search.js | 71 +++++++++ src/socket.io/user/status.js | 45 ++++++ 5 files changed, 305 insertions(+), 260 deletions(-) create mode 100644 src/socket.io/user/picture.js create mode 100644 src/socket.io/user/profile.js create mode 100644 src/socket.io/user/search.js create mode 100644 src/socket.io/user/status.js diff --git a/src/socket.io/user.js b/src/socket.io/user.js index 9d7a229120..99b4299be1 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -1,12 +1,10 @@ 'use strict'; var async = require('async'), - nconf = require('nconf'), - winston = require('winston'), + + user = require('../user'), - groups = require('../groups'), topics = require('../topics'), - posts = require('../posts'), notifications = require('../notifications'), messaging = require('../messaging'), plugins = require('../plugins'), @@ -16,8 +14,15 @@ var async = require('async'), events = require('../events'), emailer = require('../emailer'), db = require('../database'), + SocketUser = {}; + +require('./user/profile')(SocketUser); +require('./user/search')(SocketUser); +require('./user/status')(SocketUser); +require('./user/picture')(SocketUser); + SocketUser.exists = function(socket, data, callback) { if (data && data.username) { meta.userOrGroupExists(utils.slugify(data.username), callback); @@ -66,22 +71,6 @@ SocketUser.emailConfirm = function(socket, data, callback) { } }; -SocketUser.search = function(socket, data, callback) { - if (!data) { - return callback(new Error('[[error:invalid-data]]')); - } - if (!socket.uid && parseInt(meta.config.allowGuestUserSearching, 10) !== 1) { - return callback(new Error('[[error:not-logged-in]]')); - } - user.search({ - query: data.query, - page: data.page, - searchBy: data.searchBy, - sortBy: data.sortBy, - onlineOnly: data.onlineOnly, - uid: socket.uid - }, callback); -}; // Password Reset SocketUser.reset = {}; @@ -127,47 +116,8 @@ SocketUser.reset.commit = function(socket, data, callback) { }); }; -SocketUser.checkStatus = function(socket, uid, callback) { - if (!socket.uid) { - return callback('[[error:invalid-uid]]'); - } - var online = websockets.isUserOnline(uid); - if (!online) { - return callback(null, 'offline'); - } - user.getUserField(uid, 'status', function(err, status) { - if (err) { - return callback(err); - } - status = status || 'online'; - callback(null, status); - }); -}; - -SocketUser.changePassword = function(socket, data, callback) { - if (!data || !data.uid || data.newPassword.length < meta.config.minimumPasswordLength) { - return callback(new Error('[[error:invalid-data]]')); - } - if (!socket.uid) { - return callback('[[error:invalid-uid]]'); - } - - user.changePassword(socket.uid, data, function(err) { - if (err) { - return callback(err); - } - events.log({ - type: 'password-change', - uid: socket.uid, - targetUid: data.uid, - ip: socket.ip - }); - callback(); - }); -}; - -function isAdminOrSelf(socket, uid, callback) { +SocketUser.isAdminOrSelf = function(socket, uid, callback) { if (socket.uid === parseInt(uid, 10)) { return callback(); } @@ -177,141 +127,6 @@ function isAdminOrSelf(socket, uid, callback) { } callback(); }); -} - -SocketUser.updateProfile = function(socket, data, callback) { - function update(oldUserData) { - function done(err, userData) { - if (err) { - return callback(err); - } - - if (userData.email !== oldUserData.email) { - events.log({ - type: 'email-change', - uid: socket.uid, - targetUid: data.uid, - ip: socket.ip, - oldEmail: oldUserData.email, - newEmail: userData.email - }); - } - - if (userData.username !== oldUserData.username) { - events.log({ - type: 'username-change', - uid: socket.uid, - targetUid: data.uid, - ip: socket.ip, - oldUsername: oldUserData.username, - newUsername: userData.username - }); - } - callback(null, userData); - } - - isAdminOrSelf(socket, data.uid, function(err) { - if (err) { - return callback(err); - } - user.updateProfile(data.uid, data, done); - }); - } - - if (!socket.uid) { - return callback('[[error:invalid-uid]]'); - } - - if (!data || !data.uid) { - return callback(new Error('[[error:invalid-data]]')); - } - - user.getUserFields(data.uid, ['email', 'username'], function(err, oldUserData) { - if (err) { - return callback(err); - } - - if (parseInt(meta.config['username:disableEdit'], 10) === 1) { - data.username = oldUserData.username; - } - - update(oldUserData, callback); - }); -}; - -SocketUser.changePicture = function(socket, data, callback) { - if (!socket.uid) { - return callback('[[error:invalid-uid]]'); - } - - if (!data) { - return callback(new Error('[[error:invalid-data]]')); - } - - var type = data.type; - - if (type === 'gravatar') { - type = 'gravatarpicture'; - } else if (type === 'uploaded') { - type = 'uploadedpicture'; - } else { - return callback(new Error('[[error:invalid-image-type, ' + ['gravatar', 'uploadedpicture'].join(', ') + ']]')); - } - - async.waterfall([ - function (next) { - isAdminOrSelf(socket, data.uid, next); - }, - function (next) { - user.getUserField(data.uid, type, next); - }, - function (picture, next) { - user.setUserField(data.uid, 'picture', picture, next); - } - ], callback); -}; - -SocketUser.uploadProfileImageFromUrl = function(socket, data, callback) { - if (!socket.uid || !data.url || !data.uid) { - return; - } - - isAdminOrSelf(socket, data.uid, function(err) { - if (err) { - return callback(err); - } - user.uploadFromUrl(data.uid, data.url, function(err, uploadedImage) { - callback(err, uploadedImage ? uploadedImage.url : null); - }); - }); -}; - -SocketUser.removeUploadedPicture = function(socket, data, callback) { - if (!socket.uid || !data.uid) { - return; - } - - async.waterfall([ - function (next) { - isAdminOrSelf(socket, data.uid, next); - }, - function (next) { - user.getUserField(data.uid, 'uploadedpicture', next); - }, - function(uploadedPicture, next) { - if (!uploadedPicture.startsWith('http')) { - require('fs').unlink(uploadedPicture, function(err) { - if (err) { - winston.error(err); - } - }); - } - user.setUserField(data.uid, 'uploadedpicture', '', next); - }, - function(next) { - user.getUserField(data.uid, 'picture', next); - } - ], callback); }; SocketUser.follow = function(socket, data, callback) { @@ -367,7 +182,7 @@ SocketUser.saveSettings = function(socket, data, callback) { return callback(new Error('[[error:invalid-data]]')); } - isAdminOrSelf(socket, data.uid, function(err) { + SocketUser.isAdminOrSelf(socket, data.uid, function(err) { if (err) { return callback(err); } @@ -444,70 +259,6 @@ SocketUser.loadMore = function(socket, data, callback) { }); }; -SocketUser.loadSearchPage = function(socket, data, callback) { - function done(err, result) { - if (err) { - return callback(err); - } - var pageCount = Math.ceil(result.count / resultsPerPage); - var userData = { - matchCount: result.users.length, - timing: (process.elapsedTimeSince(startTime) / 1000).toFixed(2), - users: result.users, - pagination: pagination.create(data.page, pageCount), - pageCount: pageCount - }; - - callback(null, userData); - } - - if (!data || !data.page) { - return callback(new Error('[[error:invalid-data]]')); - } - var startTime = process.hrtime(); - var controllers = require('../controllers/users'); - var pagination = require('../pagination'); - - var resultsPerPage = parseInt(meta.config.userSearchResultsPerPage, 10) || 20; - var start = Math.max(0, data.page - 1) * resultsPerPage; - var stop = start + resultsPerPage - 1; - if (data.onlineOnly) { - async.parallel({ - users: function(next) { - user.getUsersFromSet('users:online', socket.uid, 0, 49, next); - }, - count: function(next) { - var now = Date.now(); - db.sortedSetCount('users:online', now - 300000, now, next); - } - }, done); - } else { - controllers.getUsersAndCount('users:joindate', socket.uid, start, stop, done); - } -}; - -SocketUser.setStatus = function(socket, status, callback) { - if (!socket.uid) { - return callback(new Error('[[error:invalid-uid]]')); - } - - var allowedStatus = ['online', 'offline', 'dnd', 'away']; - if (allowedStatus.indexOf(status) === -1) { - return callback(new Error('[[error:invalid-user-status]]')); - } - user.setUserField(socket.uid, 'status', status, function(err) { - if (err) { - return callback(err); - } - var data = { - uid: socket.uid, - status: status - }; - websockets.server.sockets.emit('event:user_status_change', data); - callback(null, data); - }); -}; - SocketUser.invite = function(socket, email, callback) { if (!email || !socket.uid) { return callback(new Error('[[error:invald-data]]')); diff --git a/src/socket.io/user/picture.js b/src/socket.io/user/picture.js new file mode 100644 index 0000000000..cc424f2b74 --- /dev/null +++ b/src/socket.io/user/picture.js @@ -0,0 +1,84 @@ +'use strict'; + +var async = require('async'); +var winston = require('winston'); + +var user = require('../../user'); + +module.exports = function(SocketUser) { + + SocketUser.changePicture = function(socket, data, callback) { + if (!socket.uid) { + return callback('[[error:invalid-uid]]'); + } + + if (!data) { + return callback(new Error('[[error:invalid-data]]')); + } + + var type = data.type; + + if (type === 'gravatar') { + type = 'gravatarpicture'; + } else if (type === 'uploaded') { + type = 'uploadedpicture'; + } else { + return callback(new Error('[[error:invalid-image-type, ' + ['gravatar', 'uploadedpicture'].join(', ') + ']]')); + } + + async.waterfall([ + function (next) { + SocketUser.isAdminOrSelf(socket, data.uid, next); + }, + function (next) { + user.getUserField(data.uid, type, next); + }, + function (picture, next) { + user.setUserField(data.uid, 'picture', picture, next); + } + ], callback); + }; + + SocketUser.uploadProfileImageFromUrl = function(socket, data, callback) { + if (!socket.uid || !data.url || !data.uid) { + return; + } + + SocketUser.isAdminOrSelf(socket, data.uid, function(err) { + if (err) { + return callback(err); + } + user.uploadFromUrl(data.uid, data.url, function(err, uploadedImage) { + callback(err, uploadedImage ? uploadedImage.url : null); + }); + }); + }; + + SocketUser.removeUploadedPicture = function(socket, data, callback) { + if (!socket.uid || !data.uid) { + return; + } + + async.waterfall([ + function (next) { + SocketUser.isAdminOrSelf(socket, data.uid, next); + }, + function (next) { + user.getUserField(data.uid, 'uploadedpicture', next); + }, + function(uploadedPicture, next) { + if (!uploadedPicture.startsWith('http')) { + require('fs').unlink(uploadedPicture, function(err) { + if (err) { + winston.error(err); + } + }); + } + user.setUserField(data.uid, 'uploadedpicture', '', next); + }, + function(next) { + user.getUserField(data.uid, 'picture', next); + } + ], callback); + }; +}; \ No newline at end of file diff --git a/src/socket.io/user/profile.js b/src/socket.io/user/profile.js new file mode 100644 index 0000000000..333ead1c8c --- /dev/null +++ b/src/socket.io/user/profile.js @@ -0,0 +1,94 @@ +'use strict'; + +var user = require('../../user'); +var meta = require('../../meta'); +var events = require('../../events'); + +module.exports = function(SocketUser) { + + SocketUser.changePassword = function(socket, data, callback) { + if (!data || !data.uid || data.newPassword.length < meta.config.minimumPasswordLength) { + return callback(new Error('[[error:invalid-data]]')); + } + if (!socket.uid) { + return callback('[[error:invalid-uid]]'); + } + + user.changePassword(socket.uid, data, function(err) { + if (err) { + return callback(err); + } + + events.log({ + type: 'password-change', + uid: socket.uid, + targetUid: data.uid, + ip: socket.ip + }); + callback(); + }); + }; + + + SocketUser.updateProfile = function(socket, data, callback) { + function update(oldUserData) { + function done(err, userData) { + if (err) { + return callback(err); + } + + if (userData.email !== oldUserData.email) { + events.log({ + type: 'email-change', + uid: socket.uid, + targetUid: data.uid, + ip: socket.ip, + oldEmail: oldUserData.email, + newEmail: userData.email + }); + } + + if (userData.username !== oldUserData.username) { + events.log({ + type: 'username-change', + uid: socket.uid, + targetUid: data.uid, + ip: socket.ip, + oldUsername: oldUserData.username, + newUsername: userData.username + }); + } + callback(null, userData); + } + + SocketUser.isAdminOrSelf(socket, data.uid, function(err) { + if (err) { + return callback(err); + } + user.updateProfile(data.uid, data, done); + }); + } + + if (!socket.uid) { + return callback('[[error:invalid-uid]]'); + } + + if (!data || !data.uid) { + return callback(new Error('[[error:invalid-data]]')); + } + + user.getUserFields(data.uid, ['email', 'username'], function(err, oldUserData) { + if (err) { + return callback(err); + } + + if (parseInt(meta.config['username:disableEdit'], 10) === 1) { + data.username = oldUserData.username; + } + + update(oldUserData, callback); + }); + }; + + +}; \ No newline at end of file diff --git a/src/socket.io/user/search.js b/src/socket.io/user/search.js new file mode 100644 index 0000000000..9cce95e180 --- /dev/null +++ b/src/socket.io/user/search.js @@ -0,0 +1,71 @@ +'use strict'; + +var async = require('async'); + +var db = require('../../database'); +var user = require('../../user'); +var meta = require('../../meta'); + +module.exports = function(SocketUser) { + SocketUser.search = function(socket, data, callback) { + if (!data) { + return callback(new Error('[[error:invalid-data]]')); + } + if (!socket.uid && parseInt(meta.config.allowGuestUserSearching, 10) !== 1) { + return callback(new Error('[[error:not-logged-in]]')); + } + user.search({ + query: data.query, + page: data.page, + searchBy: data.searchBy, + sortBy: data.sortBy, + onlineOnly: data.onlineOnly, + uid: socket.uid + }, callback); + }; + + SocketUser.loadSearchPage = function(socket, data, callback) { + function done(err, result) { + if (err) { + return callback(err); + } + var pageCount = Math.ceil(result.count / resultsPerPage); + var userData = { + matchCount: result.users.length, + timing: (process.elapsedTimeSince(startTime) / 1000).toFixed(2), + users: result.users, + pagination: pagination.create(data.page, pageCount), + pageCount: pageCount + }; + + callback(null, userData); + } + + if (!data || !data.page) { + return callback(new Error('[[error:invalid-data]]')); + } + var startTime = process.hrtime(); + var controllers = require('../../controllers/users'); + var pagination = require('../../pagination'); + + var resultsPerPage = parseInt(meta.config.userSearchResultsPerPage, 10) || 20; + var start = Math.max(0, data.page - 1) * resultsPerPage; + var stop = start + resultsPerPage - 1; + if (data.onlineOnly) { + async.parallel({ + users: function(next) { + user.getUsersFromSet('users:online', socket.uid, 0, 49, next); + }, + count: function(next) { + var now = Date.now(); + db.sortedSetCount('users:online', now - 300000, now, next); + } + }, done); + } else { + controllers.getUsersAndCount('users:joindate', socket.uid, start, stop, done); + } + }; + + + +}; \ No newline at end of file diff --git a/src/socket.io/user/status.js b/src/socket.io/user/status.js new file mode 100644 index 0000000000..eba38217a2 --- /dev/null +++ b/src/socket.io/user/status.js @@ -0,0 +1,45 @@ +'use strict'; + +var user = require('../../user'); +var websockets = require('../index'); + +module.exports = function(SocketUser) { + SocketUser.checkStatus = function(socket, uid, callback) { + if (!socket.uid) { + return callback('[[error:invalid-uid]]'); + } + var online = websockets.isUserOnline(uid); + if (!online) { + return callback(null, 'offline'); + } + user.getUserField(uid, 'status', function(err, status) { + if (err) { + return callback(err); + } + status = status || 'online'; + callback(null, status); + }); + }; + + SocketUser.setStatus = function(socket, status, callback) { + if (!socket.uid) { + return callback(new Error('[[error:invalid-uid]]')); + } + + var allowedStatus = ['online', 'offline', 'dnd', 'away']; + if (allowedStatus.indexOf(status) === -1) { + return callback(new Error('[[error:invalid-user-status]]')); + } + user.setUserField(socket.uid, 'status', status, function(err) { + if (err) { + return callback(err); + } + var data = { + uid: socket.uid, + status: status + }; + websockets.server.sockets.emit('event:user_status_change', data); + callback(null, data); + }); + }; +}; \ No newline at end of file