mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46:12 +01:00
chore: eslint max-len
This commit is contained in:
committed by
Julian Lam
parent
5c2f0f0557
commit
cc9d6fd08b
@@ -81,8 +81,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
// allow lines of up to 120 characters
|
// allow lines of up to 120 characters
|
||||||
// "max-len": ["error", { "code": 120, "tabWidth": 2, "ignoreUrls": true, "ignoreStrings": true, "ignoreTemplateLiterals": true, "ignoreRegExpLiterals": true }],
|
"max-len": ["error", { "code": 120, "tabWidth": 2, "ignoreUrls": true, "ignoreStrings": true, "ignoreTemplateLiterals": true, "ignoreRegExpLiterals": true }],
|
||||||
"max-len": "off", // do this LAST
|
|
||||||
|
|
||||||
// === Disable rules ===
|
// === Disable rules ===
|
||||||
// more liberal naming
|
// more liberal naming
|
||||||
|
|||||||
@@ -184,7 +184,9 @@ define('admin/manage/users', [
|
|||||||
data[cur.name] = cur.value;
|
data[cur.name] = cur.value;
|
||||||
return data;
|
return data;
|
||||||
}, {});
|
}, {});
|
||||||
var until = formData.length > 0 ? (Date.now() + (formData.length * 1000 * 60 * 60 * (parseInt(formData.unit, 10) ? 24 : 1))) : 0;
|
var until = formData.length > 0 ? (
|
||||||
|
Date.now() + (formData.length * 1000 * 60 * 60 * (parseInt(formData.unit, 10) ? 24 : 1))
|
||||||
|
) : 0;
|
||||||
|
|
||||||
Promise.all(uids.map(function (uid) {
|
Promise.all(uids.map(function (uid) {
|
||||||
return api.put('/users/' + uid + '/ban', {
|
return api.put('/users/' + uid + '/ban', {
|
||||||
|
|||||||
@@ -62,7 +62,11 @@ ajaxify = window.ajaxify || {};
|
|||||||
$('#footer, #content').removeClass('hide').addClass('ajaxifying');
|
$('#footer, #content').removeClass('hide').addClass('ajaxifying');
|
||||||
|
|
||||||
ajaxify.loadData(url, function (err, data) {
|
ajaxify.loadData(url, function (err, data) {
|
||||||
if (!err || (err && err.data && (parseInt(err.data.status, 10) !== 302 && parseInt(err.data.status, 10) !== 308))) {
|
if (!err || (
|
||||||
|
err &&
|
||||||
|
err.data &&
|
||||||
|
(parseInt(err.data.status, 10) !== 302 && parseInt(err.data.status, 10) !== 308)
|
||||||
|
)) {
|
||||||
ajaxify.updateHistory(url, quiet);
|
ajaxify.updateHistory(url, quiet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,7 +344,8 @@ ajaxify = window.ajaxify || {};
|
|||||||
if (typeof script === 'string') {
|
if (typeof script === 'string') {
|
||||||
return function (next) {
|
return function (next) {
|
||||||
require(['hooks', script], function (hooks, module) {
|
require(['hooks', script], function (hooks, module) {
|
||||||
// Hint: useful if you want to override a loaded library (e.g. replace core client-side logic), or call a method other than .init()
|
// Hint: useful if you want to override a loaded library (e.g. replace core client-side logic),
|
||||||
|
// or call a method other than .init()
|
||||||
hooks.fire('static:script.init', { tpl_url, name: script, module }).then(() => {
|
hooks.fire('static:script.init', { tpl_url, name: script, module }).then(() => {
|
||||||
if (module && module.init) {
|
if (module && module.init) {
|
||||||
module.init();
|
module.init();
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ define('forum/account/edit', [
|
|||||||
aboutme: $('#inputAboutMe').val(),
|
aboutme: $('#inputAboutMe').val(),
|
||||||
};
|
};
|
||||||
|
|
||||||
userData.groupTitle = JSON.stringify(Array.isArray(userData.groupTitle) ? userData.groupTitle : [userData.groupTitle]);
|
userData.groupTitle = JSON.stringify(
|
||||||
|
Array.isArray(userData.groupTitle) ? userData.groupTitle : [userData.groupTitle]
|
||||||
|
);
|
||||||
|
|
||||||
$(window).trigger('action:profile.update', userData);
|
$(window).trigger('action:profile.update', userData);
|
||||||
|
|
||||||
|
|||||||
@@ -150,7 +150,9 @@ define('forum/account/header', [
|
|||||||
return data;
|
return data;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
var until = formData.length > 0 ? (Date.now() + (formData.length * 1000 * 60 * 60 * (parseInt(formData.unit, 10) ? 24 : 1))) : 0;
|
var until = formData.length > 0 ? (
|
||||||
|
Date.now() + (formData.length * 1000 * 60 * 60 * (parseInt(formData.unit, 10) ? 24 : 1))
|
||||||
|
) : 0;
|
||||||
|
|
||||||
api.put('/users/' + theirid + '/ban', {
|
api.put('/users/' + theirid + '/ban', {
|
||||||
until: until,
|
until: until,
|
||||||
|
|||||||
@@ -10,7 +10,17 @@ define('forum/groups/details', [
|
|||||||
'api',
|
'api',
|
||||||
'slugify',
|
'slugify',
|
||||||
'categorySelector',
|
'categorySelector',
|
||||||
], function (memberList, iconSelect, components, coverPhoto, pictureCropper, translator, api, slugify, categorySelector) {
|
], function (
|
||||||
|
memberList,
|
||||||
|
iconSelect,
|
||||||
|
components,
|
||||||
|
coverPhoto,
|
||||||
|
pictureCropper,
|
||||||
|
translator,
|
||||||
|
api,
|
||||||
|
slugify,
|
||||||
|
categorySelector
|
||||||
|
) {
|
||||||
var Details = {};
|
var Details = {};
|
||||||
var groupName;
|
var groupName;
|
||||||
|
|
||||||
|
|||||||
@@ -130,7 +130,10 @@ define('forum/topic', [
|
|||||||
if (components.get('post/anchor', postIndex - 1).length) {
|
if (components.get('post/anchor', postIndex - 1).length) {
|
||||||
return navigator.scrollToPostIndex(postIndex - 1, true, 0);
|
return navigator.scrollToPostIndex(postIndex - 1, true, 0);
|
||||||
}
|
}
|
||||||
} else if (bookmark && (!config.usePagination || (config.usePagination && ajaxify.data.pagination.currentPage === 1)) && ajaxify.data.postcount > ajaxify.data.bookmarkThreshold) {
|
} else if (bookmark && (
|
||||||
|
!config.usePagination ||
|
||||||
|
(config.usePagination && ajaxify.data.pagination.currentPage === 1)
|
||||||
|
) && ajaxify.data.postcount > ajaxify.data.bookmarkThreshold) {
|
||||||
app.alert({
|
app.alert({
|
||||||
alert_id: 'bookmark',
|
alert_id: 'bookmark',
|
||||||
message: '[[topic:bookmark_instructions]]',
|
message: '[[topic:bookmark_instructions]]',
|
||||||
@@ -250,7 +253,14 @@ define('forum/topic', [
|
|||||||
index = Math.max(1, ajaxify.data.postcount - index + 2);
|
index = Math.max(1, ajaxify.data.postcount - index + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ajaxify.data.postcount > ajaxify.data.bookmarkThreshold && (!currentBookmark || parseInt(index, 10) > parseInt(currentBookmark, 10) || ajaxify.data.postcount < parseInt(currentBookmark, 10))) {
|
if (
|
||||||
|
ajaxify.data.postcount > ajaxify.data.bookmarkThreshold &&
|
||||||
|
(
|
||||||
|
!currentBookmark ||
|
||||||
|
parseInt(index, 10) > parseInt(currentBookmark, 10) ||
|
||||||
|
ajaxify.data.postcount < parseInt(currentBookmark, 10)
|
||||||
|
)
|
||||||
|
) {
|
||||||
if (app.user.uid) {
|
if (app.user.uid) {
|
||||||
socket.emit('topics.bookmark', {
|
socket.emit('topics.bookmark', {
|
||||||
tid: ajaxify.data.tid,
|
tid: ajaxify.data.tid,
|
||||||
|
|||||||
@@ -84,7 +84,11 @@ define('forum/topic/events', [
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onTopicPurged(data) {
|
function onTopicPurged(data) {
|
||||||
if (ajaxify.data.category && ajaxify.data.category.slug && parseInt(data.tid, 10) === parseInt(ajaxify.data.tid, 10)) {
|
if (
|
||||||
|
ajaxify.data.category &&
|
||||||
|
ajaxify.data.category.slug &&
|
||||||
|
parseInt(data.tid, 10) === parseInt(ajaxify.data.tid, 10)
|
||||||
|
) {
|
||||||
ajaxify.go('category/' + ajaxify.data.category.slug, null, true);
|
ajaxify.go('category/' + ajaxify.data.category.slug, null, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,12 @@ define('forum/topic/posts', [
|
|||||||
var Posts = { };
|
var Posts = { };
|
||||||
|
|
||||||
Posts.onNewPost = function (data) {
|
Posts.onNewPost = function (data) {
|
||||||
if (!data || !data.posts || !data.posts.length || parseInt(data.posts[0].tid, 10) !== parseInt(ajaxify.data.tid, 10)) {
|
if (
|
||||||
|
!data ||
|
||||||
|
!data.posts ||
|
||||||
|
!data.posts.length ||
|
||||||
|
parseInt(data.posts[0].tid, 10) !== parseInt(ajaxify.data.tid, 10)
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,8 +93,10 @@ define('forum/topic/posts', [
|
|||||||
ajaxify.data.pagination.pageCount = Math.max(1, Math.ceil(posts[0].topic.postcount / config.postsPerPage));
|
ajaxify.data.pagination.pageCount = Math.max(1, Math.ceil(posts[0].topic.postcount / config.postsPerPage));
|
||||||
var direction = config.topicPostSort === 'oldest_to_newest' || config.topicPostSort === 'most_votes' ? 1 : -1;
|
var direction = config.topicPostSort === 'oldest_to_newest' || config.topicPostSort === 'most_votes' ? 1 : -1;
|
||||||
|
|
||||||
var isPostVisible = (ajaxify.data.pagination.currentPage === ajaxify.data.pagination.pageCount && direction === 1) ||
|
var isPostVisible = (
|
||||||
(ajaxify.data.pagination.currentPage === 1 && direction === -1);
|
ajaxify.data.pagination.currentPage === ajaxify.data.pagination.pageCount &&
|
||||||
|
direction === 1
|
||||||
|
) || (ajaxify.data.pagination.currentPage === 1 && direction === -1);
|
||||||
|
|
||||||
if (isPostVisible) {
|
if (isPostVisible) {
|
||||||
createNewPosts(data, components.get('post').not('[data-index=0]'), direction, false, scrollToPost);
|
createNewPosts(data, components.get('post').not('[data-index=0]'), direction, false, scrollToPost);
|
||||||
@@ -299,7 +306,9 @@ define('forum/topic/posts', [
|
|||||||
}
|
}
|
||||||
|
|
||||||
Promise.all(events.map((event) => {
|
Promise.all(events.map((event) => {
|
||||||
const beforeIdx = postTimestamps.findIndex(timestamp => (reverse ? (timestamp < event.timestamp) : (timestamp > event.timestamp)));
|
const beforeIdx = postTimestamps.findIndex(
|
||||||
|
timestamp => (reverse ? (timestamp < event.timestamp) : (timestamp > event.timestamp))
|
||||||
|
);
|
||||||
let postEl;
|
let postEl;
|
||||||
if (beforeIdx > -1) {
|
if (beforeIdx > -1) {
|
||||||
postEl = document.querySelector(`[component="post"][data-pid="${ajaxify.data.posts[beforeIdx + (reverse ? 1 : 0)].pid}"]`);
|
postEl = document.querySelector(`[component="post"][data-pid="${ajaxify.data.posts[beforeIdx + (reverse ? 1 : 0)].pid}"]`);
|
||||||
|
|||||||
@@ -34,7 +34,12 @@ define('handleBack', [
|
|||||||
|
|
||||||
function onBackClicked(isMarkedUnread) {
|
function onBackClicked(isMarkedUnread) {
|
||||||
var highlightUnread = isMarkedUnread && ajaxify.data.template.unread;
|
var highlightUnread = isMarkedUnread && ajaxify.data.template.unread;
|
||||||
if (ajaxify.data.template.category || ajaxify.data.template.recent || ajaxify.data.template.popular || highlightUnread) {
|
if (
|
||||||
|
ajaxify.data.template.category ||
|
||||||
|
ajaxify.data.template.recent ||
|
||||||
|
ajaxify.data.template.popular ||
|
||||||
|
highlightUnread
|
||||||
|
) {
|
||||||
var bookmarkIndex = storage.getItem('category:bookmark');
|
var bookmarkIndex = storage.getItem('category:bookmark');
|
||||||
var clickedIndex = storage.getItem('category:bookmark:clicked');
|
var clickedIndex = storage.getItem('category:bookmark:clicked');
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,9 @@ define('hooks', [], () => {
|
|||||||
return listeners.reduce((promise, listener) => promise.then((data) => {
|
return listeners.reduce((promise, listener) => promise.then((data) => {
|
||||||
try {
|
try {
|
||||||
const result = listener(data);
|
const result = listener(data);
|
||||||
return utils.isPromise(result) ? result.then(data => Promise.resolve(data)).catch(e => _onHookError(e, listener, data)) : result;
|
return utils.isPromise(result) ?
|
||||||
|
result.then(data => Promise.resolve(data)).catch(e => _onHookError(e, listener, data)) :
|
||||||
|
result;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return _onHookError(e, listener, data);
|
return _onHookError(e, listener, data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,7 +176,9 @@ define('pictureCropper', ['cropper'], function (Cropper) {
|
|||||||
function checkCORS(cropperTool, data) {
|
function checkCORS(cropperTool, data) {
|
||||||
var imageData;
|
var imageData;
|
||||||
try {
|
try {
|
||||||
imageData = data.imageType ? cropperTool.getCroppedCanvas().toDataURL(data.imageType) : cropperTool.getCroppedCanvas().toDataURL();
|
imageData = data.imageType ?
|
||||||
|
cropperTool.getCroppedCanvas().toDataURL(data.imageType) :
|
||||||
|
cropperTool.getCroppedCanvas().toDataURL();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
var corsErrors = [
|
var corsErrors = [
|
||||||
'The operation is insecure.',
|
'The operation is insecure.',
|
||||||
|
|||||||
@@ -42,8 +42,22 @@ define('settings/key', function () {
|
|||||||
@returns Key | null The Key-Object the focused element should be set to.
|
@returns Key | null The Key-Object the focused element should be set to.
|
||||||
*/
|
*/
|
||||||
function getKey(event) {
|
function getKey(event) {
|
||||||
var anyModChange = event.ctrlKey !== lastKey.c || event.altKey !== lastKey.a || event.shiftKey !== lastKey.s || event.metaKey !== lastKey.m;
|
var anyModChange = (
|
||||||
var modChange = event.ctrlKey + event.altKey + event.shiftKey + event.metaKey - lastKey.c - lastKey.a - lastKey.s - lastKey.m;
|
event.ctrlKey !== lastKey.c ||
|
||||||
|
event.altKey !== lastKey.a ||
|
||||||
|
event.shiftKey !== lastKey.s ||
|
||||||
|
event.metaKey !== lastKey.m
|
||||||
|
);
|
||||||
|
var modChange = (
|
||||||
|
event.ctrlKey +
|
||||||
|
event.altKey +
|
||||||
|
event.shiftKey +
|
||||||
|
event.metaKey -
|
||||||
|
lastKey.c -
|
||||||
|
lastKey.a -
|
||||||
|
lastKey.s -
|
||||||
|
lastKey.m
|
||||||
|
);
|
||||||
var key = new Key();
|
var key = new Key();
|
||||||
key.c = event.ctrlKey;
|
key.c = event.ctrlKey;
|
||||||
key.a = event.altKey;
|
key.a = event.altKey;
|
||||||
|
|||||||
@@ -90,9 +90,15 @@ define('settings/object', function () {
|
|||||||
if (value[propertyName] === undefined && attributes['data-new'] !== undefined) {
|
if (value[propertyName] === undefined && attributes['data-new'] !== undefined) {
|
||||||
value[propertyName] = attributes['data-new'];
|
value[propertyName] = attributes['data-new'];
|
||||||
}
|
}
|
||||||
addObjectPropertyElement(element, key, attributes, propertyName, value[propertyName], separator.clone(), function (el) {
|
addObjectPropertyElement(
|
||||||
element.append(el);
|
element,
|
||||||
});
|
key,
|
||||||
|
attributes,
|
||||||
|
propertyName,
|
||||||
|
value[propertyName],
|
||||||
|
separator.clone(),
|
||||||
|
function (el) { element.append(el); }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,9 +96,19 @@ define('topicList', [
|
|||||||
|
|
||||||
function onNewTopic(data) {
|
function onNewTopic(data) {
|
||||||
if (
|
if (
|
||||||
(ajaxify.data.selectedCids && ajaxify.data.selectedCids.length && ajaxify.data.selectedCids.indexOf(parseInt(data.cid, 10)) === -1) ||
|
(
|
||||||
(ajaxify.data.selectedFilter && ajaxify.data.selectedFilter.filter === 'watched') ||
|
ajaxify.data.selectedCids &&
|
||||||
(ajaxify.data.template.category && parseInt(ajaxify.data.cid, 10) !== parseInt(data.cid, 10))
|
ajaxify.data.selectedCids.length &&
|
||||||
|
ajaxify.data.selectedCids.indexOf(parseInt(data.cid, 10)) === -1
|
||||||
|
) ||
|
||||||
|
(
|
||||||
|
ajaxify.data.selectedFilter &&
|
||||||
|
ajaxify.data.selectedFilter.filter === 'watched'
|
||||||
|
) ||
|
||||||
|
(
|
||||||
|
ajaxify.data.template.category &&
|
||||||
|
parseInt(ajaxify.data.cid, 10) !== parseInt(data.cid, 10)
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -113,11 +123,25 @@ define('topicList', [
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!post.topic.isFollowing && (
|
if (!post.topic.isFollowing && (
|
||||||
(parseInt(post.topic.mainPid, 10) === parseInt(post.pid, 10)) ||
|
parseInt(post.topic.mainPid, 10) === parseInt(post.pid, 10) ||
|
||||||
(ajaxify.data.selectedCids && ajaxify.data.selectedCids.length && ajaxify.data.selectedCids.indexOf(parseInt(post.topic.cid, 10)) === -1) ||
|
(
|
||||||
(ajaxify.data.selectedFilter && ajaxify.data.selectedFilter.filter === 'new') ||
|
ajaxify.data.selectedCids &&
|
||||||
(ajaxify.data.selectedFilter && ajaxify.data.selectedFilter.filter === 'watched' && !post.topic.isFollowing) ||
|
ajaxify.data.selectedCids.length &&
|
||||||
(ajaxify.data.template.category && parseInt(ajaxify.data.cid, 10) !== parseInt(post.topic.cid, 10))
|
ajaxify.data.selectedCids.indexOf(parseInt(post.topic.cid, 10)) === -1
|
||||||
|
) ||
|
||||||
|
(
|
||||||
|
ajaxify.data.selectedFilter &&
|
||||||
|
ajaxify.data.selectedFilter.filter === 'new'
|
||||||
|
) ||
|
||||||
|
(
|
||||||
|
ajaxify.data.selectedFilter &&
|
||||||
|
ajaxify.data.selectedFilter.filter === 'watched' &&
|
||||||
|
!post.topic.isFollowing
|
||||||
|
) ||
|
||||||
|
(
|
||||||
|
ajaxify.data.template.category &&
|
||||||
|
parseInt(ajaxify.data.cid, 10) !== parseInt(post.topic.cid, 10)
|
||||||
|
)
|
||||||
)) {
|
)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -308,7 +308,8 @@
|
|||||||
warn('[translator] Parameter `namespace` is ' + namespace + (namespace === '' ? '(empty string)' : ''));
|
warn('[translator] Parameter `namespace` is ' + namespace + (namespace === '' ? '(empty string)' : ''));
|
||||||
translation = Promise.resolve({});
|
translation = Promise.resolve({});
|
||||||
} else {
|
} else {
|
||||||
this.translations[namespace] = this.translations[namespace] || this.load(this.lang, namespace).catch(function () { return {}; });
|
this.translations[namespace] = this.translations[namespace] ||
|
||||||
|
this.load(this.lang, namespace).catch(function () { return {}; });
|
||||||
translation = this.translations[namespace];
|
translation = this.translations[namespace];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -646,7 +646,10 @@
|
|||||||
params.forEach(function (param) {
|
params.forEach(function (param) {
|
||||||
var val = param.split('=');
|
var val = param.split('=');
|
||||||
var key = decodeURI(val[0]);
|
var key = decodeURI(val[0]);
|
||||||
var value = options.disableToType || options.skipToType[key] ? decodeURI(val[1]) : utils.toType(decodeURI(val[1]));
|
var value = (
|
||||||
|
options.disableToType ||
|
||||||
|
options.skipToType[key] ? decodeURI(val[1]) : utils.toType(decodeURI(val[1]))
|
||||||
|
);
|
||||||
|
|
||||||
if (key) {
|
if (key) {
|
||||||
if (key.substr(-2, 2) === '[]') {
|
if (key.substr(-2, 2) === '[]') {
|
||||||
@@ -732,8 +735,11 @@
|
|||||||
isInternalURI: function (targetLocation, referenceLocation, relative_path) {
|
isInternalURI: function (targetLocation, referenceLocation, relative_path) {
|
||||||
return targetLocation.host === '' || // Relative paths are always internal links
|
return targetLocation.host === '' || // Relative paths are always internal links
|
||||||
(
|
(
|
||||||
targetLocation.host === referenceLocation.host && targetLocation.protocol === referenceLocation.protocol && // Otherwise need to check if protocol and host match
|
targetLocation.host === referenceLocation.host &&
|
||||||
(relative_path.length > 0 ? targetLocation.pathname.indexOf(relative_path) === 0 : true) // Subfolder installs need this additional check
|
// Otherwise need to check if protocol and host match
|
||||||
|
targetLocation.protocol === referenceLocation.protocol &&
|
||||||
|
// Subfolder installs need this additional check
|
||||||
|
(relative_path.length > 0 ? targetLocation.pathname.indexOf(relative_path) === 0 : true)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -181,12 +181,17 @@ Analytics.getDailyStatsForSet = async function (set, day, numDays) {
|
|||||||
|
|
||||||
const daysArr = [];
|
const daysArr = [];
|
||||||
day = new Date(day);
|
day = new Date(day);
|
||||||
day.setDate(day.getDate() + 1); // set the date to tomorrow, because getHourlyStatsForSet steps *backwards* 24 hours to sum up the values
|
// set the date to tomorrow, because getHourlyStatsForSet steps *backwards* 24 hours to sum up the values
|
||||||
|
day.setDate(day.getDate() + 1);
|
||||||
day.setHours(0, 0, 0, 0);
|
day.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
while (numDays > 0) {
|
while (numDays > 0) {
|
||||||
/* eslint-disable no-await-in-loop */
|
/* eslint-disable no-await-in-loop */
|
||||||
const dayData = await Analytics.getHourlyStatsForSet(set, day.getTime() - (1000 * 60 * 60 * 24 * (numDays - 1)), 24);
|
const dayData = await Analytics.getHourlyStatsForSet(
|
||||||
|
set,
|
||||||
|
day.getTime() - (1000 * 60 * 60 * 24 * (numDays - 1)),
|
||||||
|
24
|
||||||
|
);
|
||||||
daysArr.push(dayData.reduce((cur, next) => cur + next));
|
daysArr.push(dayData.reduce((cur, next) => cur + next));
|
||||||
numDays -= 1;
|
numDays -= 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,7 +118,9 @@ Categories.getModeratorUids = async function (cids) {
|
|||||||
const uniqGroups = _.uniq(_.flatten(sets.groupNames));
|
const uniqGroups = _.uniq(_.flatten(sets.groupNames));
|
||||||
const groupUids = await groups.getMembersOfGroups(uniqGroups);
|
const groupUids = await groups.getMembersOfGroups(uniqGroups);
|
||||||
const map = _.zipObject(uniqGroups, groupUids);
|
const map = _.zipObject(uniqGroups, groupUids);
|
||||||
const moderatorUids = cids.map((cid, index) => _.uniq(sets.uids[index].concat(_.flatten(sets.groupNames[index].map(g => map[g])))));
|
const moderatorUids = cids.map(
|
||||||
|
(cid, index) => _.uniq(sets.uids[index].concat(_.flatten(sets.groupNames[index].map(g => map[g]))))
|
||||||
|
);
|
||||||
return moderatorUids;
|
return moderatorUids;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,8 @@ function runSteps(tasks) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const message = 'NodeBB Upgrade Complete!';
|
const message = 'NodeBB Upgrade Complete!';
|
||||||
// some consoles will return undefined/zero columns, so just use 2 spaces in upgrade script if we can't get our column count
|
// some consoles will return undefined/zero columns,
|
||||||
|
// so just use 2 spaces in upgrade script if we can't get our column count
|
||||||
const { columns } = process.stdout;
|
const { columns } = process.stdout;
|
||||||
const spaces = columns ? new Array(Math.floor(columns / 2) - (message.length / 2) + 1).join(' ') : ' ';
|
const spaces = columns ? new Array(Math.floor(columns / 2) - (message.length / 2) + 1).join(' ') : ' ';
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,10 @@ helpers.getUserDataByUserSlug = async function (userslug, callerUID) {
|
|||||||
const { canViewInfo } = results;
|
const { canViewInfo } = results;
|
||||||
const isSelf = parseInt(callerUID, 10) === parseInt(userData.uid, 10);
|
const isSelf = parseInt(callerUID, 10) === parseInt(userData.uid, 10);
|
||||||
|
|
||||||
userData.age = Math.max(0, userData.birthday ? Math.floor((new Date().getTime() - new Date(userData.birthday).getTime()) / 31536000000) : 0);
|
userData.age = Math.max(
|
||||||
|
0,
|
||||||
|
userData.birthday ? Math.floor((new Date().getTime() - new Date(userData.birthday).getTime()) / 31536000000) : 0
|
||||||
|
);
|
||||||
|
|
||||||
userData.emailClass = 'hide';
|
userData.emailClass = 'hide';
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,10 @@ async function incrementProfileViews(req, userData) {
|
|||||||
if (req.uid >= 1) {
|
if (req.uid >= 1) {
|
||||||
req.session.uids_viewed = req.session.uids_viewed || {};
|
req.session.uids_viewed = req.session.uids_viewed || {};
|
||||||
|
|
||||||
if (req.uid !== userData.uid && (!req.session.uids_viewed[userData.uid] || req.session.uids_viewed[userData.uid] < Date.now() - 3600000)) {
|
if (
|
||||||
|
req.uid !== userData.uid &&
|
||||||
|
(!req.session.uids_viewed[userData.uid] || req.session.uids_viewed[userData.uid] < Date.now() - 3600000)
|
||||||
|
) {
|
||||||
await user.incrementUserFieldBy(userData.uid, 'profileviews', 1);
|
await user.incrementUserFieldBy(userData.uid, 'profileviews', 1);
|
||||||
req.session.uids_viewed[userData.uid] = Date.now();
|
req.session.uids_viewed[userData.uid] = Date.now();
|
||||||
}
|
}
|
||||||
@@ -102,7 +105,9 @@ async function getPosts(callerUid, userData, setSuffix) {
|
|||||||
}
|
}
|
||||||
if (pids.length) {
|
if (pids.length) {
|
||||||
const p = await posts.getPostSummaryByPids(pids, callerUid, { stripTags: false });
|
const p = await posts.getPostSummaryByPids(pids, callerUid, { stripTags: false });
|
||||||
postData.push(...p.filter(p => p && p.topic && (isAdmin || cidToIsMod[p.topic.cid] || (!p.deleted && !p.topic.deleted))));
|
postData.push(...p.filter(
|
||||||
|
p => p && p.topic && (isAdmin || cidToIsMod[p.topic.cid] || (!p.deleted && !p.topic.deleted))
|
||||||
|
));
|
||||||
}
|
}
|
||||||
start += count;
|
start += count;
|
||||||
} while (postData.length < count && hasMorePosts);
|
} while (postData.length < count && hasMorePosts);
|
||||||
|
|||||||
@@ -99,7 +99,9 @@ settingsController.get = async function (req, res, next) {
|
|||||||
'disabled',
|
'disabled',
|
||||||
];
|
];
|
||||||
|
|
||||||
userData.upvoteNotifFreq = notifFreqOptions.map(name => ({ name: name, selected: name === userData.settings.upvoteNotifFreq }));
|
userData.upvoteNotifFreq = notifFreqOptions.map(
|
||||||
|
name => ({ name: name, selected: name === userData.settings.upvoteNotifFreq })
|
||||||
|
);
|
||||||
|
|
||||||
userData.categoryWatchState = { [userData.settings.categoryWatchState]: true };
|
userData.categoryWatchState = { [userData.settings.categoryWatchState]: true };
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ pluginsController.get = async function (req, res) {
|
|||||||
memo[cur.label] = cur.value;
|
memo[cur.label] = cur.value;
|
||||||
return memo;
|
return memo;
|
||||||
}, {});
|
}, {});
|
||||||
const trendingPlugins = all.filter(plugin => plugin && Object.keys(trendingScores).includes(plugin.id)).sort((a, b) => trendingScores[b.id] - trendingScores[a.id]).map((plugin) => {
|
const trendingPlugins = all
|
||||||
|
.filter(plugin => plugin && Object.keys(trendingScores).includes(plugin.id))
|
||||||
|
.sort((a, b) => trendingScores[b.id] - trendingScores[a.id])
|
||||||
|
.map((plugin) => {
|
||||||
plugin.downloads = trendingScores[plugin.id];
|
plugin.downloads = trendingScores[plugin.id];
|
||||||
return plugin;
|
return plugin;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -95,7 +95,9 @@ apiController.loadConfig = async function (req) {
|
|||||||
config.usePagination = settings.usePagination;
|
config.usePagination = settings.usePagination;
|
||||||
config.topicsPerPage = settings.topicsPerPage;
|
config.topicsPerPage = settings.topicsPerPage;
|
||||||
config.postsPerPage = settings.postsPerPage;
|
config.postsPerPage = settings.postsPerPage;
|
||||||
config.userLang = validator.escape(String((req.query.lang ? req.query.lang : null) || settings.userLang || config.defaultLang));
|
config.userLang = validator.escape(
|
||||||
|
String((req.query.lang ? req.query.lang : null) || settings.userLang || config.defaultLang)
|
||||||
|
);
|
||||||
config.acpLang = validator.escape(String((req.query.lang ? req.query.lang : null) || settings.acpLang));
|
config.acpLang = validator.escape(String((req.query.lang ? req.query.lang : null) || settings.acpLang));
|
||||||
config.openOutgoingLinksInNewTab = settings.openOutgoingLinksInNewTab;
|
config.openOutgoingLinksInNewTab = settings.openOutgoingLinksInNewTab;
|
||||||
config.topicPostSort = settings.topicPostSort || config.topicPostSort;
|
config.topicPostSort = settings.topicPostSort || config.topicPostSort;
|
||||||
|
|||||||
@@ -83,7 +83,11 @@ authenticationController.register = async function (req, res) {
|
|||||||
throw new Error('[[error:invalid-email]]');
|
throw new Error('[[error:invalid-email]]');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!userData.username || userData.username.length < meta.config.minimumUsernameLength || slugify(userData.username).length < meta.config.minimumUsernameLength) {
|
if (
|
||||||
|
!userData.username ||
|
||||||
|
userData.username.length < meta.config.minimumUsernameLength ||
|
||||||
|
slugify(userData.username).length < meta.config.minimumUsernameLength
|
||||||
|
) {
|
||||||
throw new Error('[[error:username-too-short]]');
|
throw new Error('[[error:username-too-short]]');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -315,7 +315,12 @@ helpers.getVisibleCategories = async function (params) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const hasVisibleChildren = checkVisibleChildren(c, cidToAllowed, cidToWatchState, states);
|
const hasVisibleChildren = checkVisibleChildren(c, cidToAllowed, cidToWatchState, states);
|
||||||
const isCategoryVisible = cidToAllowed[c.cid] && (showLinks || !c.link) && !c.disabled && states.includes(cidToWatchState[c.cid]);
|
const isCategoryVisible = (
|
||||||
|
cidToAllowed[c.cid] &&
|
||||||
|
(showLinks || !c.link) &&
|
||||||
|
!c.disabled &&
|
||||||
|
states.includes(cidToWatchState[c.cid])
|
||||||
|
);
|
||||||
const shouldBeRemoved = !hasVisibleChildren && !isCategoryVisible;
|
const shouldBeRemoved = !hasVisibleChildren && !isCategoryVisible;
|
||||||
const shouldBeDisaplayedAsDisabled = hasVisibleChildren && !isCategoryVisible;
|
const shouldBeDisaplayedAsDisabled = hasVisibleChildren && !isCategoryVisible;
|
||||||
|
|
||||||
@@ -380,7 +385,8 @@ function checkVisibleChildren(c, cidToAllowed, cidToWatchState, states) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return c.children.some(c => !c.disabled && (
|
return c.children.some(c => !c.disabled && (
|
||||||
(cidToAllowed[c.cid] && states.includes(cidToWatchState[c.cid])) || checkVisibleChildren(c, cidToAllowed, cidToWatchState, states)
|
(cidToAllowed[c.cid] && states.includes(cidToWatchState[c.cid])) ||
|
||||||
|
checkVisibleChildren(c, cidToAllowed, cidToWatchState, states)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -202,7 +202,9 @@ Controllers.registerInterstitial = async function (req, res, next) {
|
|||||||
return helpers.redirect(res, returnTo || '/');
|
return helpers.redirect(res, returnTo || '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
const renders = data.interstitials.map(interstitial => req.app.renderAsync(interstitial.template, interstitial.data || {}));
|
const renders = data.interstitials.map(
|
||||||
|
interstitial => req.app.renderAsync(interstitial.template, interstitial.data || {})
|
||||||
|
);
|
||||||
const sections = await Promise.all(renders);
|
const sections = await Promise.all(renders);
|
||||||
|
|
||||||
res.render('registerComplete', {
|
res.render('registerComplete', {
|
||||||
|
|||||||
@@ -131,7 +131,10 @@ modsController.flags.detail = async function (req, res, next) {
|
|||||||
assignees: results.assignees,
|
assignees: results.assignees,
|
||||||
type_bool: ['post', 'user', 'empty'].reduce((memo, cur) => {
|
type_bool: ['post', 'user', 'empty'].reduce((memo, cur) => {
|
||||||
if (cur !== 'empty') {
|
if (cur !== 'empty') {
|
||||||
memo[cur] = results.flagData.type === cur && (!results.flagData.target || !!Object.keys(results.flagData.target).length);
|
memo[cur] = results.flagData.type === cur && (
|
||||||
|
!results.flagData.target ||
|
||||||
|
!!Object.keys(results.flagData.target).length
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
memo[cur] = !Object.keys(results.flagData.target).length;
|
memo[cur] = !Object.keys(results.flagData.target).length;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ const upload_url = nconf.get('upload_url');
|
|||||||
topicsController.get = async function getTopic(req, res, callback) {
|
topicsController.get = async function getTopic(req, res, callback) {
|
||||||
const tid = req.params.topic_id;
|
const tid = req.params.topic_id;
|
||||||
|
|
||||||
if ((req.params.post_index && !utils.isNumber(req.params.post_index) && req.params.post_index !== 'unread') || !utils.isNumber(tid)) {
|
if (
|
||||||
|
(req.params.post_index && !utils.isNumber(req.params.post_index) && req.params.post_index !== 'unread') ||
|
||||||
|
!utils.isNumber(tid)
|
||||||
|
) {
|
||||||
return callback();
|
return callback();
|
||||||
}
|
}
|
||||||
let postIndex = parseInt(req.params.post_index, 10) || 1;
|
let postIndex = parseInt(req.params.post_index, 10) || 1;
|
||||||
@@ -40,7 +43,11 @@ topicsController.get = async function getTopic(req, res, callback) {
|
|||||||
|
|
||||||
let currentPage = parseInt(req.query.page, 10) || 1;
|
let currentPage = parseInt(req.query.page, 10) || 1;
|
||||||
const pageCount = Math.max(1, Math.ceil((topicData && topicData.postcount) / settings.postsPerPage));
|
const pageCount = Math.max(1, Math.ceil((topicData && topicData.postcount) / settings.postsPerPage));
|
||||||
if (!topicData || userPrivileges.disabled || (settings.usePagination && (currentPage < 1 || currentPage > pageCount))) {
|
if (
|
||||||
|
!topicData ||
|
||||||
|
userPrivileges.disabled ||
|
||||||
|
(settings.usePagination && (currentPage < 1 || currentPage > pageCount))
|
||||||
|
) {
|
||||||
return callback();
|
return callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,10 @@ async function uploadAsFile(req, uploadedFile) {
|
|||||||
|
|
||||||
async function resizeImage(fileObj) {
|
async function resizeImage(fileObj) {
|
||||||
const imageData = await image.size(fileObj.path);
|
const imageData = await image.size(fileObj.path);
|
||||||
if (imageData.width < meta.config.resizeImageWidthThreshold || meta.config.resizeImageWidth > meta.config.resizeImageWidthThreshold) {
|
if (
|
||||||
|
imageData.width < meta.config.resizeImageWidthThreshold ||
|
||||||
|
meta.config.resizeImageWidth > meta.config.resizeImageWidthThreshold
|
||||||
|
) {
|
||||||
return fileObj;
|
return fileObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -168,7 +168,8 @@ Topics.deleteThumb = async (req, res) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
async function checkThumbPrivileges({ tid, uid, res }) {
|
async function checkThumbPrivileges({ tid, uid, res }) {
|
||||||
// req.params.tid could be either a tid (pushing a new thumb to an existing topic) or a post UUID (a new topic being composed)
|
// req.params.tid could be either a tid (pushing a new thumb to an existing topic)
|
||||||
|
// or a post UUID (a new topic being composed)
|
||||||
const isUUID = validator.isUUID(tid);
|
const isUUID = validator.isUUID(tid);
|
||||||
|
|
||||||
// Sanity-check the tid if it's strictly not a uuid
|
// Sanity-check the tid if it's strictly not a uuid
|
||||||
|
|||||||
@@ -95,7 +95,9 @@ module.exports = function (module) {
|
|||||||
const batch = require('../../batch');
|
const batch = require('../../batch');
|
||||||
const batchSize = Math.ceil(key.length / Math.ceil(key.length / 100));
|
const batchSize = Math.ceil(key.length / Math.ceil(key.length / 100));
|
||||||
await batch.processArray(key, async currentBatch => batches.push(currentBatch), { batch: batchSize });
|
await batch.processArray(key, async currentBatch => batches.push(currentBatch), { batch: batchSize });
|
||||||
const batchData = await Promise.all(batches.map(batch => doQuery({ $in: batch }, { _id: 0, _key: 0 }, 0, stop + 1)));
|
const batchData = await Promise.all(batches.map(
|
||||||
|
batch => doQuery({ $in: batch }, { _id: 0, _key: 0 }, 0, stop + 1)
|
||||||
|
));
|
||||||
result = dbHelpers.mergeBatch(batchData, 0, stop, sort);
|
result = dbHelpers.mergeBatch(batchData, 0, stop, sort);
|
||||||
if (start > 0) {
|
if (start > 0) {
|
||||||
result = result.slice(start, stop !== -1 ? stop + 1 : undefined);
|
result = result.slice(start, stop !== -1 ? stop + 1 : undefined);
|
||||||
|
|||||||
@@ -65,7 +65,10 @@ module.exports = function (module) {
|
|||||||
|
|
||||||
const bulk = module.client.collection('objects').initializeUnorderedBulkOp();
|
const bulk = module.client.collection('objects').initializeUnorderedBulkOp();
|
||||||
for (let i = 0; i < keys.length; i += 1) {
|
for (let i = 0; i < keys.length; i += 1) {
|
||||||
bulk.find({ _key: keys[i], value: value }).upsert().updateOne({ $set: { score: parseFloat(isArrayOfScores ? scores[i] : scores) } });
|
bulk
|
||||||
|
.find({ _key: keys[i], value: value })
|
||||||
|
.upsert()
|
||||||
|
.updateOne({ $set: { score: parseFloat(isArrayOfScores ? scores[i] : scores) } });
|
||||||
}
|
}
|
||||||
await bulk.execute();
|
await bulk.execute();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,9 +16,10 @@ module.exports = function (Groups) {
|
|||||||
|
|
||||||
// Only process those groups that have the cid in its memberPostCids setting (or no setting at all)
|
// Only process those groups that have the cid in its memberPostCids setting (or no setting at all)
|
||||||
const groupData = await groups.getGroupsFields(groupNames, ['memberPostCids']);
|
const groupData = await groups.getGroupsFields(groupNames, ['memberPostCids']);
|
||||||
groupNames = groupNames.filter(
|
groupNames = groupNames.filter((groupName, idx) => (
|
||||||
(groupName, idx) => !groupData[idx].memberPostCidsArray.length || groupData[idx].memberPostCidsArray.includes(postData.cid)
|
!groupData[idx].memberPostCidsArray.length ||
|
||||||
);
|
groupData[idx].memberPostCidsArray.includes(postData.cid)
|
||||||
|
));
|
||||||
|
|
||||||
const keys = groupNames.map(groupName => `group:${groupName}:member:pids`);
|
const keys = groupNames.map(groupName => `group:${groupName}:member:pids`);
|
||||||
await db.sortedSetsAdd(keys, postData.timestamp, postData.pid);
|
await db.sortedSetsAdd(keys, postData.timestamp, postData.pid);
|
||||||
|
|||||||
@@ -129,7 +129,13 @@ async function setupConfig() {
|
|||||||
const redisQuestions = require('./database/redis').questions;
|
const redisQuestions = require('./database/redis').questions;
|
||||||
const mongoQuestions = require('./database/mongo').questions;
|
const mongoQuestions = require('./database/mongo').questions;
|
||||||
const postgresQuestions = require('./database/postgres').questions;
|
const postgresQuestions = require('./database/postgres').questions;
|
||||||
const allQuestions = questions.main.concat(questions.optional).concat(redisQuestions).concat(mongoQuestions).concat(postgresQuestions);
|
const allQuestions = [
|
||||||
|
...questions.main,
|
||||||
|
...questions.optional,
|
||||||
|
...redisQuestions,
|
||||||
|
...mongoQuestions,
|
||||||
|
...postgresQuestions,
|
||||||
|
];
|
||||||
|
|
||||||
allQuestions.forEach((question) => {
|
allQuestions.forEach((question) => {
|
||||||
if (install.values.hasOwnProperty(question.name)) {
|
if (install.values.hasOwnProperty(question.name)) {
|
||||||
@@ -307,7 +313,8 @@ async function createAdmin() {
|
|||||||
const results = await promptGet(questions);
|
const results = await promptGet(questions);
|
||||||
return await success(results);
|
return await success(results);
|
||||||
}
|
}
|
||||||
// If automated setup did not provide a user password, generate one, it will be shown to the user upon setup completion
|
// If automated setup did not provide a user password, generate one,
|
||||||
|
// it will be shown to the user upon setup completion
|
||||||
if (!install.values.hasOwnProperty('admin:password') && !nconf.get('admin:password')) {
|
if (!install.values.hasOwnProperty('admin:password') && !nconf.get('admin:password')) {
|
||||||
console.log('Password was not provided during automated setup, generating one...');
|
console.log('Password was not provided during automated setup, generating one...');
|
||||||
password = utils.generateUUID().slice(0, 8);
|
password = utils.generateUUID().slice(0, 8);
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ module.exports = function (Messaging) {
|
|||||||
const keys = mids.map(mid => `message:${mid}`);
|
const keys = mids.map(mid => `message:${mid}`);
|
||||||
const messages = await (fields.length ? db.getObjectsFields(keys, fields) : db.getObjects(keys));
|
const messages = await (fields.length ? db.getObjectsFields(keys, fields) : db.getObjects(keys));
|
||||||
|
|
||||||
return await Promise.all(messages.map(async (message, idx) => modifyMessage(message, fields, parseInt(mids[idx], 10))));
|
return await Promise.all(messages.map(
|
||||||
|
async (message, idx) => modifyMessage(message, fields, parseInt(mids[idx], 10))
|
||||||
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
Messaging.getMessageField = async (mid, field) => {
|
Messaging.getMessageField = async (mid, field) => {
|
||||||
|
|||||||
@@ -41,7 +41,10 @@ module.exports = function (middleware) {
|
|||||||
|
|
||||||
middleware.exposePrivilegeSet = async (req, res, next) => {
|
middleware.exposePrivilegeSet = async (req, res, next) => {
|
||||||
// Exposes a user's global/admin privilege set
|
// Exposes a user's global/admin privilege set
|
||||||
res.locals.privileges = { ...await privileges.global.get(req.user.uid), ...await privileges.admin.get(req.user.uid) };
|
res.locals.privileges = {
|
||||||
|
...await privileges.global.get(req.user.uid),
|
||||||
|
...await privileges.admin.get(req.user.uid),
|
||||||
|
};
|
||||||
return next();
|
return next();
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -118,7 +118,11 @@ Notifications.create = async function (data) {
|
|||||||
}
|
}
|
||||||
data.importance = data.importance || 5;
|
data.importance = data.importance || 5;
|
||||||
const oldNotif = await db.getObject(`notifications:${data.nid}`);
|
const oldNotif = await db.getObject(`notifications:${data.nid}`);
|
||||||
if (oldNotif && parseInt(oldNotif.pid, 10) === parseInt(data.pid, 10) && parseInt(oldNotif.importance, 10) > parseInt(data.importance, 10)) {
|
if (
|
||||||
|
oldNotif &&
|
||||||
|
parseInt(oldNotif.pid, 10) === parseInt(data.pid, 10) &&
|
||||||
|
parseInt(oldNotif.importance, 10) > parseInt(data.importance, 10)
|
||||||
|
) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
|
|||||||
@@ -94,7 +94,9 @@ module.exports = function (Posts) {
|
|||||||
absolute = `//${current[1]}`;
|
absolute = `//${current[1]}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
content = content.slice(0, current.index + regex.length) + absolute + content.slice(current.index + regex.length + current[1].length);
|
content = content.slice(0, current.index + regex.length) +
|
||||||
|
absolute +
|
||||||
|
content.slice(current.index + regex.length + current[1].length);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
winston.verbose(err.messsage);
|
winston.verbose(err.messsage);
|
||||||
@@ -117,7 +119,10 @@ module.exports = function (Posts) {
|
|||||||
Posts.configureSanitize = async () => {
|
Posts.configureSanitize = async () => {
|
||||||
// Each allowed tags should have some common global attributes...
|
// Each allowed tags should have some common global attributes...
|
||||||
sanitizeConfig.allowedTags.forEach((tag) => {
|
sanitizeConfig.allowedTags.forEach((tag) => {
|
||||||
sanitizeConfig.allowedAttributes[tag] = _.union(sanitizeConfig.allowedAttributes[tag], sanitizeConfig.globalAttributes);
|
sanitizeConfig.allowedAttributes[tag] = _.union(
|
||||||
|
sanitizeConfig.allowedAttributes[tag],
|
||||||
|
sanitizeConfig.globalAttributes
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Some plugins might need to adjust or whitelist their own tags...
|
// Some plugins might need to adjust or whitelist their own tags...
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ module.exports = function (Posts) {
|
|||||||
const cidToCategory = toObject('cid', topicsAndCategories.categories);
|
const cidToCategory = toObject('cid', topicsAndCategories.categories);
|
||||||
|
|
||||||
posts.forEach((post) => {
|
posts.forEach((post) => {
|
||||||
// If the post author isn't represented in the retrieved users' data, then it means they were deleted, assume guest.
|
// If the post author isn't represented in the retrieved users' data,
|
||||||
|
// then it means they were deleted, assume guest.
|
||||||
if (!uidToUser.hasOwnProperty(post.uid)) {
|
if (!uidToUser.hasOwnProperty(post.uid)) {
|
||||||
post.uid = 0;
|
post.uid = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,8 +94,11 @@ module.exports = function (privileges) {
|
|||||||
const cidsSet = new Set(allowedCids);
|
const cidsSet = new Set(allowedCids);
|
||||||
const canViewDeleted = _.zipObject(cids, results.view_deleted);
|
const canViewDeleted = _.zipObject(cids, results.view_deleted);
|
||||||
|
|
||||||
pids = postData.filter(post => post.topic && cidsSet.has(post.topic.cid) &&
|
pids = postData.filter(post => (
|
||||||
((!post.topic.deleted && !post.deleted) || canViewDeleted[post.topic.cid] || results.isAdmin)).map(post => post.pid);
|
post.topic &&
|
||||||
|
cidsSet.has(post.topic.cid) &&
|
||||||
|
((!post.topic.deleted && !post.deleted) || canViewDeleted[post.topic.cid] || results.isAdmin)
|
||||||
|
)).map(post => post.pid);
|
||||||
|
|
||||||
const data = await plugins.hooks.fire('filter:privileges.posts.filter', {
|
const data = await plugins.hooks.fire('filter:privileges.posts.filter', {
|
||||||
privilege: privilege,
|
privilege: privilege,
|
||||||
@@ -121,10 +124,19 @@ module.exports = function (privileges) {
|
|||||||
return { flag: true };
|
return { flag: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!results.isMod && meta.config.postEditDuration && (Date.now() - results.postData.timestamp > meta.config.postEditDuration * 1000)) {
|
if (
|
||||||
|
!results.isMod &&
|
||||||
|
meta.config.postEditDuration &&
|
||||||
|
(Date.now() - results.postData.timestamp > meta.config.postEditDuration * 1000)
|
||||||
|
) {
|
||||||
return { flag: false, message: `[[error:post-edit-duration-expired, ${meta.config.postEditDuration}]]` };
|
return { flag: false, message: `[[error:post-edit-duration-expired, ${meta.config.postEditDuration}]]` };
|
||||||
}
|
}
|
||||||
if (!results.isMod && meta.config.newbiePostEditDuration > 0 && meta.config.newbiePostDelayThreshold > results.userData.reputation && Date.now() - results.postData.timestamp > meta.config.newbiePostEditDuration * 1000) {
|
if (
|
||||||
|
!results.isMod &&
|
||||||
|
meta.config.newbiePostEditDuration > 0 &&
|
||||||
|
meta.config.newbiePostDelayThreshold > results.userData.reputation &&
|
||||||
|
Date.now() - results.postData.timestamp > meta.config.newbiePostEditDuration * 1000
|
||||||
|
) {
|
||||||
return { flag: false, message: `[[error:post-edit-duration-expired, ${meta.config.newbiePostEditDuration}]]` };
|
return { flag: false, message: `[[error:post-edit-duration-expired, ${meta.config.newbiePostEditDuration}]]` };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,12 +71,18 @@ module.exports = function (privileges) {
|
|||||||
const cids = _.uniq(topicsData.map(topic => topic.cid));
|
const cids = _.uniq(topicsData.map(topic => topic.cid));
|
||||||
const results = await privileges.categories.getBase(privilege, cids, uid);
|
const results = await privileges.categories.getBase(privilege, cids, uid);
|
||||||
|
|
||||||
const allowedCids = cids.filter((cid, index) => !results.categories[index].disabled && (results.allowedTo[index] || results.isAdmin));
|
const allowedCids = cids.filter((cid, index) => (
|
||||||
|
!results.categories[index].disabled &&
|
||||||
|
(results.allowedTo[index] || results.isAdmin)
|
||||||
|
));
|
||||||
|
|
||||||
const cidsSet = new Set(allowedCids);
|
const cidsSet = new Set(allowedCids);
|
||||||
const canViewDeleted = _.zipObject(cids, results.view_deleted);
|
const canViewDeleted = _.zipObject(cids, results.view_deleted);
|
||||||
|
|
||||||
tids = topicsData.filter(t => cidsSet.has(t.cid) && (!t.deleted || canViewDeleted[t.cid] || results.isAdmin)).map(t => t.tid);
|
tids = topicsData.filter(t => (
|
||||||
|
cidsSet.has(t.cid) &&
|
||||||
|
(!t.deleted || canViewDeleted[t.cid] || results.isAdmin)
|
||||||
|
)).map(t => t.tid);
|
||||||
|
|
||||||
const data = await plugins.hooks.fire('filter:privileges.topics.filter', {
|
const data = await plugins.hooks.fire('filter:privileges.topics.filter', {
|
||||||
privilege: privilege,
|
privilege: privilege,
|
||||||
|
|||||||
@@ -97,7 +97,9 @@ async function generateForTopic(req, res) {
|
|||||||
const replies = topicData.posts.slice(1);
|
const replies = topicData.posts.slice(1);
|
||||||
replies.forEach((postData) => {
|
replies.forEach((postData) => {
|
||||||
if (!postData.deleted) {
|
if (!postData.deleted) {
|
||||||
const dateStamp = new Date(parseInt(parseInt(postData.edited, 10) === 0 ? postData.timestamp : postData.edited, 10)).toUTCString();
|
const dateStamp = new Date(
|
||||||
|
parseInt(parseInt(postData.edited, 10) === 0 ? postData.timestamp : postData.edited, 10)
|
||||||
|
).toUTCString();
|
||||||
|
|
||||||
feed.item({
|
feed.item({
|
||||||
title: `Reply to ${utils.stripHTMLTags(topicData.title, utils.tags)} on ${dateStamp}`,
|
title: `Reply to ${utils.stripHTMLTags(topicData.title, utils.tags)} on ${dateStamp}`,
|
||||||
|
|||||||
@@ -11,7 +11,14 @@ helpers.setupPageRoute = function (router, name, middleware, middlewares, contro
|
|||||||
middleware.pluginHooks,
|
middleware.pluginHooks,
|
||||||
].concat(middlewares);
|
].concat(middlewares);
|
||||||
|
|
||||||
router.get(name, middleware.busyCheck, middleware.applyCSRF, middleware.buildHeader, middlewares, helpers.tryRoute(controller));
|
router.get(
|
||||||
|
name,
|
||||||
|
middleware.busyCheck,
|
||||||
|
middleware.applyCSRF,
|
||||||
|
middleware.buildHeader,
|
||||||
|
middlewares,
|
||||||
|
helpers.tryRoute(controller)
|
||||||
|
);
|
||||||
router.get(`/api${name}`, middlewares, helpers.tryRoute(controller));
|
router.get(`/api${name}`, middlewares, helpers.tryRoute(controller));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,16 @@ const { setupApiRoute } = routeHelpers;
|
|||||||
module.exports = function () {
|
module.exports = function () {
|
||||||
const middlewares = [middleware.authenticate];
|
const middlewares = [middleware.authenticate];
|
||||||
|
|
||||||
// setupApiRoute(router, 'put', '/', [...middlewares, middleware.checkRequired.bind(null, ['path']), middleware.assert.folder], controllers.write.files.upload);
|
// setupApiRoute(router, 'put', '/', [
|
||||||
setupApiRoute(router, 'delete', '/', [...middlewares, middleware.checkRequired.bind(null, ['path']), middleware.assert.path], controllers.write.files.delete);
|
// ...middlewares,
|
||||||
|
// middleware.checkRequired.bind(null, ['path']),
|
||||||
|
// middleware.assert.folder
|
||||||
|
// ], controllers.write.files.upload);
|
||||||
|
setupApiRoute(router, 'delete', '/', [
|
||||||
|
...middlewares,
|
||||||
|
middleware.checkRequired.bind(null, ['path']),
|
||||||
|
middleware.assert.path,
|
||||||
|
], controllers.write.files.delete);
|
||||||
|
|
||||||
return router;
|
return router;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -42,7 +42,9 @@ SocketAdmin.before = async function (socket, method) {
|
|||||||
|
|
||||||
// Check admin privileges mapping (if not in mapping, deny access)
|
// Check admin privileges mapping (if not in mapping, deny access)
|
||||||
const privilegeSet = privileges.admin.socketMap.hasOwnProperty(method) ? privileges.admin.socketMap[method].split(';') : [];
|
const privilegeSet = privileges.admin.socketMap.hasOwnProperty(method) ? privileges.admin.socketMap[method].split(';') : [];
|
||||||
const hasPrivilege = (await Promise.all(privilegeSet.map(async privilege => privileges.admin.can(privilege, socket.uid)))).some(Boolean);
|
const hasPrivilege = (await Promise.all(privilegeSet.map(
|
||||||
|
async privilege => privileges.admin.can(privilege, socket.uid)
|
||||||
|
))).some(Boolean);
|
||||||
if (privilegeSet.length && hasPrivilege) {
|
if (privilegeSet.length && hasPrivilege) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ Analytics.get = function (socket, data, callback) {
|
|||||||
},
|
},
|
||||||
}, (err, data) => {
|
}, (err, data) => {
|
||||||
data.pastDay = data.pageviews.reduce((a, b) => parseInt(a, 10) + parseInt(b, 10));
|
data.pastDay = data.pageviews.reduce((a, b) => parseInt(a, 10) + parseInt(b, 10));
|
||||||
data.pageviews[data.pageviews.length - 1] = parseInt(data.pageviews[data.pageviews.length - 1], 10) + analytics.getUnwrittenPageviews();
|
const last = data.pageviews.length - 1;
|
||||||
|
data.pageviews[last] = parseInt(data.pageviews[last], 10) + analytics.getUnwrittenPageviews();
|
||||||
callback(err, data);
|
callback(err, data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,7 +185,9 @@ async function checkMaintenance(socket) {
|
|||||||
throw new Error(`[[pages:maintenance.text, ${validator.escape(String(meta.config.title || 'NodeBB'))}]]`);
|
throw new Error(`[[pages:maintenance.text, ${validator.escape(String(meta.config.title || 'NodeBB'))}]]`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getSessionAsync = util.promisify((sid, callback) => db.sessionStore.get(sid, (err, sessionObj) => callback(err, sessionObj || null)));
|
const getSessionAsync = util.promisify(
|
||||||
|
(sid, callback) => db.sessionStore.get(sid, (err, sessionObj) => callback(err, sessionObj || null))
|
||||||
|
);
|
||||||
|
|
||||||
async function validateSession(socket) {
|
async function validateSession(socket) {
|
||||||
const req = socket.request;
|
const req = socket.request;
|
||||||
|
|||||||
@@ -26,7 +26,10 @@ module.exports = function (SocketTopics) {
|
|||||||
const reverse = data.topicPostSort === 'newest_to_oldest' || data.topicPostSort === 'most_votes';
|
const reverse = data.topicPostSort === 'newest_to_oldest' || data.topicPostSort === 'most_votes';
|
||||||
let start = Math.max(0, parseInt(data.after, 10));
|
let start = Math.max(0, parseInt(data.after, 10));
|
||||||
|
|
||||||
const infScrollPostsPerPage = Math.max(0, Math.min(meta.config.postsPerPage || 20, parseInt(data.count, 10) || meta.config.postsPerPage || 20));
|
const infScrollPostsPerPage = Math.max(0, Math.min(
|
||||||
|
meta.config.postsPerPage || 20,
|
||||||
|
parseInt(data.count, 10) || meta.config.postsPerPage || 20
|
||||||
|
));
|
||||||
|
|
||||||
if (data.direction === -1) {
|
if (data.direction === -1) {
|
||||||
start -= (infScrollPostsPerPage + 1);
|
start -= (infScrollPostsPerPage + 1);
|
||||||
@@ -96,7 +99,10 @@ module.exports = function (SocketTopics) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function calculateStartStop(data) {
|
function calculateStartStop(data) {
|
||||||
const itemsPerPage = Math.min(meta.config.topicsPerPage || 20, parseInt(data.count, 10) || meta.config.topicsPerPage || 20);
|
const itemsPerPage = Math.min(
|
||||||
|
meta.config.topicsPerPage || 20,
|
||||||
|
parseInt(data.count, 10) || meta.config.topicsPerPage || 20
|
||||||
|
);
|
||||||
let start = Math.max(0, parseInt(data.after, 10));
|
let start = Math.max(0, parseInt(data.after, 10));
|
||||||
if (data.direction === -1) {
|
if (data.direction === -1) {
|
||||||
start -= itemsPerPage;
|
start -= itemsPerPage;
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ const Events = module.exports;
|
|||||||
* You are able to define additional topic event types here.
|
* You are able to define additional topic event types here.
|
||||||
* Register to hook `filter:topicEvents.init` and append your custom type to the `types` object.
|
* Register to hook `filter:topicEvents.init` and append your custom type to the `types` object.
|
||||||
* You can then log a custom topic event by calling `topics.events.log(tid, { type, uid });`
|
* You can then log a custom topic event by calling `topics.events.log(tid, { type, uid });`
|
||||||
* `uid` is optional; if you pass in a valid uid in the payload, the user avatar/username will be rendered as part of the event text
|
* `uid` is optional; if you pass in a valid uid in the payload,
|
||||||
|
* the user avatar/username will be rendered as part of the event text
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
Events._types = {
|
Events._types = {
|
||||||
|
|||||||
@@ -151,7 +151,12 @@ module.exports = function (Topics) {
|
|||||||
topicData = filtered;
|
topicData = filtered;
|
||||||
|
|
||||||
const cids = params.cids && params.cids.map(String);
|
const cids = params.cids && params.cids.map(String);
|
||||||
tids = topicData.filter(t => t && t.cid && !isCidIgnored[t.cid] && (!cids || cids.includes(String(t.cid)))).map(t => t.tid);
|
tids = topicData.filter(t => (
|
||||||
|
t &&
|
||||||
|
t.cid &&
|
||||||
|
!isCidIgnored[t.cid] &&
|
||||||
|
(!cids || cids.includes(String(t.cid)))
|
||||||
|
)).map(t => t.tid);
|
||||||
|
|
||||||
const result = await plugins.hooks.fire('filter:topics.filterSortedTids', { tids: tids, params: params });
|
const result = await plugins.hooks.fire('filter:topics.filterSortedTids', { tids: tids, params: params });
|
||||||
return result.tids;
|
return result.tids;
|
||||||
|
|||||||
@@ -56,7 +56,8 @@ module.exports = function (Topics) {
|
|||||||
users[user.uid] = user;
|
users[user.uid] = user;
|
||||||
});
|
});
|
||||||
postData.forEach((post) => {
|
postData.forEach((post) => {
|
||||||
// If the post author isn't represented in the retrieved users' data, then it means they were deleted, assume guest.
|
// If the post author isn't represented in the retrieved users' data,
|
||||||
|
// then it means they were deleted, assume guest.
|
||||||
if (!users.hasOwnProperty(post.uid)) {
|
if (!users.hasOwnProperty(post.uid)) {
|
||||||
post.uid = 0;
|
post.uid = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,12 @@ module.exports = {
|
|||||||
|
|
||||||
// has no history, but is banned, create plain object with just uid and timestmap
|
// has no history, but is banned, create plain object with just uid and timestmap
|
||||||
if (!results.bans.length && parseInt(results.userData.banned, 10)) {
|
if (!results.bans.length && parseInt(results.userData.banned, 10)) {
|
||||||
const banTimestamp = results.userData.lastonline || results.userData.lastposttime || results.userData.joindate || Date.now();
|
const banTimestamp = (
|
||||||
|
results.userData.lastonline ||
|
||||||
|
results.userData.lastposttime ||
|
||||||
|
results.userData.joindate ||
|
||||||
|
Date.now()
|
||||||
|
);
|
||||||
const banKey = `uid:${uid}:ban:${banTimestamp}`;
|
const banKey = `uid:${uid}:ban:${banTimestamp}`;
|
||||||
addBan(banKey, { uid: uid, timestamp: banTimestamp }, next);
|
addBan(banKey, { uid: uid, timestamp: banTimestamp }, next);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -62,8 +62,12 @@ module.exports = function (User) {
|
|||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getSessionFromStore = util.promisify((sid, callback) => db.sessionStore.get(sid, (err, sessObj) => callback(err, sessObj || null)));
|
const getSessionFromStore = util.promisify(
|
||||||
const sessionStoreDestroy = util.promisify((sid, callback) => db.sessionStore.destroy(sid, err => callback(err)));
|
(sid, callback) => db.sessionStore.get(sid, (err, sessObj) => callback(err, sessObj || null))
|
||||||
|
);
|
||||||
|
const sessionStoreDestroy = util.promisify(
|
||||||
|
(sid, callback) => db.sessionStore.destroy(sid, err => callback(err))
|
||||||
|
);
|
||||||
|
|
||||||
User.auth.getSessions = async function (uid, curSessionId) {
|
User.auth.getSessions = async function (uid, curSessionId) {
|
||||||
await cleanExpiredSessions(uid);
|
await cleanExpiredSessions(uid);
|
||||||
|
|||||||
@@ -33,7 +33,19 @@ process.on('message', async (msg) => {
|
|||||||
const profilePath = path.join(__dirname, '../../../build/export', profileFile);
|
const profilePath = path.join(__dirname, '../../../build/export', profileFile);
|
||||||
|
|
||||||
const user = require('../index');
|
const user = require('../index');
|
||||||
const [userData, userSettings, ips, sessions, usernames, emails, bookmarks, watchedTopics, upvoted, downvoted, following] = await Promise.all([
|
const [
|
||||||
|
userData,
|
||||||
|
userSettings,
|
||||||
|
ips,
|
||||||
|
sessions,
|
||||||
|
usernames,
|
||||||
|
emails,
|
||||||
|
bookmarks,
|
||||||
|
watchedTopics,
|
||||||
|
upvoted,
|
||||||
|
downvoted,
|
||||||
|
following,
|
||||||
|
] = await Promise.all([
|
||||||
db.getObject(`user:${targetUid}`),
|
db.getObject(`user:${targetUid}`),
|
||||||
db.getObject(`user:${targetUid}:settings`),
|
db.getObject(`user:${targetUid}:settings`),
|
||||||
user.getIPs(targetUid, 9),
|
user.getIPs(targetUid, 9),
|
||||||
|
|||||||
@@ -41,7 +41,11 @@ module.exports = function (User) {
|
|||||||
|
|
||||||
const lasttime = userData[field] || 0;
|
const lasttime = userData[field] || 0;
|
||||||
|
|
||||||
if (meta.config.newbiePostDelay > 0 && meta.config.newbiePostDelayThreshold > userData.reputation && now - lasttime < meta.config.newbiePostDelay * 1000) {
|
if (
|
||||||
|
meta.config.newbiePostDelay > 0 &&
|
||||||
|
meta.config.newbiePostDelayThreshold > userData.reputation &&
|
||||||
|
now - lasttime < meta.config.newbiePostDelay * 1000
|
||||||
|
) {
|
||||||
throw new Error(`[[error:too-many-posts-newbie, ${meta.config.newbiePostDelay}, ${meta.config.newbiePostDelayThreshold}]]`);
|
throw new Error(`[[error:too-many-posts-newbie, ${meta.config.newbiePostDelay}, ${meta.config.newbiePostDelayThreshold}]]`);
|
||||||
} else if (now - lasttime < meta.config.postDelay * 1000) {
|
} else if (now - lasttime < meta.config.postDelay * 1000) {
|
||||||
throw new Error(`[[error:too-many-posts, ${meta.config.postDelay}]]`);
|
throw new Error(`[[error:too-many-posts, ${meta.config.postDelay}]]`);
|
||||||
|
|||||||
@@ -47,15 +47,15 @@ module.exports = function (User) {
|
|||||||
settings.openOutgoingLinksInNewTab = parseInt(getSetting(settings, 'openOutgoingLinksInNewTab', 0), 10) === 1;
|
settings.openOutgoingLinksInNewTab = parseInt(getSetting(settings, 'openOutgoingLinksInNewTab', 0), 10) === 1;
|
||||||
settings.dailyDigestFreq = getSetting(settings, 'dailyDigestFreq', 'off');
|
settings.dailyDigestFreq = getSetting(settings, 'dailyDigestFreq', 'off');
|
||||||
settings.usePagination = parseInt(getSetting(settings, 'usePagination', 0), 10) === 1;
|
settings.usePagination = parseInt(getSetting(settings, 'usePagination', 0), 10) === 1;
|
||||||
settings.topicsPerPage =
|
settings.topicsPerPage = Math.min(
|
||||||
Math.min(
|
|
||||||
meta.config.maxTopicsPerPage,
|
meta.config.maxTopicsPerPage,
|
||||||
Math.min(settings.topicsPerPage ? parseInt(settings.topicsPerPage, 10) : defaultTopicsPerPage, defaultTopicsPerPage)
|
settings.topicsPerPage ? parseInt(settings.topicsPerPage, 10) : defaultTopicsPerPage,
|
||||||
|
defaultTopicsPerPage
|
||||||
);
|
);
|
||||||
settings.postsPerPage =
|
settings.postsPerPage = Math.min(
|
||||||
Math.min(
|
|
||||||
meta.config.maxPostsPerPage,
|
meta.config.maxPostsPerPage,
|
||||||
Math.min(settings.postsPerPage ? parseInt(settings.postsPerPage, 10) : defaultPostsPerPage, defaultPostsPerPage)
|
settings.postsPerPage ? parseInt(settings.postsPerPage, 10) : defaultPostsPerPage,
|
||||||
|
defaultPostsPerPage
|
||||||
);
|
);
|
||||||
settings.userLang = settings.userLang || meta.config.defaultLang || 'en-GB';
|
settings.userLang = settings.userLang || meta.config.defaultLang || 'en-GB';
|
||||||
settings.acpLang = settings.acpLang || settings.userLang;
|
settings.acpLang = settings.acpLang || settings.userLang;
|
||||||
@@ -91,12 +91,20 @@ module.exports = function (User) {
|
|||||||
|
|
||||||
User.saveSettings = async function (uid, data) {
|
User.saveSettings = async function (uid, data) {
|
||||||
const maxPostsPerPage = meta.config.maxPostsPerPage || 20;
|
const maxPostsPerPage = meta.config.maxPostsPerPage || 20;
|
||||||
if (!data.postsPerPage || parseInt(data.postsPerPage, 10) <= 1 || parseInt(data.postsPerPage, 10) > maxPostsPerPage) {
|
if (
|
||||||
|
!data.postsPerPage ||
|
||||||
|
parseInt(data.postsPerPage, 10) <= 1 ||
|
||||||
|
parseInt(data.postsPerPage, 10) > maxPostsPerPage
|
||||||
|
) {
|
||||||
throw new Error(`[[error:invalid-pagination-value, 2, ${maxPostsPerPage}]]`);
|
throw new Error(`[[error:invalid-pagination-value, 2, ${maxPostsPerPage}]]`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const maxTopicsPerPage = meta.config.maxTopicsPerPage || 20;
|
const maxTopicsPerPage = meta.config.maxTopicsPerPage || 20;
|
||||||
if (!data.topicsPerPage || parseInt(data.topicsPerPage, 10) <= 1 || parseInt(data.topicsPerPage, 10) > maxTopicsPerPage) {
|
if (
|
||||||
|
!data.topicsPerPage ||
|
||||||
|
parseInt(data.topicsPerPage, 10) <= 1 ||
|
||||||
|
parseInt(data.topicsPerPage, 10) > maxTopicsPerPage
|
||||||
|
) {
|
||||||
throw new Error(`[[error:invalid-pagination-value, 2, ${maxTopicsPerPage}]]`);
|
throw new Error(`[[error:invalid-pagination-value, 2, ${maxTopicsPerPage}]]`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -286,7 +286,8 @@ describe('API', async () => {
|
|||||||
generateTests(writeApi, Object.keys(writeApi.paths), writeApi.servers[0].url);
|
generateTests(writeApi, Object.keys(writeApi.paths), writeApi.servers[0].url);
|
||||||
|
|
||||||
function generateTests(api, paths, prefix) {
|
function generateTests(api, paths, prefix) {
|
||||||
// Iterate through all documented paths, make a call to it, and compare the result body with what is defined in the spec
|
// Iterate through all documented paths, make a call to it,
|
||||||
|
// and compare the result body with what is defined in the spec
|
||||||
const pathLib = path; // for calling path module from inside this forEach
|
const pathLib = path; // for calling path module from inside this forEach
|
||||||
paths.forEach((path) => {
|
paths.forEach((path) => {
|
||||||
const context = api.paths[path];
|
const context = api.paths[path];
|
||||||
|
|||||||
@@ -545,7 +545,11 @@ describe('Categories', () => {
|
|||||||
},
|
},
|
||||||
function (category, next) {
|
function (category, next) {
|
||||||
child1Cid = category.cid;
|
child1Cid = category.cid;
|
||||||
socketCategories.copySettingsFrom({ uid: adminUid }, { fromCid: parentCid, toCid: child1Cid, copyParent: true }, next);
|
socketCategories.copySettingsFrom(
|
||||||
|
{ uid: adminUid },
|
||||||
|
{ fromCid: parentCid, toCid: child1Cid, copyParent: true },
|
||||||
|
next
|
||||||
|
);
|
||||||
},
|
},
|
||||||
function (destinationCategory, next) {
|
function (destinationCategory, next) {
|
||||||
Categories.getCategoryField(child1Cid, 'description', next);
|
Categories.getCategoryField(child1Cid, 'description', next);
|
||||||
|
|||||||
@@ -224,7 +224,10 @@ describe('Messaging Library', () => {
|
|||||||
|
|
||||||
it('should send not a user-leave system message when a user tries to leave a room they are not in', async () => {
|
it('should send not a user-leave system message when a user tries to leave a room they are not in', async () => {
|
||||||
await socketModules.chats.leave({ uid: bazUid }, roomId);
|
await socketModules.chats.leave({ uid: bazUid }, roomId);
|
||||||
const messages = await socketModules.chats.getMessages({ uid: fooUid }, { uid: fooUid, roomId: roomId, start: 0 });
|
const messages = await socketModules.chats.getMessages(
|
||||||
|
{ uid: fooUid },
|
||||||
|
{ uid: fooUid, roomId: roomId, start: 0 }
|
||||||
|
);
|
||||||
assert.equal(messages.length, 4);
|
assert.equal(messages.length, 4);
|
||||||
const message = messages.pop();
|
const message = messages.pop();
|
||||||
assert.strictEqual(message.system, true);
|
assert.strictEqual(message.system, true);
|
||||||
|
|||||||
@@ -446,7 +446,10 @@ describe('Post\'s', () => {
|
|||||||
|
|
||||||
it('should purge posts and purge topic', (done) => {
|
it('should purge posts and purge topic', (done) => {
|
||||||
createTopicWithReply((topicPostData, replyData) => {
|
createTopicWithReply((topicPostData, replyData) => {
|
||||||
socketPosts.purgePosts({ uid: voterUid }, { pids: [replyData.pid, topicPostData.postData.pid], tid: topicPostData.topicData.tid }, (err) => {
|
socketPosts.purgePosts({ uid: voterUid }, {
|
||||||
|
pids: [replyData.pid, topicPostData.postData.pid],
|
||||||
|
tid: topicPostData.topicData.tid,
|
||||||
|
}, (err) => {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
posts.exists(`post:${replyData.pid}`, (err, exists) => {
|
posts.exists(`post:${replyData.pid}`, (err, exists) => {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
|
|||||||
@@ -58,7 +58,12 @@ describe('Topic\'s', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should create a new topic with proper parameters', (done) => {
|
it('should create a new topic with proper parameters', (done) => {
|
||||||
topics.post({ uid: topic.userId, title: topic.title, content: topic.content, cid: topic.categoryId }, (err, result) => {
|
topics.post({
|
||||||
|
uid: topic.userId,
|
||||||
|
title: topic.title,
|
||||||
|
content: topic.content,
|
||||||
|
cid: topic.categoryId,
|
||||||
|
}, (err, result) => {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
assert(result);
|
assert(result);
|
||||||
topic.tid = result.topicData.tid;
|
topic.tid = result.topicData.tid;
|
||||||
@@ -170,7 +175,12 @@ describe('Topic\'s', () => {
|
|||||||
let newPost;
|
let newPost;
|
||||||
|
|
||||||
before((done) => {
|
before((done) => {
|
||||||
topics.post({ uid: topic.userId, title: topic.title, content: topic.content, cid: topic.categoryId }, (err, result) => {
|
topics.post({
|
||||||
|
uid: topic.userId,
|
||||||
|
title: topic.title,
|
||||||
|
content: topic.content,
|
||||||
|
cid: topic.categoryId,
|
||||||
|
}, (err, result) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return done(err);
|
return done(err);
|
||||||
}
|
}
|
||||||
@@ -265,7 +275,12 @@ describe('Topic\'s', () => {
|
|||||||
let newPost;
|
let newPost;
|
||||||
|
|
||||||
before((done) => {
|
before((done) => {
|
||||||
topics.post({ uid: topic.userId, title: topic.title, content: topic.content, cid: topic.categoryId }, (err, result) => {
|
topics.post({
|
||||||
|
uid: topic.userId,
|
||||||
|
title: topic.title,
|
||||||
|
content: topic.content,
|
||||||
|
cid: topic.categoryId,
|
||||||
|
}, (err, result) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return done(err);
|
return done(err);
|
||||||
}
|
}
|
||||||
@@ -471,7 +486,12 @@ describe('Topic\'s', () => {
|
|||||||
before((done) => {
|
before((done) => {
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function (next) {
|
function (next) {
|
||||||
topics.post({ uid: topic.userId, title: topic.title, content: topic.content, cid: topic.categoryId }, (err, result) => {
|
topics.post({
|
||||||
|
uid: topic.userId,
|
||||||
|
title: topic.title,
|
||||||
|
content: topic.content,
|
||||||
|
cid: topic.categoryId,
|
||||||
|
}, (err, result) => {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
newTopic = result.topicData;
|
newTopic = result.topicData;
|
||||||
next();
|
next();
|
||||||
@@ -985,7 +1005,12 @@ describe('Topic\'s', () => {
|
|||||||
groups.join('administrators', topic.userId, next);
|
groups.join('administrators', topic.userId, next);
|
||||||
},
|
},
|
||||||
function (next) {
|
function (next) {
|
||||||
topics.post({ uid: topic.userId, title: topic.title, content: topic.content, cid: topic.categoryId }, (err, result) => {
|
topics.post({
|
||||||
|
uid: topic.userId,
|
||||||
|
title: topic.title,
|
||||||
|
content: topic.content,
|
||||||
|
cid: topic.categoryId,
|
||||||
|
}, (err, result) => {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
newTopic = result.topicData;
|
newTopic = result.topicData;
|
||||||
next();
|
next();
|
||||||
@@ -1276,7 +1301,12 @@ describe('Topic\'s', () => {
|
|||||||
const socketTopics = require('../src/socket.io/topics');
|
const socketTopics = require('../src/socket.io/topics');
|
||||||
let tid;
|
let tid;
|
||||||
before((done) => {
|
before((done) => {
|
||||||
topics.post({ uid: topic.userId, title: topic.title, content: topic.content, cid: topic.categoryId }, (err, result) => {
|
topics.post({
|
||||||
|
uid: topic.userId,
|
||||||
|
title: topic.title,
|
||||||
|
content: topic.content,
|
||||||
|
cid: topic.categoryId,
|
||||||
|
}, (err, result) => {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
tid = result.topicData.tid;
|
tid = result.topicData.tid;
|
||||||
done();
|
done();
|
||||||
|
|||||||
@@ -196,36 +196,51 @@ describe('Upload Controllers', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// it('should fail if topic thumbs are disabled', function (done) {
|
// it('should fail if topic thumbs are disabled', function (done) {
|
||||||
// helpers.uploadFile(nconf.get('url') + '/api/topic/thumb/upload', path.join(__dirname, '../test/files/test.png'), {}, jar, csrf_token, function (err, res, body) {
|
// helpers.uploadFile(
|
||||||
|
// nconf.get('url') + '/api/topic/thumb/upload',
|
||||||
|
// path.join(__dirname, '../test/files/test.png'),
|
||||||
|
// {}, jar, csrf_token,
|
||||||
|
// function (err, res, body) {
|
||||||
// assert.ifError(err);
|
// assert.ifError(err);
|
||||||
// assert.strictEqual(res.statusCode, 404);
|
// assert.strictEqual(res.statusCode, 404);
|
||||||
// console.log(body);
|
// console.log(body);
|
||||||
// assert(body && body.status && body.status.code);
|
// assert(body && body.status && body.status.code);
|
||||||
// assert.strictEqual(body.status.code, '[[error:topic-thumbnails-are-disabled]]');
|
// assert.strictEqual(body.status.code, '[[error:topic-thumbnails-are-disabled]]');
|
||||||
// done();
|
// done();
|
||||||
// });
|
// }
|
||||||
|
// );
|
||||||
// });
|
// });
|
||||||
|
|
||||||
// it('should fail if file is not image', function (done) {
|
// it('should fail if file is not image', function (done) {
|
||||||
// meta.config.allowTopicsThumbnail = 1;
|
// meta.config.allowTopicsThumbnail = 1;
|
||||||
// helpers.uploadFile(nconf.get('url') + '/api/topic/thumb/upload', path.join(__dirname, '../test/files/503.html'), {}, jar, csrf_token, function (err, res, body) {
|
// helpers.uploadFile(
|
||||||
|
// nconf.get('url') + '/api/topic/thumb/upload',
|
||||||
|
// path.join(__dirname, '../test/files/503.html'),
|
||||||
|
// {}, jar, csrf_token,
|
||||||
|
// function (err, res, body) {
|
||||||
// assert.ifError(err);
|
// assert.ifError(err);
|
||||||
// assert.equal(res.statusCode, 500);
|
// assert.equal(res.statusCode, 500);
|
||||||
// assert.equal(body.error, '[[error:invalid-file]]');
|
// assert.equal(body.error, '[[error:invalid-file]]');
|
||||||
// done();
|
// done();
|
||||||
// });
|
// }
|
||||||
|
// );
|
||||||
// });
|
// });
|
||||||
|
|
||||||
// it('should upload topic thumb', function (done) {
|
// it('should upload topic thumb', function (done) {
|
||||||
// meta.config.allowTopicsThumbnail = 1;
|
// meta.config.allowTopicsThumbnail = 1;
|
||||||
// helpers.uploadFile(nconf.get('url') + '/api/topic/thumb/upload', path.join(__dirname, '../test/files/test.png'), {}, jar, csrf_token, function (err, res, body) {
|
// helpers.uploadFile(
|
||||||
|
// nconf.get('url') + '/api/topic/thumb/upload',
|
||||||
|
// path.join(__dirname, '../test/files/test.png'),
|
||||||
|
// {}, jar, csrf_token,
|
||||||
|
// function (err, res, body) {
|
||||||
// assert.ifError(err);
|
// assert.ifError(err);
|
||||||
// assert.equal(res.statusCode, 200);
|
// assert.equal(res.statusCode, 200);
|
||||||
// assert(Array.isArray(body));
|
// assert(Array.isArray(body));
|
||||||
// assert(body[0].path);
|
// assert(body[0].path);
|
||||||
// assert(body[0].url);
|
// assert(body[0].url);
|
||||||
// done();
|
// done();
|
||||||
// });
|
// }
|
||||||
|
// );
|
||||||
// });
|
// });
|
||||||
|
|
||||||
it('should not allow non image uploads', (done) => {
|
it('should not allow non image uploads', (done) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user