diff --git a/package.json b/package.json index 594892df75..d165ffcb6f 100644 --- a/package.json +++ b/package.json @@ -44,16 +44,16 @@ "mongodb": "~2.1.3", "morgan": "^1.3.2", "nconf": "~0.8.2", - "nodebb-plugin-composer-default": "3.0.10", + "nodebb-plugin-composer-default": "3.0.11", "nodebb-plugin-dbsearch": "1.0.0", "nodebb-plugin-emoji-extended": "1.0.3", "nodebb-plugin-markdown": "4.0.17", - "nodebb-plugin-mentions": "1.0.18", + "nodebb-plugin-mentions": "1.0.20", "nodebb-plugin-soundpack-default": "0.1.6", "nodebb-plugin-spam-be-gone": "0.4.5", "nodebb-rewards-essentials": "0.0.8", "nodebb-theme-lavender": "3.0.9", - "nodebb-theme-persona": "4.0.99", + "nodebb-theme-persona": "4.0.100", "nodebb-theme-vanilla": "5.0.56", "nodebb-widget-essentials": "2.0.8", "nodemailer": "2.0.0", diff --git a/public/src/admin/manage/group.js b/public/src/admin/manage/group.js index 58c5017540..06284e4e88 100644 --- a/public/src/admin/manage/group.js +++ b/public/src/admin/manage/group.js @@ -98,7 +98,7 @@ define('admin/manage/group', [ templates.parse('partials/groups/memberlist', 'members', {group: {isOwner: ajaxify.data.group.isOwner, members: [member]}}, function(html) { translator.translate(html, function(html) { - $('[component="groups/members"] tr').first().before(html); + $('[component="groups/members"] tbody').prepend(html); }); }); }); diff --git a/public/src/client/topic/posts.js b/public/src/client/topic/posts.js index f534aefad5..c83b8c245f 100644 --- a/public/src/client/topic/posts.js +++ b/public/src/client/topic/posts.js @@ -26,19 +26,17 @@ define('forum/topic/posts', [ post.selfPost = !!app.user.uid && parseInt(post.uid, 10) === parseInt(app.user.uid, 10); post.display_moderator_tools = post.selfPost || ajaxify.data.privileges.isAdminOrMod; post.display_move_tools = ajaxify.data.privileges.isAdminOrMod; - post.display_post_menu = post.selfPost || ajaxify.data.privileges.isAdminOrMod; + post.display_post_menu = post.selfPost || ajaxify.data.privileges.isAdminOrMod || !post.deleted; }); updatePostCounts(data.posts); ajaxify.data.postcount ++; postTools.updatePostCount(ajaxify.data.postcount); - if (ajaxify.data.scrollToMyPost) { - if (config.usePagination) { - onNewPostPagination(data); - } else { - onNewPostInfiniteScroll(data); - } + if (config.usePagination) { + onNewPostPagination(data); + } else { + onNewPostInfiniteScroll(data); } }; @@ -64,7 +62,7 @@ define('forum/topic/posts', [ if (isPostVisible) { createNewPosts(data, components.get('post').not('[data-index=0]'), direction, scrollToPost); - } else if (parseInt(posts[0].uid, 10) === parseInt(app.user.uid, 10)) { + } else if (config.scrollToMyPost && parseInt(posts[0].uid, 10) === parseInt(app.user.uid, 10)) { pagination.loadPage(ajaxify.data.pagination.pageCount, scrollToPost); } } @@ -81,6 +79,9 @@ define('forum/topic/posts', [ } function scrollToPostIfSelf(post) { + if (!config.scrollToMyPost) { + return; + } var isSelfPost = parseInt(post.uid, 10) === parseInt(app.user.uid, 10); if (isSelfPost) { navigator.scrollBottom(post.index); @@ -262,4 +263,4 @@ define('forum/topic/posts', [ return Posts; -}); \ No newline at end of file +}); diff --git a/src/controllers/accounts/helpers.js b/src/controllers/accounts/helpers.js index 0a35315854..1cb7bb3c77 100644 --- a/src/controllers/accounts/helpers.js +++ b/src/controllers/accounts/helpers.js @@ -64,12 +64,14 @@ helpers.getUserDataByUserSlug = function(userslug, callerUID, callback) { userData.lastonlineISO = utils.toISOString(userData.lastonline || userData.joindate); userData.age = Math.max(0, userData.birthday ? Math.floor((new Date().getTime() - new Date(userData.birthday).getTime()) / 31536000000) : 0); + userData.emailClass = 'hide'; + if (!(isAdmin || isGlobalModerator || self || (userData.email && userSettings.showemail))) { userData.email = ''; + } else if (!userSettings.showemail) { + userData.emailClass = ''; } - userData.emailClass = (self && !userSettings.showemail) ? '' : 'hide'; - if (!isAdmin && !isGlobalModerator && !self && !userSettings.showfullname) { userData.fullname = ''; } @@ -172,4 +174,4 @@ function filterLinks(links, self) { }); } -module.exports = helpers; \ No newline at end of file +module.exports = helpers; diff --git a/src/controllers/helpers.js b/src/controllers/helpers.js index 94dfe022c2..3962e2036b 100644 --- a/src/controllers/helpers.js +++ b/src/controllers/helpers.js @@ -41,7 +41,7 @@ helpers.redirect = function(res, url) { if (res.locals.isAPI) { res.status(308).json(url); } else { - res.redirect(nconf.get('relative_path') + url); + res.redirect(nconf.get('relative_path') + encodeURI(url)); } }; @@ -109,4 +109,4 @@ helpers.buildTitle = function(pageTitle) { return title; }; -module.exports = helpers; \ No newline at end of file +module.exports = helpers; diff --git a/src/middleware/render.js b/src/middleware/render.js index 2a9d0ba5d2..79911f71bd 100644 --- a/src/middleware/render.js +++ b/src/middleware/render.js @@ -13,7 +13,7 @@ module.exports = function(middleware) { req = this.req, defaultFn = function(err, str){ if (err) { - return req.next(err); + return next(err); } self.send(str); @@ -96,4 +96,4 @@ module.exports = function(middleware) { return parts.join(' '); } -}; \ No newline at end of file +}; diff --git a/src/notifications.js b/src/notifications.js index af88fd7b5b..f32ca031d3 100644 --- a/src/notifications.js +++ b/src/notifications.js @@ -450,10 +450,13 @@ var async = require('async'), }); var numUsers = usernames.length; + var title = S(notifications[modifyIndex].topicTitle).decodeHTMLEntities().s; + var titleEscaped = title.replace(/%/g, '%').replace(/,/g, ','); + if (numUsers === 2) { - notifications[modifyIndex].bodyShort = '[[' + mergeId + '_dual, ' + usernames.join(', ') + ', ' + notifications[modifyIndex].topicTitle + ']]'; + notifications[modifyIndex].bodyShort = '[[' + mergeId + '_dual, ' + usernames.join(', ') + ', ' + titleEscaped + ']]'; } else if (numUsers > 2) { - notifications[modifyIndex].bodyShort = '[[' + mergeId + '_multiple, ' + usernames[0] + ', ' + (numUsers-1) + ', ' + notifications[modifyIndex].topicTitle + ']]'; + notifications[modifyIndex].bodyShort = '[[' + mergeId + '_multiple, ' + usernames[0] + ', ' + (numUsers-1) + ', ' + titleEscaped + ']]'; } break; diff --git a/src/posts/user.js b/src/posts/user.js index 0d41397960..cd675cbfa3 100644 --- a/src/posts/user.js +++ b/src/posts/user.js @@ -1,6 +1,7 @@ 'use strict'; var async = require('async'), + validator = require('validator'), db = require('../database'), user = require('../user'), @@ -69,6 +70,8 @@ module.exports = function(Posts) { userData.picture = userData.picture || ''; userData.status = user.getStatus(userData); userData.groupTitle = results.groupTitles[i].groupTitle; + userData.signature = validator.escape(userData.signature || ''); + userData.fullname = validator.escape(userData.fullname || ''); }); async.map(userData, function(userData, next) { diff --git a/src/socket.io/helpers.js b/src/socket.io/helpers.js index 3aeaaf0bf3..5524faf156 100644 --- a/src/socket.io/helpers.js +++ b/src/socket.io/helpers.js @@ -2,6 +2,7 @@ var async = require('async'); var winston = require('winston'); +var S = require('string'); var nconf = require('nconf'); var websockets = require('./index'); @@ -62,8 +63,11 @@ SocketHelpers.sendNotificationToPostOwner = function(pid, fromuid, notification) return; } + var title = S(results.topicTitle).decodeHTMLEntities().s; + var titleEscaped = title.replace(/%/g, '%').replace(/,/g, ','); + notifications.create({ - bodyShort: '[[' + notification + ', ' + results.username + ', ' + results.topicTitle + ']]', + bodyShort: '[[' + notification + ', ' + results.username + ', ' + titleEscaped + ']]', bodyLong: results.postObj.content, pid: pid, nid: 'post:' + pid + ':uid:' + fromuid, @@ -93,8 +97,11 @@ SocketHelpers.sendNotificationToTopicOwner = function(tid, fromuid, notification return; } + var title = S(results.topicData.title).decodeHTMLEntities().s; + var titleEscaped = title.replace(/%/g, '%').replace(/,/g, ','); + notifications.create({ - bodyShort: '[[' + notification + ', ' + results.username + ', ' + results.topicData.title + ']]', + bodyShort: '[[' + notification + ', ' + results.username + ', ' + titleEscaped + ']]', path: nconf.get('relative_path') + '/topic/' + results.topicData.slug, nid: 'tid:' + tid + ':uid:' + fromuid, from: fromuid @@ -111,4 +118,4 @@ SocketHelpers.emitToTopicAndCategory = function(event, data) { websockets.in('category_' + data.cid).emit(event, data); }; -module.exports = SocketHelpers; \ No newline at end of file +module.exports = SocketHelpers; diff --git a/src/socket.io/posts/flag.js b/src/socket.io/posts/flag.js index eaefcea1e2..bbf7a4721c 100644 --- a/src/socket.io/posts/flag.js +++ b/src/socket.io/posts/flag.js @@ -1,6 +1,7 @@ 'use strict'; var async = require('async'); +var S = require('string'); var user = require('../../user'); var groups = require('../../groups'); @@ -82,8 +83,11 @@ module.exports = function(SocketPosts) { }, next); }, function (results, next) { + var title = S(post.topic.title).decodeHTMLEntities().s; + var titleEscaped = title.replace(/%/g, '%').replace(/,/g, ','); + notifications.create({ - bodyShort: '[[notifications:user_flagged_post_in, ' + flaggingUser.username + ', ' + post.topic.title + ']]', + bodyShort: '[[notifications:user_flagged_post_in, ' + flaggingUser.username + ', ' + titleEscaped + ']]', bodyLong: post.content, pid: data.pid, nid: 'post_flag:' + data.pid + ':uid:' + socket.uid, @@ -163,4 +167,4 @@ module.exports = function(SocketPosts) { }, ], callback); }; -}; \ No newline at end of file +}; diff --git a/src/views/admin/manage/group.tpl b/src/views/admin/manage/group.tpl index f579065df5..a50fdba51b 100644 --- a/src/views/admin/manage/group.tpl +++ b/src/views/admin/manage/group.tpl @@ -63,7 +63,7 @@