diff --git a/public/src/app.js b/public/src/app.js index e467343a39..99b4b29615 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -36,7 +36,7 @@ var socket, app.uid = data.uid; app.showLoginMessage(); - socket.emit('api:meta.updateHeader', { + socket.emit('meta.updateHeader', { fields: ['username', 'picture', 'userslug'] }, app.updateHeader); }); @@ -77,14 +77,14 @@ var socket, } app.enterRoom(room, true); - socket.emit('api:meta.reconnected'); + socket.emit('meta.reconnected'); setTimeout(function() { reconnectEl.removeClass('active').addClass("hide"); }, 3000); } - socket.emit('api:meta.updateHeader', { + socket.emit('meta.updateHeader', { fields: ['username', 'picture', 'userslug'] }, app.updateHeader); }); @@ -122,6 +122,8 @@ var socket, setTimeout(app.logout, 1000); }); + socket.on('meta.updateHeader', app.updateHeader); + app.enterRoom('global'); } }, @@ -235,7 +237,7 @@ var socket, return; } - socket.emit('api:meta.rooms.enter', { + socket.emit('meta.rooms.enter', { 'enter': room, 'leave': app.currentRoom }); @@ -248,42 +250,22 @@ var socket, var uids = []; jQuery('.post-row').each(function () { - uids.push(this.getAttribute('data-uid')); + var uid = $(this).attr('data-uid'); + if(uids.indexOf(uid) === -1) { + uids.push(uid); + } }); - socket.emit('api:user.get_online_users', uids, function (users) { - jQuery('a.username-field').each(function () { - if (this.processed === true) - return; - - var el = jQuery(this), - uid = el.parents('li').attr('data-uid'); - - if (uid && jQuery.inArray(uid, users) !== -1) { - el.find('i').remove(); - el.prepend(''); - } else { - el.find('i').remove(); - el.prepend(''); - } - - el.processed = true; - }); - jQuery('button .username-field').each(function () { - //DRY FAIL - if (this.processed === true) - return; - + socket.emit('user.getOnlineUsers', uids, function (err, users) { + jQuery('button .username-field').each(function (index, element) { var el = jQuery(this), uid = el.parents('li').attr('data-uid'); if (uid && jQuery.inArray(uid, users) !== -1) { - el.parent().addClass('btn-success'); + el.parent().addClass('btn-success').removeClass('btn-danger'); } else { - el.parent().addClass('btn-danger'); + el.parent().addClass('btn-danger').removeClass('btn-success'); } - - el.processed = true; }); }); }; @@ -419,6 +401,7 @@ var socket, interval: undefined, titles: [] }; + app.alternatingTitle = function (title) { if (typeof title !== 'string') { return; @@ -449,13 +432,13 @@ var socket, url = a.pathname.slice(1); } - socket.emit('api:meta.buildTitle', url, function(title, numNotifications) { + socket.emit('meta.buildTitle', url, function(err, title, numNotifications) { titleObj.titles[0] = (numNotifications > 0 ? '(' + numNotifications + ') ' : '') + title; app.alternatingTitle(''); }); }; - app.updateHeader = function(data) { + app.updateHeader = function(err, data) { $('#search-button').off().on('click', function(e) { e.stopPropagation(); $('#search-fields').removeClass('hide').show(); diff --git a/public/src/forum/account.js b/public/src/forum/account.js index 8354461fe4..d3c639cf66 100644 --- a/public/src/forum/account.js +++ b/public/src/forum/account.js @@ -35,31 +35,31 @@ define(['forum/accountheader'], function(header) { } followBtn.on('click', function() { - socket.emit('api:user.follow', { + socket.emit('user.follow', { uid: theirid - }, function(success) { - if (success) { - followBtn.addClass('hide'); - unfollowBtn.removeClass('hide'); - app.alertSuccess('You are now following ' + username + '!'); - } else { - app.alertError('There was an error following' + username + '!'); + }, function(err) { + if(err) { + return app.alertError('There was an error following' + username + '!'); } + + followBtn.addClass('hide'); + unfollowBtn.removeClass('hide'); + app.alertSuccess('You are now following ' + username + '!'); }); return false; }); unfollowBtn.on('click', function() { - socket.emit('api:user.unfollow', { + socket.emit('user.unfollow', { uid: theirid - }, function(success) { - if (success) { - followBtn.removeClass('hide'); - unfollowBtn.addClass('hide'); - app.alertSuccess('You are no longer following ' + username + '!'); - } else { - app.alertError('There was an error unfollowing ' + username + '!'); + }, function(err) { + if(err) { + return app.alertError('There was an error unfollowing ' + username + '!'); } + + followBtn.removeClass('hide'); + unfollowBtn.addClass('hide'); + app.alertSuccess('You are no longer following ' + username + '!'); }); return false; }); @@ -72,9 +72,9 @@ define(['forum/accountheader'], function(header) { ajaxify.go($(this).attr('topic-url')); }); - socket.on('api:user.isOnline', Account.handleUserOnline); + socket.on('user.isOnline', Account.handleUserOnline); - socket.emit('api:user.isOnline', theirid, Account.handleUserOnline); + socket.emit('user.isOnline', theirid, Account.handleUserOnline); socket.on('event:new_post', function(data) { var html = templates.prepare(templates['account'].blocks['posts']).parse(data); @@ -85,7 +85,7 @@ define(['forum/accountheader'], function(header) { }); }; - Account.handleUserOnline = function(data) { + Account.handleUserOnline = function(err, data) { var onlineStatus = $('.account-online-status'); if (data.online) { diff --git a/public/src/forum/accountedit.js b/public/src/forum/accountedit.js index 8b213ca868..d12b98f634 100644 --- a/public/src/forum/accountedit.js +++ b/public/src/forum/accountedit.js @@ -24,7 +24,7 @@ define(['forum/accountheader', 'uploader'], function(header, uploader) { signature: $('#inputSignature').val() }; - socket.emit('api:user.updateProfile', userData, function(err, data) { + socket.emit('user.updateProfile', userData, function(err, data) { if (data.success) { app.alertSuccess('Your profile has been updated successfully!'); if (data.picture) { @@ -36,7 +36,7 @@ define(['forum/accountheader', 'uploader'], function(header, uploader) { gravatarPicture = data.gravatarpicture; } } else { - app.alertError('There was an error updating your profile! ' + err.error); + app.alertError('There was an error updating your profile! ' + err.message); } }); return false; @@ -108,7 +108,7 @@ define(['forum/accountheader', 'uploader'], function(header, uploader) { uploadedPicture = imageUrlOnServer; - socket.emit('api:meta.updateHeader', { + socket.emit('meta.updateHeader', { fields: ['username', 'picture', 'userslug'] }, app.updateHeader); }); @@ -174,7 +174,7 @@ define(['forum/accountheader', 'uploader'], function(header, uploader) { $('#changePasswordBtn').on('click', function() { if (passwordvalid && passwordsmatch && currentPassword.val()) { - socket.emit('api:user.changePassword', { + socket.emit('user.changePassword', { 'currentPassword': currentPassword.val(), 'newPassword': password.val() }, function(err) { @@ -186,7 +186,7 @@ define(['forum/accountheader', 'uploader'], function(header, uploader) { passwordvalid = false; if (err) { - app.alertError(err.error); + app.alertError(err.message); return; } @@ -206,9 +206,9 @@ define(['forum/accountheader', 'uploader'], function(header, uploader) { type: type }; - socket.emit('api:user.changePicture', userData, function(success) { - if (!success) { - app.alertError('There was an error changing picture!'); + socket.emit('user.changePicture', userData, function(err) { + if(err) { + app.alertError(err.message); } }); } diff --git a/public/src/forum/accountsettings.js b/public/src/forum/accountsettings.js index 8746c1c5b3..db21bb4efa 100644 --- a/public/src/forum/accountsettings.js +++ b/public/src/forum/accountsettings.js @@ -10,12 +10,11 @@ define(['forum/accountheader'], function(header) { showemail: $('#showemailCheckBox').is(':checked') ? 1 : 0 }; - socket.emit('api:user.saveSettings', settings, function(err) { - if (!err) { - app.alertSuccess('Settings saved!'); - } else { - app.alertError('There was an error saving settings!'); + socket.emit('user.saveSettings', settings, function(err) { + if (err) { + return app.alertError('There was an error saving settings!'); } + app.alertSuccess('Settings saved!'); }); return false; }); diff --git a/public/src/forum/admin/categories.js b/public/src/forum/admin/categories.js index c7404f3279..327e29968f 100644 --- a/public/src/forum/admin/categories.js +++ b/public/src/forum/admin/categories.js @@ -13,7 +13,7 @@ define(['uploader'], function(uploader) { } function save() { - socket.emit('api:admin.categories.update', modified_categories); + socket.emit('admin.categories.update', modified_categories); modified_categories = {}; } @@ -86,23 +86,26 @@ define(['uploader'], function(uploader) { order: $('.admin-categories #entry-container').children().length + 1 }; - socket.emit('api:admin.categories.create', category, function(err, data) { - if (!err) { - app.alert({ - alert_id: 'category_created', - title: 'Created', - message: 'Category successfully created!', - type: 'success', - timeout: 2000 - }); - - var html = templates.prepare(templates['admin/categories'].blocks['categories']).parse({ - categories: [data] - }); - $('#entry-container').append(html); - - $('#new-category-modal').modal('hide'); + socket.emit('admin.categories.create', category, function(err, data) { + if(err) { + return app.alertError(err.message); } + + app.alert({ + alert_id: 'category_created', + title: 'Created', + message: 'Category successfully created!', + type: 'success', + timeout: 2000 + }); + + var html = templates.prepare(templates['admin/categories'].blocks['categories']).parse({ + categories: [data] + }); + + $('#entry-container').append(html); + $('#new-category-modal').modal('hide'); + }); } @@ -223,7 +226,14 @@ define(['uploader'], function(uploader) { clearTimeout(searchDelay); searchDelay = setTimeout(function() { - socket.emit('api:admin.categories.search', searchEl.value, cid, function(err, results) { + socket.emit('admin.categories.search', { + username: searchEl.value, + cid: cid + }, function(err, results) { + if(err) { + return app.alertError(err.message); + } + var numResults = results.length, resultObj; for(var x=0;x 0) { var numResults = results.length, resultsSlug = document.createDocumentFragment(), @@ -152,7 +157,7 @@ define(function() { }); if (members.indexOf(uid) === -1) { - socket.emit('api:admin.groups.join', { + socket.emit('admin.groups.join', { gid: gid, uid: uid }, function(err, data) { @@ -167,7 +172,7 @@ define(function() { var uid = this.getAttribute('data-uid'), gid = detailsModal.attr('data-gid'); - socket.emit('api:admin.groups.leave', { + socket.emit('admin.groups.leave', { gid: gid, uid: uid }, function(err, data) { @@ -183,7 +188,7 @@ define(function() { descEl = formEl.find('#change-group-desc'), gid = detailsModal.attr('data-gid'); - socket.emit('api:admin.groups.update', { + socket.emit('admin.groups.update', { gid: gid, values: { name: nameEl.val(), diff --git a/public/src/forum/admin/index.js b/public/src/forum/admin/index.js index d35712c215..fada97e28e 100644 --- a/public/src/forum/admin/index.js +++ b/public/src/forum/admin/index.js @@ -2,10 +2,10 @@ define(function() { var Admin = {}; Admin.init = function() { - ajaxify.register_events(['api:meta.rooms.getAll']); + ajaxify.register_events(['meta.rooms.getAll']); app.enterRoom('admin'); - socket.emit('api:meta.rooms.getAll', Admin.updateRoomUsage); + socket.emit('meta.rooms.getAll', Admin.updateRoomUsage); socket.on('event:meta.rooms.update', Admin.updateRoomUsage); $('#logout-link').on('click', function() { @@ -17,15 +17,15 @@ define(function() { }) }; - Admin.updateRoomUsage = function(data) { - console.log('room usage updating', data); + Admin.updateRoomUsage = function(err, data) { + console.log(arguments); var active_users = document.getElementById('active_users'), total = 0; active_users.innerHTML = ''; for (var room in data) { if (room !== '') { - var count = data[room].length; + var count = $(data[room]).length; total += count; active_users.innerHTML = active_users.innerHTML + "
" + room + " " + count + " active user" + (count > 1 ? "s" : "") + "
"; } diff --git a/public/src/forum/admin/plugins.js b/public/src/forum/admin/plugins.js index 66b8038055..6f197e8bb0 100644 --- a/public/src/forum/admin/plugins.js +++ b/public/src/forum/admin/plugins.js @@ -8,10 +8,10 @@ define(function() { if (numPlugins > 0) { pluginsList.on('click', 'button[data-action="toggleActive"]', function() { pluginID = $(this).parents('li').attr('data-plugin-id'); - socket.emit('api:admin.plugins.toggle', pluginID); + socket.emit('admin.plugins.toggle', pluginID); }); - socket.on('api:admin.plugins.toggle', function(status) { + socket.on('admin.plugins.toggle', function(status) { pluginTgl = document.querySelector('.plugins li[data-plugin-id="' + status.id + '"] button'); pluginTgl.innerHTML = ' ' + (status.active ? 'Dea' : 'A') + 'ctivate'; diff --git a/public/src/forum/admin/settings.js b/public/src/forum/admin/settings.js index d294b9311b..777b82bb9f 100644 --- a/public/src/forum/admin/settings.js +++ b/public/src/forum/admin/settings.js @@ -70,20 +70,12 @@ define(['uploader'], function(uploader) { value = fields[x].value; } - socket.emit('api:admin.config.set', { + socket.emit('admin.config.set', { key: key, value: value - }, function(data) { - if (data.status === 'ok') { - app.alert({ - alert_id: 'config_status', - timeout: 2500, - title: 'Changes Saved', - message: 'Your changes to the NodeBB configuration have been saved.', - type: 'success' - }); - } else { - app.alert({ + }, function(err) { + if(err) { + return app.alert({ alert_id: 'config_status', timeout: 2500, title: 'Changes Not Saved', @@ -91,6 +83,15 @@ define(['uploader'], function(uploader) { type: 'danger' }); } + + app.alert({ + alert_id: 'config_status', + timeout: 2500, + title: 'Changes Saved', + message: 'Your changes to the NodeBB configuration have been saved.', + type: 'success' + }); + }); } }); @@ -119,7 +120,7 @@ define(['uploader'], function(uploader) { }; Settings.remove = function(key) { - socket.emit('api:admin.config.remove', key); + socket.emit('admin.config.remove', key); }; return Settings; diff --git a/public/src/forum/admin/themes.js b/public/src/forum/admin/themes.js index 2a613ffc96..5163f0df1d 100644 --- a/public/src/forum/admin/themes.js +++ b/public/src/forum/admin/themes.js @@ -23,7 +23,7 @@ define(function() { cssSrc = parentEl.attr('data-css'), themeId = parentEl.attr('data-theme'); - socket.emit('api:admin.themes.set', { + socket.emit('admin.themes.set', { type: themeType, id: themeId, src: cssSrc @@ -47,7 +47,7 @@ define(function() { revertEl.addEventListener('click', function() { bootbox.confirm('Are you sure you wish to remove the custom theme and restore the NodeBB default theme?', function(confirm) { if (confirm) { - socket.emit('api:admin.themes.set', { + socket.emit('admin.themes.set', { type: 'local', id: 'nodebb-theme-cerulean' }, function(err) { @@ -64,7 +64,11 @@ define(function() { }, false); // Installed Themes - socket.emit('api:admin.themes.getInstalled', function(themes) { + socket.emit('admin.themes.getInstalled', function(err, themes) { + if(err) { + return app.alertError(err.message); + } + var instListEl = document.getElementById('installed_themes'), themeFrag = document.createDocumentFragment(), liEl = document.createElement('li'); diff --git a/public/src/forum/admin/topics.js b/public/src/forum/admin/topics.js index 2b923f3583..1d112ddca4 100644 --- a/public/src/forum/admin/topics.js +++ b/public/src/forum/admin/topics.js @@ -15,37 +15,25 @@ define(function() { switch (action) { case 'pin': if (!$this.hasClass('active')) { - socket.emit('api:topics.pin', { - tid: tid - }, Topics.pin); + socket.emit('topics.pin', tid, Topics.pin); } else { - socket.emit('api:topics.unpin', { - tid: tid - }, Topics.unpin); + socket.emit('topics.unpin', tid, Topics.unpin); } break; case 'lock': if (!$this.hasClass('active')) { - socket.emit('api:topics.lock', { - tid: tid - }, Topics.lock); + socket.emit('topics.lock', tid, Topics.lock); } else { - socket.emit('api:topics.unlock', { - tid: tid - }, Topics.unlock); + socket.emit('topics.unlock', tid, Topics.unlock); } break; case 'delete': if (!$this.hasClass('active')) { - socket.emit('api:topics.delete', { - tid: tid - }, Topics.setDeleted); + socket.emit('topics.delete', tid, Topics.setDeleted); } else { - socket.emit('api:topics.restore', { - tid: tid - }, Topics.restore); + socket.emit('topics.restore', tid, Topics.restore); } break; @@ -63,13 +51,16 @@ define(function() { var lastTid = parseInt(topics[topics.length - 1].getAttribute('data-tid')); this.innerHTML = ' Retrieving topics'; - socket.emit('api:admin.topics.getMore', { + socket.emit('admin.topics.getMore', { limit: 10, after: lastTid - }, function(topics) { + }, function(err, topics) { + if(err) { + return app.alertError(err.message); + } + var btnEl = document.getElementById('topics_loadmore'); - topics = JSON.parse(topics); if (topics.length > 0) { var html = templates.prepare(templates['admin/topics'].blocks['topics']).parse({ topics: topics @@ -116,8 +107,12 @@ define(function() { } } - Topics.setDeleted = function(response) { - if (response.status === 'ok') { + Topics.setDeleted = function(err, response) { + if(err) { + return app.alert(err.message); + } + + if (response && response.tid) { var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="delete"]'); $(btnEl).addClass('active'); @@ -125,8 +120,12 @@ define(function() { } }; - Topics.restore = function(response) { - if (response.status === 'ok') { + Topics.restore = function(err, response) { + if(err) { + return app.alert(err.message); + } + + if (response && response.tid) { var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="delete"]'); $(btnEl).removeClass('active'); @@ -134,16 +133,24 @@ define(function() { } }; - Topics.lock = function(response) { - if (response.status === 'ok') { + Topics.lock = function(err, response) { + if(err) { + return app.alert(err.message); + } + + if (response && response.tid) { var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="lock"]'); $(btnEl).addClass('active'); } }; - Topics.unlock = function(response) { - if (response.status === 'ok') { + Topics.unlock = function(err, response) { + if(err) { + return app.alert(err.message); + } + + if (response && response.tid) { var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="lock"]'); $(btnEl).removeClass('active'); @@ -151,16 +158,24 @@ define(function() { }; - Topics.unpin = function(response) { - if (response.status === 'ok') { + Topics.unpin = function(err, response) { + if(err) { + return app.alert(err.message); + } + + if (response && response.tid) { var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="pin"]'); $(btnEl).removeClass('active'); } }; - Topics.pin = function(response) { - if (response.status === 'ok') { + Topics.pin = function(err, response) { + if(err) { + return app.alert(err.message); + } + + if (response && response.tid) { var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="pin"]'); $(btnEl).addClass('active'); diff --git a/public/src/forum/admin/users.js b/public/src/forum/admin/users.js index a1083f9660..e890329118 100644 --- a/public/src/forum/admin/users.js +++ b/public/src/forum/admin/users.js @@ -68,14 +68,14 @@ define(function() { if (!isAdmin) { if (isBanned) { - socket.emit('api:admin.user.unbanUser', uid); + socket.emit('admin.user.unbanUser', uid); banBtn.removeClass('btn-warning'); parent.attr('data-banned', 0); updateUserAdminButtons(); } else { bootbox.confirm('Do you really want to ban "' + parent.attr('data-username') + '"?', function(confirm) { if (confirm) { - socket.emit('api:admin.user.banUser', uid); + socket.emit('admin.user.banUser', uid); banBtn.addClass('btn-warning'); parent.attr('data-banned', 1); updateUserAdminButtons(); @@ -103,7 +103,7 @@ define(function() { }); } else if (!isAdmin) { - socket.emit('api:admin.user.makeAdmin', uid); + socket.emit('admin.user.makeAdmin', uid); adminBtn.attr('value', 'UnMake Admin').html('Remove Admin'); parent.attr('data-admin', 1); updateUserBanButtons(); @@ -111,7 +111,7 @@ define(function() { } else if(uid !== yourid) { bootbox.confirm('Do you really want to remove this user as admin "' + parent.attr('data-username') + '"?', function(confirm) { if (confirm) { - socket.emit('api:admin.user.removeAdmin', uid); + socket.emit('admin.user.removeAdmin', uid); adminBtn.attr('value', 'Make Admin').html('Make Admin'); parent.attr('data-admin', 0); updateUserBanButtons(); @@ -126,16 +126,19 @@ define(function() { } function handleUserCreate() { + var errorEl = $('#create-modal-error'); $('#createUser').on('click', function() { $('#create-modal').modal('show'); + $('#create-modal form')[0].reset(); + errorEl.addClass('hide'); }); $('#create-modal-go').on('click', function() { var username = $('#create-user-name').val(), email = $('#create-user-email').val(), password = $('#create-user-password').val(), - passwordAgain = $('#create-user-password-again').val(), - errorEl = $('#create-modal-error'); + passwordAgain = $('#create-user-password-again').val(); + if(password !== passwordAgain) { return errorEl.html('Error

Passwords must match!

').removeClass('hide'); @@ -147,13 +150,15 @@ define(function() { password: password }; - socket.emit('api:admin.user.createUser', user, function(err, data) { + socket.emit('admin.user.createUser', user, function(err) { if(err) { - return errorEl.html('Error

' + err + '

').removeClass('hide'); + return errorEl.html('Error

' + err.message + '

').removeClass('hide'); } $('#create-modal').modal('hide'); + $('#create-modal').on('hidden.bs.modal', function() { + ajaxify.go('admin/users'); + }); app.alertSuccess('User created!'); - ajaxify.go('admin/users'); }); }); @@ -188,10 +193,10 @@ define(function() { jQuery('.fa-spinner').removeClass('none'); - socket.emit('api:admin.user.search', username, function(err, data) { + socket.emit('admin.user.search', username, function(err, data) { if(err) { return app.alertError(err.message); - } + }console.log(data) var html = templates.prepare(templates['admin/users'].blocks['users']).parse({ users: data @@ -242,11 +247,11 @@ define(function() { if (set) { loadingMoreUsers = true; - socket.emit('api:user.loadMore', { + socket.emit('user.loadMore', { set: set, after: $('#users-container').children().length - }, function(data) { - if (data.users.length) { + }, function(err, data) { + if (data && data.users.length) { onUsersLoaded(data.users); } loadingMoreUsers = false; diff --git a/public/src/forum/category.js b/public/src/forum/category.js index c76c6871dc..56ea94b6e4 100644 --- a/public/src/forum/category.js +++ b/public/src/forum/category.js @@ -40,7 +40,7 @@ define(['composer'], function(composer) { socket.on('event:new_topic', Category.onNewTopic); - socket.emit('api:categories.getRecentReplies', cid, renderRecentReplies); + socket.emit('categories.getRecentReplies', cid, renderRecentReplies); $(window).off('scroll').on('scroll', function (ev) { var bottom = ($(document).height() - $(window).height()) * 0.9; @@ -81,7 +81,7 @@ define(['composer'], function(composer) { } topic.hide().fadeIn('slow'); - socket.emit('api:categories.getRecentReplies', templates.get('category_id'), renderRecentReplies); + socket.emit('categories.getRecentReplies', templates.get('category_id'), renderRecentReplies); addActiveUser(data); @@ -129,19 +129,23 @@ define(['composer'], function(composer) { } loadingMoreTopics = true; - socket.emit('api:categories.loadMore', { + socket.emit('categories.loadMore', { cid: cid, after: $('#topics-container').children('.category-item').length - }, function (data) { - if (data.topics.length) { + }, function (err, data) { + if(err) { + return app.alertError(err.message); + } + + if (data && data.topics.length) { Category.onTopicsLoaded(data.topics); } loadingMoreTopics = false; }); } - function renderRecentReplies(posts) { - if (!posts || posts.length === 0) { + function renderRecentReplies(err, posts) { + if (err || !posts || posts.length === 0) { return; } diff --git a/public/src/forum/footer.js b/public/src/forum/footer.js index 766d56f0dc..1bcdac57bf 100644 --- a/public/src/forum/footer.js +++ b/public/src/forum/footer.js @@ -1,6 +1,6 @@ define(['notifications', 'chat'], function(Notifications, Chat) { - socket.emit('api:meta.updateHeader', { + socket.emit('meta.updateHeader', { fields: ['username', 'picture', 'userslug'] }, app.updateHeader); @@ -8,11 +8,11 @@ define(['notifications', 'chat'], function(Notifications, Chat) { Chat.prepareDOM(); translator.prepareDOM(); - function updateUnreadCount(count) { + function updateUnreadCount(err, count) { $('#unread-count').toggleClass('unread-count', count > 0); $('#unread-count').attr('data-content', count > 20 ? '20+' : count); } socket.on('event:unread.updateCount', updateUnreadCount); - socket.emit('api:user.getUnreadCount', updateUnreadCount); + socket.emit('user.getUnreadCount', updateUnreadCount); }); \ No newline at end of file diff --git a/public/src/forum/home.js b/public/src/forum/home.js index 017435464e..c38568bd6c 100644 --- a/public/src/forum/home.js +++ b/public/src/forum/home.js @@ -4,23 +4,32 @@ define(function() { home.init = function() { ajaxify.register_events([ - 'api:user.count', - 'post.stats', - 'api:user.getActiveUsers' + 'user.count', + 'meta.getUsageStats', + 'user.getActiveUsers' ]); - socket.emit('api:user.count', function(data) { + socket.emit('user.count', updateUserCount); + socket.on('user.count', updateUserCount); + + function updateUserCount(err, data) { $('#stats_users').html(utils.makeNumberHumanReadable(data.count)).attr('title', data.count); - }); + } + + socket.emit('meta.getUsageStats', updateUsageStats); + socket.on('meta.getUsageStats', updateUsageStats); - socket.emit('api:meta.getUsageStats', function(data) { + function updateUsageStats(err, data) { $('#stats_topics').html(utils.makeNumberHumanReadable(data.topics)).attr('title', data.topics); $('#stats_posts').html(utils.makeNumberHumanReadable(data.posts)).attr('title', data.posts); - }); + } + + socket.emit('user.getActiveUsers', updateActiveUsers); + socket.on('user.getActiveUsers', updateActiveUsers); - socket.emit('api:user.getActiveUsers', function(data) { + function updateActiveUsers(err, data) { $('#stats_online').html(data.users); - }); + } } return home; diff --git a/public/src/forum/recent.js b/public/src/forum/recent.js index c883c9c54b..7a7dbc26f1 100644 --- a/public/src/forum/recent.js +++ b/public/src/forum/recent.js @@ -84,7 +84,7 @@ define(function() { var html = templates.prepare(templates['recent'].blocks['topics']).parse({ topics: topics }); - + translator.translate(html, function(translatedHTML) { var container = $('#topics-container'); @@ -99,10 +99,13 @@ define(function() { Recent.loadMoreTopics = function() { Recent.loadingMoreTopics = true; - socket.emit('api:topics.loadMoreRecentTopics', { + socket.emit('topics.loadMoreRecentTopics', { after: $('#topics-container').children('li').length, term: active - }, function(data) { + }, function(err, data) { + if(err) { + return app.alertError(err.message); + } if (data.topics && data.topics.length) { Recent.onTopicsLoaded(data.topics); } diff --git a/public/src/forum/register.js b/public/src/forum/register.js index 3e839c6f58..aa8fc66b59 100644 --- a/public/src/forum/register.js +++ b/public/src/forum/register.js @@ -42,10 +42,14 @@ define(function() { if (!utils.isEmailValid(emailEl.val())) { showError(email_notify, 'Invalid email address.'); } else { - socket.emit('api:user.emailExists', { + socket.emit('user.emailExists', { email: emailEl.val() - }, function(exists) { - if (exists === true) { + }, function(err, exists) { + if(err) { + return app.alertError(err.message); + } + + if (exists) { showError(email_notify, 'Email address already taken!'); } else { showSuccess(email_notify, successIcon); @@ -71,8 +75,18 @@ define(function() { } else if (!utils.isUserNameValid(username.val()) || !utils.slugify(username.val())) { showError(username_notify, 'Invalid username!'); } else { - socket.emit('api:user.exists', { + socket.emit('user.exists', { username: username.val() + }, function(err, exists) { + if(err) { + return app.alertError(err.message); + } + + if (exists) { + showError(username_notify, 'Username already taken!'); + } else { + showSuccess(username_notify, successIcon); + } }); } } @@ -80,6 +94,7 @@ define(function() { username.on('keyup', function() { jQuery('#yourUsername').html(this.value.length > 0 ? this.value : 'username'); }); + username.on('blur', function() { validateUsername(); }); @@ -123,16 +138,6 @@ define(function() { validatePasswordConfirm(); }); - ajaxify.register_events(['api:user.exists', 'api:user.emailExists']); - - socket.on('api:user.exists', function(data) { - if (data.exists === true) { - showError(username_notify, 'Username already taken!'); - } else { - showSuccess(username_notify, successIcon); - } - }); - function validateForm() { validationError = false; diff --git a/public/src/forum/reset.js b/public/src/forum/reset.js index 2d2b797a4b..a04b3d31e5 100644 --- a/public/src/forum/reset.js +++ b/public/src/forum/reset.js @@ -8,8 +8,19 @@ define(function() { document.getElementById('reset').onclick = function() { if (inputEl.value.length > 0 && inputEl.value.indexOf('@') !== -1) { - socket.emit('api:user.reset.send', { + socket.emit('user.reset.send', { email: inputEl.value + }, function(err, data) { + if(err) { + return app.alertError(err.message); + } + + var submitEl = document.getElementById('reset'); + + jQuery('#error').hide(); + jQuery('#success').show(); + jQuery('#success p').html('An email has been dispatched to "' + inputEl.value + '" with instructions on setting a new password.'); + inputEl.value = ''; }); } else { jQuery('#success').hide(); @@ -17,30 +28,6 @@ define(function() { errorTextEl.innerHTML = 'Please enter a valid email'; } }; - - ajaxify.register_events(['user.send_reset']); - - socket.on('user.send_reset', function(data) { - var submitEl = document.getElementById('reset'); - - if (data.status === 'ok') { - jQuery('#error').hide(); - jQuery('#success').show(); - jQuery('#success p').html('An email has been dispatched to "' + data.email + '" with instructions on setting a new password.'); - inputEl.value = ''; - } else { - jQuery('#success').hide(); - jQuery(errorEl).show(); - switch (data.message) { - case 'invalid-email': - errorTextEl.innerHTML = 'The email you put in (' + data.email + ') is not registered with us. Please try again.'; - break; - case 'send-failed': - errorTextEl.innerHTML = 'There was a problem sending the reset code. Please try again later.'; - break; - } - } - }); }; return ResetPassword; diff --git a/public/src/forum/reset_code.js b/public/src/forum/reset_code.js index 46c7dd9c0a..2eb4b49f28 100644 --- a/public/src/forum/reset_code.js +++ b/public/src/forum/reset_code.js @@ -21,36 +21,37 @@ define(function() { noticeEl.querySelector('p').innerHTML = 'The two passwords you\'ve entered do not match.'; noticeEl.style.display = 'block'; } else { - socket.emit('api:user.reset.commit', { + socket.emit('user.reset.commit', { code: reset_code, password: password.value + }, function(err) { + if(err) { + return app.alert(err.message); + } + + $('#error').hide(); + $('#notice').hide(); + $('#success').show(); }); } }, false); // Enable the form if the code is valid - socket.emit('api:user.reset.valid', { + socket.emit('user.reset.valid', { code: reset_code - }); - + }, function(err, valid) { + if(err) { + return app.alertError(err.message); + } - ajaxify.register_events(['api:user.reset.valid', 'api:user.reset.commit']); - socket.on('api:user.reset.valid', function(data) { - if ( !! data.valid) resetEl.disabled = false; - else { + if (valid) { + resetEl.disabled = false; + } else { var formEl = document.getElementById('reset-form'); // Show error message $('#error').show(); formEl.parentNode.removeChild(formEl); } - }) - - socket.on('api:user.reset.commit', function(data) { - if (data.status === 'ok') { - $('#error').hide(); - $('#notice').hide(); - $('#success').show(); - } }); }; diff --git a/public/src/forum/topic.js b/public/src/forum/topic.js index 17f80def3f..74b3c3e6af 100644 --- a/public/src/forum/topic.js +++ b/public/src/forum/topic.js @@ -52,16 +52,14 @@ define(['composer'], function(composer) { if (thread_state.deleted !== '1') { bootbox.confirm('Are you sure you want to delete this thread?', function(confirm) { if (confirm) { - socket.emit('api:topics.delete', { - tid: tid - }, null); + socket.emit('topics.delete', tid); } }); } else { bootbox.confirm('Are you sure you want to restore this thread?', function(confirm) { - if (confirm) socket.emit('api:topics.restore', { - tid: tid - }, null); + if (confirm) { + socket.emit('topics.restore', tid); + } }); } return false; @@ -69,26 +67,18 @@ define(['composer'], function(composer) { $('.lock_thread').on('click', function(e) { if (thread_state.locked !== '1') { - socket.emit('api:topics.lock', { - tid: tid - }, null); + socket.emit('topics.lock', tid); } else { - socket.emit('api:topics.unlock', { - tid: tid - }, null); + socket.emit('topics.unlock', tid); } return false; }); $('.pin_thread').on('click', function(e) { if (thread_state.pinned !== '1') { - socket.emit('api:topics.pin', { - tid: tid - }, null); + socket.emit('topics.pin', tid); } else { - socket.emit('api:topics.unpin', { - tid: tid - }, null); + socket.emit('topics.unpin', tid); } return false; }); @@ -102,7 +92,7 @@ define(['composer'], function(composer) { var loadingEl = document.getElementById('categories-loading'); if (loadingEl) { - socket.emit('api:categories.get', function(data) { + socket.emit('categories.get', function(err, data) { // Render categories var categoriesFrag = document.createDocumentFragment(), categoryEl = document.createElement('li'), @@ -145,21 +135,13 @@ define(['composer'], function(composer) { $(moveThreadModal).find('.modal-header button').fadeOut(250); commitEl.innerHTML = 'Moving '; - socket.emit('api:topics.move', { + socket.emit('topics.move', { tid: tid, cid: targetCid - }, function(data) { + }, function(err) { moveThreadModal.modal('hide'); - if (data.status === 'ok') { - app.alert({ - 'alert_id': 'thread_move', - type: 'success', - title: 'Topic Successfully Moved', - message: 'This topic has been successfully moved to ' + targetCatLabel, - timeout: 5000 - }); - } else { - app.alert({ + if(err) { + return app.alert({ 'alert_id': 'thread_move', type: 'danger', title: 'Unable to Move Topic', @@ -167,6 +149,14 @@ define(['composer'], function(composer) { timeout: 5000 }); } + + app.alert({ + 'alert_id': 'thread_move', + type: 'success', + title: 'Topic Successfully Moved', + message: 'This topic has been successfully moved to ' + targetCatLabel, + timeout: 5000 + }); }); } }); @@ -192,7 +182,7 @@ define(['composer'], function(composer) { forkCommit.on('click', createTopicFromPosts); function createTopicFromPosts() { - socket.emit('api:topics.createTopicFromPosts', { + socket.emit('topics.createTopicFromPosts', { title: forkModal.find('#fork-title').val(), pids: pids }, function(err) { @@ -298,15 +288,15 @@ define(['composer'], function(composer) { } }; - socket.emit('api:topics.followCheck', tid, function(state) { + socket.emit('topics.followCheck', tid, function(err, state) { set_follow_state(state, true); }); + if (followEl[0]) { followEl[0].addEventListener('click', function() { - socket.emit('api:topics.follow', tid, function(data) { - if (data.status && data.status === 'ok') set_follow_state(data.follow); - else { - app.alert({ + socket.emit('topics.follow', tid, function(err, state) { + if(err) { + return app.alert({ type: 'danger', alert_id: 'topic_follow', title: 'Please Log In', @@ -314,6 +304,8 @@ define(['composer'], function(composer) { timeout: 5000 }); } + + set_follow_state(state); }); }, false); } @@ -375,9 +367,14 @@ define(['composer'], function(composer) { username = '@' + post.attr('data-username'); } - socket.emit('api:posts.getRawPost', {pid: pid}, function(data) { - - quoted = '> ' + data.post.replace(/\n/g, '\n> ') + '\n\n'; + socket.emit('posts.getRawPost', pid, function(err, post) { + if(err) { + return app.alert(err.message); + } + var quoted = ''; + if(post) { + quoted = '> ' + post.replace(/\n/g, '\n> ') + '\n\n'; + } composer.newReply(tid, topic_name, username + ' said:\n' + quoted); }); @@ -389,12 +386,12 @@ define(['composer'], function(composer) { var uid = $(this).parents('li').attr('data-uid'); if ($(this).attr('data-favourited') == 'false') { - socket.emit('api:posts.favourite', { + socket.emit('posts.favourite', { pid: pid, room_id: app.currentRoom }); } else { - socket.emit('api:posts.unfavourite', { + socket.emit('posts.unfavourite', { pid: pid, room_id: app.currentRoom }); @@ -436,30 +433,20 @@ define(['composer'], function(composer) { $('#post-container').on('click', '.delete', function(e) { var pid = $(this).parents('li').attr('data-pid'), postEl = $(document.querySelector('#post-container li[data-pid="' + pid + '"]')), - deleteAction = !postEl.hasClass('deleted') ? true : false, - confirmDel = confirm((deleteAction ? 'Delete' : 'Restore') + ' this post?'); + action = !postEl.hasClass('deleted') ? 'delete' : 'restore'; - if (confirmDel) { - if(deleteAction) { - socket.emit('api:posts.delete', { - pid: pid, - tid: tid - }, function(err) { - if(err) { - return app.alertError('Can\'t delete post!'); - } - }); - } else { - socket.emit('api:posts.restore', { + bootbox.confirm('Are you sure you want to ' + action + ' this post?', function(confirm) { + if (confirm) { + socket.emit('posts.' + action, { pid: pid, tid: tid }, function(err) { if(err) { - return app.alertError('Can\'t restore post!'); + return app.alertError('Can\'t ' + action + ' post!'); } }); } - } + }); }); $('#post-container').on('click', '.move', function(e) { @@ -488,7 +475,7 @@ define(['composer'], function(composer) { }); moveBtn.on('click', function() { - socket.emit('api:topics.movePost', {pid: pid, tid: topicId.val()}, function(err) { + socket.emit('topics.movePost', {pid: pid, tid: topicId.val()}, function(err) { if(err) { return app.alertError(err.message); } @@ -515,15 +502,15 @@ define(['composer'], function(composer) { }); ajaxify.register_events([ - 'event:rep_up', 'event:rep_down', 'event:new_post', 'api:get_users_in_room', + 'event:rep_up', 'event:rep_down', 'event:new_post', 'get_users_in_room', 'event:topic_deleted', 'event:topic_restored', 'event:topic:locked', 'event:topic_unlocked', 'event:topic_pinned', 'event:topic_unpinned', 'event:topic_moved', 'event:post_edited', 'event:post_deleted', 'event:post_restored', - 'api:posts.favourite' + 'posts.favourite' ]); - socket.on('api:get_users_in_room', function(data) { + socket.on('get_users_in_room', function(data) { if(data) { var activeEl = $('.thread_active_users'); @@ -629,45 +616,47 @@ define(['composer'], function(composer) { }); socket.on('event:topic_deleted', function(data) { - if (data.tid === tid && data.status === 'ok') { + if (data && data.tid === tid) { set_locked_state(true); set_delete_state(true); } }); socket.on('event:topic_restored', function(data) { - if (data.tid === tid && data.status === 'ok') { + if (data && data.tid === tid) { set_locked_state(false); set_delete_state(false); } }); socket.on('event:topic_locked', function(data) { - if (data.tid === tid && data.status === 'ok') { + if (data && data.tid === tid) { set_locked_state(true, 1); } }); socket.on('event:topic_unlocked', function(data) { - if (data.tid === tid && data.status === 'ok') { + if (data && data.tid === tid) { set_locked_state(false, 1); } }); socket.on('event:topic_pinned', function(data) { - if (data.tid === tid && data.status === 'ok') { + if (data && data.tid === tid) { set_pinned_state(true, 1); } }); socket.on('event:topic_unpinned', function(data) { - if (data.tid === tid && data.status === 'ok') { + if (data && data.tid === tid) { set_pinned_state(false, 1); } }); socket.on('event:topic_moved', function(data) { - if (data && data.tid > 0) ajaxify.go('topic/' + data.tid); + if (data && data.tid > 0) { + ajaxify.go('topic/' + data.tid); + } }); socket.on('event:post_edited', function(data) { @@ -689,8 +678,8 @@ define(['composer'], function(composer) { }); - socket.on('api:posts.favourite', function(data) { - if (data.status === 'ok' && data.pid) { + socket.on('posts.favourite', function(data) { + if (data && data.pid) { var favBtn = $('li[data-pid="' + data.pid + '"] .favourite'); if(favBtn.length) { favBtn.addClass('btn-warning') @@ -700,8 +689,8 @@ define(['composer'], function(composer) { } }); - socket.on('api:posts.unfavourite', function(data) { - if (data.status === 'ok' && data.pid) { + socket.on('posts.unfavourite', function(data) { + if (data && data.pid) { var favBtn = $('li[data-pid="' + data.pid + '"] .favourite'); if(favBtn.length) { favBtn.removeClass('btn-warning') @@ -861,7 +850,11 @@ define(['composer'], function(composer) { favEl = postEl.find('.favourite'), replyEl = postEl.find('.post_reply'); - socket.emit('api:posts.getPrivileges', pid, function(privileges) { + socket.emit('posts.getPrivileges', pid, function(err, privileges) { + if(err) { + return app.alert(err.message); + } + if (privileges.editable) { if (!postEl.hasClass('deleted')) { toggle_post_tools(pid, false); @@ -1056,7 +1049,10 @@ define(['composer'], function(composer) { .fadeIn('slow'); for (var x = 0, numPosts = data.posts.length; x < numPosts; x++) { - socket.emit('api:posts.getPrivileges', data.posts[x].pid, function(privileges) { + socket.emit('posts.getPrivileges', data.posts[x].pid, function(err, privileges) { + if(err) { + return app.alertError(err.message); + } toggle_mod_tools(privileges.pid, privileges.editable); }); } @@ -1087,7 +1083,7 @@ define(['composer'], function(composer) { } function updatePostCount() { - socket.emit('api:topics.postcount', templates.get('topic_id'), function(err, postcount) { + socket.emit('topics.postcount', templates.get('topic_id'), function(err, postcount) { if(!err) { Topic.postCount = postcount; $('#topic-post-count').html(Topic.postCount); @@ -1109,12 +1105,16 @@ define(['composer'], function(composer) { indicatorEl.fadeIn(); } - socket.emit('api:topics.loadMore', { + socket.emit('topics.loadMore', { tid: tid, after: parseInt($('#post-container .post-row.infiniteloaded').last().attr('data-index'), 10) + 1 - }, function (data) { + }, function (err, data) { + if(err) { + return app.alertError(err.message); + } + infiniteLoaderActive = false; - if (data.posts.length) { + if (data && data.posts && data.posts.length) { indicatorEl.attr('done', '0'); createNewPosts(data, true); } else { diff --git a/public/src/forum/unread.js b/public/src/forum/unread.js index 3abafa1521..aa70690165 100644 --- a/public/src/forum/unread.js +++ b/public/src/forum/unread.js @@ -8,7 +8,7 @@ define(function() { ajaxify.register_events([ 'event:new_topic', 'event:new_post', - 'api:topics.markAllRead' + 'topics.markAllRead' ]); var newTopicCount = 0, @@ -55,19 +55,19 @@ define(function() { $('#mark-allread-btn').on('click', function() { var btn = $(this); - socket.emit('api:topics.markAllRead', {}, function(success) { - if (success) { - btn.remove(); - $('#topics-container').empty(); - $('#category-no-topics').removeClass('hidden'); - app.alertSuccess('All topics marked as read!'); - $('#numUnreadBadge') - .removeClass('badge-important') - .addClass('badge-inverse') - .html('0'); - } else { - app.alertError('There was an error marking topics read!'); + socket.emit('topics.markAllRead', function(err) { + if(err) { + return app.alertError('There was an error marking topics read!'); } + + btn.remove(); + $('#topics-container').empty(); + $('#category-no-topics').removeClass('hidden'); + app.alertSuccess('All topics marked as read!'); + $('#numUnreadBadge') + .removeClass('badge-important') + .addClass('badge-inverse') + .html('0'); }); }); @@ -91,9 +91,13 @@ define(function() { function loadMoreTopics() { loadingMoreTopics = true; - socket.emit('api:topics.loadMoreUnreadTopics', { + socket.emit('topics.loadMoreUnreadTopics', { after: parseInt($('#topics-container').attr('data-next-start'), 10) - }, function(data) { + }, function(err, data) { + if(err) { + return app.alertError(err.message); + } + if (data.topics && data.topics.length) { onTopicsLoaded(data.topics); $('#topics-container').attr('data-next-start', data.nextStart); diff --git a/public/src/forum/users.js b/public/src/forum/users.js index 23f2a2c27c..de00f3bc38 100644 --- a/public/src/forum/users.js +++ b/public/src/forum/users.js @@ -47,7 +47,7 @@ define(function() { jQuery('#user-notfound-notify').html(''); setTimeout(function() { - socket.emit('api:admin.user.search', username, function(err, data) { + socket.emit('admin.user.search', username, function(err, data) { if(err) { return app.alert(err.message); } @@ -80,10 +80,10 @@ define(function() { }, 250); }); - socket.on('api:user.isOnline', function(data) { + socket.on('user.isOnline', function(err, data) { if(getActiveSection() == 'online' && !loadingMoreUsers) { startLoading('users:online', 0, true); - socket.emit('api:user.getOnlineAnonCount', {} , function(anonCount) { + socket.emit('user.getOnlineAnonCount', {} , function(err, anonCount) { if(parseInt(anonCount, 10) > 0) { $('#users-container .anon-user').removeClass('hide'); $('#online_anon_count').html(anonCount); @@ -123,11 +123,11 @@ define(function() { function startLoading(set, after, emptyContainer) { loadingMoreUsers = true; - socket.emit('api:user.loadMore', { + socket.emit('user.loadMore', { set: set, after: after - }, function(data) { - if (data.users.length) { + }, function(err, data) { + if (data && data.users.length) { onUsersLoaded(data.users, emptyContainer); $('#load-more-users-btn').removeClass('disabled'); } else { diff --git a/public/src/modules/chat.js b/public/src/modules/chat.js index 7184dca42d..82855d0d9f 100644 --- a/public/src/modules/chat.js +++ b/public/src/modules/chat.js @@ -13,13 +13,13 @@ define(['taskbar', 'string'], function(taskbar, S) { return; } - socket.emit('api:modules.chats.list', function(chats) { + socket.emit('modules.chats.list', function(err, chats) { var chatsFrag = document.createDocumentFragment(), chatEl = document.createElement('li'), numChats = chats.length, x, userObj; - if (numChats > 0) { + if (!err && numChats > 0) { for(x=0;x 0) { titleEl.val(postData.title); titleEl.prop('readOnly', true); - socket.emit('api:modules.composer.editCheck', postData.pid, function(editCheck) { - if (editCheck.titleEditable) { + socket.emit('modules.composer.editCheck', postData.pid, function(err, editCheck) { + if (!err && editCheck.titleEditable) { postContainer.find('input').prop('readonly', false); } }); @@ -434,7 +435,7 @@ define(['taskbar'], function(taskbar) { // Still here? Let's post. if (parseInt(postData.cid) > 0) { - socket.emit('api:topics.post', { + socket.emit('topics.post', { 'title' : titleEl.val(), 'content' : bodyEl.val(), 'category_id' : postData.cid @@ -442,14 +443,14 @@ define(['taskbar'], function(taskbar) { composer.discard(post_uuid); }); } else if (parseInt(postData.tid) > 0) { - socket.emit('api:posts.reply', { + socket.emit('posts.reply', { 'topic_id' : postData.tid, 'content' : bodyEl.val() }, function() { composer.discard(post_uuid); }); } else if (parseInt(postData.pid) > 0) { - socket.emit('api:posts.edit', { + socket.emit('posts.edit', { pid: postData.pid, content: bodyEl.val(), title: titleEl.val() @@ -568,12 +569,12 @@ define(['taskbar'], function(taskbar) { dropDiv.hide(); if(file.type.match('image.*')) { - uploadFile('api:posts.uploadImage', post_uuid, fileData); + uploadFile('posts.uploadImage', post_uuid, fileData); } else { if(file.size > parseInt(config.maximumFileSize, 10) * 1024) { return composerAlert('File too big', 'Maximum allowed file size is ' + config.maximumFileSize + 'kbs'); } - uploadFile('api:posts.uploadFile', post_uuid, fileData); + uploadFile('posts.uploadFile', post_uuid, fileData); } }); @@ -582,7 +583,7 @@ define(['taskbar'], function(taskbar) { function uploadFile(method, post_uuid, img) { - var linkStart = method === 'api:posts.uploadImage' ? '!' : '', + var linkStart = method === 'posts.uploadImage' ? '!' : '', postContainer = $('#cmp-uuid-' + post_uuid), textarea = postContainer.find('textarea'), text = textarea.val(), diff --git a/public/src/modules/notifications.js b/public/src/modules/notifications.js index 250bf6e77d..8994ba008a 100644 --- a/public/src/modules/notifications.js +++ b/public/src/modules/notifications.js @@ -11,14 +11,14 @@ define(function() { notifTrigger.addEventListener('click', function(e) { e.preventDefault(); if (notifContainer.className.indexOf('open') === -1) { - socket.emit('api:notifications.get', null, function(data) { + socket.emit('notifications.get', null, function(err, data) { var notifFrag = document.createDocumentFragment(), notifEl = document.createElement('li'), numRead = data.read.length, numUnread = data.unread.length, x; notifList.innerHTML = ''; - if ((data.read.length + data.unread.length) > 0) { + if (!err && (data.read.length + data.unread.length) > 0) { for (x = 0; x < numUnread; x++) { notifEl.setAttribute('data-nid', data.unread[x].nid); notifEl.className = 'unread'; @@ -51,13 +51,15 @@ define(function() { notifIcon.toggleClass('active', false); } - socket.emit('api:modules.notifications.mark_all_read', null, function() { - notifIcon.toggleClass('active', false); - app.refreshTitle(); + socket.emit('modules.notifications.mark_all_read', null, function(err) { + if (!err) { + notifIcon.toggleClass('active', false); + app.refreshTitle(); - // Update favicon + local count - Tinycon.setBubble(0); - localStorage.setItem('notifications:count', 0); + // Update favicon + local count + Tinycon.setBubble(0); + localStorage.setItem('notifications:count', 0); + } }); }); } @@ -78,7 +80,7 @@ define(function() { } if (target) { var nid = parseInt(target.getAttribute('data-nid')); - if (nid > 0) socket.emit('api:modules.notifications.mark_read', nid); + if (nid > 0) socket.emit('modules.notifications.mark_read', nid); } }); @@ -95,7 +97,7 @@ define(function() { localStorage.setItem('notifications:count', count); }; - socket.emit('api:notifications.getCount', function(err, count) { + socket.emit('notifications.getCount', function(err, count) { if (!err) { updateNotifCount(count); } else { diff --git a/public/templates/unread.tpl b/public/templates/unread.tpl index 1054e6d03b..142945b20e 100644 --- a/public/templates/unread.tpl +++ b/public/templates/unread.tpl @@ -15,7 +15,7 @@
-
+
  • diff --git a/src/admin/user.js b/src/admin/user.js index 1c9453b9fb..f295f78916 100644 --- a/src/admin/user.js +++ b/src/admin/user.js @@ -6,11 +6,16 @@ var utils = require('../../public/src/utils'), UserAdmin.createUser = function(uid, userData, callback) { user.isAdministrator(uid, function(err, isAdmin) { + if(err) { + return callback(err); + } + if (isAdmin) { user.create(userData.username, userData.password, userData.email, function(err) { if(err) { - return callback(err.message); + return callback(err); } + callback(null); }); } else { diff --git a/src/categories.js b/src/categories.js index 939073ffcb..465ee43d81 100644 --- a/src/categories.js +++ b/src/categories.js @@ -86,9 +86,7 @@ var db = require('./database.js'), }; function getTopics(next) { - topics.getTopicsByTids(tids, current_user, function(topicsData) { - next(null, topicsData); - }, category_id); + topics.getTopicsByTids(tids, category_id, current_user, next); } function getModerators(next) { @@ -126,9 +124,11 @@ var db = require('./database.js'), Categories.getCategoryTopics = function(cid, start, stop, uid, callback) { Categories.getTopicIds(cid, start, stop, function(err, tids) { - topics.getTopicsByTids(tids, uid, function(topicsData) { - callback(topicsData); - }, cid); + if(err) { + return callback(err); + } + + topics.getTopicsByTids(tids, cid, uid, callback); }); }; @@ -137,7 +137,6 @@ var db = require('./database.js'), }; - Categories.getAllCategories = function(current_user, callback) { db.getListRange('categories:cid', 0, -1, function(err, cids) { if(err) { diff --git a/src/favourites.js b/src/favourites.js index cf19918d94..77e9606084 100644 --- a/src/favourites.js +++ b/src/favourites.js @@ -46,8 +46,7 @@ var db = require('./database'), }); } - socket.emit('api:posts.favourite', { - status: 'ok', + socket.emit('posts.favourite', { pid: pid }); } @@ -83,8 +82,7 @@ var db = require('./database'), }); } - socket.emit('api:posts.unfavourite', { - status: 'ok', + socket.emit('posts.unfavourite', { pid: pid }); } diff --git a/src/meta.js b/src/meta.js index f161cfeb2f..329c6bfe01 100644 --- a/src/meta.js +++ b/src/meta.js @@ -122,7 +122,7 @@ var fs = require('fs'), 'theme:templates': '', 'theme:src': '' }; - +console.log(themeData); switch(data.type) { case 'local': async.waterfall([ diff --git a/src/postTools.js b/src/postTools.js index 64939d67fe..aca3214ded 100644 --- a/src/postTools.js +++ b/src/postTools.js @@ -51,7 +51,11 @@ var winston = require('winston'), } // [getThreadPrivileges, isOwnPost, hasEnoughRep] }, function(err, results) { - callback({ + if(err) { + return callback(err); + } + + callback(null, { read: results.topicPrivs.read, editable: results.topicPrivs.editable || results.isOwner || results.hasEnoughRep, view_deleted: results.topicPrivs.view_deleted || results.isOwner || results.hasEnoughRep @@ -111,7 +115,7 @@ var winston = require('winston'), }); }; - PostTools.privileges(pid, uid, function(privileges) { + PostTools.privileges(pid, uid, function(err, privileges) { if (privileges.editable) { plugins.fireHook('filter:post.save', content, function(err, parsedContent) { if (!err) content = parsedContent; @@ -169,7 +173,7 @@ var winston = require('winston'), return callback(new Error('Post already deleted!')); } - PostTools.privileges(pid, uid, function(privileges) { + PostTools.privileges(pid, uid, function(err, privileges) { if (privileges.editable) { success(); } @@ -223,7 +227,7 @@ var winston = require('winston'), return callback(new Error('Post already restored')); } - PostTools.privileges(pid, uid, function(privileges) { + PostTools.privileges(pid, uid, function(err, privileges) { if (privileges.editable) { success(); } diff --git a/src/posts.js b/src/posts.js index 42165f2b47..bf3be7bfdb 100644 --- a/src/posts.js +++ b/src/posts.js @@ -368,41 +368,41 @@ var db = require('./database'), Posts.uploadPostImage = function(image, callback) { if(meta.config.imgurClientID) { - if(!image) { + if(!image || !image.data) { return callback('invalid image', null); } require('./imgur').upload(meta.config.imgurClientID, image.data, 'base64', function(err, data) { if(err) { - callback(err.message, null); - } else { - callback(null, { - url: data.link, - name: image.name - }); + return callback(err); } + + callback(null, { + url: data.link, + name: image.name + }); }); } else if (meta.config.allowFileUploads) { Posts.uploadPostFile(image, callback); } else { - callback('Uploads are disabled!'); + callback(new Error('Uploads are disabled!')); } } Posts.uploadPostFile = function(file, callback) { if(!meta.config.allowFileUploads) { - return callback('File uploads are not allowed'); + return callback(new Error('File uploads are not allowed')); } - if(!file) { - return callback('invalid file'); + if(!file || !file.data) { + return callback(new Error('invalid file')); } var buffer = new Buffer(file.data, 'base64'); if(buffer.length > parseInt(meta.config.maximumFileSize, 10) * 1024) { - return callback('File too big'); + return callback(new Error('File too big')); } var filename = 'upload-' + utils.generateUUID() + path.extname(file.name); @@ -410,13 +410,13 @@ var db = require('./database'), fs.writeFile(uploadPath, buffer, function (err) { if(err) { - callback(err.message, null); - } else { - callback(null, { - url: nconf.get('upload_url') + filename, - name: file.name - }); + return callback(err); } + + callback(null, { + url: nconf.get('upload_url') + filename, + name: file.name + }); }); } @@ -427,7 +427,7 @@ var db = require('./database'), } async.filter(pids, function(pid, next) { - postTools.privileges(pid, 0, function(privileges) { + postTools.privileges(pid, 0, function(err, privileges) { next(privileges.read); }); }, function(pids) { diff --git a/src/routes/api.js b/src/routes/api.js index 44a155370f..700949d6e5 100644 --- a/src/routes/api.js +++ b/src/routes/api.js @@ -189,16 +189,24 @@ var path = require('path'), }); }); - app.get('/unread', function (req, res) { + app.get('/unread', function (req, res, next) { var uid = (req.user) ? req.user.uid : 0; - topics.getUnreadTopics(uid, 0, 19, function (data) { + topics.getUnreadTopics(uid, 0, 19, function (err, data) { + if(err) { + return next(err); + } + res.json(data); }); }); - app.get('/unread/total', function (req, res) { + app.get('/unread/total', function (req, res, next) { var uid = (req.user) ? req.user.uid : 0; - topics.getTotalUnread(uid, function (data) { + topics.getTotalUnread(uid, function (err, data) { + if(err) { + return next(err); + } + res.json(data); }); }); @@ -286,9 +294,9 @@ var path = require('path'), return callback(err, null); } - topics.getTopicsByTids(tids, 0, function (topics) { + topics.getTopicsByTids(tids, 0, 0, function (topics) { callback(null, topics); - }, 0); + }); }); } diff --git a/src/socket.io/admin.js b/src/socket.io/admin.js index 80125df302..320f0d4a64 100644 --- a/src/socket.io/admin.js +++ b/src/socket.io/admin.js @@ -15,16 +15,17 @@ var groups = require('../groups'), async = require('async'), winston = require('winston'), + index = require('./index'), SocketAdmin = {}; -SocketAdmin.before = function(sessionData, next) { +SocketAdmin.before = function(socket, next) { // Verify administrative privileges - user.isAdministrator(sessionData.uid, function(err, isAdmin) { + user.isAdministrator(socket.uid, function(err, isAdmin) { if (isAdmin) { next(); } else { - winston.warn('[socket.io] Call to admin method blocked (accessed by uid ' + sessionData.uid + ')'); + winston.warn('[socket.io] Call to admin method blocked (accessed by uid ' + socket.uid + ')'); } }); }; @@ -33,54 +34,51 @@ SocketAdmin.before = function(sessionData, next) { SocketAdmin.topics = {}; -SocketAdmin.topics.getMore = function(data, callback) { - topics.getAllTopics(data.limit, data.after, function(err, topics) { - callback(JSON.stringify(topics)); - }); +SocketAdmin.topics.getMore = function(socket, data, callback) { + if(!data) { + return callback(new Error('invalid data')); + } + + topics.getAllTopics(data.limit, data.after, callback); }; /* User */ SocketAdmin.user = {}; -SocketAdmin.user.makeAdmin = function(theirid, sessionData) { - if (sessionData.uid && sessionData.uid > 0) { - admin.user.makeAdmin(sessionData.uid, theirid, sessionData.socket); - } +SocketAdmin.user.makeAdmin = function(socket, theirid) { + admin.user.makeAdmin(socket.uid, theirid, socket); }; -SocketAdmin.user.removeAdmin = function(theirid, sessionData) { - if (sessionData.uid && sessionData.uid > 0) { - admin.user.removeAdmin(sessionData.uid, theirid, sessionData.socket); - } +SocketAdmin.user.removeAdmin = function(socket, theirid) { + admin.user.removeAdmin(socket.uid, theirid, socket); }; -SocketAdmin.user.createUser = function(user, callback, sessionData) { - if (sessionData.uid && sessionData.uid > 0) { - admin.user.createUser(sessionData.uid, user, callback); +SocketAdmin.user.createUser = function(socket, user, callback) { + if(!user) { + return callback(new Error('invalid data')); } + admin.user.createUser(socket.uid, user, callback); }; -SocketAdmin.user.banUser = function(theirid, sessionData) { - if (sessionData.uid && sessionData.uid > 0) { - admin.user.banUser(sessionData.uid, theirid, sessionData.socket, function(isBanned) { - if(isBanned) { - if(sessionData.userSockets[theirid]) { - for(var i=0; i 0; + return !!Sockets.userSockets[uid] && Sockets.userSockets[uid].length > 0; } Sockets.updateRoomBrowsingText = updateRoomBrowsingText; @@ -251,15 +236,15 @@ function updateRoomBrowsingText(roomName) { return anonCount; } - var uids = getUidsInRoom(rooms[roomName]), + var uids = getUidsInRoom(Sockets.rooms[roomName]), anonymousCount = getAnonymousCount(roomName); if (uids.length === 0) { - io.sockets.in(roomName).emit('api:get_users_in_room', { users: [], anonymousCount: anonymousCount }); + io.sockets.in(roomName).emit('get_users_in_room', { users: [], anonymousCount: anonymousCount }); } else { user.getMultipleUserFields(uids, ['uid', 'username', 'userslug', 'picture'], function(err, users) { if(!err) { - io.sockets.in(roomName).emit('api:get_users_in_room', { users: users, anonymousCount: anonymousCount }); + io.sockets.in(roomName).emit('get_users_in_room', { users: users, anonymousCount: anonymousCount }); } }); } @@ -278,17 +263,17 @@ function emitTopicPostStats(callback) { }; if (!callback) { - io.sockets.emit('post.stats', stats); + io.sockets.emit('post.stats', null, stats); } else { - callback(stats); + callback(null, stats); } }); } Sockets.emitOnlineUserCount = emitOnlineUserCount; function emitOnlineUserCount(callback) { - var anon = userSockets[0] ? userSockets[0].length : 0; - var registered = Object.keys(userSockets).length; + var anon = Sockets.userSockets[0] ? Sockets.userSockets[0].length : 0; + var registered = Object.keys(Sockets.userSockets).length; if (anon) { registered = registered - 1; } @@ -299,9 +284,9 @@ function emitOnlineUserCount(callback) { }; if (callback) { - callback(returnObj); + callback(null, returnObj); } else { - io.sockets.emit('api:user.active.get', returnObj); + io.sockets.emit('user.getActiveUsers', null, returnObj); } } diff --git a/src/socket.io/meta.js b/src/socket.io/meta.js index dbba311fab..9c8d2b8ed8 100644 --- a/src/socket.io/meta.js +++ b/src/socket.io/meta.js @@ -7,12 +7,13 @@ var meta = require('../meta'), nconf = require('nconf'), gravatar = require('gravatar'), winston = require('winston'), + server = require('./'), SocketMeta = {}; -SocketMeta.reconnected = function(sessionData) { - var uid = sessionData.uid, - sessionID = sessionData.socket.id; +SocketMeta.reconnected = function(socket) { + var uid = socket.uid, + sessionID = socket.id; if (uid) { topics.pushUnreadCount(uid); @@ -28,22 +29,30 @@ SocketMeta.reconnected = function(sessionData) { } }; -SocketMeta.buildTitle = function(text, callback) { - meta.title.build(text, function(err, title) { - callback(title); - }); +SocketMeta.buildTitle = function(socket, text, callback) { + meta.title.build(text, callback); }; -SocketMeta.updateHeader = function(data, callback, sessionData) { - if (sessionData.uid) { - user.getUserFields(sessionData.uid, data.fields, function(err, fields) { - if (!err && fields) { - fields.uid = sessionData.uid; - callback(fields); +SocketMeta.updateHeader = function(socket, data, callback) { + if(!data) { + return callback(new Error('invalid data')); + } + + if (socket.uid) { + user.getUserFields(socket.uid, data.fields, function(err, fields) { + if(err) { + return callback(err); + } + + if (fields) { + fields.uid = socket.uid; + callback(null, fields); + } else { + callback(null, []); } }); } else { - callback({ + callback(null, { uid: 0, username: "Anonymous User", email: '', @@ -57,7 +66,7 @@ SocketMeta.updateHeader = function(data, callback, sessionData) { } }; -SocketMeta.getUsageStats = function(callback) { +SocketMeta.getUsageStats = function(socket, data, callback) { module.parent.exports.emitTopicPostStats(callback); }; @@ -65,19 +74,23 @@ SocketMeta.getUsageStats = function(callback) { SocketMeta.rooms = {}; -SocketMeta.rooms.enter = function(data, sessionData) { +SocketMeta.rooms.enter = function(socket, data) { + if(!data) { + return callback(new Error('invalid data')); + } + if (data.leave !== null) { - sessionData.socket.leave(data.leave); + socket.leave(data.leave); } - sessionData.socket.join(data.enter); - sessionData.rooms[data.enter] = sessionData.rooms[data.enter] || {}; + socket.join(data.enter); + server.rooms[data.enter] = server.rooms[data.enter] || {}; - if (sessionData.uid) { - sessionData.rooms[data.enter][sessionData.socket.id] = sessionData.uid; + if (socket.uid) { + server.rooms[data.enter][socket.id] = socket.uid; - if (data.leave && sessionData.rooms[data.leave] && sessionData.rooms[data.leave][sessionData.socket.id] && data.enter !== data.leave) { - delete sessionData.rooms[data.leave][sessionData.socket.id]; + if (data.leave && server.rooms[data.leave] && server.rooms[data.leave][socket.id] && data.enter !== data.leave) { + delete server.rooms[data.leave][socket.id]; } } @@ -88,12 +101,12 @@ SocketMeta.rooms.enter = function(data, sessionData) { module.parent.exports.updateRoomBrowsingText(data.enter); if (data.enter != 'admin') { - sessionData.server.sockets.in('admin').emit('event:meta.rooms.update', sessionData.server.sockets.manager.rooms); + server.in('admin').emit('event:meta.rooms.update', null, server.rooms); } }; -SocketMeta.rooms.getAll = function(callback, sessionData) { - callback(sessionData.server.sockets.manager.rooms); +SocketMeta.rooms.getAll = function(socket, data, callback) { + callback(null, server.rooms); }; /* Exports */ diff --git a/src/socket.io/modules.js b/src/socket.io/modules.js index a85a38bb2d..22d8458e23 100644 --- a/src/socket.io/modules.js +++ b/src/socket.io/modules.js @@ -11,6 +11,7 @@ var posts = require('../posts'), async = require('async'), S = require('string'), winston = require('winston'), + server = require('./'), SocketModules = {}; @@ -18,38 +19,44 @@ var posts = require('../posts'), SocketModules.composer = {}; -SocketModules.composer.push = function(data, callback, sessionData) { - if (parseInt(sessionData.uid, 10) > 0 || parseInt(meta.config.allowGuestPosting, 10) === 1) { - if (parseInt(data.pid, 10) > 0) { +SocketModules.composer.push = function(socket, pid, callback) { + if (socket.uid || parseInt(meta.config.allowGuestPosting, 10)) { + if (parseInt(pid, 10) > 0) { async.parallel([ function(next) { - posts.getPostFields(data.pid, ['content'], next); + posts.getPostFields(pid, ['content'], next); }, function(next) { - topics.getTitleByPid(data.pid, function(title) { + topics.getTitleByPid(pid, function(title) { next(null, title); }); } ], function(err, results) { - callback({ + if(err) { + return callback(err); + } + + callback(null, { title: results[1], - pid: data.pid, + pid: pid, body: results[0].content }); }); } } else { - callback({ - error: 'no-uid' - }); + callback(new Error('no-uid')); } }; -SocketModules.composer.editCheck = function(pid, callback) { +SocketModules.composer.editCheck = function(socket, pid, callback) { posts.getPostField(pid, 'tid', function(err, tid) { + if (err) { + return callback(err); + } + postTools.isMain(pid, tid, function(err, isMain) { - callback({ + callback(err, { titleEditable: isMain }); }); @@ -60,27 +67,27 @@ SocketModules.composer.editCheck = function(pid, callback) { SocketModules.chats = {}; -SocketModules.chats.get = function(data, callback, sessionData) { - var touid = data.touid; - Messaging.getMessages(sessionData.uid, touid, function(err, messages) { - if (err) { - return callback(null); - } +SocketModules.chats.get = function(socket, data, callback) { + if(!data) { + return callback(new Error('invalid data')); + } - callback(messages); - }); + Messaging.getMessages(socket.uid, data.touid, callback); }; -SocketModules.chats.send = function(data, sessionData) { +SocketModules.chats.send = function(socket, data) { + if(!data) { + return callback(new Error('invalid data')); + } var touid = data.touid; - if (touid === sessionData.uid || sessionData.uid === 0) { + if (touid === socket.uid || socket.uid === 0) { return; } var msg = S(data.message).stripTags().s; - user.getMultipleUserFields([sessionData.uid, touid], ['username'], function(err, usersData) { + user.getMultipleUserFields([socket.uid, touid], ['username'], function(err, usersData) { if(err) { return; } @@ -91,23 +98,23 @@ SocketModules.chats.send = function(data, sessionData) { notifText = 'New message from ' + username + ''; if (!module.parent.exports.isUserOnline(touid)) { - notifications.create(notifText, 'javascript:app.openChat('' + username + '', ' + sessionData.uid + ');', 'notification_' + sessionData.uid + '_' + touid, function(nid) { + notifications.create(notifText, 'javascript:app.openChat('' + username + '', ' + socket.uid + ');', 'notification_' + socket.uid + '_' + touid, function(nid) { notifications.push(nid, [touid], function(success) { }); }); } - Messaging.parse(msg, sessionData.uid, sessionData.uid, toUsername, function(parsed) { - Messaging.addMessage(sessionData.uid, touid, msg, function(err, message) { + Messaging.parse(msg, socket.uid, socket.uid, toUsername, function(parsed) { + Messaging.addMessage(socket.uid, touid, msg, function(err, message) { var numSockets = 0, x; - if (sessionData.userSockets[touid]) { - numSockets = sessionData.userSockets[touid].length; + if (server.userSockets[touid]) { + numSockets = server.userSockets[touid].length; for (x = 0; x < numSockets; ++x) { - sessionData.userSockets[touid][x].emit('event:chats.receive', { - fromuid: sessionData.uid, + server.userSockets[touid][x].emit('event:chats.receive', { + fromuid: socket.uid, username: username, // todo this isnt very nice, but can't think of a better way atm message: parsed.replace("chat-user-you'>You", "'>" + username), @@ -116,12 +123,12 @@ SocketModules.chats.send = function(data, sessionData) { } } - if (sessionData.userSockets[sessionData.uid]) { + if (server.userSockets[socket.uid]) { - numSockets = sessionData.userSockets[sessionData.uid].length; + numSockets = server.userSockets[socket.uid].length; for (x = 0; x < numSockets; ++x) { - sessionData.userSockets[sessionData.uid][x].emit('event:chats.receive', { + server.userSockets[socket.uid][x].emit('event:chats.receive', { fromuid: touid, username: toUsername, message: parsed, @@ -134,30 +141,20 @@ SocketModules.chats.send = function(data, sessionData) { }); }; -SocketModules.chats.list = function(callback, sessionData) { - Messaging.getRecentChats(sessionData.uid, function(err, uids) { - if (err) { - winston.warn('[(socket) api:chats.list] Problem retrieving chats: ' + err.message); - } - - callback(uids || []); - }); +SocketModules.chats.list = function(socket, data, callback) { + Messaging.getRecentChats(socket.uid, callback); }; /* Notifications */ SocketModules.notifications = {}; -SocketModules.notifications.mark_read = function(nid, sessionData) { - notifications.mark_read(nid, sessionData.uid); +SocketModules.notifications.mark_read = function(socket, nid) { + notifications.mark_read(nid, socket.uid); }; -SocketModules.notifications.mark_all_read = function(data, callback, sessionData) { - notifications.mark_all_read(sessionData.uid, function(err) { - if (!err) { - callback(); - } - }); +SocketModules.notifications.mark_all_read = function(socket, data, callback) { + notifications.mark_all_read(socket.uid, callback); }; module.exports = SocketModules; \ No newline at end of file diff --git a/src/socket.io/notifications.js b/src/socket.io/notifications.js index 6f8085311b..3c41f33d5d 100644 --- a/src/socket.io/notifications.js +++ b/src/socket.io/notifications.js @@ -1,17 +1,15 @@ +"use strict"; + var user = require('../user'), SocketNotifs = {}; -SocketNotifs.get = function(data, callback, sessionData) { - user.notifications.get(sessionData.uid, function(notifs) { - callback(notifs); - }); +SocketNotifs.get = function(socket, data, callback) { + user.notifications.get(socket.uid, callback); }; -SocketNotifs.getCount = function(callback, sessionData) { - user.notifications.getUnreadCount(sessionData.uid, function(err, count) { - callback(err ? err.message : null, count); - }); +SocketNotifs.getCount = function(socket, data, callback) { + user.notifications.getUnreadCount(socket.uid, callback); }; module.exports = SocketNotifs; \ No newline at end of file diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js index 950bcff8c8..0baed5d0b4 100644 --- a/src/socket.io/posts.js +++ b/src/socket.io/posts.js @@ -3,12 +3,13 @@ var posts = require('../posts'), topics = require('../topics'), favourites = require('../favourites'), postTools = require('../postTools'), + index = require('./index'), SocketPosts = {}; -SocketPosts.reply = function(data, callback, sessionData) { - if (sessionData.uid < 1 && parseInt(meta.config.allowGuestPosting, 10) === 0) { - sessionData.socket.emit('event:alert', { +SocketPosts.reply = function(socket, data, callback) { + if (!socket.uid && !parseInt(meta.config.allowGuestPosting, 10)) { + socket.emit('event:alert', { title: 'Reply Unsuccessful', message: 'You don't seem to be logged in, so you cannot reply.', type: 'danger', @@ -17,35 +18,39 @@ SocketPosts.reply = function(data, callback, sessionData) { return; } - topics.reply(data.topic_id, sessionData.uid, data.content, function(err, postData) { + if(!data || !data.topic_id || !data.content) { + return callback(new Error('invalid data')); + } + + topics.reply(data.topic_id, socket.uid, data.content, function(err, postData) { if(err) { if (err.message === 'content-too-short') { - module.parent.exports.emitContentTooShortAlert(sessionData.socket); + module.parent.exports.emitContentTooShortAlert(socket); } else if (err.message === 'too-many-posts') { - module.parent.exports.emitTooManyPostsAlert(sessionData.socket); + module.parent.exports.emitTooManyPostsAlert(socket); } else if (err.message === 'reply-error') { - sessionData.socket.emit('event:alert', { + socket.emit('event:alert', { title: 'Reply Unsuccessful', message: 'Your reply could not be posted at this time. Please try again later.', type: 'warning', timeout: 2000 }); } else if (err.message === 'no-privileges') { - sessionData.socket.emit('event:alert', { + socket.emit('event:alert', { title: 'Unable to post', message: 'You do not have posting privileges in this category.', type: 'danger', timeout: 7500 }); } - return; + return callback(err); } if (postData) { module.parent.exports.emitTopicPostStats(); - sessionData.socket.emit('event:alert', { + socket.emit('event:alert', { title: 'Reply Successful', message: 'You have successfully replied. Click here to view your reply.', type: 'success', @@ -54,62 +59,71 @@ SocketPosts.reply = function(data, callback, sessionData) { var socketData = { posts: [postData] }; - sessionData.server.sockets.in('topic_' + postData.tid).emit('event:new_post', socketData); - sessionData.server.sockets.in('recent_posts').emit('event:new_post', socketData); - sessionData.server.sockets.in('user/' + postData.uid).emit('event:new_post', socketData); + index.server.sockets.in('topic_' + postData.tid).emit('event:new_post', socketData); + index.server.sockets.in('recent_posts').emit('event:new_post', socketData); + index.server.sockets.in('user/' + postData.uid).emit('event:new_post', socketData); callback(); } - }); }; -SocketPosts.favourite = function(data, sessionData) { - favourites.favourite(data.pid, data.room_id, sessionData.uid, sessionData.socket); +SocketPosts.favourite = function(socket, data) { + if(data && data.pid && data.room_id) { + favourites.favourite(data.pid, data.room_id, socket.uid, socket); + } }; -SocketPosts.unfavourite = function(data, sessionData) { - favourites.unfavourite(data.pid, data.room_id, sessionData.uid, sessionData.socket); +SocketPosts.unfavourite = function(socket, data) { + if(data && data.pid && data.room_id) { + favourites.unfavourite(data.pid, data.room_id, socket.uid, socket); + } }; -SocketPosts.uploadImage = function(data, callback) { - posts.uploadPostImage(data, callback); +SocketPosts.uploadImage = function(socket, data, callback) { + if(data) { + posts.uploadPostImage(data, callback); + } }; -SocketPosts.uploadFile = function(data, callback) { - posts.uploadPostFile(data, callback); +SocketPosts.uploadFile = function(socket, data, callback) { + if(data) { + posts.uploadPostFile(data, callback); + } }; -SocketPosts.getRawPost = function(data, callback) { - posts.getPostField(data.pid, 'content', function(err, raw) { - callback({ - post: raw - }); - }); +SocketPosts.getRawPost = function(socket, pid, callback) { + posts.getPostField(pid, 'content', callback); }; -SocketPosts.edit = function(data, callback, sessionData) { - if(!sessionData.uid) { - sessionData.socket.emit('event:alert', { +SocketPosts.edit = function(socket, data, callback) { + if(!socket.uid) { + socket.emit('event:alert', { title: 'Can't edit', message: 'Guests can't edit posts!', type: 'warning', timeout: 2000 }); return; + } else if(!data || !data.pid || !data.title || !data.content) { + return callback(new Error('invalid data')); } else if (!data.title || data.title.length < parseInt(meta.config.minimumTitleLength, 10)) { - topics.emitTitleTooShortAlert(sessionData.socket); + topics.emitTitleTooShortAlert(socket); return; } else if (!data.content || data.content.length < parseInt(meta.config.minimumPostLength, 10)) { - module.parent.exports.emitContentTooShortAlert(sessionData.socket); + module.parent.exports.emitContentTooShortAlert(socket); return; } - postTools.edit(sessionData.uid, data.pid, data.title, data.content, data.images); + postTools.edit(socket.uid, data.pid, data.title, data.content); callback(); }; -SocketPosts.delete = function(data, callback, sessionData) { - postTools.delete(sessionData.uid, data.pid, function(err) { +SocketPosts.delete = function(socket, data, callback) { + if(!data) { + return callback(new Error('invalid data')); + } + + postTools.delete(socket.uid, data.pid, function(err) { if(err) { return callback(err); @@ -117,32 +131,40 @@ SocketPosts.delete = function(data, callback, sessionData) { module.parent.exports.emitTopicPostStats(); - sessionData.server.sockets.in('topic_' + data.tid).emit('event:post_deleted', { + index.server.sockets.in('topic_' + data.tid).emit('event:post_deleted', { pid: data.pid }); - callback(null); + callback(); }); }; -SocketPosts.restore = function(data, callback, sessionData) { - postTools.restore(sessionData.uid, data.pid, function(err) { +SocketPosts.restore = function(socket, data, callback) { + if(!data) { + return callback(new Error('invalid data')); + } + + postTools.restore(socket.uid, data.pid, function(err) { if(err) { return callback(err); } module.parent.exports.emitTopicPostStats(); - sessionData.server.sockets.in('topic_' + data.tid).emit('event:post_restored', { + index.server.sockets.in('topic_' + data.tid).emit('event:post_restored', { pid: data.pid }); - callback(null); + + callback(); }); }; -SocketPosts.getPrivileges = function(pid, callback, sessionData) { - postTools.privileges(pid, sessionData.uid, function(privileges) { +SocketPosts.getPrivileges = function(socket, pid, callback) { + postTools.privileges(pid, socket.uid, function(err, privileges) { + if(err) { + return callback(err); + } privileges.pid = parseInt(pid); - callback(privileges); + callback(null, privileges); }); }; diff --git a/src/socket.io/topics.js b/src/socket.io/topics.js index 43e8b8e127..d79bb1b8a6 100644 --- a/src/socket.io/topics.js +++ b/src/socket.io/topics.js @@ -1,12 +1,15 @@ var topics = require('../topics'), threadTools = require('../threadTools'), - + index = require('./index'), SocketTopics = {}; -SocketTopics.post = function(data, callback, sessionData) { - var socket = sessionData.socket; +SocketTopics.post = function(socket, data, callback) { + + if(!data) { + return callback(new Error('Invalid data')); + } - if (sessionData.uid < 1 && parseInt(meta.config.allowGuestPosting, 10) === 0) { + if (!socket.uid && !parseInt(meta.config.allowGuestPosting, 10)) { socket.emit('event:alert', { title: 'Post Unsuccessful', message: 'You don't seem to be logged in, so you cannot reply.', @@ -16,7 +19,7 @@ SocketTopics.post = function(data, callback, sessionData) { return; } - topics.post(sessionData.uid, data.title, data.content, data.category_id, function(err, result) { + topics.post(socket.uid, data.title, data.content, data.category_id, function(err, result) { if(err) { if (err.message === 'title-too-short') { module.parent.exports.emitAlert(socket, 'Title too short', 'Please enter a longer title. At least ' + meta.config.minimumTitleLength + ' characters.'); @@ -45,9 +48,9 @@ SocketTopics.post = function(data, callback, sessionData) { } if (result) { - sessionData.server.sockets.in('category_' + data.category_id).emit('event:new_topic', result.topicData); - sessionData.server.sockets.in('recent_posts').emit('event:new_topic', result.topicData); - sessionData.server.sockets.in('user/' + sessionData.uid).emit('event:new_post', { + index.server.sockets.in('category_' + data.category_id).emit('event:new_topic', result.topicData); + index.server.sockets.in('recent_posts').emit('event:new_topic', result.topicData); + index.server.sockets.in('user/' + socket.uid).emit('event:new_post', { posts: result.postData }); @@ -59,95 +62,73 @@ SocketTopics.post = function(data, callback, sessionData) { type: 'success', timeout: 2000 }); - callback(); + callback(null); } }); }; -SocketTopics.postcount = function(tid, callback) { +SocketTopics.postcount = function(socket, tid, callback) { topics.getTopicField(tid, 'postcount', callback); }; -SocketTopics.markAllRead = function(data, callback, sessionData) { - topics.markAllRead(sessionData.uid, function(err, success) { - if (!err && success) { - callback(true); - sessionData.server.sockets.in('uid_' + sessionData.uid).emit('event:unread.updateCount', 0); - } else { - callback(false); +SocketTopics.markAllRead = function(socket, data, callback) { + topics.markAllRead(socket.uid, function(err) { + if(err) { + return callback(err); } + + index.server.sockets.in('uid_' + socket.uid).emit('event:unread.updateCount', null, 0); + + callback(null); }); }; -SocketTopics.delete = function(data, callback, sessionData) { - threadTools.privileges(data.tid, sessionData.uid, function(err, privileges) { - if (!err && privileges.editable) { - threadTools.delete(data.tid, sessionData.uid, function(err) { - if (!err) { - module.parent.exports.emitTopicPostStats(); - if (callback) { - callback('api:topic.delete', { - status: 'ok', - tid: data.tid - }); - } - } - }); +function doTopicAction(action, socket, tid, callback) { + if(!tid) { + return callback(new Error('Invalid tid')); + } + + threadTools.privileges(tid, socket.uid, function(err, privileges) { + if(err) { + return callback(err); } - }); -}; -SocketTopics.restore = function(data, callback, sessionData) { - threadTools.privileges(data.tid, sessionData.uid, function(err, privileges) { - if (!err && privileges.editable) { - threadTools.restore(data.tid, sessionData.uid, function(err) { - module.parent.exports.emitTopicPostStats(); + if(!privileges || !privileges.editable) { + return callback(new Error('not-allowed')); + } - if (callback) { - callback('api:topic.restore', { - status: 'ok', - tid: data.tid - }); - } - }); + if(threadTools[action]) { + threadTools[action](tid, socket.uid, callback); } }); +} + +SocketTopics.delete = function(socket, tid, callback) { + doTopicAction('delete', socket, tid, callback); }; -SocketTopics.lock = function(data, callback, sessionData) { - threadTools.privileges(data.tid, sessionData.uid, function(err, privileges) { - if (!err && privileges.editable) { - threadTools.lock(data.tid, callback); - } - }); +SocketTopics.restore = function(socket, tid, callback) { + doTopicAction('restore', socket, tid, callback); }; -SocketTopics.unlock = function(data, callback, sessionData) { - threadTools.privileges(data.tid, sessionData.uid, function(err, privileges) { - if (!err && privileges.editable) { - threadTools.unlock(data.tid, callback); - } - }); +SocketTopics.lock = function(socket, tid, callback) { + doTopicAction('lock', socket, tid, callback); }; -SocketTopics.pin = function(data, callback, sessionData) { - threadTools.privileges(data.tid, sessionData.uid, function(err, privileges) { - if (!err && privileges.editable) { - threadTools.pin(data.tid, callback); - } - }); +SocketTopics.unlock = function(socket, tid, callback) { + doTopicAction('unlock', socket, tid, callback); }; -SocketTopics.unpin = function(data, callback, sessionData) { - threadTools.privileges(data.tid, sessionData.uid, function(err, privileges) { - if (!err && privileges.editable) { - threadTools.unpin(data.tid, callback); - } - }); +SocketTopics.pin = function(socket, tid, callback) { + doTopicAction('pin', socket, tid, callback); +}; + +SocketTopics.unpin = function(socket, tid, callback) { + doTopicAction('unpin', socket, tid, callback); }; -SocketTopics.createTopicFromPosts = function(data, callback, sessionData) { - if(!sessionData.uid) { +SocketTopics.createTopicFromPosts = function(socket, data, callback) { + if(!socket.uid) { socket.emit('event:alert', { title: 'Can't fork', message: 'Guests can't fork topics!', @@ -157,13 +138,15 @@ SocketTopics.createTopicFromPosts = function(data, callback, sessionData) { return; } - topics.createTopicFromPosts(sessionData.uid, data.title, data.pids, function(err, data) { - callback(err?{message:err.message}:null, data); - }); + if(!data || !data.title || !data.pids || !Array.isArray(data.pids)) { + return callback(new Error('invalid data')); + } + + topics.createTopicFromPosts(socket.uid, data.title, data.pids, callback); }; -SocketTopics.movePost = function(data, callback, sessionData) { - if(!sessionData.uid) { +SocketTopics.movePost = function(socket, data, callback) { + if(!socket.uid) { socket.emit('event:alert', { title: 'Can't fork', message: 'Guests can't fork topics!', @@ -173,65 +156,74 @@ SocketTopics.movePost = function(data, callback, sessionData) { return; } - topics.movePostToTopic(data.pid, data.tid, function(err, data) { - callback(err?{message:err.message}:null, data); - }); -}; + if(!data || !data.pid || !data.tid) { + return callback(new Error('invalid data')); + } -SocketTopics.move = function(data, callback, sessionData) { - threadTools.move(data.tid, data.cid, callback, sessionData); + topics.movePostToTopic(data.pid, data.tid, callback); }; -SocketTopics.followCheck = function(tid, callback, sessionData) { - threadTools.isFollowing(tid, sessionData.uid, function(following) { - callback(following); +SocketTopics.move = function(socket, data, callback) { + + if(!data || !data.tid || !data.cid) { + return callback(new Error('invalid data')); + } + + threadTools.move(data.tid, data.cid, function(err) { + if(err) { + return callback(err); + } + + index.server.sockets.in('topic_' + data.tid).emit('event:topic_moved', { + tid: data.tid + }); + + callback(null); }); }; -SocketTopics.follow = function(tid, callback, sessionData) { - if (sessionData.uid && sessionData.uid > 0) { - threadTools.toggleFollow(tid, sessionData.uid, function(follow) { - if (follow.status === 'ok') callback(follow); - }); - } else { - callback({ - status: 'error', - error: 'not-logged-in' - }); +SocketTopics.followCheck = function(socket, tid, callback) { + threadTools.isFollowing(tid, socket.uid, callback); +}; + +SocketTopics.follow = function(socket, tid, callback) { + if(!socket.uid) { + return callback(new Error('not-logged-in')); } + + + threadTools.toggleFollow(tid, socket.uid, callback); }; -SocketTopics.loadMore = function(data, callback, sessionData) { +SocketTopics.loadMore = function(socket, data, callback) { + if(!data || !data.tid) { + return callback(new Error('invalid data')); + } + var start = data.after, end = start + 9; - topics.getTopicPosts(data.tid, start, end, sessionData.uid, function(err, posts) { - callback({ - posts: posts - }); + topics.getTopicPosts(data.tid, start, end, socket.uid, function(err, posts) { + callback(err, {posts: posts}); }); }; -SocketTopics.loadMoreRecentTopics = function(data, callback, sessionData) { +SocketTopics.loadMoreRecentTopics = function(socket, data, callback) { + if(!data || !data.term) { + return callback(new Error('invalid data')); + } + var start = data.after, end = start + 9; - topics.getLatestTopics(sessionData.uid, start, end, data.term, function(err, latestTopics) { - if (!err) { - callback(latestTopics); - } else { - winston.error('[socket api:topics.loadMoreRecentTopics] ' + err.message); - } - }); + topics.getLatestTopics(socket.uid, start, end, data.term, callback); }; -SocketTopics.loadMoreUnreadTopics = function(data, callback, sessionData) { +SocketTopics.loadMoreUnreadTopics = function(socket, data, callback) { var start = data.after, end = start + 9; - topics.getUnreadTopics(sessionData.uid, start, end, function(unreadTopics) { - callback(unreadTopics); - }); + topics.getUnreadTopics(socket.uid, start, end, callback); }; module.exports = SocketTopics; \ No newline at end of file diff --git a/src/socket.io/user.js b/src/socket.io/user.js index d81779ad50..81df38e33a 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -3,149 +3,164 @@ var user = require('../user'), SocketUser = {}; -SocketUser.exists = function(data, sessionData) { - if (data.username) { - user.exists(utils.slugify(data.username), function(exists) { - sessionData.socket.emit('api:user.exists', { - exists: exists - }); - }); +SocketUser.exists = function(socket, data, callback) { + if (data && data.username) { + user.exists(utils.slugify(data.username), callback); } }; -SocketUser.count = function(callback) { +SocketUser.count = function(socket, data, callback) { user.count(callback); }; -SocketUser.emailExists = function(data, callback, sessionData) { - user.email.exists(undefined, data.email, callback); +SocketUser.emailExists = function(socket, data, callback) { + if(data && data.email) { + user.email.exists(data.email, callback); + } }; // Password Reset SocketUser.reset = {}; -SocketUser.reset.send = function(data, sessionData) { - user.reset.send(sessionData.socket, data.email); +SocketUser.reset.send = function(socket, data, callback) { + if(data && data.email) { + user.reset.send(socket, data.email, callback); + } }; -SocketUser.reset.valid = function(data, sessionData) { - user.reset.validate(sessionData.socket, data.code); +SocketUser.reset.valid = function(socket, data, callback) { + if(data && data.code) { + user.reset.validate(socket, data.code, callback); + } }; -SocketUser.reset.commit = function(data, sessionData) { - user.reset.commit(sessionData.socket, data.code, data.password); +SocketUser.reset.commit = function(socket, data, callback) { + if(data && data.code && data.password) { + user.reset.commit(socket, data.code, data.password, callback); + } }; -SocketUser.isOnline = function(uid, callback) { - callback({ +SocketUser.isOnline = function(socket, uid, callback) { + callback(null, { online: module.parent.exports.isUserOnline(uid), uid: uid, timestamp: Date.now() }); }; -SocketUser.changePassword = function(data, callback, sessionData) { - user.changePassword(sessionData.uid, data, callback); +SocketUser.changePassword = function(socket, data, callback) { + if(data) { + user.changePassword(socket.uid, data, callback); + } }; -SocketUser.updateProfile = function(data, callback, sessionData) { - user.updateProfile(sessionData.uid, data, callback); +SocketUser.updateProfile = function(socket, data, callback) { + if(data) { + user.updateProfile(socket.uid, data, callback); + } }; -SocketUser.changePicture = function(data, callback, sessionData) { +SocketUser.changePicture = function(socket, data, callback) { + if(!data) { + return; + } var type = data.type; function updateHeader() { - user.getUserFields(sessionData.uid, ['picture'], function(err, fields) { - if (!err && fields) { - fields.uid = sessionData.uid; - sessionData.socket.emit('api:updateHeader', fields); - callback(true); - } else { - callback(false); + user.getUserFields(socket.uid, ['picture'], function(err, fields) { + if(err) { + return callback(err); } + + if (fields) { + fields.uid = socket.uid; + socket.emit('meta.updateHeader', null, fields); + } + + callback(null); }); } if (type === 'gravatar') { - user.getUserField(sessionData.uid, 'gravatarpicture', function(err, gravatar) { - user.setUserField(sessionData.uid, 'picture', gravatar); - updateHeader(); - }); + type = 'gravatarpicture'; } else if (type === 'uploaded') { - user.getUserField(sessionData.uid, 'uploadedpicture', function(err, uploadedpicture) { - user.setUserField(sessionData.uid, 'picture', uploadedpicture); - updateHeader(); - }); + type = 'uploadedpicture'; } else { - callback(false); + return callback(new Error('invalid-image-type')); } + + user.getUserField(socket.uid, type, function(err, picture) { + user.setUserField(socket.uid, 'picture', picture); + updateHeader(); + }); }; -SocketUser.follow = function(data, callback, sessionData) { - if (sessionData.uid) { - user.follow(sessionData.uid, data.uid, callback); +SocketUser.follow = function(socket, data, callback) { + if (socket.uid && data) { + user.follow(socket.uid, data.uid, callback); } }; -SocketUser.unfollow = function(data, callback, sessionData) { - if (sessionData.uid) { - user.unfollow(sessionData.uid, data.uid, callback); +SocketUser.unfollow = function(socket, data, callback) { + if (socket.uid && data) { + user.unfollow(socket.uid, data.uid, callback); } }; -SocketUser.saveSettings = function(data, callback, sessionData) { - if (sessionData.uid) { - user.setUserFields(sessionData.uid, { +SocketUser.saveSettings = function(socket, data, callback) { + if (socket.uid && data) { + user.setUserFields(socket.uid, { showemail: data.showemail - }, function(err, result) { - callback(err); - }); + }, callback); } }; -SocketUser.get_online_users = function(data, callback) { +SocketUser.getOnlineUsers = function(socket, data, callback) { var returnData = []; - - for (var i = 0; i < data.length; ++i) { - var uid = data[i]; - if (module.parent.exports.isUserOnline(uid)) - returnData.push(uid); - else - returnData.push(0); + if(data) { + for (var i = 0; i < data.length; ++i) { + var uid = data[i]; + if (module.parent.exports.isUserOnline(uid)) { + returnData.push(uid); + } else { + returnData.push(0); + } + } } - callback(returnData); + callback(null, returnData); }; -SocketUser.getOnlineAnonCount = function(data, callback) { - callback(module.parent.exports.getOnlineAnonCount()); +SocketUser.getOnlineAnonCount = function(socket, data, callback) { + callback(null, module.parent.exports.getOnlineAnonCount()); }; -SocketUser.getUnreadCount = function(callback, sessionData) { - topics.getUnreadTids(sessionData.uid, 0, 19, function(err, tids) { - callback(tids.length); +SocketUser.getUnreadCount = function(socket, data, callback) { + topics.getUnreadTids(socket.uid, 0, 19, function(err, tids) { + callback(err, tids?tids.length:0); }); }; -SocketUser.getActiveUsers = function(callback) { +SocketUser.getActiveUsers = function(socket, data, callback) { module.parent.exports.emitOnlineUserCount(callback); }; -SocketUser.loadMore = function(data, callback) { - var start = data.after, - end = start + 19; +SocketUser.loadMore = function(socket, data, callback) { + if(data) { + var start = data.after, + end = start + 19; + + user.getUsers(data.set, start, end, function(err, data) { + if(err) { + return callback(err); + } - user.getUsers(data.set, start, end, function(err, data) { - if (err) { - winston.err(err); - } else { - callback({ + callback(null, { users: data }); - } - }); + }); + } }; /* Exports */ diff --git a/src/threadTools.js b/src/threadTools.js index 6d4fe41abe..d0ccd20e50 100644 --- a/src/threadTools.js +++ b/src/threadTools.js @@ -66,13 +66,16 @@ var winston = require('winston'), events.logTopicDelete(uid, tid); + websockets.emitTopicPostStats(); + websockets.in('topic_' + tid).emit('event:topic_deleted', { - tid: tid, - status: 'ok' + tid: tid }); if (callback) { - callback(null); + callback(null, { + tid: tid + }); } } @@ -83,9 +86,10 @@ var winston = require('winston'), events.logTopicRestore(uid, tid); + websockets.emitTopicPostStats(); + websockets.in('topic_' + tid).emit('event:topic_restored', { - tid: tid, - status: 'ok' + tid: tid }); topics.getTopicField(tid, 'title', function(err, title) { @@ -93,81 +97,75 @@ var winston = require('winston'), }); if(callback) { - callback(null); + callback(null, { + tid:tid + }); } } - ThreadTools.lock = function(tid, callback) { + ThreadTools.lock = function(tid, uid, callback) { topics.setTopicField(tid, 'locked', 1); websockets.in('topic_' + tid).emit('event:topic_locked', { - tid: tid, - status: 'ok' + tid: tid }); if (callback) { - callback({ - status: 'ok', + callback(null, { tid: tid }); } } - ThreadTools.unlock = function(tid, callback) { + ThreadTools.unlock = function(tid, uid, callback) { topics.setTopicField(tid, 'locked', 0); websockets.in('topic_' + tid).emit('event:topic_unlocked', { - tid: tid, - status: 'ok' + tid: tid }); if (callback) { - callback({ - status: 'ok', + callback(null, { tid: tid }); } } - ThreadTools.pin = function(tid, callback) { + ThreadTools.pin = function(tid, uid, callback) { topics.setTopicField(tid, 'pinned', 1); topics.getTopicField(tid, 'cid', function(err, cid) { db.sortedSetAdd('categories:' + cid + ':tid', Math.pow(2, 53), tid); }); websockets.in('topic_' + tid).emit('event:topic_pinned', { - tid: tid, - status: 'ok' + tid: tid }); if (callback) { - callback({ - status: 'ok', + callback(null, { tid: tid }); } } - ThreadTools.unpin = function(tid, callback) { + ThreadTools.unpin = function(tid, uid, callback) { topics.setTopicField(tid, 'pinned', 0); topics.getTopicFields(tid, ['cid', 'lastposttime'], function(err, topicData) { db.sortedSetAdd('categories:' + topicData.cid + ':tid', topicData.lastposttime, tid); }); websockets.in('topic_' + tid).emit('event:topic_unpinned', { - tid: tid, - status: 'ok' + tid: tid }); if (callback) { - callback({ - status: 'ok', + callback(null, { tid: tid }); } } - ThreadTools.move = function(tid, cid, callback, sessionData) { + ThreadTools.move = function(tid, cid, callback) { topics.getTopicFields(tid, ['cid', 'lastposttime'], function(err, topicData) { var oldCid = topicData.cid; @@ -175,9 +173,7 @@ var winston = require('winston'), db.sortedSetAdd('categories:' + cid + ':tid', topicData.lastposttime, tid, function(err, result) { if(err) { - return callback({ - status: 'error' - }); + return callback(err); } topics.setTopicField(tid, 'cid', cid); @@ -193,61 +189,46 @@ var winston = require('winston'), categories.incrementCategoryFieldBy(oldCid, 'topic_count', -1); categories.incrementCategoryFieldBy(cid, 'topic_count', 1); - callback({ - status: 'ok' - }); - - sessionData.server.sockets.in('topic_' + tid).emit('event:topic_moved', { - tid: tid - }); + callback(null); }); }); }); } - ThreadTools.isFollowing = function(tid, current_user, callback) { - db.isSetMember('tid:' + tid + ':followers', current_user, function(err, following) { - callback(following); - }); + ThreadTools.isFollowing = function(tid, uid, callback) { + db.isSetMember('tid:' + tid + ':followers', uid, callback); } - ThreadTools.toggleFollow = function(tid, current_user, callback) { - ThreadTools.isFollowing(tid, current_user, function(following) { - if (!following) { - db.setAdd('tid:' + tid + ':followers', current_user, function(err, success) { - if (callback) { - if (!err) { - callback({ - status: 'ok', - follow: true - }); - } else callback({ - status: 'error' - }); - } - }); - } else { - db.setRemove('tid:' + tid + ':followers', current_user, function(err, success) { - if (callback) { - if (!err) { - callback({ - status: 'ok', - follow: false - }); - } else callback({ - status: 'error' - }); - } - }); + ThreadTools.toggleFollow = function(tid, uid, callback) { + ThreadTools.isFollowing(tid, uid, function(err, following) { + if(err) { + return callback(err); } + + db[following?'setRemove':'setAdd']('tid:' + tid + ':followers', uid, function(err, success) { + if (callback) { + if(err) { + return callback(err); + } + + callback(null, !following); + } + }); }); } ThreadTools.getFollowers = function(tid, callback) { db.getSetMembers('tid:' + tid + ':followers', function(err, followers) { - callback(err, followers.map(function(follower) { - return parseInt(follower, 10); - })); + if(err) { + return callback(err); + } + + if(followers) { + followers = followers.map(function(follower) { + return parseInt(follower, 10); + }); + } + callback(null, followers); }); } diff --git a/src/topics.js b/src/topics.js index f2e245d72a..44713da623 100644 --- a/src/topics.js +++ b/src/topics.js @@ -75,19 +75,24 @@ var async = require('async'), return callback(new Error('no-privileges')); } else if (!cid) { return callback(new Error('invalid-cid')); - } else if (!title || title.length < parseInt(meta.config.minimumTitleLength, 10)) { + } + + if (title) { + title = title.trim(); + } + + if (!title || title.length < parseInt(meta.config.minimumTitleLength, 10)) { return callback(new Error('title-too-short'), null); } else if(title.length > parseInt(meta.config.maximumTitleLength, 10)) { return callback(new Error('title-too-long'), null); - } else if (!content || content.length < meta.config.miminumPostLength) { - return callback(new Error('content-too-short'), null); } if (content) { content = content.trim(); } - if (title) { - title = title.trim(); + + if (!content || content.length < meta.config.miminumPostLength) { + return callback(new Error('content-too-short'), null); } user.getUserField(uid, 'lastposttime', function(err, lastposttime) { @@ -257,7 +262,7 @@ var async = require('async'), }); function move(pid, next) { - postTools.privileges(pid, uid, function(privileges) { + postTools.privileges(pid, uid, function(err, privileges) { if(privileges.editable) { Topics.movePostToTopic(pid, tid, next); } else { @@ -379,9 +384,7 @@ var async = require('async'), } function getPrivileges(next) { - postTools.privileges(tid, current_user, function(privData) { - next(null, privData); - }); + postTools.privileges(tid, current_user, next); } async.parallel([getFavouritesData, addUserInfoToPosts, getPrivileges], function(err, results) { @@ -449,7 +452,7 @@ var async = require('async'), } }); }, function(tids) { - Topics.getTopicsByTids(tids, current_user, function(topicData) { + Topics.getTopicsByTids(tids, 0, current_user, function(err, topicData) { latestTopics.topics = topicData; callback(err, latestTopics); }); @@ -471,8 +474,9 @@ var async = require('async'), function(callback) { db.getSortedSetRevRange('topics:recent', start, stop, function(err, tids) { - if (err) + if (err) { return callback(err); + } if (tids && !tids.length) { done = true; @@ -494,7 +498,7 @@ var async = require('async'), }); }, function(err) { - callback({ + callback(null, { count: unreadTids.length }); } @@ -564,19 +568,22 @@ var async = require('async'), 'show_topic_button': 'hidden', 'show_markallread_button': 'show', 'no_topics_message': 'hidden', - 'topic_row_size': 'col-md-12', 'topics': [] }; function noUnreadTopics() { unreadTopics.no_topics_message = 'show'; unreadTopics.show_markallread_button = 'hidden'; - callback(unreadTopics); + callback(null, unreadTopics); } function sendUnreadTopics(topicIds) { - Topics.getTopicsByTids(topicIds, uid, function(topicData) { + Topics.getTopicsByTids(topicIds, 0, uid, function(err, topicData) { + if(err) { + return callback(err); + } + unreadTopics.topics = topicData; unreadTopics.nextStart = stop + 1; if (!topicData || topicData.length === 0) { @@ -586,13 +593,13 @@ var async = require('async'), unreadTopics.show_markallread_button = 'hidden'; } - callback(unreadTopics); + callback(null, unreadTopics); }); } Topics.getUnreadTids(uid, start, stop, function(err, unreadTids) { if (err) { - return callback([]); + return callback(err); } if (unreadTids.length) { @@ -615,7 +622,7 @@ var async = require('async'), async.each(uids, function(uid, next) { Topics.getUnreadTids(uid, 0, 19, function(err, tids) { - websockets.in('uid_' + uid).emit('event:unread.updateCount', tids.length); + websockets.in('uid_' + uid).emit('event:unread.updateCount', null, tids.length); next(); }); }, function(err) { @@ -629,13 +636,12 @@ var async = require('async'), }); }; - Topics.getTopicsByTids = function(tids, current_user, callback, category_id) { + Topics.getTopicsByTids = function(tids, cid, current_user, callback) { var retrieved_topics = []; if (!Array.isArray(tids) || tids.length === 0) { - callback(retrieved_topics); - return; + return callback(null, retrieved_topics); } function getTopicInfo(topicData, callback) { @@ -659,19 +665,19 @@ var async = require('async'), // temporary. I don't think this call should belong here function getPrivileges(next) { - categoryTools.privileges(category_id, current_user, function(err, user_privs) { - next(err, user_privs); - }); + categoryTools.privileges(cid, current_user, next); } function getCategoryInfo(next) { - categories.getCategoryFields(topicData.cid, ['name', 'slug', 'icon'], function(err, categoryData) { - next(err, categoryData); - }); + categories.getCategoryFields(topicData.cid, ['name', 'slug', 'icon'], next); } async.parallel([getUserInfo, hasReadTopic, getTeaserInfo, getPrivileges, getCategoryInfo], function(err, results) { - callback({ + if(err) { + return callback(err); + } + + callback(null, { username: results[0].username, userslug: results[0].userslug, picture: results[0].picture, @@ -689,13 +695,20 @@ var async = require('async'), return !deleted || (deleted && topicInfo.privileges.view_deleted) || topicData.uid === current_user; } - function loadTopic(tid, callback) { + function loadTopic(tid, next) { Topics.getTopicData(tid, function(err, topicData) { + if(err) { + return next(err); + } + if (!topicData) { - return callback(null); + return next(); } - getTopicInfo(topicData, function(topicInfo) { + getTopicInfo(topicData, function(err, topicInfo) { + if(err) { + return next(err); + } topicData['pin-icon'] = parseInt(topicData.pinned, 10) === 1 ? 'fa-thumb-tack' : 'none'; topicData['lock-icon'] = parseInt(topicData.locked, 10) === 1 ? 'fa-lock' : 'none'; @@ -715,18 +728,17 @@ var async = require('async'), topicData.teaser_pid = topicInfo.teaserInfo.pid; topicData.teaser_timestamp = topicInfo.teaserInfo.timestamp ? (new Date(parseInt(topicInfo.teaserInfo.timestamp, 10)).toISOString()) : ''; - if (isTopicVisible(topicData, topicInfo)) + if (isTopicVisible(topicData, topicInfo)) { retrieved_topics.push(topicData); + } - callback(null); + next(null); }); }); } async.eachSeries(tids, loadTopic, function(err) { - if (!err) { - callback(retrieved_topics); - } + callback(err, retrieved_topics); }); } @@ -888,7 +900,7 @@ var async = require('async'), Topics.markAllRead = function(uid, callback) { db.getSetMembers('topics:tid', function(err, tids) { if (err) { - return callback(err, null); + return callback(err); } if (tids && tids.length) { @@ -897,7 +909,7 @@ var async = require('async'), } } - callback(null, true); + callback(null); }); } diff --git a/src/user.js b/src/user.js index b66c923f75..9a6e1dc133 100644 --- a/src/user.js +++ b/src/user.js @@ -46,7 +46,10 @@ var bcrypt = require('bcrypt'), } }, function(next) { - User.exists(userslug, function(exists) { + User.exists(userslug, function(err, exists) { + if (err) { + return next(err); + } next(exists ? new Error('Username taken!') : null); }); }, @@ -193,9 +196,7 @@ var bcrypt = require('bcrypt'), function isSignatureValid(next) { if (data.signature !== undefined && data.signature.length > meta.config.maximumSignatureLength) { - next({ - error: 'Signature can\'t be longer than ' + meta.config.maximumSignatureLength + ' characters!' - }, false); + next(new Error('Signature can\'t be longer than ' + meta.config.maximumSignatureLength + ' characters!'), false); } else { next(null, true); } @@ -217,9 +218,7 @@ var bcrypt = require('bcrypt'), } if (!available) { - next({ - error: 'Email not available!' - }, false); + next(new Error('Email not available!'), false); } else { next(null, true); } @@ -237,16 +236,16 @@ var bcrypt = require('bcrypt'), } if(!utils.isUserNameValid(data.username) || !userslug) { - return next({ - error: 'Invalid Username!' - }, false); + return next(new Error('Invalid Username!'), false); } - User.exists(userslug, function(exists) { + User.exists(userslug, function(err, exists) { + if(err) { + return next(err); + } + if(exists) { - next({ - error: 'Username not available!' - }, false); + next(new Error('Username not available!'), false); } else { next(null, true); } @@ -348,13 +347,11 @@ var bcrypt = require('bcrypt'), User.changePassword = function(uid, data, callback) { if (!utils.isPasswordValid(data.newPassword)) { - return callback({ - error: 'Invalid password!' - }); + return callback(new Error('Invalid password!')); } - User.getUserField(uid, 'password', function(err, user_password) { - bcrypt.compare(data.currentPassword, user_password, function(err, res) { + User.getUserField(uid, 'password', function(err, currentPassword) { + bcrypt.compare(data.currentPassword, currentPassword, function(err, res) { if (err) { return callback(err); } @@ -366,9 +363,7 @@ var bcrypt = require('bcrypt'), callback(null); }); } else { - callback({ - error: 'Your current password is not correct!' - }); + callback(new Error('Your current password is not correct!')); } }); }); @@ -542,31 +537,21 @@ var bcrypt = require('bcrypt'), User.follow = function(uid, followid, callback) { db.setAdd('following:' + uid, followid, function(err, data) { - if (!err) { - db.setAdd('followers:' + followid, uid, function(err, data) { - if (!err) { - callback(true); - } else { - console.log(err); - callback(false); - } - }); - } else { - console.log(err); - callback(false); + if(err) { + return callback(err); } + + db.setAdd('followers:' + followid, uid, callback); }); }; User.unfollow = function(uid, unfollowid, callback) { db.setRemove('following:' + uid, unfollowid, function(err, data) { - if (!err) { - db.setRemove('followers:' + unfollowid, uid, function(err, data) { - callback(data); - }); - } else { - console.log(err); + if(err) { + return callback(err); } + + db.setRemove('followers:' + unfollowid, uid, callback); }); }; @@ -667,17 +652,17 @@ var bcrypt = require('bcrypt'), User.exists = function(userslug, callback) { User.getUidByUserslug(userslug, function(err, exists) { - callback( !! exists); + callback(err, !! exists); }); }; User.count = function(callback) { db.getObjectField('global', 'userCount', function(err, count) { if(err) { - return; + return callback(err); } - callback({ + callback(null, { count: count ? count : 0 }); }); @@ -785,92 +770,70 @@ var bcrypt = require('bcrypt'), User.reset = { validate: function(socket, code, callback) { - if (typeof callback !== 'function') { - callback = null; - } - db.getObjectField('reset:uid', code, function(err, uid) { if (err) { - return callback(false); + return callback(err); } if (uid !== null) { db.getObjectField('reset:expiry', code, function(err, expiry) { if (err) { - return callback(false); + return callback(err); } if (expiry >= +Date.now() / 1000 | 0) { - if (!callback) { - socket.emit('user:reset.valid', { - valid: true - }); - } else { - callback(true); - } + callback(null, true); } else { // Expired, delete from db db.deleteObjectField('reset:uid', code); db.deleteObjectField('reset:expiry', code); - if (!callback) { - socket.emit('user:reset.valid', { - valid: false - }); - } else { - callback(false); - } + callback(null, false); } }); } else { - if (!callback) { - socket.emit('user:reset.valid', { - valid: false - }); - } else { - callback(false); - } + callback(null, false); } }); }, - send: function(socket, email) { + send: function(socket, email, callback) { User.getUidByEmail(email, function(err, uid) { - if (uid !== null) { - // Generate a new reset code - var reset_code = utils.generateUUID(); - db.setObjectField('reset:uid', reset_code, uid); - db.setObjectField('reset:expiry', reset_code, (60 * 60) + new Date() / 1000 | 0); // Active for one hour + if(err) { + return callback(err); + } - var reset_link = nconf.get('url') + 'reset/' + reset_code; + if(!uid) { + return callback(new Error('invalid-email')); + } - Emailer.send('reset', uid, { - 'site_title': (meta.config['title'] || 'NodeBB'), - 'reset_link': reset_link, + // Generate a new reset code + var reset_code = utils.generateUUID(); + db.setObjectField('reset:uid', reset_code, uid); + db.setObjectField('reset:expiry', reset_code, (60 * 60) + new Date() / 1000 | 0); // Active for one hour - subject: 'Password Reset Requested - ' + (meta.config['title'] || 'NodeBB') + '!', - template: 'reset', - uid: uid - }); + var reset_link = nconf.get('url') + 'reset/' + reset_code; - socket.emit('user.send_reset', { - status: "ok", - message: "code-sent", - email: email - }); - } else { - socket.emit('user.send_reset', { - status: "error", - message: "invalid-email", - email: email - }); - } + Emailer.send('reset', uid, { + 'site_title': (meta.config['title'] || 'NodeBB'), + 'reset_link': reset_link, + + subject: 'Password Reset Requested - ' + (meta.config['title'] || 'NodeBB') + '!', + template: 'reset', + uid: uid + }); + + callback(null); }); }, - commit: function(socket, code, password) { - this.validate(socket, code, function(validated) { + commit: function(socket, code, password, callback) { + this.validate(socket, code, function(err, validated) { + if(err) { + return callback(err); + } + if (validated) { db.getObjectField('reset:uid', code, function(err, uid) { if (err) { - return; + return callback(err); } User.hashPassword(password, function(err, hash) { @@ -881,9 +844,7 @@ var bcrypt = require('bcrypt'), db.deleteObjectField('reset:uid', code); db.deleteObjectField('reset:expiry', code); - socket.emit('user:reset.commit', { - status: 'ok' - }); + callback(null); }); } }); @@ -932,9 +893,9 @@ var bcrypt = require('bcrypt'), }); }); }, - exists: function(socket, email, callback) { + exists: function(email, callback) { User.getUidByEmail(email, function(err, exists) { - callback(!!exists); + callback(err, !!exists); }); }, confirm: function(code, callback) { @@ -1031,7 +992,7 @@ var bcrypt = require('bcrypt'), notifications.read.length = maxNotifs - notifications.unread.length; } - callback(notifications); + callback(err, notifications); }); }, getAll: function(uid, limit, before, callback) { diff --git a/tests/categories.js b/tests/categories.js index 070a71e884..009d195e92 100644 --- a/tests/categories.js +++ b/tests/categories.js @@ -44,7 +44,7 @@ describe('Categories', function() { describe('.getCategoryTopics', function() { it('should return a list of topics', function(done) { - Categories.getCategoryTopics(categoryObj.cid, 0, 10, 0, function(topics) { + Categories.getCategoryTopics(categoryObj.cid, 0, 10, 0, function(err, topics) { assert(Array.isArray(topics)); assert(topics.every(function(topic) { return topic instanceof Object;