mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-02 03:55:55 +01:00
Merge remote-tracking branch 'upstream/master'
Conflicts: public/src/client/topic/posts.js
This commit is contained in:
@@ -79,9 +79,7 @@
|
||||
"textClass": "visible-xs-inline",
|
||||
"text": "\\[\\[global:header.search\\]\\]",
|
||||
"properties": {
|
||||
"installed": {
|
||||
"search": true
|
||||
}
|
||||
"searchInstalled": true
|
||||
}
|
||||
}
|
||||
]
|
||||
16
package.json
16
package.json
@@ -2,7 +2,7 @@
|
||||
"name": "nodebb",
|
||||
"license": "GPL-3.0",
|
||||
"description": "NodeBB Forum",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.2",
|
||||
"homepage": "http://www.nodebb.org",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -44,17 +44,17 @@
|
||||
"mongodb": "~2.1.3",
|
||||
"morgan": "^1.3.2",
|
||||
"nconf": "~0.8.2",
|
||||
"nodebb-plugin-composer-default": "3.0.9",
|
||||
"nodebb-plugin-dbsearch": "1.0.0",
|
||||
"nodebb-plugin-composer-default": "3.0.14",
|
||||
"nodebb-plugin-dbsearch": "1.0.1",
|
||||
"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-plugin-spam-be-gone": "0.4.6",
|
||||
"nodebb-rewards-essentials": "0.0.8",
|
||||
"nodebb-theme-lavender": "3.0.9",
|
||||
"nodebb-theme-persona": "4.0.99",
|
||||
"nodebb-theme-vanilla": "5.0.56",
|
||||
"nodebb-theme-persona": "4.0.110",
|
||||
"nodebb-theme-vanilla": "5.0.58",
|
||||
"nodebb-widget-essentials": "2.0.8",
|
||||
"nodemailer": "2.0.0",
|
||||
"nodemailer-sendmail-transport": "1.0.0",
|
||||
@@ -75,7 +75,7 @@
|
||||
"socket.io-redis": "^1.0.0",
|
||||
"socketio-wildcard": "~0.3.0",
|
||||
"string": "^3.0.0",
|
||||
"templates.js": "0.3.3",
|
||||
"templates.js": "0.3.4",
|
||||
"toobusy-js": "^0.4.2",
|
||||
"uglify-js": "^2.6.0",
|
||||
"underscore": "^1.8.3",
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
"change_username": "Change Username",
|
||||
"change_email": "Change Email",
|
||||
"edit": "Edit",
|
||||
"edit-profile": "Edit Profile",
|
||||
"default_picture": "Default Icon",
|
||||
"uploaded_picture": "Uploaded Picture",
|
||||
"upload_new_picture": "Upload New Picture",
|
||||
|
||||
@@ -155,12 +155,6 @@ define('admin/manage/category', [
|
||||
} else {
|
||||
$('a[href="#analytics"]').on('shown.bs.tab', Category.setupGraphs);
|
||||
}
|
||||
|
||||
// Fix the input field for the category name, as it can contain a translation key
|
||||
var nameInput = $('#cid-' + ajaxify.data.cid + '-name');
|
||||
if (ajaxify.data.category.name !== nameInput.val()) {
|
||||
$('#cid-' + ajaxify.data.category.cid + '-name').val(ajaxify.data.category.name);
|
||||
}
|
||||
};
|
||||
|
||||
Category.setupPrivilegeTable = function() {
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -326,7 +326,10 @@ app.cacheBuster = null;
|
||||
return;
|
||||
}
|
||||
require(['translator'], function(translator) {
|
||||
title = config.titleLayout.replace(/{/g, '{').replace(/}/g, '}').replace('{pageTitle}', title).replace('{browserTitle}', config.browserTitle);
|
||||
title = config.titleLayout.replace(/{/g, '{').replace(/}/g, '}')
|
||||
.replace('{pageTitle}', function() { return title; })
|
||||
.replace('{browserTitle}', function() { return config.browserTitle; });
|
||||
|
||||
translator.translate(title, function(translated) {
|
||||
titleObj.titles[0] = translated;
|
||||
app.alternatingTitle('');
|
||||
|
||||
@@ -7,12 +7,6 @@ define('forum/groups/list', ['forum/infinitescroll'], function(infinitescroll) {
|
||||
Groups.init = function() {
|
||||
var groupsEl = $('#groups-list');
|
||||
|
||||
groupsEl.on('click', '.list-cover', function() {
|
||||
var groupSlug = $(this).parents('[data-slug]').attr('data-slug');
|
||||
|
||||
ajaxify.go('groups/' + groupSlug);
|
||||
});
|
||||
|
||||
infinitescroll.init(Groups.loadMoreGroups);
|
||||
|
||||
// Group creation
|
||||
|
||||
@@ -221,7 +221,9 @@ define('forum/topic', [
|
||||
} else {
|
||||
span.html('').hide();
|
||||
}
|
||||
app.removeAlert('bookmark');
|
||||
if ($(window).scrollTop() > 300) {
|
||||
app.removeAlert('bookmark');
|
||||
}
|
||||
}
|
||||
|
||||
Topic.calculateIndex = function(index, elementCount) {
|
||||
|
||||
@@ -124,7 +124,7 @@ define('forum/topic/events', [
|
||||
|
||||
var editData = {
|
||||
editor: data.editor,
|
||||
relativeEditTime: utils.toISOString(data.post.edited)
|
||||
editedISO: utils.toISOString(data.post.edited)
|
||||
};
|
||||
|
||||
templates.parse('partials/topic/post-editor', editData, function(html) {
|
||||
|
||||
@@ -34,7 +34,6 @@ define('forum/topic/postTools', ['share', 'navigator', 'components', 'translator
|
||||
return app.alertError(err);
|
||||
}
|
||||
data.posts.display_move_tools = data.posts.display_move_tools && index !== 0;
|
||||
data.postSharing = data.postSharing.filter(function(share) { return share.activated === true; });
|
||||
|
||||
templates.parse('partials/topic/post-menu-list', data, function(html) {
|
||||
translator.translate(html, function(html) {
|
||||
@@ -65,17 +64,21 @@ define('forum/topic/postTools', ['share', 'navigator', 'components', 'translator
|
||||
};
|
||||
|
||||
function addVoteHandler() {
|
||||
components.get('topic').on('mouseenter', '[data-pid] [component="post/vote-count"]', function() {
|
||||
loadDataAndCreateTooltip($(this).parent());
|
||||
});
|
||||
components.get('topic').on('mouseenter', '[data-pid] [component="post/vote-count"]', loadDataAndCreateTooltip);
|
||||
}
|
||||
|
||||
function loadDataAndCreateTooltip(el) {
|
||||
var pid = el.parents('[data-pid]').attr('data-pid');
|
||||
function loadDataAndCreateTooltip() {
|
||||
var $this = $(this),
|
||||
el = $this.parent(),
|
||||
pid = el.parents('[data-pid]').attr('data-pid');
|
||||
|
||||
$this.off('mouseenter', loadDataAndCreateTooltip);
|
||||
socket.emit('posts.getUpvoters', [pid], function(err, data) {
|
||||
if (!err && data.length) {
|
||||
createTooltip(el, data[0]);
|
||||
}
|
||||
|
||||
$this.on('mouseenter', loadDataAndCreateTooltip);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ 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 = ajaxify.data.privileges.isAdminOrMod || post.selfPost || ((app.user.uid || ajaxify.data.postSharing.length) && !post.deleted);
|
||||
});
|
||||
|
||||
updatePostCounts(data.posts);
|
||||
@@ -50,9 +50,7 @@ define('forum/topic/posts', [
|
||||
|
||||
function onNewPostPagination(data) {
|
||||
function scrollToPost() {
|
||||
if (ajaxify.data.scrollToMyPost) {
|
||||
scrollToPostIfSelf(data.posts[0]);
|
||||
}
|
||||
scrollToPostIfSelf(data.posts[0]);
|
||||
}
|
||||
|
||||
var posts = data.posts;
|
||||
|
||||
@@ -50,7 +50,8 @@ define('chat', ['components', 'taskbar', 'string', 'sounds', 'forum/chats', 'tra
|
||||
|
||||
taskbar.push('chat', modal.attr('UUID'), {
|
||||
title: username,
|
||||
touid: data.message.fromUser.uid
|
||||
touid: data.message.fromUser.uid,
|
||||
roomId: data.roomId
|
||||
});
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
if ((properties.loggedIn && !data.config.loggedIn) ||
|
||||
(properties.globalMod && !data.isGlobalMod && !data.isAdmin) ||
|
||||
(properties.adminOnly && !data.isAdmin) ||
|
||||
(properties.installed && properties.installed.search && !data.searchEnabled)) {
|
||||
(properties.searchInstalled && !data.searchEnabled)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ define('navigator', ['forum/pagination', 'components'], function(pagination, com
|
||||
scrollTo.parents('[component="post"]').addClass('highlight');
|
||||
setTimeout(function() {
|
||||
scrollTo.parents('[component="post"]').removeClass('highlight');
|
||||
}, 3000);
|
||||
}, 10000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ define('taskbar', function() {
|
||||
|
||||
$(window).trigger('filter:taskbar.push', data);
|
||||
|
||||
if (!element.length) {
|
||||
if (!element.length && data.module) {
|
||||
createTaskbar(data);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -213,13 +213,14 @@
|
||||
|
||||
function insertLanguage(text, key, value, variables) {
|
||||
if (value) {
|
||||
var variable;
|
||||
for (var i = 1, ii = variables.length; i < ii; i++) {
|
||||
variable = S(variables[i]).chompRight(']]').collapseWhitespace().decodeHTMLEntities().escapeHTML().s;
|
||||
value = value.replace('%' + i, variable);
|
||||
}
|
||||
variables.forEach(function(variable, index) {
|
||||
if (index > 0) {
|
||||
variable = S(variable).chompRight(']]').collapseWhitespace().decodeHTMLEntities().escapeHTML().s;
|
||||
value = value.replace('%' + index, function() { return variable; });
|
||||
}
|
||||
});
|
||||
|
||||
text = text.replace(key, value);
|
||||
text = text.replace(key, function() { return value; });
|
||||
} else {
|
||||
var string = key.split(':');
|
||||
text = text.replace(key, string[string.length-1].replace(regexes.replace, ''));
|
||||
|
||||
@@ -92,6 +92,23 @@
|
||||
return str;
|
||||
},
|
||||
|
||||
cleanUpTag: function(tag, maxLength) {
|
||||
if (typeof tag !== 'string' || !tag.length ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
tag = tag.trim().toLowerCase();
|
||||
// see https://github.com/NodeBB/NodeBB/issues/4378
|
||||
tag = tag.replace(/\u202E/gi, '');
|
||||
tag = tag.replace(/[,\/#!$%\^\*;:{}=_`<>'"~()?\|]/g, '');
|
||||
tag = tag.substr(0, maxLength || 15).trim();
|
||||
var matches = tag.match(/^[.-]*(.+?)[.-]*$/);
|
||||
if (matches && matches.length > 1) {
|
||||
tag = matches[1];
|
||||
}
|
||||
return tag;
|
||||
},
|
||||
|
||||
removePunctuation: function(str) {
|
||||
return str.replace(/[\.,-\/#!$%\^&\*;:{}=\-_`<>'"~()?]/g, '');
|
||||
},
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
/*
|
||||
* bootstrap-tagsinput v0.8.0
|
||||
*
|
||||
*/
|
||||
|
||||
.bootstrap-tagsinput {
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
display: inline-block;
|
||||
padding: 4px 6px;
|
||||
margin-bottom: 10px;
|
||||
color: #555;
|
||||
vertical-align: middle;
|
||||
border-radius: 4px;
|
||||
@@ -17,11 +21,21 @@
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
padding: 0 6px;
|
||||
margin: 0;
|
||||
width: auto !important;
|
||||
width: auto;
|
||||
max-width: inherit;
|
||||
}
|
||||
.bootstrap-tagsinput.form-control input::-moz-placeholder {
|
||||
color: #777;
|
||||
opacity: 1;
|
||||
}
|
||||
.bootstrap-tagsinput.form-control input:-ms-input-placeholder {
|
||||
color: #777;
|
||||
}
|
||||
.bootstrap-tagsinput.form-control input::-webkit-input-placeholder {
|
||||
color: #777;
|
||||
}
|
||||
.bootstrap-tagsinput input:focus {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
@@ -43,4 +57,4 @@
|
||||
}
|
||||
.bootstrap-tagsinput .tag [data-role="remove"]:hover:active {
|
||||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -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;
|
||||
module.exports = helpers;
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
var async = require('async'),
|
||||
|
||||
categories = require('../../categories'),
|
||||
privileges = require('../../privileges'),
|
||||
analytics = require('../../analytics'),
|
||||
plugins = require('../../plugins');
|
||||
var async = require('async');
|
||||
|
||||
var categories = require('../../categories');
|
||||
var privileges = require('../../privileges');
|
||||
var analytics = require('../../analytics');
|
||||
var plugins = require('../../plugins');
|
||||
var translator = require('../../../public/src/modules/translator')
|
||||
|
||||
|
||||
var categoriesController = {};
|
||||
@@ -24,7 +25,7 @@ categoriesController.get = function(req, res, next) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
data.category.name = translator.escape(data.category.name);
|
||||
res.render('admin/manage/category', {
|
||||
category: data.category,
|
||||
privileges: data.privileges,
|
||||
|
||||
@@ -52,7 +52,7 @@ categoryController.get = function(req, res, callback) {
|
||||
}
|
||||
|
||||
if (!res.locals.isAPI && (!req.params.slug || results.categoryData.slug !== cid + '/' + req.params.slug) && (results.categoryData.slug && results.categoryData.slug !== cid + '/')) {
|
||||
return helpers.redirect(res, '/category/' + encodeURI(results.categoryData.slug));
|
||||
return helpers.redirect(res, '/category/' + results.categoryData.slug);
|
||||
}
|
||||
|
||||
var settings = results.userSettings;
|
||||
|
||||
@@ -113,7 +113,7 @@ groupsController.members = function(req, res, next) {
|
||||
user.getUsersFromSet('group:' + groupName + ':members', req.uid, 0, 49, next);
|
||||
},
|
||||
], function(err, users) {
|
||||
if (err) {
|
||||
if (err || !groupName) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -105,8 +105,12 @@ helpers.buildTitle = function(pageTitle) {
|
||||
|
||||
var browserTitle = validator.escape(meta.config.browserTitle || meta.config.title || 'NodeBB');
|
||||
pageTitle = pageTitle || '';
|
||||
var title = titleLayout.replace('{pageTitle}', pageTitle).replace('{browserTitle}', browserTitle);
|
||||
var title = titleLayout.replace('{pageTitle}', function() {
|
||||
return pageTitle;
|
||||
}).replace('{browserTitle}', function() {
|
||||
return browserTitle;
|
||||
});
|
||||
return title;
|
||||
};
|
||||
|
||||
module.exports = helpers;
|
||||
module.exports = helpers;
|
||||
|
||||
@@ -65,6 +65,9 @@ tagsController.getTags = function(req, res, next) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
tags = tags.filter(function(tag) {
|
||||
return tag && tag.score > 0;
|
||||
});
|
||||
var data = {
|
||||
tags: tags,
|
||||
nextStart: 100,
|
||||
|
||||
@@ -55,7 +55,7 @@ topicsController.get = function(req, res, callback) {
|
||||
}
|
||||
|
||||
if (!res.locals.isAPI && (!req.params.slug || results.topic.slug !== tid + '/' + req.params.slug) && (results.topic.slug && results.topic.slug !== tid + '/')) {
|
||||
var url = '/topic/' + encodeURI(results.topic.slug);
|
||||
var url = '/topic/' + results.topic.slug;
|
||||
if (req.params.post_index){
|
||||
url += '/'+req.params.post_index;
|
||||
}
|
||||
@@ -124,7 +124,7 @@ topicsController.get = function(req, res, callback) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
topics.modifyPostsByPrivilege(topicData.posts, userPrivileges);
|
||||
topics.modifyPostsByPrivilege(topicData, userPrivileges);
|
||||
|
||||
plugins.fireHook('filter:controllers.topic.get', {topicData: topicData, uid: req.uid}, next);
|
||||
},
|
||||
|
||||
@@ -45,11 +45,26 @@ uploadsController.upload = function(req, res, filesIterator, next) {
|
||||
|
||||
uploadsController.uploadPost = function(req, res, next) {
|
||||
uploadsController.upload(req, res, function(uploadedFile, next) {
|
||||
if (uploadedFile.type.match(/image./)) {
|
||||
uploadImage(req.uid, uploadedFile, next);
|
||||
} else {
|
||||
uploadFile(req.uid, uploadedFile, next);
|
||||
var isImage = uploadedFile.type.match(/image./);
|
||||
if (isImage && plugins.hasListeners('filter:uploadImage')) {
|
||||
return plugins.fireHook('filter:uploadImage', {image: uploadedFile, uid: req.uid}, next);
|
||||
}
|
||||
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
if (isImage) {
|
||||
file.isFileTypeAllowed(uploadedFile.path, next);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
},
|
||||
function (next) {
|
||||
if (parseInt(meta.config.allowFileUploads, 10) !== 1) {
|
||||
return next(new Error('[[error:uploads-are-disabled]]'));
|
||||
}
|
||||
uploadFile(req.uid, uploadedFile, next);
|
||||
}
|
||||
], next);
|
||||
}, next);
|
||||
};
|
||||
|
||||
@@ -65,22 +80,27 @@ uploadsController.uploadThumb = function(req, res, next) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
if (uploadedFile.type.match(/image./)) {
|
||||
var size = parseInt(meta.config.topicThumbSize, 10) || 120;
|
||||
image.resizeImage({
|
||||
path: uploadedFile.path,
|
||||
extension: path.extname(uploadedFile.name),
|
||||
width: size,
|
||||
height: size
|
||||
}, function(err) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
uploadImage(req.uid, uploadedFile, next);
|
||||
});
|
||||
} else {
|
||||
next(new Error('[[error:invalid-file]]'));
|
||||
if (!uploadedFile.type.match(/image./)) {
|
||||
return next(new Error('[[error:invalid-file]]'));
|
||||
}
|
||||
|
||||
var size = parseInt(meta.config.topicThumbSize, 10) || 120;
|
||||
image.resizeImage({
|
||||
path: uploadedFile.path,
|
||||
extension: path.extname(uploadedFile.name),
|
||||
width: size,
|
||||
height: size
|
||||
}, function(err) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
if (plugins.hasListeners('filter:uploadImage')) {
|
||||
return plugins.fireHook('filter:uploadImage', {image: uploadedFile, uid: req.uid}, next);
|
||||
}
|
||||
|
||||
uploadFile(req.uid, uploadedFile, next);
|
||||
});
|
||||
});
|
||||
}, next);
|
||||
};
|
||||
@@ -102,32 +122,11 @@ uploadsController.uploadGroupCover = function(uid, uploadedFile, callback) {
|
||||
});
|
||||
};
|
||||
|
||||
function uploadImage(uid, image, callback) {
|
||||
if (plugins.hasListeners('filter:uploadImage')) {
|
||||
return plugins.fireHook('filter:uploadImage', {image: image, uid: uid}, callback);
|
||||
}
|
||||
|
||||
file.isFileTypeAllowed(image.path, function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
if (parseInt(meta.config.allowFileUploads, 10)) {
|
||||
uploadFile(uid, image, callback);
|
||||
} else {
|
||||
callback(new Error('[[error:uploads-are-disabled]]'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function uploadFile(uid, uploadedFile, callback) {
|
||||
if (plugins.hasListeners('filter:uploadFile')) {
|
||||
return plugins.fireHook('filter:uploadFile', {file: uploadedFile, uid: uid}, callback);
|
||||
}
|
||||
|
||||
if (parseInt(meta.config.allowFileUploads, 10) !== 1) {
|
||||
return callback(new Error('[[error:uploads-are-disabled]]'));
|
||||
}
|
||||
|
||||
if (!uploadedFile) {
|
||||
return callback(new Error('[[error:invalid-file]]'));
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ usersController.getUsers = function(set, uid, page, callback) {
|
||||
}
|
||||
|
||||
page = parseInt(page, 10) || 1;
|
||||
var resultsPerPage = parseInt(meta.config.userSearchResultsPerPage, 10) || 20;
|
||||
var resultsPerPage = parseInt(meta.config.userSearchResultsPerPage, 10) || 50;
|
||||
var start = Math.max(0, page - 1) * resultsPerPage;
|
||||
var stop = start + resultsPerPage - 1;
|
||||
|
||||
|
||||
@@ -78,16 +78,24 @@ Blacklist.validate = function(rules, callback) {
|
||||
var cidr = [];
|
||||
var invalid = [];
|
||||
|
||||
var isCidrSubnet = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$/;
|
||||
var isCidrSubnet = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$/,
|
||||
inlineCommentMatch = /#.*$/,
|
||||
whitelist = ['127.0.0.1', '::1', '::ffff:0:127.0.0.1'];
|
||||
|
||||
// Filter out blank lines and lines starting with the hash character (comments)
|
||||
// Also trim inputs and remove inline comments
|
||||
rules = rules.map(function(rule) {
|
||||
rule = rule.trim();
|
||||
rule = rule.replace(inlineCommentMatch, '').trim();
|
||||
return rule.length && !rule.startsWith('#') ? rule : null;
|
||||
}).filter(Boolean);
|
||||
|
||||
// Filter out invalid rules
|
||||
rules = rules.filter(function(rule) {
|
||||
if (whitelist.indexOf(rule) !== -1) {
|
||||
invalid.push(rule);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ip.isV4Format(rule)) {
|
||||
ipv4.push(rule);
|
||||
return true;
|
||||
|
||||
@@ -21,10 +21,10 @@ Templates.compile = function(callback) {
|
||||
|
||||
if (nconf.get('isPrimary') === 'false' || fromFile.match('tpl')) {
|
||||
if (fromFile.match('tpl')) {
|
||||
emitter.emit('templates:compiled');
|
||||
winston.info('[minifier] Compiling templates skipped');
|
||||
}
|
||||
|
||||
emitter.emit('templates:compiled');
|
||||
return callback();
|
||||
}
|
||||
|
||||
@@ -48,20 +48,28 @@ function getBaseTemplates(theme) {
|
||||
}
|
||||
|
||||
function preparePaths(baseTemplatesPaths, callback) {
|
||||
var coreTemplatesPath = nconf.get('core_templates_path'),
|
||||
viewsPath = nconf.get('views_dir');
|
||||
var coreTemplatesPath = nconf.get('core_templates_path');
|
||||
var viewsPath = nconf.get('views_dir');
|
||||
|
||||
async.waterfall([
|
||||
async.apply(plugins.fireHook, 'static:templates.precompile', {}),
|
||||
async.apply(plugins.getTemplates)
|
||||
function (next) {
|
||||
rimraf(viewsPath, next);
|
||||
},
|
||||
function (next) {
|
||||
mkdirp(viewsPath, next);
|
||||
},
|
||||
function(viewsPath, next) {
|
||||
plugins.fireHook('static:templates.precompile', {}, next);
|
||||
},
|
||||
function(next) {
|
||||
plugins.getTemplates(next);
|
||||
}
|
||||
], function(err, pluginTemplates) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
winston.verbose('[meta/templates] Compiling templates');
|
||||
rimraf.sync(viewsPath);
|
||||
mkdirp.sync(viewsPath);
|
||||
|
||||
async.parallel({
|
||||
coreTpls: function(next) {
|
||||
@@ -111,7 +119,7 @@ function compile(callback) {
|
||||
var themeConfig = require(nconf.get('theme_config')),
|
||||
baseTemplatesPaths = themeConfig.baseTheme ? getBaseTemplates(themeConfig.baseTheme) : [nconf.get('base_templates_path')],
|
||||
viewsPath = nconf.get('views_dir');
|
||||
|
||||
|
||||
|
||||
preparePaths(baseTemplatesPaths, function(err, paths) {
|
||||
if (err) {
|
||||
|
||||
@@ -259,7 +259,6 @@ middleware.busyCheck = function(req, res, next) {
|
||||
|
||||
middleware.applyBlacklist = function(req, res, next) {
|
||||
meta.blacklist.test(req.ip, function(err) {
|
||||
console.log('blacklist returned:', err);
|
||||
next(err);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -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(' ');
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
@@ -106,7 +106,7 @@ var async = require('async'),
|
||||
});
|
||||
|
||||
callback(null, _nids.filter(function(nid, idx) {
|
||||
return mergeIds.indexOf(sets[idx]) !== -1
|
||||
return mergeIds.indexOf(sets[idx]) !== -1;
|
||||
}));
|
||||
});
|
||||
};
|
||||
@@ -450,10 +450,14 @@ var async = require('async'),
|
||||
});
|
||||
var numUsers = usernames.length;
|
||||
|
||||
var title = S(notifications[modifyIndex].topicTitle || '').decodeHTMLEntities().s;
|
||||
var titleEscaped = title.replace(/%/g, '%').replace(/,/g, ',');
|
||||
titleEscaped = titleEscaped ? (', ' + titleEscaped) : '';
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ module.exports = function(Posts) {
|
||||
|
||||
if (title) {
|
||||
topicData.title = title;
|
||||
topicData.slug = tid + '/' + utils.slugify(title);
|
||||
topicData.slug = tid + '/' + (utils.slugify(title) || 'topic');
|
||||
}
|
||||
|
||||
if (data.topic_thumb) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -37,7 +37,7 @@ module.exports = function(privileges) {
|
||||
|
||||
var disabled = parseInt(results.disabled, 10) === 1;
|
||||
var locked = parseInt(topic.locked, 10) === 1;
|
||||
var isAdminOrMod = results.isAdministrator || results.isModerator;
|
||||
var isAdminOrMod = results.isAdministrator || results.isModerator;
|
||||
var editable = isAdminOrMod;
|
||||
var deletable = isAdminOrMod || results.isOwner;
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ function generateForTopic(req, res, callback) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
topics.modifyPostsByPrivilege(topicData.posts, userPrivileges);
|
||||
topics.modifyPostsByPrivilege(topicData, userPrivileges);
|
||||
|
||||
var description = topicData.posts.length ? topicData.posts[0].content : '';
|
||||
var image_url = topicData.posts.length ? topicData.posts[0].picture : '';
|
||||
|
||||
@@ -6,7 +6,13 @@ var async = require('async');
|
||||
|
||||
var social = {};
|
||||
|
||||
social.postSharing = null;
|
||||
|
||||
social.getPostSharing = function(callback) {
|
||||
if (social.postSharing) {
|
||||
return callback(null, social.postSharing);
|
||||
}
|
||||
|
||||
var networks = [
|
||||
{
|
||||
id: "facebook",
|
||||
@@ -39,20 +45,41 @@ social.getPostSharing = function(callback) {
|
||||
networks[i].activated = (activated.indexOf(network.id) !== -1);
|
||||
});
|
||||
|
||||
social.postSharing = networks;
|
||||
next(null, networks);
|
||||
});
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
social.setActivePostSharingNetworks = function(networkIDs, callback) {
|
||||
db.delete('social:posts.activated', function(err) {
|
||||
if (!networkIDs.length) {
|
||||
social.getActivePostSharing = function(callback) {
|
||||
social.getPostSharing(function(err, networks) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
db.setAdd('social:posts.activated', networkIDs, callback);
|
||||
networks = networks.filter(function(network) {
|
||||
return network && network.activated;
|
||||
});
|
||||
callback(null, networks);
|
||||
});
|
||||
};
|
||||
|
||||
social.setActivePostSharingNetworks = function(networkIDs, callback) {
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
db.delete('social:posts.activated', next);
|
||||
},
|
||||
function (next) {
|
||||
if (!networkIDs.length) {
|
||||
return next();
|
||||
}
|
||||
db.setAdd('social:posts.activated', networkIDs, next);
|
||||
},
|
||||
function (next) {
|
||||
social.postSharing = null;
|
||||
next();
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
module.exports = social;
|
||||
@@ -155,7 +155,7 @@ SocketGroups.kick = isOwner(function(socket, data, callback) {
|
||||
if (socket.uid === parseInt(data.uid, 10)) {
|
||||
return callback(new Error('[[error:cant-kick-self]]'));
|
||||
}
|
||||
|
||||
|
||||
groups.ownership.isOwner(data.uid, data.groupName, function(err, isOwner) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
@@ -178,16 +178,16 @@ SocketGroups.create = function(socket, data, callback) {
|
||||
};
|
||||
|
||||
SocketGroups.delete = function(socket, data, callback) {
|
||||
if (data.groupName === 'administrators' || data.groupName === 'registered-users') {
|
||||
if (data.groupName === 'administrators' ||
|
||||
data.groupName === 'registered-users' ||
|
||||
data.groupName === 'Global Moderators') {
|
||||
return callback(new Error('[[error:not-allowed]]'));
|
||||
}
|
||||
|
||||
var tasks = {
|
||||
async.parallel({
|
||||
isOwner: async.apply(groups.ownership.isOwner, socket.uid, data.groupName),
|
||||
isAdmin: async.apply(user.isAdministrator, socket.uid)
|
||||
};
|
||||
|
||||
async.parallel(tasks, function(err, checks) {
|
||||
}, function(err, checks) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
module.exports = SocketHelpers;
|
||||
|
||||
@@ -240,6 +240,7 @@ SocketModules.chats.markRead = function(socket, roomId, callback) {
|
||||
user.notifications.pushCount(socket.uid);
|
||||
});
|
||||
|
||||
server.in('uid_' + socket.uid).emit('event:chats.markedAsRead', {roomId: roomId});
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -32,7 +32,7 @@ module.exports = function(SocketPosts) {
|
||||
plugins.fireHook('filter:post.tools', {pid: data.pid, uid: socket.uid, tools: []}, next);
|
||||
},
|
||||
postSharing: function(next) {
|
||||
social.getPostSharing(next);
|
||||
social.getActivePostSharing(next);
|
||||
}
|
||||
}, function(err, results) {
|
||||
if (err) {
|
||||
|
||||
@@ -6,6 +6,7 @@ var topics = require('../../topics');
|
||||
var privileges = require('../../privileges');
|
||||
var meta = require('../../meta');
|
||||
var utils = require('../../../public/src/utils');
|
||||
var social = require('../../social');
|
||||
|
||||
module.exports = function(SocketTopics) {
|
||||
|
||||
@@ -68,6 +69,9 @@ module.exports = function(SocketTopics) {
|
||||
},
|
||||
posts: function(next) {
|
||||
topics.getTopicPosts(data.tid, set, start, stop, socket.uid, reverse, next);
|
||||
},
|
||||
postSharing: function (next) {
|
||||
social.getActivePostSharing(next);
|
||||
}
|
||||
}, function(err, topicData) {
|
||||
if (err) {
|
||||
@@ -81,7 +85,7 @@ module.exports = function(SocketTopics) {
|
||||
topicData['reputation:disabled'] = parseInt(meta.config['reputation:disabled'], 10) === 1;
|
||||
topicData['downvote:disabled'] = parseInt(meta.config['downvote:disabled'], 10) === 1;
|
||||
|
||||
topics.modifyPostsByPrivilege(topicData.posts, results.privileges);
|
||||
topics.modifyPostsByPrivilege(topicData, results.privileges);
|
||||
callback(null, topicData);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,14 +20,16 @@ module.exports = function(SocketTopics) {
|
||||
return callback(new Error('[[error:invalid-data]]'));
|
||||
}
|
||||
|
||||
var start = parseInt(data.after, 10),
|
||||
stop = start + 99;
|
||||
var start = parseInt(data.after, 10);
|
||||
var stop = start + 99;
|
||||
|
||||
topics.getTags(start, stop, function(err, tags) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
tags = tags.filter(function(tag) {
|
||||
return tag && tag.score > 0;
|
||||
});
|
||||
callback(null, {tags: tags, nextStart: stop + 1});
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
"use strict";
|
||||
|
||||
var async = require('async'),
|
||||
_ = require('underscore'),
|
||||
var async = require('async');
|
||||
var _ = require('underscore');
|
||||
|
||||
db = require('./database'),
|
||||
posts = require('./posts'),
|
||||
utils = require('../public/src/utils'),
|
||||
plugins = require('./plugins'),
|
||||
user = require('./user'),
|
||||
categories = require('./categories'),
|
||||
privileges = require('./privileges');
|
||||
var db = require('./database');
|
||||
var posts = require('./posts');
|
||||
var utils = require('../public/src/utils');
|
||||
var plugins = require('./plugins');
|
||||
var user = require('./user');
|
||||
var categories = require('./categories');
|
||||
var privileges = require('./privileges');
|
||||
var social = require('./social');
|
||||
|
||||
(function(Topics) {
|
||||
|
||||
@@ -125,11 +126,14 @@ var async = require('async'),
|
||||
user.getUsersFields(uids, ['uid', 'username', 'fullname', 'userslug', 'reputation', 'postcount', 'picture', 'signature', 'banned', 'status'], next);
|
||||
},
|
||||
categories: function(next) {
|
||||
categories.getCategoriesFields(cids, ['cid', 'name', 'slug', 'icon', 'bgColor', 'color', 'disabled'], next);
|
||||
categories.getCategoriesFields(cids, ['cid', 'name', 'slug', 'icon', 'image', 'bgColor', 'color', 'disabled'], next);
|
||||
},
|
||||
hasRead: function(next) {
|
||||
Topics.hasReadTopics(tids, uid, next);
|
||||
},
|
||||
bookmarks: function(next) {
|
||||
Topics.getUserBookmarks(tids, uid, next);
|
||||
},
|
||||
teasers: function(next) {
|
||||
Topics.getTeasers(topics, next);
|
||||
},
|
||||
@@ -154,6 +158,7 @@ var async = require('async'),
|
||||
topics[i].locked = parseInt(topics[i].locked, 10) === 1;
|
||||
topics[i].deleted = parseInt(topics[i].deleted, 10) === 1;
|
||||
topics[i].unread = !results.hasRead[i];
|
||||
topics[i].bookmark = results.bookmarks[i];
|
||||
topics[i].unreplied = !topics[i].teaser;
|
||||
}
|
||||
}
|
||||
@@ -179,7 +184,8 @@ var async = require('async'),
|
||||
threadTools: async.apply(plugins.fireHook, 'filter:topic.thread_tools', {topic: topicData, uid: uid, tools: []}),
|
||||
tags: async.apply(Topics.getTopicTagsObjects, topicData.tid),
|
||||
isFollowing: async.apply(Topics.isFollowing, [topicData.tid], uid),
|
||||
bookmark: async.apply(Topics.getUserBookmark, topicData.tid, uid)
|
||||
bookmark: async.apply(Topics.getUserBookmark, topicData.tid, uid),
|
||||
postSharing: async.apply(social.getActivePostSharing)
|
||||
}, next);
|
||||
},
|
||||
function (results, next) {
|
||||
@@ -189,6 +195,7 @@ var async = require('async'),
|
||||
topicData.tags = results.tags;
|
||||
topicData.isFollowing = results.isFollowing[0];
|
||||
topicData.bookmark = results.bookmark;
|
||||
topicData.postSharing = results.postSharing;
|
||||
|
||||
topicData.unreplied = parseInt(topicData.postcount, 10) === 1;
|
||||
topicData.deleted = parseInt(topicData.deleted, 10) === 1;
|
||||
@@ -289,6 +296,17 @@ var async = require('async'),
|
||||
db.sortedSetScore('tid:' + tid + ':bookmarks', uid, callback);
|
||||
};
|
||||
|
||||
Topics.getUserBookmarks = function(tids, uid, callback) {
|
||||
if (!parseInt(uid, 10)) {
|
||||
return callback(null, tids.map(function() {
|
||||
return null;
|
||||
}));
|
||||
}
|
||||
db.sortedSetsScore(tids.map(function(tid) {
|
||||
return 'tid:' + tid + ':bookmarks';
|
||||
}), uid, callback);
|
||||
};
|
||||
|
||||
Topics.setUserBookmark = function(tid, uid, index, callback) {
|
||||
db.sortedSetAdd('tid:' + tid + ':bookmarks', index, uid, callback);
|
||||
};
|
||||
|
||||
@@ -59,7 +59,7 @@ module.exports = function(Topics) {
|
||||
return;
|
||||
}
|
||||
topic.titleRaw = topic.title;
|
||||
topic.title = validator.escape(topic.title);
|
||||
topic.title = validator.escape(String(topic.title));
|
||||
topic.timestampISO = utils.toISOString(topic.timestamp);
|
||||
topic.lastposttimeISO = utils.toISOString(topic.lastposttime);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var async = require('async'),
|
||||
winston = require('winston'),
|
||||
|
||||
db = require('../database'),
|
||||
user = require('../user'),
|
||||
posts = require('../posts'),
|
||||
privileges = require('../privileges'),
|
||||
plugins = require('../plugins');
|
||||
var async = require('async');
|
||||
var winston = require('winston');
|
||||
var db = require('../database');
|
||||
var user = require('../user');
|
||||
var posts = require('../posts');
|
||||
var privileges = require('../privileges');
|
||||
var plugins = require('../plugins');
|
||||
var meta = require('../meta');
|
||||
|
||||
|
||||
module.exports = function(Topics) {
|
||||
@@ -18,8 +18,10 @@ module.exports = function(Topics) {
|
||||
title = title.trim();
|
||||
}
|
||||
|
||||
if (!title) {
|
||||
return callback(new Error('[[error:invalid-title]]'));
|
||||
if (title.length < parseInt(meta.config.minimumTitleLength, 10)) {
|
||||
return callback(new Error('[[error:title-too-short, ' + meta.config.minimumTitleLength + ']]'));
|
||||
} else if (title.length > parseInt(meta.config.maximumTitleLength, 10)) {
|
||||
return callback(new Error('[[error:title-too-long, ' + meta.config.maximumTitleLength + ']]'));
|
||||
}
|
||||
|
||||
if (!pids || !pids.length) {
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
|
||||
|
||||
'use strict';
|
||||
|
||||
var async = require('async'),
|
||||
_ = require('underscore'),
|
||||
validator = require('validator'),
|
||||
var async = require('async');
|
||||
var _ = require('underscore');
|
||||
var validator = require('validator');
|
||||
|
||||
db = require('../database'),
|
||||
user = require('../user'),
|
||||
favourites = require('../favourites'),
|
||||
posts = require('../posts'),
|
||||
meta = require('../meta');
|
||||
var db = require('../database');
|
||||
var user = require('../user');
|
||||
var favourites = require('../favourites');
|
||||
var posts = require('../posts');
|
||||
var meta = require('../meta');
|
||||
|
||||
module.exports = function(Topics) {
|
||||
|
||||
@@ -138,16 +137,20 @@ module.exports = function(Topics) {
|
||||
});
|
||||
};
|
||||
|
||||
Topics.modifyPostsByPrivilege = function(postData, topicPrivileges) {
|
||||
postData.forEach(function(post) {
|
||||
Topics.modifyPostsByPrivilege = function(topicData, topicPrivileges) {
|
||||
var loggedIn = !!parseInt(topicPrivileges.uid, 10);
|
||||
topicData.posts.forEach(function(post) {
|
||||
if (post) {
|
||||
post.display_moderator_tools = topicPrivileges.isAdminOrMod || post.selfPost;
|
||||
post.display_move_tools = topicPrivileges.isAdminOrMod && post.index !== 0;
|
||||
post.display_post_menu = topicPrivileges.isAdminOrMod || post.selfPost || !post.deleted;
|
||||
post.display_post_menu = topicPrivileges.isAdminOrMod || post.selfPost || ((loggedIn || topicData.postSharing.length) && !post.deleted);
|
||||
post.ip = topicPrivileges.isAdminOrMod ? post.ip : undefined;
|
||||
|
||||
if (post.deleted && !(topicPrivileges.isAdminOrMod || post.selfPost)) {
|
||||
post.content = '[[topic:post_is_deleted]]';
|
||||
if (post.user) {
|
||||
post.user.signature = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var async = require('async'),
|
||||
var async = require('async');
|
||||
|
||||
db = require('../database'),
|
||||
meta = require('../meta'),
|
||||
_ = require('underscore'),
|
||||
plugins = require('../plugins');
|
||||
var db = require('../database');
|
||||
var meta = require('../meta');
|
||||
var _ = require('underscore');
|
||||
var plugins = require('../plugins');
|
||||
var utils = require('../../public/src/utils');
|
||||
|
||||
|
||||
module.exports = function(Topics) {
|
||||
@@ -24,7 +25,9 @@ module.exports = function(Topics) {
|
||||
},
|
||||
function (data, next) {
|
||||
tags = data.tags.slice(0, meta.config.maximumTagsPerTopic || 5);
|
||||
tags = tags.map(Topics.cleanUpTag).filter(function(tag, index, array) {
|
||||
tags = tags.map(function(tag) {
|
||||
return utils.cleanUpTag(tag, meta.config.maximumTagLength);
|
||||
}).filter(function(tag, index, array) {
|
||||
return tag && tag.length >= (meta.config.minimumTagLength || 3) && array.indexOf(tag) === index;
|
||||
});
|
||||
|
||||
@@ -45,20 +48,6 @@ module.exports = function(Topics) {
|
||||
], callback);
|
||||
};
|
||||
|
||||
Topics.cleanUpTag = function(tag) {
|
||||
if (typeof tag !== 'string' || !tag.length ) {
|
||||
return '';
|
||||
}
|
||||
tag = tag.trim().toLowerCase();
|
||||
tag = tag.replace(/[,\/#!$%\^\*;:{}=_`<>'"~()?\|]/g, '');
|
||||
tag = tag.substr(0, meta.config.maximumTagLength || 15).trim();
|
||||
var matches = tag.match(/^[.-]*(.+?)[.-]*$/);
|
||||
if (matches && matches.length > 1) {
|
||||
tag = matches[1];
|
||||
}
|
||||
return tag;
|
||||
};
|
||||
|
||||
Topics.updateTag = function(tag, data, callback) {
|
||||
db.setObject('tag:' + tag, data, callback);
|
||||
};
|
||||
|
||||
@@ -74,7 +74,7 @@ module.exports = function(Topics) {
|
||||
tidToPost[topic.tid].index = meta.config.teaserPost === 'first' ? 1 : counts[index];
|
||||
if (tidToPost[topic.tid].content) {
|
||||
var s = S(tidToPost[topic.tid].content);
|
||||
tidToPost[topic.tid].content = s.stripTags.apply(s, utils.stripTags).s;
|
||||
tidToPost[topic.tid].content = s.stripTags.apply(s, utils.stripTags.concat(['img'])).s;
|
||||
}
|
||||
}
|
||||
return tidToPost[topic.tid];
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
var async = require('async'),
|
||||
db = require('../database'),
|
||||
utils = require('../../public/src/utils'),
|
||||
validator = require('validator'),
|
||||
plugins = require('../plugins'),
|
||||
groups = require('../groups'),
|
||||
meta = require('../meta'),
|
||||
notifications = require('../notifications'),
|
||||
translator = require('../../public/src/modules/translator');
|
||||
var async = require('async');
|
||||
var db = require('../database');
|
||||
var utils = require('../../public/src/utils');
|
||||
var validator = require('validator');
|
||||
var plugins = require('../plugins');
|
||||
var groups = require('../groups');
|
||||
var meta = require('../meta');
|
||||
|
||||
|
||||
module.exports = function(User) {
|
||||
|
||||
@@ -90,7 +89,11 @@ module.exports = function(User) {
|
||||
db.sortedSetAdd('userslug:uid', userData.uid, userData.userslug, next);
|
||||
},
|
||||
function(next) {
|
||||
db.sortedSetsAdd(['users:joindate', 'users:online', 'users:notvalidated'], timestamp, userData.uid, next);
|
||||
var sets = ['users:joindate', 'users:online'];
|
||||
if (parseInt(userData.uid) !== 1) {
|
||||
sets.push('users:notvalidated');
|
||||
}
|
||||
db.sortedSetsAdd(sets, timestamp, userData.uid, next);
|
||||
},
|
||||
function(next) {
|
||||
db.sortedSetsAdd(['users:postcount', 'users:reputation'], 0, userData.uid, next);
|
||||
@@ -176,7 +179,7 @@ module.exports = function(User) {
|
||||
next();
|
||||
}
|
||||
}
|
||||
}, function(err, results) {
|
||||
}, function(err) {
|
||||
callback(err);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -84,6 +84,15 @@
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<strong>Installed Plugins Required:</strong>
|
||||
|
||||
<div class="checkbox">
|
||||
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
||||
<input class="mdl-switch__input" type="checkbox" name="property:searchInstalled" <!-- IF enabled.properties.searchInstalled -->checked<!-- ENDIF enabled.properties.searchInstalled -->/>
|
||||
<span class="mdl-switch__label"><strong>Search plugin</strong></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-danger delete">Delete</button>
|
||||
<!-- IF enabled.enabled -->
|
||||
<button class="btn btn-warning toggle">Disable</button>
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
<fieldset>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input id="group-hidden" name="hidden" type="checkbox"<!-- IF group.hidden --> checked<!-- ENDIF group.hidden -->> <strong>[Hidden</strong>
|
||||
<input id="group-hidden" name="hidden" type="checkbox"<!-- IF group.hidden --> checked<!-- ENDIF group.hidden -->> <strong>Hidden</strong>
|
||||
<p class="help-block">
|
||||
If enabled, this group will not be found in the groups listing, and users will have to be invited manually
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user