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
|
||||
// "max-len": ["error", { "code": 120, "tabWidth": 2, "ignoreUrls": true, "ignoreStrings": true, "ignoreTemplateLiterals": true, "ignoreRegExpLiterals": true }],
|
||||
"max-len": "off", // do this LAST
|
||||
"max-len": ["error", { "code": 120, "tabWidth": 2, "ignoreUrls": true, "ignoreStrings": true, "ignoreTemplateLiterals": true, "ignoreRegExpLiterals": true }],
|
||||
|
||||
// === Disable rules ===
|
||||
// more liberal naming
|
||||
|
||||
@@ -184,7 +184,9 @@ define('admin/manage/users', [
|
||||
data[cur.name] = cur.value;
|
||||
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) {
|
||||
return api.put('/users/' + uid + '/ban', {
|
||||
|
||||
@@ -62,7 +62,11 @@ ajaxify = window.ajaxify || {};
|
||||
$('#footer, #content').removeClass('hide').addClass('ajaxifying');
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -340,7 +344,8 @@ ajaxify = window.ajaxify || {};
|
||||
if (typeof script === 'string') {
|
||||
return function (next) {
|
||||
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(() => {
|
||||
if (module && module.init) {
|
||||
module.init();
|
||||
|
||||
@@ -43,7 +43,9 @@ define('forum/account/edit', [
|
||||
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);
|
||||
|
||||
|
||||
@@ -150,7 +150,9 @@ define('forum/account/header', [
|
||||
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', {
|
||||
until: until,
|
||||
|
||||
@@ -10,7 +10,17 @@ define('forum/groups/details', [
|
||||
'api',
|
||||
'slugify',
|
||||
'categorySelector',
|
||||
], function (memberList, iconSelect, components, coverPhoto, pictureCropper, translator, api, slugify, categorySelector) {
|
||||
], function (
|
||||
memberList,
|
||||
iconSelect,
|
||||
components,
|
||||
coverPhoto,
|
||||
pictureCropper,
|
||||
translator,
|
||||
api,
|
||||
slugify,
|
||||
categorySelector
|
||||
) {
|
||||
var Details = {};
|
||||
var groupName;
|
||||
|
||||
|
||||
@@ -130,7 +130,10 @@ define('forum/topic', [
|
||||
if (components.get('post/anchor', postIndex - 1).length) {
|
||||
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({
|
||||
alert_id: 'bookmark',
|
||||
message: '[[topic:bookmark_instructions]]',
|
||||
@@ -250,7 +253,14 @@ define('forum/topic', [
|
||||
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) {
|
||||
socket.emit('topics.bookmark', {
|
||||
tid: ajaxify.data.tid,
|
||||
|
||||
@@ -84,7 +84,11 @@ define('forum/topic/events', [
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,12 @@ define('forum/topic/posts', [
|
||||
var Posts = { };
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -88,8 +93,10 @@ define('forum/topic/posts', [
|
||||
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 isPostVisible = (ajaxify.data.pagination.currentPage === ajaxify.data.pagination.pageCount && direction === 1) ||
|
||||
(ajaxify.data.pagination.currentPage === 1 && direction === -1);
|
||||
var isPostVisible = (
|
||||
ajaxify.data.pagination.currentPage === ajaxify.data.pagination.pageCount &&
|
||||
direction === 1
|
||||
) || (ajaxify.data.pagination.currentPage === 1 && direction === -1);
|
||||
|
||||
if (isPostVisible) {
|
||||
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) => {
|
||||
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;
|
||||
if (beforeIdx > -1) {
|
||||
postEl = document.querySelector(`[component="post"][data-pid="${ajaxify.data.posts[beforeIdx + (reverse ? 1 : 0)].pid}"]`);
|
||||
|
||||
@@ -34,7 +34,12 @@ define('handleBack', [
|
||||
|
||||
function onBackClicked(isMarkedUnread) {
|
||||
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 clickedIndex = storage.getItem('category:bookmark:clicked');
|
||||
|
||||
|
||||
@@ -28,7 +28,9 @@ define('hooks', [], () => {
|
||||
return listeners.reduce((promise, listener) => promise.then((data) => {
|
||||
try {
|
||||
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) {
|
||||
return _onHookError(e, listener, data);
|
||||
}
|
||||
|
||||
@@ -176,7 +176,9 @@ define('pictureCropper', ['cropper'], function (Cropper) {
|
||||
function checkCORS(cropperTool, data) {
|
||||
var imageData;
|
||||
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) {
|
||||
var corsErrors = [
|
||||
'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.
|
||||
*/
|
||||
function getKey(event) {
|
||||
var anyModChange = 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 anyModChange = (
|
||||
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();
|
||||
key.c = event.ctrlKey;
|
||||
key.a = event.altKey;
|
||||
|
||||
@@ -90,9 +90,15 @@ define('settings/object', function () {
|
||||
if (value[propertyName] === undefined && attributes['data-new'] !== undefined) {
|
||||
value[propertyName] = attributes['data-new'];
|
||||
}
|
||||
addObjectPropertyElement(element, key, attributes, propertyName, value[propertyName], separator.clone(), function (el) {
|
||||
element.append(el);
|
||||
});
|
||||
addObjectPropertyElement(
|
||||
element,
|
||||
key,
|
||||
attributes,
|
||||
propertyName,
|
||||
value[propertyName],
|
||||
separator.clone(),
|
||||
function (el) { element.append(el); }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,9 +96,19 @@ define('topicList', [
|
||||
|
||||
function onNewTopic(data) {
|
||||
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.template.category && parseInt(ajaxify.data.cid, 10) !== parseInt(data.cid, 10))
|
||||
(
|
||||
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.template.category &&
|
||||
parseInt(ajaxify.data.cid, 10) !== parseInt(data.cid, 10)
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
@@ -113,11 +123,25 @@ define('topicList', [
|
||||
return;
|
||||
}
|
||||
if (!post.topic.isFollowing && (
|
||||
(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.selectedFilter && ajaxify.data.selectedFilter.filter === 'watched' && !post.topic.isFollowing) ||
|
||||
(ajaxify.data.template.category && parseInt(ajaxify.data.cid, 10) !== parseInt(post.topic.cid, 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.selectedFilter &&
|
||||
ajaxify.data.selectedFilter.filter === 'watched' &&
|
||||
!post.topic.isFollowing
|
||||
) ||
|
||||
(
|
||||
ajaxify.data.template.category &&
|
||||
parseInt(ajaxify.data.cid, 10) !== parseInt(post.topic.cid, 10)
|
||||
)
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -308,7 +308,8 @@
|
||||
warn('[translator] Parameter `namespace` is ' + namespace + (namespace === '' ? '(empty string)' : ''));
|
||||
translation = Promise.resolve({});
|
||||
} 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];
|
||||
}
|
||||
|
||||
|
||||
@@ -646,7 +646,10 @@
|
||||
params.forEach(function (param) {
|
||||
var val = param.split('=');
|
||||
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.substr(-2, 2) === '[]') {
|
||||
@@ -732,8 +735,11 @@
|
||||
isInternalURI: function (targetLocation, referenceLocation, relative_path) {
|
||||
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
|
||||
(relative_path.length > 0 ? targetLocation.pathname.indexOf(relative_path) === 0 : true) // Subfolder installs need this additional check
|
||||
targetLocation.host === referenceLocation.host &&
|
||||
// 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 = [];
|
||||
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);
|
||||
|
||||
while (numDays > 0) {
|
||||
/* 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));
|
||||
numDays -= 1;
|
||||
}
|
||||
|
||||
@@ -118,7 +118,9 @@ Categories.getModeratorUids = async function (cids) {
|
||||
const uniqGroups = _.uniq(_.flatten(sets.groupNames));
|
||||
const groupUids = await groups.getMembersOfGroups(uniqGroups);
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
@@ -68,7 +68,8 @@ function runSteps(tasks) {
|
||||
}
|
||||
|
||||
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 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 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';
|
||||
|
||||
|
||||
@@ -65,7 +65,10 @@ async function incrementProfileViews(req, userData) {
|
||||
if (req.uid >= 1) {
|
||||
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);
|
||||
req.session.uids_viewed[userData.uid] = Date.now();
|
||||
}
|
||||
@@ -102,7 +105,9 @@ async function getPosts(callerUid, userData, setSuffix) {
|
||||
}
|
||||
if (pids.length) {
|
||||
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;
|
||||
} while (postData.length < count && hasMorePosts);
|
||||
|
||||
@@ -99,7 +99,9 @@ settingsController.get = async function (req, res, next) {
|
||||
'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 };
|
||||
|
||||
|
||||
@@ -22,10 +22,13 @@ pluginsController.get = async function (req, res) {
|
||||
memo[cur.label] = cur.value;
|
||||
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) => {
|
||||
plugin.downloads = trendingScores[plugin.id];
|
||||
return 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];
|
||||
return plugin;
|
||||
});
|
||||
|
||||
res.render('admin/extend/plugins', {
|
||||
installed: installedPlugins,
|
||||
|
||||
@@ -95,7 +95,9 @@ apiController.loadConfig = async function (req) {
|
||||
config.usePagination = settings.usePagination;
|
||||
config.topicsPerPage = settings.topicsPerPage;
|
||||
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.openOutgoingLinksInNewTab = settings.openOutgoingLinksInNewTab;
|
||||
config.topicPostSort = settings.topicPostSort || config.topicPostSort;
|
||||
|
||||
@@ -83,7 +83,11 @@ authenticationController.register = async function (req, res) {
|
||||
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]]');
|
||||
}
|
||||
|
||||
|
||||
@@ -315,7 +315,12 @@ helpers.getVisibleCategories = async function (params) {
|
||||
return false;
|
||||
}
|
||||
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 shouldBeDisaplayedAsDisabled = hasVisibleChildren && !isCategoryVisible;
|
||||
|
||||
@@ -380,7 +385,8 @@ function checkVisibleChildren(c, cidToAllowed, cidToWatchState, states) {
|
||||
return false;
|
||||
}
|
||||
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 || '/');
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
res.render('registerComplete', {
|
||||
|
||||
@@ -131,7 +131,10 @@ modsController.flags.detail = async function (req, res, next) {
|
||||
assignees: results.assignees,
|
||||
type_bool: ['post', 'user', 'empty'].reduce((memo, cur) => {
|
||||
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 {
|
||||
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) {
|
||||
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();
|
||||
}
|
||||
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;
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,10 @@ async function uploadAsFile(req, uploadedFile) {
|
||||
|
||||
async function resizeImage(fileObj) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -168,7 +168,8 @@ Topics.deleteThumb = async (req, 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);
|
||||
|
||||
// Sanity-check the tid if it's strictly not a uuid
|
||||
|
||||
@@ -95,7 +95,9 @@ module.exports = function (module) {
|
||||
const batch = require('../../batch');
|
||||
const batchSize = Math.ceil(key.length / Math.ceil(key.length / 100));
|
||||
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);
|
||||
if (start > 0) {
|
||||
result = result.slice(start, stop !== -1 ? stop + 1 : undefined);
|
||||
|
||||
@@ -65,7 +65,10 @@ module.exports = function (module) {
|
||||
|
||||
const bulk = module.client.collection('objects').initializeUnorderedBulkOp();
|
||||
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();
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
const groupData = await groups.getGroupsFields(groupNames, ['memberPostCids']);
|
||||
groupNames = groupNames.filter(
|
||||
(groupName, idx) => !groupData[idx].memberPostCidsArray.length || groupData[idx].memberPostCidsArray.includes(postData.cid)
|
||||
);
|
||||
groupNames = groupNames.filter((groupName, idx) => (
|
||||
!groupData[idx].memberPostCidsArray.length ||
|
||||
groupData[idx].memberPostCidsArray.includes(postData.cid)
|
||||
));
|
||||
|
||||
const keys = groupNames.map(groupName => `group:${groupName}:member:pids`);
|
||||
await db.sortedSetsAdd(keys, postData.timestamp, postData.pid);
|
||||
|
||||
@@ -129,7 +129,13 @@ async function setupConfig() {
|
||||
const redisQuestions = require('./database/redis').questions;
|
||||
const mongoQuestions = require('./database/mongo').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) => {
|
||||
if (install.values.hasOwnProperty(question.name)) {
|
||||
@@ -307,7 +313,8 @@ async function createAdmin() {
|
||||
const results = await promptGet(questions);
|
||||
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')) {
|
||||
console.log('Password was not provided during automated setup, generating one...');
|
||||
password = utils.generateUUID().slice(0, 8);
|
||||
|
||||
@@ -20,7 +20,9 @@ module.exports = function (Messaging) {
|
||||
const keys = mids.map(mid => `message:${mid}`);
|
||||
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) => {
|
||||
|
||||
@@ -41,7 +41,10 @@ module.exports = function (middleware) {
|
||||
|
||||
middleware.exposePrivilegeSet = async (req, res, next) => {
|
||||
// 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();
|
||||
};
|
||||
};
|
||||
|
||||
@@ -118,7 +118,11 @@ Notifications.create = async function (data) {
|
||||
}
|
||||
data.importance = data.importance || 5;
|
||||
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;
|
||||
}
|
||||
const now = Date.now();
|
||||
|
||||
@@ -94,7 +94,9 @@ module.exports = function (Posts) {
|
||||
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) {
|
||||
winston.verbose(err.messsage);
|
||||
@@ -117,7 +119,10 @@ module.exports = function (Posts) {
|
||||
Posts.configureSanitize = async () => {
|
||||
// Each allowed tags should have some common global attributes...
|
||||
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...
|
||||
|
||||
@@ -39,7 +39,8 @@ module.exports = function (Posts) {
|
||||
const cidToCategory = toObject('cid', topicsAndCategories.categories);
|
||||
|
||||
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)) {
|
||||
post.uid = 0;
|
||||
}
|
||||
|
||||
@@ -94,8 +94,11 @@ module.exports = function (privileges) {
|
||||
const cidsSet = new Set(allowedCids);
|
||||
const canViewDeleted = _.zipObject(cids, results.view_deleted);
|
||||
|
||||
pids = postData.filter(post => post.topic && cidsSet.has(post.topic.cid) &&
|
||||
((!post.topic.deleted && !post.deleted) || canViewDeleted[post.topic.cid] || results.isAdmin)).map(post => post.pid);
|
||||
pids = postData.filter(post => (
|
||||
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', {
|
||||
privilege: privilege,
|
||||
@@ -121,10 +124,19 @@ module.exports = function (privileges) {
|
||||
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}]]` };
|
||||
}
|
||||
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}]]` };
|
||||
}
|
||||
|
||||
|
||||
@@ -71,12 +71,18 @@ module.exports = function (privileges) {
|
||||
const cids = _.uniq(topicsData.map(topic => topic.cid));
|
||||
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 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', {
|
||||
privilege: privilege,
|
||||
|
||||
@@ -97,7 +97,9 @@ async function generateForTopic(req, res) {
|
||||
const replies = topicData.posts.slice(1);
|
||||
replies.forEach((postData) => {
|
||||
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({
|
||||
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,
|
||||
].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));
|
||||
};
|
||||
|
||||
|
||||
@@ -10,8 +10,16 @@ const { setupApiRoute } = routeHelpers;
|
||||
module.exports = function () {
|
||||
const middlewares = [middleware.authenticate];
|
||||
|
||||
// setupApiRoute(router, 'put', '/', [...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);
|
||||
// setupApiRoute(router, 'put', '/', [
|
||||
// ...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;
|
||||
};
|
||||
|
||||
@@ -42,7 +42,9 @@ SocketAdmin.before = async function (socket, method) {
|
||||
|
||||
// Check admin privileges mapping (if not in mapping, deny access)
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,8 @@ Analytics.get = function (socket, data, callback) {
|
||||
},
|
||||
}, (err, data) => {
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -185,7 +185,9 @@ async function checkMaintenance(socket) {
|
||||
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) {
|
||||
const req = socket.request;
|
||||
|
||||
@@ -26,7 +26,10 @@ module.exports = function (SocketTopics) {
|
||||
const reverse = data.topicPostSort === 'newest_to_oldest' || data.topicPostSort === 'most_votes';
|
||||
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) {
|
||||
start -= (infScrollPostsPerPage + 1);
|
||||
@@ -96,7 +99,10 @@ module.exports = function (SocketTopics) {
|
||||
};
|
||||
|
||||
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));
|
||||
if (data.direction === -1) {
|
||||
start -= itemsPerPage;
|
||||
|
||||
@@ -12,7 +12,8 @@ const Events = module.exports;
|
||||
* 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.
|
||||
* 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 = {
|
||||
|
||||
@@ -151,7 +151,12 @@ module.exports = function (Topics) {
|
||||
topicData = filtered;
|
||||
|
||||
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 });
|
||||
return result.tids;
|
||||
|
||||
@@ -56,7 +56,8 @@ module.exports = function (Topics) {
|
||||
users[user.uid] = user;
|
||||
});
|
||||
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)) {
|
||||
post.uid = 0;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,12 @@ module.exports = {
|
||||
|
||||
// has no history, but is banned, create plain object with just uid and timestmap
|
||||
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}`;
|
||||
addBan(banKey, { uid: uid, timestamp: banTimestamp }, next);
|
||||
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 sessionStoreDestroy = util.promisify((sid, callback) => db.sessionStore.destroy(sid, err => callback(err)));
|
||||
const getSessionFromStore = util.promisify(
|
||||
(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) {
|
||||
await cleanExpiredSessions(uid);
|
||||
|
||||
@@ -33,7 +33,19 @@ process.on('message', async (msg) => {
|
||||
const profilePath = path.join(__dirname, '../../../build/export', profileFile);
|
||||
|
||||
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}:settings`),
|
||||
user.getIPs(targetUid, 9),
|
||||
|
||||
@@ -41,7 +41,11 @@ module.exports = function (User) {
|
||||
|
||||
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}]]`);
|
||||
} else if (now - lasttime < meta.config.postDelay * 1000) {
|
||||
throw new Error(`[[error:too-many-posts, ${meta.config.postDelay}]]`);
|
||||
|
||||
@@ -47,16 +47,16 @@ module.exports = function (User) {
|
||||
settings.openOutgoingLinksInNewTab = parseInt(getSetting(settings, 'openOutgoingLinksInNewTab', 0), 10) === 1;
|
||||
settings.dailyDigestFreq = getSetting(settings, 'dailyDigestFreq', 'off');
|
||||
settings.usePagination = parseInt(getSetting(settings, 'usePagination', 0), 10) === 1;
|
||||
settings.topicsPerPage =
|
||||
Math.min(
|
||||
meta.config.maxTopicsPerPage,
|
||||
Math.min(settings.topicsPerPage ? parseInt(settings.topicsPerPage, 10) : defaultTopicsPerPage, defaultTopicsPerPage)
|
||||
);
|
||||
settings.postsPerPage =
|
||||
Math.min(
|
||||
meta.config.maxPostsPerPage,
|
||||
Math.min(settings.postsPerPage ? parseInt(settings.postsPerPage, 10) : defaultPostsPerPage, defaultPostsPerPage)
|
||||
);
|
||||
settings.topicsPerPage = Math.min(
|
||||
meta.config.maxTopicsPerPage,
|
||||
settings.topicsPerPage ? parseInt(settings.topicsPerPage, 10) : defaultTopicsPerPage,
|
||||
defaultTopicsPerPage
|
||||
);
|
||||
settings.postsPerPage = Math.min(
|
||||
meta.config.maxPostsPerPage,
|
||||
settings.postsPerPage ? parseInt(settings.postsPerPage, 10) : defaultPostsPerPage,
|
||||
defaultPostsPerPage
|
||||
);
|
||||
settings.userLang = settings.userLang || meta.config.defaultLang || 'en-GB';
|
||||
settings.acpLang = settings.acpLang || settings.userLang;
|
||||
settings.topicPostSort = getSetting(settings, 'topicPostSort', 'oldest_to_newest');
|
||||
@@ -91,12 +91,20 @@ module.exports = function (User) {
|
||||
|
||||
User.saveSettings = async function (uid, data) {
|
||||
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}]]`);
|
||||
}
|
||||
|
||||
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}]]`);
|
||||
}
|
||||
|
||||
|
||||
@@ -286,7 +286,8 @@ describe('API', async () => {
|
||||
generateTests(writeApi, Object.keys(writeApi.paths), writeApi.servers[0].url);
|
||||
|
||||
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
|
||||
paths.forEach((path) => {
|
||||
const context = api.paths[path];
|
||||
|
||||
@@ -545,7 +545,11 @@ describe('Categories', () => {
|
||||
},
|
||||
function (category, next) {
|
||||
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) {
|
||||
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 () => {
|
||||
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);
|
||||
const message = messages.pop();
|
||||
assert.strictEqual(message.system, true);
|
||||
|
||||
@@ -446,7 +446,10 @@ describe('Post\'s', () => {
|
||||
|
||||
it('should purge posts and purge topic', (done) => {
|
||||
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);
|
||||
posts.exists(`post:${replyData.pid}`, (err, exists) => {
|
||||
assert.ifError(err);
|
||||
|
||||
@@ -58,7 +58,12 @@ describe('Topic\'s', () => {
|
||||
});
|
||||
|
||||
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(result);
|
||||
topic.tid = result.topicData.tid;
|
||||
@@ -170,7 +175,12 @@ describe('Topic\'s', () => {
|
||||
let newPost;
|
||||
|
||||
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) {
|
||||
return done(err);
|
||||
}
|
||||
@@ -265,7 +275,12 @@ describe('Topic\'s', () => {
|
||||
let newPost;
|
||||
|
||||
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) {
|
||||
return done(err);
|
||||
}
|
||||
@@ -471,7 +486,12 @@ describe('Topic\'s', () => {
|
||||
before((done) => {
|
||||
async.waterfall([
|
||||
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);
|
||||
newTopic = result.topicData;
|
||||
next();
|
||||
@@ -985,7 +1005,12 @@ describe('Topic\'s', () => {
|
||||
groups.join('administrators', topic.userId, 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);
|
||||
newTopic = result.topicData;
|
||||
next();
|
||||
@@ -1276,7 +1301,12 @@ describe('Topic\'s', () => {
|
||||
const socketTopics = require('../src/socket.io/topics');
|
||||
let tid;
|
||||
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);
|
||||
tid = result.topicData.tid;
|
||||
done();
|
||||
|
||||
@@ -196,36 +196,51 @@ describe('Upload Controllers', () => {
|
||||
});
|
||||
|
||||
// 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) {
|
||||
// assert.ifError(err);
|
||||
// assert.strictEqual(res.statusCode, 404);
|
||||
// console.log(body);
|
||||
// assert(body && body.status && body.status.code);
|
||||
// assert.strictEqual(body.status.code, '[[error:topic-thumbnails-are-disabled]]');
|
||||
// done();
|
||||
// });
|
||||
// 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.strictEqual(res.statusCode, 404);
|
||||
// console.log(body);
|
||||
// assert(body && body.status && body.status.code);
|
||||
// assert.strictEqual(body.status.code, '[[error:topic-thumbnails-are-disabled]]');
|
||||
// done();
|
||||
// }
|
||||
// );
|
||||
// });
|
||||
|
||||
// it('should fail if file is not image', function (done) {
|
||||
// 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) {
|
||||
// assert.ifError(err);
|
||||
// assert.equal(res.statusCode, 500);
|
||||
// assert.equal(body.error, '[[error:invalid-file]]');
|
||||
// done();
|
||||
// });
|
||||
// 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.equal(res.statusCode, 500);
|
||||
// assert.equal(body.error, '[[error:invalid-file]]');
|
||||
// done();
|
||||
// }
|
||||
// );
|
||||
// });
|
||||
|
||||
// it('should upload topic thumb', function (done) {
|
||||
// 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) {
|
||||
// assert.ifError(err);
|
||||
// assert.equal(res.statusCode, 200);
|
||||
// assert(Array.isArray(body));
|
||||
// assert(body[0].path);
|
||||
// assert(body[0].url);
|
||||
// done();
|
||||
// });
|
||||
// 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.equal(res.statusCode, 200);
|
||||
// assert(Array.isArray(body));
|
||||
// assert(body[0].path);
|
||||
// assert(body[0].url);
|
||||
// done();
|
||||
// }
|
||||
// );
|
||||
// });
|
||||
|
||||
it('should not allow non image uploads', (done) => {
|
||||
|
||||
Reference in New Issue
Block a user