mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-01-11 10:03:44 +01:00
refactor: tab rules
This commit is contained in:
@@ -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 *
|
||||
|
||||
14
src/flags.js
14
src/flags.js
@@ -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);
|
||||
|
||||
20
test/api.js
20
test/api.js
@@ -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]]');
|
||||
|
||||
14
test/user.js
14
test/user.js
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user