refactor: tab rules

isekai-main
Barış Soner Uşaklı 3 years ago
parent c26870d227
commit fb363957d1

@ -146,7 +146,7 @@
"@commitlint/config-angular": "14.1.0",
"coveralls": "3.1.1",
"eslint": "7.32.0",
"eslint-config-nodebb": "0.0.3",
"eslint-config-nodebb": "0.1.1",
"eslint-plugin-import": "2.25.3",
"grunt": "1.4.1",
"grunt-contrib-watch": "1.1.0",

@ -84,7 +84,7 @@ define('admin/manage/privileges', [
Privileges.exposeAssumedPrivileges();
checkboxRowSelector.updateAll();
Privileges.addEvents(); // events with confirmation modals
Privileges.addEvents(); // events with confirmation modals
};
Privileges.addEvents = function () {

@ -145,7 +145,7 @@ define('admin/manage/users', [
const uids = getSelectedUids();
if (!uids.length) {
app.alertError('[[error:no-users-selected]]');
return false; // specifically to keep the menu open
return false; // specifically to keep the menu open
}
bootbox.confirm((uids.length > 1 ? '[[admin/manage/users:alerts.confirm-ban-multi]]' : '[[admin/manage/users:alerts.confirm-ban]]'), function (confirm) {
@ -163,7 +163,7 @@ define('admin/manage/users', [
const uids = getSelectedUids();
if (!uids.length) {
app.alertError('[[error:no-users-selected]]');
return false; // specifically to keep the menu open
return false; // specifically to keep the menu open
}
Benchpress.render('admin/partials/temporary-ban', {}).then(function (html) {
@ -207,7 +207,7 @@ define('admin/manage/users', [
const uids = getSelectedUids();
if (!uids.length) {
app.alertError('[[error:no-users-selected]]');
return false; // specifically to keep the menu open
return false; // specifically to keep the menu open
}
Promise.all(uids.map(function (uid) {

@ -536,7 +536,7 @@ $(document).ready(function () {
}
// eslint-disable-next-line no-script-url
if (hrefEmpty(this.href) || this.protocol === 'javascript:' || href === '#' || href === '') {
if (hrefEmpty(this.href) || this.protocol === 'javascript:' || href === '#' || href === '') {
return e.preventDefault();
}

@ -37,7 +37,7 @@ app.flags = {};
* e.g. New Topic/Reply, post tools
*/
if (document.body) {
let earlyQueue = []; // once we can ES6, use Set instead
let earlyQueue = []; // once we can ES6, use Set instead
const earlyClick = function (ev) {
let btnEl = ev.target.closest('button');
const anchorEl = ev.target.closest('a');
@ -114,7 +114,7 @@ app.flags = {};
});
};
app.require = async (modules) => { // allows you to await require.js modules
app.require = async (modules) => { // allows you to await require.js modules
const single = !Array.isArray(modules);
if (single) {
modules = [modules];

@ -45,7 +45,7 @@ define('forum/chats/search', ['components', 'api'], function (components, api) {
function displayUser(chatsListEl, userObj) {
function createUserImage() {
return (userObj.picture ?
'<img src="' + userObj.picture + '" title="' + userObj.username + '" />' :
'<img src="' + userObj.picture + '" title="' + userObj.username + '" />' :
'<div class="user-icon" style="background-color: ' + userObj['icon:bgColor'] + '">' + userObj['icon:text'] + '</div>') +
'<i class="fa fa-circle status ' + userObj.status + '"></i> ' + userObj.username;
}

@ -102,7 +102,7 @@ define('forum/groups/details', [
Details.deleteGroup();
break;
case 'join': // intentional fall-throughs!
case 'join': // intentional fall-throughs!
api.put('/groups/' + ajaxify.data.group.slug + '/membership/' + (uid || app.user.uid), undefined).then(() => ajaxify.refresh()).catch(app.alertError);
break;
@ -111,7 +111,7 @@ define('forum/groups/details', [
break;
// TODO (14/10/2020): rewrite these to use api module and merge with above 2 case blocks
case 'accept': // intentional fall-throughs!
case 'accept': // intentional fall-throughs!
case 'reject':
case 'issueInvite':
case 'rescindInvite':

@ -5,7 +5,7 @@ define('forum/infinitescroll', ['hooks'], function (hooks) {
const scroll = {};
let callback;
let previousScrollTop = 0;
let loadingMore = false;
let loadingMore = false;
let container;
let scrollTimeout = 0;

@ -1,7 +1,7 @@
'use strict';
define('chat', [
'components', 'taskbar', 'translator', 'hooks', 'bootbox',
'components', 'taskbar', 'translator', 'hooks', 'bootbox',
], function (components, taskbar, translator, hooks, bootbox) {
const module = {};
let newMessage = false;

@ -285,7 +285,7 @@
case 'iPad':
icons += '<i class="fa fa-fw fa-tablet"></i>';
break;
case 'iPod': // intentional fall-through
case 'iPod': // intentional fall-through
case 'iPhone':
icons += '<i class="fa fa-fw fa-mobile"></i>';
break;

@ -6,10 +6,10 @@ define('hooks', [], () => {
temporary: new Set(),
runOnce: new Set(),
deprecated: {
'action:script.load': 'filter:script.load', // 👋 @ 1.18.0
'action:category.loaded': 'action:topics.loaded', // 👋 @ 1.19.0
'action:category.loading': 'action:topics.loading', // 👋 @ 1.19.0
'action:composer.check': 'filter:composer.check', // 👋 @ 1.19.0
'action:script.load': 'filter:script.load', // 👋 @ 1.18.0
'action:category.loaded': 'action:topics.loaded', // 👋 @ 1.19.0
'action:category.loading': 'action:topics.loading', // 👋 @ 1.19.0
'action:composer.check': 'filter:composer.check', // 👋 @ 1.19.0
},
};

@ -142,7 +142,7 @@ define('notifications', [
Tinycon.setBubble(count > 99 ? '99+' : count);
}
if (navigator.setAppBadge) { // feature detection
if (navigator.setAppBadge) { // feature detection
navigator.setAppBadge(count);
}
};

@ -20,7 +20,7 @@ define('scrollStop', function () {
if (
(e.originalEvent.deltaY < 0 && scrollTop === 0) || // scroll up
(e.originalEvent.deltaY > 0 && (elementHeight + scrollTop) >= scrollHeight) // scroll down
(e.originalEvent.deltaY > 0 && (elementHeight + scrollTop) >= scrollHeight) // scroll down
) {
return false;
}

@ -737,7 +737,7 @@
},
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 &&
// Otherwise need to check if protocol and host match

@ -94,7 +94,7 @@ postsAPI.edit = async function (caller, data) {
]);
const uids = _.uniq(_.flatten(memberData).concat(String(caller.uid)));
uids.forEach(uid => websockets.in(`uid_${uid}`).emit('event:post_edited', editResult));
uids.forEach(uid => websockets.in(`uid_${uid}`).emit('event:post_edited', editResult));
return returnData;
};

@ -71,7 +71,7 @@ topicsAPI.reply = async function (caller, data) {
return queueObj;
}
const postData = await topics.reply(payload); // postData seems to be a subset of postObj, refactor?
const postData = await topics.reply(payload); // postData seems to be a subset of postObj, refactor?
const postObj = await posts.getPostSummaryByPids([postData.pid], caller.uid, {});
const result = {

@ -21,7 +21,7 @@ module.exports = function (Categories) {
data.name = String(data.name || `Category ${cid}`);
const slug = `${cid}/${slugify(data.name)}`;
const smallestOrder = firstChild.length ? firstChild[0].score - 1 : 1;
const order = data.order || smallestOrder; // If no order provided, place it at the top
const order = data.order || smallestOrder; // If no order provided, place it at the top
const colours = Categories.assignColours();
let category = {

@ -392,7 +392,7 @@ Categories.buildForSelectCategories = function (categories, fields, parentCid) {
rootCategories.forEach(category => recursive(category, categoriesData, '', 0));
const pickFields = [
'cid', 'name', 'level', 'icon', 'parentCid',
'cid', 'name', 'level', 'icon', 'parentCid',
'color', 'bgColor', 'backgroundImage', 'imageClass',
];
fields = fields || [];

@ -153,7 +153,7 @@ module.exports = function (Categories) {
function getPostsRecursive(category, posts) {
if (Array.isArray(category.posts)) {
category.posts.forEach(p => posts.push(p));
category.posts.forEach(p => posts.push(p));
}
category.children.forEach(child => getPostsRecursive(child, posts));

@ -100,7 +100,7 @@ nconf.argv(opts).env({
prestart.setupWinston();
// Alternate configuration file support
const configFile = path.resolve(paths.baseDir, nconf.get('config') || 'config.json');
const configFile = path.resolve(paths.baseDir, nconf.get('config') || 'config.json');
const configExists = file.existsSync(configFile) || (nconf.get('url') && nconf.get('secret') && nconf.get('database'));
prestart.loadConfig(configFile);

@ -97,7 +97,7 @@ async function checkPlugins() {
const toCheck = Object.keys(plugins);
if (!toCheck.length) {
process.stdout.write(' OK'.green + ''.reset);
return []; // no extraneous plugins installed
return []; // no extraneous plugins installed
}
const suggestedModules = await getSuggestedModules(nbbVersion, toCheck);
process.stdout.write(' OK'.green + ''.reset);

@ -78,7 +78,7 @@ helpers.getUserDataByUserSlug = async function (userslug, callerUID, query = {})
userData.isSelf = isSelf;
userData.isFollowing = results.isFollowing;
userData.hasPrivateChat = results.hasPrivateChat;
userData.showHidden = results.canEdit; // remove in v1.19.0
userData.showHidden = results.canEdit; // remove in v1.19.0
userData.groups = Array.isArray(results.groups) && results.groups.length ? results.groups[0] : [];
userData.disableSignatures = meta.config.disableSignatures === 1;
userData['reputation:disabled'] = meta.config['reputation:disabled'] === 1;

@ -60,17 +60,17 @@ settingsController.get = async function (req, res, next) {
userData.bootswatchSkinOptions = [
{ name: 'Default', value: '' },
{ name: 'Cerulean', value: 'cerulean' },
{ name: 'Cosmo', value: 'cosmo' },
{ name: 'Cosmo', value: 'cosmo' },
{ name: 'Cyborg', value: 'cyborg' },
{ name: 'Darkly', value: 'darkly' },
{ name: 'Flatly', value: 'flatly' },
{ name: 'Journal', value: 'journal' },
{ name: 'Journal', value: 'journal' },
{ name: 'Lumen', value: 'lumen' },
{ name: 'Paper', value: 'paper' },
{ name: 'Readable', value: 'readable' },
{ name: 'Sandstone', value: 'sandstone' },
{ name: 'Simplex', value: 'simplex' },
{ name: 'Slate', value: 'slate' },
{ name: 'Slate', value: 'slate' },
{ name: 'Spacelab', value: 'spacelab' },
{ name: 'Superhero', value: 'superhero' },
{ name: 'United', value: 'united' },

@ -188,7 +188,7 @@ async function getStatsFromAnalytics(set, field) {
today: data.slice(-1)[0],
lastweek: sum(data.slice(-14)),
thisweek: sum(data.slice(-7)),
lastmonth: sum(data.slice(0)), // entire set
lastmonth: sum(data.slice(0)), // entire set
thismonth: sum(data.slice(-30)),
alltime: await getGlobalField(field),
};

@ -15,8 +15,8 @@ eventsController.get = async function (req, res) {
// Limit by date
let from = req.query.start ? new Date(req.query.start) || undefined : undefined;
let to = req.query.end ? new Date(req.query.end) || undefined : new Date();
from = from && from.setHours(0, 0, 0, 0); // setHours returns a unix timestamp (Number, not Date)
to = to && to.setHours(23, 59, 59, 999); // setHours returns a unix timestamp (Number, not Date)
from = from && from.setHours(0, 0, 0, 0); // setHours returns a unix timestamp (Number, not Date)
to = to && to.setHours(23, 59, 59, 999); // setHours returns a unix timestamp (Number, not Date)
const currentFilter = req.query.type || '';

@ -21,7 +21,7 @@ privilegesController.get = async function (req, res) {
name: '[[admin/manage/privileges:global]]',
icon: 'fa-list',
}, {
cid: 'admin', // what do?
cid: 'admin',
name: '[[admin/manage/privileges:admin]]',
icon: 'fa-lock',
}];

@ -106,7 +106,7 @@ authenticationController.register = async function (req, res) {
user.isPasswordValid(userData.password);
res.locals.processLogin = true; // set it to false in plugin if you wish to just register only
res.locals.processLogin = true; // set it to false in plugin if you wish to just register only
await plugins.hooks.fire('filter:register.check', { req: req, res: res, userData: userData });
const data = await registerAndLoginUser(req, res, userData);
@ -151,7 +151,7 @@ authenticationController.registerComplete = async function (req, res) {
req.body.files = req.files;
if (
(cur.callback.constructor && cur.callback.constructor.name === 'AsyncFunction') ||
cur.callback.length === 2 // non-async function w/o callback
cur.callback.length === 2 // non-async function w/o callback
) {
memo.push(cur.callback);
} else {
@ -187,7 +187,7 @@ authenticationController.registerComplete = async function (req, res) {
if (req.session.registration.register === true) {
res.locals.processLogin = true;
req.body.noscript = 'true'; // trigger full page load on error
req.body.noscript = 'true'; // trigger full page load on error
const data = await registerAndLoginUser(req, res, req.session.registration);
if (!data) {
@ -388,7 +388,9 @@ authenticationController.onSuccessfulLogin = async function (req, uid) {
version: req.useragent.version,
});
await Promise.all([
new Promise(resolve => req.session.save(resolve)),
new Promise((resolve) => {
req.session.save(resolve);
}),
user.auth.addSession(uid, req.sessionID),
user.updateLastOnlineTime(uid),
user.updateOnlineUsers(uid),

@ -114,7 +114,7 @@ modsController.flags.detail = async function (req, res, next) {
results.privileges = { ...results.privileges[0], ...results.privileges[1] };
if (!results.flagData || (!(results.isAdminOrGlobalMod || !!results.moderatedCids.length))) {
return next(); // 404
return next(); // 404
}
if (results.flagData.type === 'user') {

@ -50,7 +50,7 @@ Topics.pin = async (req, res) => {
if (req.body.expiry) {
await topics.tools.setPinExpiry(req.params.tid, req.body.expiry, req.uid);
}
await api.topics.pin(req, { tids: [req.params.tid] });
await api.topics.pin(req, { tids: [req.params.tid] });
helpers.formatApiResponse(200, res);
};
@ -107,7 +107,7 @@ Topics.deleteTags = async (req, res) => {
};
Topics.getThumbs = async (req, res) => {
if (isFinite(req.params.tid)) { // post_uuids can be passed in occasionally, in that case no checks are necessary
if (isFinite(req.params.tid)) { // post_uuids can be passed in occasionally, in that case no checks are necessary
const [exists, canRead] = await Promise.all([
topics.exists(req.params.tid),
privileges.topics.can('topics:read', req.params.tid, req.uid),
@ -126,7 +126,7 @@ Topics.addThumb = async (req, res) => {
return;
}
const files = await uploadsController.uploadThumb(req, res); // response is handled here
const files = await uploadsController.uploadThumb(req, res); // response is handled here
// Add uploaded files to topic zset
if (files && files.length) {

@ -58,7 +58,7 @@ module.exports = function (module) {
if (params.withScores) {
project.score = '$totalScore';
}
pipeline.push({ $project: project });
pipeline.push({ $project: project });
let data = await module.client.collection('objects').aggregate(pipeline).toArray();
if (!params.withScores) {

@ -28,7 +28,7 @@ module.exports = function (module) {
});
return key.map(k => res.rows.some(r => r.k === k));
}
const res = await module.pool.query({
const res = await module.pool.query({
name: 'exists',
text: `
SELECT EXISTS(SELECT *

@ -64,8 +64,8 @@ Flags.init = async function () {
cid: function (sets, orSets, key) {
prepareSets(sets, orSets, 'flags:byCid:', key);
},
page: function () { /* noop */ },
perPage: function () { /* noop */ },
page: function () { /* noop */ },
perPage: function () { /* noop */ },
quick: function (sets, orSets, key, uid) {
switch (key) {
case 'mine':
@ -141,7 +141,7 @@ Flags.getFlagIdsWithFilters = async function ({ filters, uid, query }) {
winston.warn(`[flags/list] No flag filter type found: ${type}`);
}
}
sets = (sets.length || orSets.length) ? sets : ['flags:datetime']; // No filter default
sets = (sets.length || orSets.length) ? sets : ['flags:datetime']; // No filter default
let flagIds = [];
if (sets.length === 1) {
@ -244,7 +244,7 @@ Flags.sort = async function (flagIds, sort) {
break;
}
case 'upvotes': // fall-through
case 'upvotes': // fall-through
case 'downvotes':
case 'replies': {
flagIds = await filterPosts(flagIds);
@ -426,8 +426,8 @@ Flags.create = async function (type, id, uid, reason, timestamp) {
}),
Flags.addReport(flagId, type, id, uid, reason, timestamp),
db.sortedSetAdd('flags:datetime', timestamp, flagId), // by time, the default
db.sortedSetAdd(`flags:byType:${type}`, timestamp, flagId), // by flag type
db.sortedSetIncrBy('flags:byTarget', 1, [type, id].join(':')), // by flag target (score is count)
db.sortedSetAdd(`flags:byType:${type}`, timestamp, flagId), // by flag type
db.sortedSetIncrBy('flags:byTarget', 1, [type, id].join(':')), // by flag target (score is count)
analytics.increment('flags') // some fancy analytics
);
@ -441,7 +441,7 @@ Flags.create = async function (type, id, uid, reason, timestamp) {
if (type === 'post') {
batched.push(
db.sortedSetAdd(`flags:byPid:${id}`, timestamp, flagId), // by target pid
db.sortedSetAdd(`flags:byPid:${id}`, timestamp, flagId), // by target pid
posts.setPostField(id, 'flagId', flagId)
);

@ -45,7 +45,7 @@ module.exports = function (Groups) {
groupNames = [groupNames];
}
const sets = [];
groupNames.forEach(groupName => sets.push(`group:${groupName}:pending`, `group:${groupName}:invited`));
groupNames.forEach(groupName => sets.push(`group:${groupName}:pending`, `group:${groupName}:invited`));
await db.setsRemove(sets, uid);
};

@ -42,7 +42,7 @@ module.exports = function (Groups) {
groups.sort((a, b) => b.createtime - a.createtime);
break;
case 'alpha': // intentional fall-through
case 'alpha': // intentional fall-through
default:
groups.sort((a, b) => (a.slug > b.slug ? 1 : -1));
}

@ -7,7 +7,7 @@ const plugins = require('../plugins');
const meta = require('../meta');
module.exports = function (Messaging) {
Messaging.notifyQueue = {}; // Only used to notify a user of a new chat message, see Messaging.notifyUser
Messaging.notifyQueue = {}; // Only used to notify a user of a new chat message, see Messaging.notifyUser
Messaging.notifyUsersInRoom = async (fromUid, roomId, messageObj) => {
let uids = await Messaging.getUidsInRoom(roomId, 0, -1);

@ -45,8 +45,8 @@ Blacklist.get = async function () {
Blacklist.test = async function (clientIp) {
// Some handy test addresses
// clientIp = '2001:db8:85a3:0:0:8a2e:370:7334'; // IPv6
// clientIp = '127.0.15.1'; // IPv4
// clientIp = '2001:db8:85a3:0:0:8a2e:370:7334'; // IPv6
// clientIp = '127.0.15.1'; // IPv4
// clientIp = '127.0.15.1:3443'; // IPv4 with port strip port to not fail
if (!clientIp) {
return;
@ -62,15 +62,15 @@ Blacklist.test = async function (clientIp) {
}
if (
!Blacklist._rules.ipv4.includes(clientIp) && // not explicitly specified in ipv4 list
!Blacklist._rules.ipv6.includes(clientIp) && // not explicitly specified in ipv6 list
!Blacklist._rules.ipv4.includes(clientIp) && // not explicitly specified in ipv4 list
!Blacklist._rules.ipv6.includes(clientIp) && // not explicitly specified in ipv6 list
!Blacklist._rules.cidr.some((subnet) => {
const cidr = ipaddr.parseCIDR(subnet);
if (addr.kind() !== cidr[0].kind()) {
return false;
}
return addr.match(cidr);
}) // not in a blacklisted IPv4 or IPv6 cidr range
}) // not in a blacklisted IPv4 or IPv6 cidr range
) {
try {
// To return test failure, pass back an error in callback

@ -37,7 +37,7 @@ Errors.log404 = function (route) {
if (!route) {
return;
}
route = route.slice(0, 512).replace(/\/$/, ''); // remove trailing slashes
route = route.slice(0, 512).replace(/\/$/, ''); // remove trailing slashes
analytics.increment('errors:404');
counters[route] = counters[route] || 0;
counters[route] += 1;

@ -94,7 +94,7 @@ Settings.set = async function (hash, values, quiet) {
plugins.hooks.fire('action:settings.set', {
plugin: hash,
settings: { ...values, ...sortedListData }, // Add back sorted list data to values hash
settings: { ...values, ...sortedListData }, // Add back sorted list data to values hash
});
pubsub.publish(`action:settings.set.${hash}`, values);

@ -73,7 +73,7 @@ module.exports = function (middleware) {
await plugins.hooks.fire('response:middleware.authenticate', {
req: req,
res: res,
next: function () {}, // no-op for backwards compatibility
next: function () {}, // no-op for backwards compatibility
});
if (!res.headersSent) {

@ -371,7 +371,7 @@ Notifications.merge = async function (notifications) {
notifications = mergeIds.reduce((notifications, mergeId) => {
const isolated = notifications.filter(n => n && n.hasOwnProperty('mergeId') && n.mergeId.split('|')[0] === mergeId);
if (isolated.length <= 1) {
return notifications; // Nothing to merge
return notifications; // Nothing to merge
}
// Each isolated mergeId may have multiple differentiators, so process each separately

@ -8,8 +8,8 @@ const utils = require('../utils');
const Hooks = module.exports;
Hooks.deprecatedHooks = {
'filter:email.send': 'static:email.send', // 👋 @ 1.19.0
'filter:router.page': 'response:router.page', // 👋 @ 2.0.0
'filter:email.send': 'static:email.send', // 👋 @ 1.19.0
'filter:router.page': 'response:router.page', // 👋 @ 2.0.0
};
Hooks.internals = {

@ -19,7 +19,7 @@ const socketHelpers = require('../socket.io/helpers');
module.exports = function (Posts) {
Posts.getQueuedPosts = async (filter = {}, options = {}) => {
options = { metadata: true, ...options }; // defaults
options = { metadata: true, ...options }; // defaults
let postData = _.cloneDeep(cache.get('post-queue'));
if (!postData) {
const ids = await db.getSortedSetRange('post:queue', 0, -1);

@ -206,7 +206,7 @@ module.exports = function (Posts) {
let current = voteStatus.upvoted ? 'upvote' : 'downvote';
if (unvote) { // e.g. unvoting, removing a upvote or downvote
hook = 'unvote';
} else { // e.g. User *has not* voted, clicks upvote or downvote
} else { // e.g. User *has not* voted, clicks upvote or downvote
current = 'unvote';
}
// action:post.upvote

@ -137,9 +137,7 @@ Auth.reloadRoutes = async function (params) {
res.locals.strategy = strategy;
next();
})(req, res, next);
},
Auth.middleware.validateAuth,
(req, res, next) => {
}, Auth.middleware.validateAuth, (req, res, next) => {
async.waterfall([
async.apply(req.login.bind(req), res.locals.user),
async.apply(controllers.authentication.onSuccessfulLogin, req, req.uid),

@ -203,7 +203,7 @@ function addRemountableRoutes(app, router, middleware, mounts) {
const original = mount;
mount = mounts[original];
if (!mount) { // do not mount at all
if (!mount) { // do not mount at all
winston.warn(`[router] Not mounting /${original}`);
return;
}

@ -11,9 +11,9 @@ module.exports = function () {
const middlewares = [middleware.ensureLoggedIn, middleware.admin.checkPrivileges];
// setupApiRoute(router, 'put', '/', [
// ...middlewares,
// middleware.checkRequired.bind(null, ['path']),
// middleware.assert.folder
// ...middlewares,
// middleware.checkRequired.bind(null, ['path']),
// middleware.assert.folder
// ], controllers.write.files.upload);
setupApiRoute(router, 'delete', '/', [
...middlewares,

@ -11,7 +11,7 @@ module.exports = function () {
const middlewares = [middleware.ensureLoggedIn];
setupApiRoute(router, 'post', '/', [...middlewares], controllers.write.flags.create);
// setupApiRoute(router, 'delete', ...); // does not exist
// setupApiRoute(router, 'delete', ...); // does not exist
setupApiRoute(router, 'get', '/:flagId', [...middlewares, middleware.assert.flag], controllers.write.flags.get);
setupApiRoute(router, 'put', '/:flagId', [...middlewares, middleware.assert.flag], controllers.write.flags.update);

@ -30,7 +30,7 @@ module.exports = function () {
setupApiRoute(router, 'put', '/:tid/follow', [...middlewares, middleware.assert.topic], controllers.write.topics.follow);
setupApiRoute(router, 'delete', '/:tid/follow', [...middlewares, middleware.assert.topic], controllers.write.topics.unfollow);
setupApiRoute(router, 'put', '/:tid/ignore', [...middlewares, middleware.assert.topic], controllers.write.topics.ignore);
setupApiRoute(router, 'delete', '/:tid/ignore', [...middlewares, middleware.assert.topic], controllers.write.topics.unfollow); // intentional, unignore == unfollow
setupApiRoute(router, 'delete', '/:tid/ignore', [...middlewares, middleware.assert.topic], controllers.write.topics.unfollow); // intentional, unignore == unfollow
setupApiRoute(router, 'put', '/:tid/tags', [...middlewares, middleware.checkRequired.bind(null, ['tags']), middleware.assert.topic], controllers.write.topics.addTags);
setupApiRoute(router, 'delete', '/:tid/tags', [...middlewares, middleware.assert.topic], controllers.write.topics.deleteTags);

@ -15,7 +15,7 @@ SocketFlags.create = async function (socket, data) {
SocketFlags.update = async function (socket, data) {
sockets.warnDeprecated(socket, 'PUT /api/v3/flags/:flagId');
if (!data || !(data.flagId && data.data)) { // check only req'd in socket.io
if (!data || !(data.flagId && data.data)) { // check only req'd in socket.io
throw new Error('[[error:invalid-data]]');
}

@ -28,7 +28,7 @@ module.exports = function (SocketPosts) {
canDelete: privileges.posts.canDelete(data.pid, socket.uid),
canPurge: privileges.posts.canPurge(data.pid, socket.uid),
canFlag: privileges.posts.canFlag(data.pid, socket.uid),
flagged: flags.exists('post', data.pid, socket.uid), // specifically, whether THIS calling user flagged
flagged: flags.exists('post', data.pid, socket.uid), // specifically, whether THIS calling user flagged
bookmarked: posts.hasBookmarked(data.pid, socket.uid),
postSharing: social.getActivePostSharing(),
history: posts.diffs.exists(data.pid),

@ -84,8 +84,8 @@ module.exports = function (Topics) {
};
async function getTids(params) {
const counts = { '': 0, new: 0, watched: 0, unreplied: 0 };
const tidsByFilter = { '': [], new: [], watched: [], unreplied: [] };
const counts = { '': 0, new: 0, watched: 0, unreplied: 0 };
const tidsByFilter = { '': [], new: [], watched: [], unreplied: [] };
if (params.uid <= 0) {
return { counts: counts, tids: [], tidsByFilter: tidsByFilter };

@ -8,9 +8,9 @@ module.exports = {
timestamp: Date.UTC(2017, 8, 6),
method: async function () {
const matches = [
'112e541b40023d6530dd44df4b0d9c5d', // digest @ 75917e25b3b5ad7bed8ed0c36433fb35c9ab33eb
'110b8805f70395b0282fd10555059e9f', // digest @ 9b02bb8f51f0e47c6e335578f776ffc17bc03537
'9538e7249edb369b2a25b03f2bd3282b', // digest @ 3314ab4b83138c7ae579ac1f1f463098b8c2d414
'112e541b40023d6530dd44df4b0d9c5d', // digest @ 75917e25b3b5ad7bed8ed0c36433fb35c9ab33eb
'110b8805f70395b0282fd10555059e9f', // digest @ 9b02bb8f51f0e47c6e335578f776ffc17bc03537
'9538e7249edb369b2a25b03f2bd3282b', // digest @ 3314ab4b83138c7ae579ac1f1f463098b8c2d414
];
const fieldset = await meta.configs.getFields(['email:custom:digest']);
const hash = fieldset['email:custom:digest'] ? crypto.createHash('md5').update(fieldset['email:custom:digest']).digest('hex') : null;

@ -95,7 +95,7 @@ module.exports = function (User) {
const sid = uuidMapping[uuid];
const sessionObj = await getSessionFromStore(sid);
const expired = !sessionObj || !sessionObj.hasOwnProperty('passport') ||
!sessionObj.passport.hasOwnProperty('user') ||
!sessionObj.passport.hasOwnProperty('user') ||
parseInt(sessionObj.passport.user, 10) !== parseInt(uid, 10);
if (expired) {
expiredUUIDs.push(uuid);

@ -65,9 +65,9 @@ UserEmail.expireValidation = async (uid) => {
UserEmail.sendValidationEmail = async function (uid, options) {
/*
* Options:
* - email, overrides email retrieval
* - force, sends email even if it is too soon to send another
* Options:
* - email, overrides email retrieval
* - force, sends email even if it is too soon to send another
*/
if (meta.config.sendValidationEmail !== 1) {

@ -230,9 +230,9 @@ User.addInterstitials = function (callback) {
plugins.hooks.register('core', {
hook: 'filter:register.interstitial',
method: [
User.interstitials.email, // Email address (for password reset + digest)
User.interstitials.gdpr, // GDPR information collection/processing consent + email consent
User.interstitials.tou, // Forum Terms of Use
User.interstitials.email, // Email address (for password reset + digest)
User.interstitials.gdpr, // GDPR information collection/processing consent + email consent
User.interstitials.tou, // Forum Terms of Use
],
});

@ -36,7 +36,7 @@ Interstitials.email = async (data) => {
uid: userData.uid,
email: formData.email,
registration: false,
allowed: true, // change this value to disallow
allowed: true, // change this value to disallow
error: '[[error:invalid-email]]',
}),
]);
@ -79,7 +79,7 @@ Interstitials.email = async (data) => {
uid: null,
email: formData.email,
registration: true,
allowed: true, // change this value to disallow
allowed: true, // change this value to disallow
error: '[[error:invalid-email]]',
});

@ -91,7 +91,7 @@ UserReset.commit = async function (code, password) {
// don't verify email if password reset is due to expiry
const isPasswordExpired = userData.passwordExpiry && userData.passwordExpiry < Date.now();
if (!isPasswordExpired) {
data['email:confirmed'] = 1;
data['email:confirmed'] = 1;
await groups.join('verified-users', uid);
await groups.leave('unverified-users', uid);
}

@ -168,7 +168,7 @@ function setupExpressApp(app) {
app.use((req, res, next) => {
als.run({ uid: req.uid }, next);
});
app.use(middleware.autoLocale); // must be added after auth middlewares are added
app.use(middleware.autoLocale); // must be added after auth middlewares are added
const toobusy = require('toobusy-js');
toobusy.maxLag(meta.config.eventLoopLagThreshold);

@ -33,7 +33,7 @@ describe('API', async () => {
let jar;
let csrfToken;
let setup = false;
const unauthenticatedRoutes = ['/api/login', '/api/register']; // Everything else will be called with the admin user
const unauthenticatedRoutes = ['/api/login', '/api/register']; // Everything else will be called with the admin user
const mocks = {
head: {},
@ -73,19 +73,19 @@ describe('API', async () => {
{
in: 'path',
name: 'uuid',
example: '', // to be defined below...
example: '', // to be defined below...
},
],
'/posts/{pid}/diffs/{timestamp}': [
{
in: 'path',
name: 'pid',
example: '', // to be defined below...
example: '', // to be defined below...
},
{
in: 'path',
name: 'timestamp',
example: '', // to be defined below...
example: '', // to be defined below...
},
],
},
@ -116,7 +116,7 @@ describe('API', async () => {
for (let x = 0; x < 4; x++) {
// eslint-disable-next-line no-await-in-loop
await user.create({ username: 'deleteme', password: '123456' }); // for testing of DELETE /users (uids 5, 6) and DELETE /user/:uid/account (uid 7)
await user.create({ username: 'deleteme', password: '123456' }); // for testing of DELETE /users (uids 5, 6) and DELETE /user/:uid/account (uid 7)
}
await groups.join('administrators', adminUid);
@ -299,7 +299,7 @@ describe('API', async () => {
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
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) => {
const context = api.paths[path];
let schema;
@ -393,9 +393,9 @@ describe('API', async () => {
method: method,
jar: !unauthenticatedRoutes.includes(path) ? jar : undefined,
json: true,
followRedirect: false, // all responses are significant (e.g. 302)
simple: false, // don't throw on non-200 (e.g. 302)
resolveWithFullResponse: true, // send full request back (to check statusCode)
followRedirect: false, // all responses are significant (e.g. 302)
simple: false, // don't throw on non-200 (e.g. 302)
resolveWithFullResponse: true, // send full request back (to check statusCode)
headers: headers,
qs: qs,
body: body,
@ -572,7 +572,7 @@ describe('API', async () => {
// Compare the response to the schema
Object.keys(response).forEach((prop) => {
if (additionalProperties) { // All bets are off
if (additionalProperties) { // All bets are off
return;
}

@ -60,7 +60,7 @@ describe('Groups', () => {
// Also create a hidden group
await Groups.join('Hidden', 'Test');
// create another group that starts with test for search/sort
await Groups.create({ name: 'Test2', description: 'Foobar!' });
await Groups.create({ name: 'Test2', description: 'Foobar!' });
testUid = await User.create({
username: 'testuser',

@ -19,7 +19,7 @@ describe('i18n', () => {
});
it('should contain folders named after the language code', async () => {
const valid = /(?:README.md|^[a-z]{2}(?:-[A-Z]{2})?$|^[a-z]{2}(?:-x-[a-z]+)?$)/; // good luck
const valid = /(?:README.md|^[a-z]{2}(?:-[A-Z]{2})?$|^[a-z]{2}(?:-x-[a-z]+)?$)/; // good luck
folders.forEach((folder) => {
assert(valid.test(folder));

@ -17,17 +17,17 @@ const helpers = require('./helpers');
const socketModules = require('../src/socket.io/modules');
describe('Messaging Library', () => {
let fooUid; // the admin
let bazUid; // the user with chat restriction enabled
let fooUid; // the admin
let bazUid; // the user with chat restriction enabled
let herpUid;
let roomId;
before((done) => {
// Create 3 users: 1 admin, 2 regular
async.series([
async.apply(User.create, { username: 'foo', password: 'barbar' }), // admin
async.apply(User.create, { username: 'baz', password: 'quuxquux' }), // restricted user
async.apply(User.create, { username: 'herp', password: 'derpderp' }), // regular user
async.apply(User.create, { username: 'foo', password: 'barbar' }), // admin
async.apply(User.create, { username: 'baz', password: 'quuxquux' }), // restricted user
async.apply(User.create, { username: 'herp', password: 'derpderp' }), // regular user
], (err, uids) => {
if (err) {
return done(err);

@ -19,9 +19,9 @@ describe('meta', () => {
Groups.cache.reset();
// Create 3 users: 1 admin, 2 regular
async.series([
async.apply(User.create, { username: 'foo', password: 'barbar' }), // admin
async.apply(User.create, { username: 'baz', password: 'quuxquux' }), // restricted user
async.apply(User.create, { username: 'herp', password: 'derpderp' }), // regular user
async.apply(User.create, { username: 'foo', password: 'barbar' }), // admin
async.apply(User.create, { username: 'baz', password: 'quuxquux' }), // restricted user
async.apply(User.create, { username: 'herp', password: 'derpderp' }), // regular user
], (err, uids) => {
if (err) {
return done(err);

@ -1514,7 +1514,7 @@ describe('Post\'s', () => {
const events = await topics.events.get(tid1, 1);
assert(events);
assert.strictEqual(events.length, 1); // should still equal 1
assert.strictEqual(events.length, 1); // should still equal 1
});
it('should not show backlink events if the feature is disabled', async () => {

@ -716,7 +716,7 @@ describe('socket.io', () => {
event: async.apply(events.getEvents, '', 0, 0),
}, (err, data) => {
assert.ifError(err);
assert.strictEqual(data.count, 1); // should still equal 1
assert.strictEqual(data.count, 1); // should still equal 1
// Event validity
assert.strictEqual(data.event.length, 1);

@ -175,7 +175,7 @@ describe('Topic thumbs', () => {
const score = await db.sortedSetScore(`topic:${tid}:thumbs`, relativeThumbPaths[0]);
assert(isFinite(score)); // exists in set
assert(isFinite(score)); // exists in set
assert.strictEqual(score, 2);
});
@ -188,7 +188,7 @@ describe('Topic thumbs', () => {
const score = await db.sortedSetScore(`topic:${tid}:thumbs`, relativeThumbPaths[0]);
assert(isFinite(score)); // exists in set
assert(isFinite(score)); // exists in set
assert.strictEqual(score, 0);
});

@ -243,54 +243,6 @@ 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();
// }
// );
// });
// 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();
// }
// );
// });
// 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();
// }
// );
// });
it('should not allow non image uploads', (done) => {
socketUser.updateCover({ uid: 1 }, { uid: 1, file: { path: '../../text.txt' } }, (err) => {
assert.equal(err.message, '[[error:invalid-data]]');

@ -869,7 +869,7 @@ describe('User', () => {
assert.ifError(err);
Object.keys(data).forEach((key) => {
if (key === 'email') {
assert.strictEqual(userData.email, 'just@for.updated'); // email remains the same until confirmed
assert.strictEqual(userData.email, 'just@for.updated'); // email remains the same until confirmed
} else if (key !== 'password') {
assert.equal(data[key], userData[key]);
} else {
@ -1500,9 +1500,9 @@ describe('User', () => {
function (next) {
User.digest.getSubscribers('day', (err, subs) => {
assert.ifError(err);
assert.strictEqual(subs.includes(uidIndex.daysub.toString()), true); // daysub does get emailed
assert.strictEqual(subs.includes(uidIndex.weeksub.toString()), false); // weeksub does not get emailed
assert.strictEqual(subs.includes(uidIndex.offsub.toString()), false); // offsub doesn't get emailed
assert.strictEqual(subs.includes(uidIndex.daysub.toString()), true); // daysub does get emailed
assert.strictEqual(subs.includes(uidIndex.weeksub.toString()), false); // weeksub does not get emailed
assert.strictEqual(subs.includes(uidIndex.offsub.toString()), false); // offsub doesn't get emailed
next();
});
@ -1516,9 +1516,9 @@ describe('User', () => {
function (next) {
User.digest.getSubscribers('week', (err, subs) => {
assert.ifError(err);
assert.strictEqual(subs.includes(uidIndex.weeksub.toString()), true); // weeksub gets emailed
assert.strictEqual(subs.includes(uidIndex.daysub.toString()), false); // daysub gets emailed
assert.strictEqual(subs.includes(uidIndex.offsub.toString()), false); // offsub does not get emailed
assert.strictEqual(subs.includes(uidIndex.weeksub.toString()), true); // weeksub gets emailed
assert.strictEqual(subs.includes(uidIndex.daysub.toString()), false); // daysub gets emailed
assert.strictEqual(subs.includes(uidIndex.offsub.toString()), false); // offsub does not get emailed
next();
});

@ -259,6 +259,7 @@ describe('Utility Methods', () => {
});
it('should return passed in value if invalid', (done) => {
// eslint-disable-next-line no-loss-of-precision
const bigInt = -111111111111111111;
const result = utils.toISOString(bigInt);
assert.equal(bigInt, result);

Loading…
Cancel
Save