diff --git a/README.md b/README.md index 831a6aa303..563b3edae4 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # NodeBB [![Build Status](https://travis-ci.org/NodeBB/NodeBB.svg?branch=master)](https://travis-ci.org/NodeBB/NodeBB) [![Dependency Status](https://david-dm.org/nodebb/nodebb.svg)](https://david-dm.org/nodebb/nodebb) -[![Code Climate](https://codeclimate.com/github/designcreateplay/NodeBB.png)](https://codeclimate.com/github/designcreateplay/NodeBB) +[![Code Climate](https://codeclimate.com/github/NodeBB/NodeBB/badges/gpa.svg)](https://codeclimate.com/github/NodeBB/NodeBB) [![Documentation Status](https://readthedocs.org/projects/nodebb/badge/?version=latest)](https://readthedocs.org/projects/nodebb/?badge=latest) **NodeBB Forum Software** is powered by Node.js and built on a Redis database. It utilizes web sockets for instant interactions and real-time notifications. NodeBB is compatible down to IE8 and has many modern features out of the box such as social network integration and streaming discussions. diff --git a/public/src/forum/account/profile.js b/public/src/forum/account/profile.js index 9563fda6f1..343be867c2 100644 --- a/public/src/forum/account/profile.js +++ b/public/src/forum/account/profile.js @@ -43,7 +43,7 @@ define('forum/account/profile', ['forum/account/header'], function(header) { }; function processPage() { - $('.user-recent-posts img').addClass('img-responsive'); + $('.user-recent-posts img, .post-signature img').addClass('img-responsive'); } function updateButtons() { diff --git a/public/theme-rocket/cover/0231ab8358cc9079b8207bcc78b66c1d b/public/theme-rocket/cover/0231ab8358cc9079b8207bcc78b66c1d deleted file mode 100644 index b88748ab3a..0000000000 Binary files a/public/theme-rocket/cover/0231ab8358cc9079b8207bcc78b66c1d and /dev/null differ diff --git a/src/categories.js b/src/categories.js index bf42392596..eae19b4595 100644 --- a/src/categories.js +++ b/src/categories.js @@ -188,7 +188,7 @@ var db = require('./database'), }); }; - Categories.getVisibleCategories = function(uid, callback) { + Categories.getCategoriesByPrivilege = function(uid, privilege, callback) { db.getSortedSetRange('categories:cid', 0, -1, function(err, cids) { if (err) { return callback(err); @@ -198,7 +198,7 @@ var db = require('./database'), return callback(null, []); } - privileges.categories.filter('find', cids, uid, function(err, cids) { + privileges.categories.filter(privilege, cids, uid, function(err, cids) { if (err) { return callback(err); } diff --git a/src/controllers/index.js b/src/controllers/index.js index ccea529f5b..96748917b6 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -64,7 +64,7 @@ Controllers.home = function(req, res, next) { }, categories: function (next) { var uid = req.user ? req.user.uid : 0; - categories.getVisibleCategories(uid, function (err, categoryData) { + categories.getCategoriesByPrivilege(uid, 'find', function (err, categoryData) { if (err) { return next(err); } diff --git a/src/controllers/topics.js b/src/controllers/topics.js index 0b20eb7af6..51d1706885 100644 --- a/src/controllers/topics.js +++ b/src/controllers/topics.js @@ -70,7 +70,7 @@ topicsController.get = function(req, res, next) { function (topicData, next) { var description = ''; - if(topicData.posts.length) { + if (topicData.posts[0] && topicData.posts[0].content) { description = S(topicData.posts[0].content).stripTags().decodeHTMLEntities().s; } @@ -83,7 +83,7 @@ topicsController.get = function(req, res, next) { var ogImageUrl = ''; if (topicData.thumb) { ogImageUrl = topicData.thumb; - } else if(topicData.posts.length && topicData.posts[0].user && topicData.posts[0].user.picture){ + } else if(topicData.posts.length && topicData.posts[0] && topicData.posts[0].user && topicData.posts[0].user.picture){ ogImageUrl = topicData.posts[0].user.picture; } else if(meta.config['brand:logo']) { ogImageUrl = meta.config['brand:logo']; diff --git a/src/meta/title.js b/src/meta/title.js index 652001af97..0019cdb686 100644 --- a/src/meta/title.js +++ b/src/meta/title.js @@ -1,6 +1,7 @@ 'use strict'; -var user = require('../user'), +var winston = require('winston'), + user = require('../user'), translator = require('../../public/src/translator'); module.exports = function(Meta) { @@ -14,7 +15,14 @@ module.exports = function(Meta) { }; Meta.title.build = function (urlFragment, language, callback) { - Meta.title.parseFragment(decodeURIComponent(urlFragment), language, function(err, title) { + var uri = ''; + try { + uri = decodeURIComponent(urlFragment); + } catch(e) { + winston.error('Invalid url fragment : ' + urlFragment, e.stack); + return callback(null, Meta.config.browserTitle || 'NodeBB'); + } + Meta.title.parseFragment(uri, language, function(err, title) { if (err) { title = Meta.config.browserTitle || 'NodeBB'; } else { diff --git a/src/posts.js b/src/posts.js index a2c691dc28..856145c4c0 100644 --- a/src/posts.js +++ b/src/posts.js @@ -152,7 +152,7 @@ var async = require('async'), if (!data || !Array.isArray(data.posts)) { return callback(null, []); } - + data.posts = data.posts.filter(Boolean); callback(null, data.posts); }); }); @@ -357,7 +357,7 @@ var async = require('async'), } posts = posts.filter(function(post) { - return parseInt(results.topics[post.tid].deleted, 10) !== 1; + return results.topics[post.tid] && parseInt(results.topics[post.tid].deleted, 10) !== 1; }); async.map(posts, function(post, next) { diff --git a/src/sitemap.js b/src/sitemap.js index e01a2cde3e..5db793a128 100644 --- a/src/sitemap.js +++ b/src/sitemap.js @@ -31,7 +31,7 @@ var path = require('path'), async.parallel([ function(next) { var categoryUrls = []; - categories.getVisibleCategories(0, function(err, categoriesData) { + categories.getCategoriesByPrivilege(0, 'find', function(err, categoriesData) { if (err) { return next(err); } diff --git a/src/socket.io/categories.js b/src/socket.io/categories.js index c594361589..bbe578d870 100644 --- a/src/socket.io/categories.js +++ b/src/socket.io/categories.js @@ -24,7 +24,7 @@ SocketCategories.getRecentReplies = function(socket, cid, callback) { }; SocketCategories.get = function(socket, data, callback) { - categories.getAllCategories(callback); + categories.getCategoriesByPrivilege(socket.uid, 'find', callback); }; SocketCategories.loadMore = function(socket, data, callback) { diff --git a/src/socket.io/modules.js b/src/socket.io/modules.js index 45fde242dd..1156b1c379 100644 --- a/src/socket.io/modules.js +++ b/src/socket.io/modules.js @@ -71,6 +71,10 @@ SocketModules.composer.push = function(socket, pid, callback) { return callback(err); } + if (!results.topic) { + return callback(new Error('[[error:no-topic]]')); + } + callback(null, { pid: pid, body: postData.content, diff --git a/src/topics.js b/src/topics.js index 34fe471163..18b25c7c32 100644 --- a/src/topics.js +++ b/src/topics.js @@ -172,9 +172,9 @@ var async = require('async'), Topics.getTopicsData(tids, function(err, topics) { function mapFilter(array, field) { return array.map(function(topic) { - return topic[field]; + return topic && topic[field]; }).filter(function(value, index, array) { - return array.indexOf(value) === index; + return value && array.indexOf(value) === index; }); } @@ -225,21 +225,23 @@ var async = require('async'), }); for (var i=0; i