Add i18n to bumplock/lock/sticky/cycle, change board/globalsettings, changepassword, and create board pages

Update a bunch of middleware, pages  and libs to destructure i18n funcs if used more than once to not repeat res.locals
ref #396 (going to try and remember this from now on)
indiachan-spamvector
Thomas Lynch 1 year ago
parent 8a59a569e1
commit 46358a3503
  1. 13
      lib/middleware/captcha/blockbypass.js
  2. 5
      lib/middleware/captcha/verify.js
  3. 17
      lib/middleware/file/filemiddlewares.js
  4. 9
      lib/middleware/input/paramconverter.js
  5. 5
      lib/middleware/ip/dnsbl.js
  6. 5
      lib/middleware/ip/processip.js
  7. 5
      lib/middleware/misc/referrercheck.js
  8. 15
      lib/middleware/permission/haspermsmiddleware.js
  9. 9
      lib/post/filteractions.js
  10. 8
      models/forms/actionhandler.js
  11. 8
      models/forms/bumplockposts.js
  12. 5
      models/forms/changeboardsettings.js
  13. 5
      models/forms/changeglobalsettings.js
  14. 17
      models/forms/changepassword.js
  15. 9
      models/forms/create.js
  16. 8
      models/forms/cycleposts.js
  17. 8
      models/forms/lockposts.js
  18. 8
      models/forms/stickyposts.js
  19. 5
      models/pages/twofactor.js

@ -12,6 +12,7 @@ module.exports = {
check: async (req, res, next) => {
const { __ } = res.locals;
const { secureCookies, blockBypass } = config.get;
//bypass captcha permission
@ -25,12 +26,12 @@ module.exports = {
if (!res.locals.solvedCaptcha && (!bypassId || bypassId.length !== 24)) {
deleteTempFiles(req).catch(console.error);
return dynamicResponse(req, res, 403, 'message', {
'title': res.locals.__('Forbidden'),
'message': res.locals.__('Please complete a block bypass to continue'),
'title': __('Forbidden'),
'message': __('Please complete a block bypass to continue'),
'frame': '/bypass_minimal.html',
'link': {
'href': '/bypass.html',
'text': res.locals.__('Get block bypass'),
'text': __('Get block bypass'),
},
});
}
@ -69,12 +70,12 @@ module.exports = {
deleteTempFiles(req).catch(console.error);
res.clearCookie('bypassid');
return dynamicResponse(req, res, 403, 'message', {
'title': res.locals.__('Forbidden'),
'message': res.locals.__('Block bypass expired or exceeded max uses'),
'title': __('Forbidden'),
'message': __('Block bypass expired or exceeded max uses'),
'frame': '/bypass_minimal.html',
'link': {
'href': '/bypass.html',
'text': res.locals.__('Get block bypass'),
'text': __('Get block bypass'),
},
});

@ -37,9 +37,10 @@ module.exports = async (req, res, next) => {
return next(err);
}
const page = (req.body.minimal || req.path === '/blockbypass' ? 'bypass' : 'message');
const { __ } = res.locals;
return dynamicResponse(req, res, 403, page, {
'title': res.locals.__('Forbidden'),
'message': res.locals.__(err),
'title': __('Forbidden'),
'message': __(err),
'redirect': req.headers.referer,
});
}

@ -6,16 +6,18 @@ const { debugLogs } = require(__dirname+'/../../../configs/secrets.js')
, upload = require('@fatchan/express-fileupload')
, fileHandlers = {}
, fileSizeLimitFunction = (req, res) => {
const { __ } = res.locals;
return dynamicResponse(req, res, 413, 'message', {
'title': res.locals.__('Payload Too Large'),
'message': res.locals.__('Your upload was too large'),
'title': __('Payload Too Large'),
'message': __('Your upload was too large'),
'redirect': req.headers.referer
});
}
, missingExtensionLimitFunction = (req, res) => {
const { __ } = res.locals;
return dynamicResponse(req, res, 400, 'message', {
'title': res.locals.__('Bad Request'),
'message': res.locals.__('Missing file extensions'),
'title': __('Bad Request'),
'message': __('Missing file extensions'),
'redirect': req.headers.referer
});
}
@ -25,12 +27,13 @@ const { debugLogs } = require(__dirname+'/../../../configs/secrets.js')
const fileSizeLimit = globalLimits[`${fileType}FilesSize`];
const fileNumLimit = globalLimits[`${fileType}Files`];
const fileNumLimitFunction = (req, res) => {
const { __ } = res.locals;
const isPostform = req.path.endsWith('/post') || req.path.endsWith('/modpost');
const message = (isPostform && res.locals.board)
? res.locals.__(`Max files per post ${res.locals.board.settings.maxFiles < globalLimits.postFiles.max ? 'on this board ' : ''}is %s`, res.locals.board.settings.maxFiles)
: res.locals.__('Max files per request is %s', fileNumLimit.max);
? __(`Max files per post ${res.locals.board.settings.maxFiles < globalLimits.postFiles.max ? 'on this board ' : ''}is %s`, res.locals.board.settings.maxFiles)
: __('Max files per request is %s', fileNumLimit.max);
return dynamicResponse(req, res, 400, 'message', {
'title': res.locals.__('Too many files'),
'title': __('Too many files'),
'message': message,
'redirect': req.headers.referer
});

@ -27,6 +27,7 @@ module.exports = (options) => {
return (req, res, next) => {
const { __ } = res.locals;
const { timeFields, trimFields, allowedArrays, processThreadIdParam,
processDateParam, processMessageLength, numberFields, numberArrays,
objectIdParams, objectIdFields, objectIdArrays } = options;
@ -39,8 +40,8 @@ module.exports = (options) => {
const val = req.body[key];
if (!allowedArrays.includes(key) && Array.isArray(val)) {
return dynamicResponse(req, res, 400, 'message', {
'title': res.locals.__('Bad request'),
'message': res.locals.__('Malformed input'),
'title': __('Bad request'),
'message': __('Malformed input'),
});
} else if (allowedArrays.includes(key) && !Array.isArray(val)) {
req.body[key] = makeArrayIfSingle(req.body[key]); //convert to arrays with single item for simpler case batch handling later
@ -134,8 +135,8 @@ module.exports = (options) => {
}
} catch (e) {
return dynamicResponse(req, res, 400, 'message', {
'title': res.locals.__('Bad request'),
'message': res.locals.__('Malformed input'),
'title': __('Bad request'),
'message': __('Malformed input'),
});
}

@ -29,9 +29,10 @@ module.exports = async (req, res, next) => {
}
//otherwise dnsbl cant be bypassed
deleteTempFiles(req).catch(console.error);
const { __ } = res.locals;
return dynamicResponse(req, res, 403, 'message', {
'title': res.locals.__('Forbidden'),
'message': res.locals.__('Your request was blocked because your IP address is listed on a blacklist.'),
'title': __('Forbidden'),
'message': __('Your request was blocked because your IP address is listed on a blacklist.'),
'redirect': req.headers.referer || '/',
});
}

@ -53,9 +53,10 @@ module.exports = (req, res, next) => {
} catch(e) {
//should never get here
console.error('Ip parse failed', e);
const { __ } = res.locals;
return res.status(400).render('message', {
'title': res.locals.__('Bad request'),
'message': res.locals.__('Malformed IP'),
'title': __('Bad request'),
'message': __('Malformed IP'),
});
}

@ -24,9 +24,10 @@ module.exports = (req, res, next) => {
//referrer is invalid url
}
if (refererCheck === true && (!req.headers.referer || !validReferer)) {
const { __ } = res.locals;
return dynamicResponse(req, res, 403, 'message', {
'title': res.locals.__('Forbidden'),
'message': res.locals.__('Invalid or missing "Referer" header. Are you posting from the correct URL?'),
'title': __('Forbidden'),
'message': __('Invalid or missing "Referer" header. Are you posting from the correct URL?'),
});
}
next();

@ -10,9 +10,10 @@ module.exports = {
one: (requiredPermission) => {
return cache.one[requiredPermission] || (cache.one[requiredPermission] = function(req, res, next) {
if (!res.locals.permissions.get(requiredPermission)) {
const { __ } = res.locals;
return res.status(403).render('message', {
'title': res.locals.__('Forbidden'),
'message': res.locals.__('No Permission'),
'title': __('Forbidden'),
'message': __('No Permission'),
'redirect': req.headers.referer || '/',
});
}
@ -24,9 +25,10 @@ module.exports = {
//these caches working as intended with arrays?
return cache.all[requiredPermissions] || (cache.all[requiredPermissions] = function(req, res, next) {
if (!res.locals.permissions.hasAll(...requiredPermissions)) {
const { __ } = res.locals;
return res.status(403).render('message', {
'title': res.locals.__('Forbidden'),
'message': res.locals.__('No Permission'),
'title': __('Forbidden'),
'message': __('No Permission'),
'redirect': req.headers.referer || '/',
});
}
@ -38,9 +40,10 @@ module.exports = {
//these caches working as intended with arrays?
return cache.any[requiredPermissions] || (cache.any[requiredPermissions] = function(req, res, next) {
if (!res.locals.permissions.hasAny(...requiredPermissions)) {
const { __ } = res.locals;
return res.status(403).render('message', {
'title': res.locals.__('Forbidden'),
'message': res.locals.__('No Permission'),
'title': __('Forbidden'),
'message': __('No Permission'),
'redirect': req.headers.referer || '/',
});
}

@ -7,13 +7,14 @@ const { Bans } = require(__dirname+'/../../db/')
module.exports = async (req, res, hitGlobalFilter, hitLocalFilter, boardFilterMode, globalFilterMode,
boardFilterBanDuration, globalFilterBanDuration, filterBanAppealable, redirect) => {
const { __ } = res.locals;
//global filter mode takes prio
const useFilterMode = hitGlobalFilter ? globalFilterMode : boardFilterMode;
if (useFilterMode === 1) {
return dynamicResponse(req, res, 400, 'message', {
'title': res.locals.__('Bad request'),
'message': res.locals.__('Your post was blocked by a word filter'),
'title': __('Bad request'),
'message': __('Your post was blocked by a word filter'),
'redirect': redirect
});
} else {
@ -28,7 +29,7 @@ module.exports = async (req, res, hitGlobalFilter, hitLocalFilter, boardFilterMo
'type': res.locals.ip.type,
},
'range': 0,
'reason': res.locals.__(`${hitGlobalFilter ? 'global ' :''}word filter auto ban`),
'reason': __(`${hitGlobalFilter ? 'global ' :''}word filter auto ban`),
'board': banBoard,
'posts': null,
'issuer': 'system', //todo: make a "system" property instead?
@ -36,7 +37,7 @@ module.exports = async (req, res, hitGlobalFilter, hitLocalFilter, boardFilterMo
'expireAt': banExpiry,
'allowAppeal': hitGlobalFilter ? filterBanAppealable : true,
'showUser': true,
'note': res.locals.__(`${hitGlobalFilter ? 'global ' :''}filter hit: "%s"`, (hitGlobalFilter || hitLocalFilter)),
'note': __(`${hitGlobalFilter ? 'global ' :''}filter hit: "%s"`, (hitGlobalFilter || hitLocalFilter)),
'seen': true,
};
const insertedResult = await Bans.insertOne(ban);

@ -231,7 +231,7 @@ module.exports = async (req, res, next) => {
}
//lock, sticky, bumplock, cyclic
if (req.body.bumplock) {
const { message, action, query } = bumplockPosts(res.locals.posts);
const { message, action, query } = bumplockPosts(res.locals);
if (action) {
modlogActions.push('Bumplock');
combinedQuery[action] = { ...combinedQuery[action], ...query};
@ -239,7 +239,7 @@ module.exports = async (req, res, next) => {
messages.push(message);
}
if (req.body.lock) {
const { message, action, query } = lockPosts(res.locals.posts);
const { message, action, query } = lockPosts(res.locals);
if (action) {
modlogActions.push('Lock');
combinedQuery[action] = { ...combinedQuery[action], ...query};
@ -247,7 +247,7 @@ module.exports = async (req, res, next) => {
messages.push(message);
}
if (req.body.sticky != null) {
const { message, action, query } = stickyPosts(res.locals.posts, req.body.sticky);
const { message, action, query } = stickyPosts(res.locals, req.body.sticky);
if (action) {
modlogActions.push('Sticky');
combinedQuery[action] = { ...combinedQuery[action], ...query};
@ -255,7 +255,7 @@ module.exports = async (req, res, next) => {
messages.push(message);
}
if (req.body.cyclic) {
const { message, action, query } = cyclePosts(res.locals.posts);
const { message, action, query } = cyclePosts(res.locals);
if (action) {
modlogActions.push('Cycle');
combinedQuery[action] = { ...combinedQuery[action], ...query};

@ -2,7 +2,9 @@
const { NumberInt } = require(__dirname+'/../../db/db.js');
module.exports = (posts) => {
module.exports = (locals) => {
const { posts, __, __n } = locals;
const filteredposts = posts.filter(post => {
return !post.thread;
@ -10,12 +12,12 @@ module.exports = (posts) => {
if (filteredposts.length === 0) {
return {
message: 'No threads to bumplock',
message: __('No threads selected to Bumplock'),
};
}
return {
message: `Toggled bumplock for ${filteredposts.length} thread(s)`,
message: __n('Toggled Bumplock for %s threads', filteredposts.length),
action: '$bit',
query: {
'bumplocked': {

@ -35,6 +35,7 @@ const { Boards, Posts } = require(__dirname+'/../../db/')
module.exports = async (req, res) => {
const { __ } = res.locals;
const { globalLimits } = config.get;
//oldsettings before changes
@ -232,8 +233,8 @@ module.exports = async (req, res) => {
debugLogs && console.log(req.params.board, 'board settings changed');
return dynamicResponse(req, res, 200, 'message', {
'title': res.locals.__('Success'),
'message': 'Updated settings.',
'title': __('Success'),
'message': __('Updated settings.'),
'redirect': `/${req.params.board}/manage/settings.html`
});

@ -40,6 +40,7 @@ const { Boards } = require(__dirname+'/../../db/')
module.exports = async (req, res) => {
const { __ } = res.locals;
const promises = [];
const oldSettings = config.get;
@ -371,8 +372,8 @@ module.exports = async (req, res) => {
});
return dynamicResponse(req, res, 200, 'message', {
'title': res.locals.__('Success'),
'message': 'Updated settings.',
'title': __('Success'),
'message': __('Updated settings.'),
'redirect': '/globalmanage/settings.html'
});

@ -8,6 +8,7 @@ const bcrypt = require('bcrypt')
module.exports = async (req, res) => {
const { __ } = res.locals;
const username = req.body.username.toLowerCase();
const password = req.body.password;
const newPassword = req.body.newpassword;
@ -18,8 +19,8 @@ module.exports = async (req, res) => {
//if the account doesnt exist, reject
if (!account) {
return dynamicResponse(req, res, 403, 'message', {
'title': 'Forbidden',
'message': 'Incorrect account credentials',
'title': __('Forbidden'),
'message': __('Incorrect account credentials'),
'redirect': '/changepassword.html'
});
}
@ -30,8 +31,8 @@ module.exports = async (req, res) => {
//if hashes matched
if (passwordMatch === false) {
return dynamicResponse(req, res, 403, 'message', {
'title': 'Forbidden',
'message': 'Incorrect account credentials',
'title': __('Forbidden'),
'message': __('Incorrect account credentials'),
'redirect': '/changepassword.html'
});
}
@ -40,8 +41,8 @@ module.exports = async (req, res) => {
const delta = await doTwoFactor(username, account.twofactor, req.body.twofactor);
if (delta === null) {
return dynamicResponse(req, res, 403, 'message', {
'title': 'Forbidden',
'message': 'Incorrect account credentials',
'title': __('Forbidden'),
'message': __('Incorrect account credentials'),
'redirect': '/changepassword.html'
});
}
@ -54,8 +55,8 @@ module.exports = async (req, res) => {
]);
return dynamicResponse(req, res, 200, 'message', {
'title': res.locals.__('Success'),
'message': 'Changed password',
'title': __('Success'),
'message': __('Password updated successfully'),
'redirect': '/login.html'
});

@ -11,6 +11,7 @@ const { Boards, Accounts } = require(__dirname+'/../../db/')
module.exports = async (req, res) => {
const { __ } = res.locals;
const { boardDefaults } = config.get;
const { name, description } = req.body
@ -20,8 +21,8 @@ module.exports = async (req, res) => {
if (restrictedURIs.has(uri)) {
return dynamicResponse(req, res, 400, 'message', {
'title': 'Bad Request',
'message': 'That URI is not available for board creation',
'title': __('Bad Request'),
'message': __('URI "%s" is reserved', uri),
'redirect': '/create.html'
});
}
@ -31,8 +32,8 @@ module.exports = async (req, res) => {
// if board exists reject
if (board != null) {
return dynamicResponse(req, res, 409, 'message', {
'title': 'Conflict',
'message': 'Board with this URI already exists',
'title': __('Conflict'),
'message': __('Board with this URI already exists'),
'redirect': '/create.html'
});
}

@ -2,7 +2,9 @@
const { NumberInt } = require(__dirname+'/../../db/db.js');
module.exports = (posts) => {
module.exports = (locals) => {
const { posts, __, __n } = locals;
const filteredposts = posts.filter(post => {
return !post.thread;
@ -10,12 +12,12 @@ module.exports = (posts) => {
if (filteredposts.length === 0) {
return {
message: 'No thread(s) to cycle',
message: __('No threads selected to make Cyclical'),
};
}
return {
message: `Toggled Cyclical mode for ${filteredposts.length} thread(s)`,
message: __n('Toggled Cyclical mode for %s threads', filteredposts.length),
action: '$bit',
query: {
'cyclic': {

@ -2,7 +2,9 @@
const { NumberInt } = require(__dirname+'/../../db/db.js');
module.exports = (posts) => {
module.exports = (locals) => {
const { posts, __, __n } = locals;
const filteredposts = posts.filter(post => {
return !post.thread;
@ -10,12 +12,12 @@ module.exports = (posts) => {
if (filteredposts.length === 0) {
return {
message: 'No thread(s) to lock',
message: __('No threads selected to Lock'),
};
}
return {
message: `Toggled Lock for ${filteredposts.length} thread(s)`,
message: __n('Toggled Lock for %s threads', filteredposts.length),
action: '$bit',
query: {
'locked': {

@ -2,7 +2,9 @@
const { NumberInt } = require(__dirname+'/../../db/db.js');
module.exports = (posts, sticky) => {
module.exports = (locals, sticky) => {
const { posts, __, __n } = locals;
const filteredposts = posts.filter(post => {
return !post.thread;
@ -10,14 +12,14 @@ module.exports = (posts, sticky) => {
if (filteredposts.length === 0) {
return {
message: 'No thread(s) to sticky',
message: __('No threads selected to Sticky'),
};
}
const stickyValue = NumberInt(sticky);
return {
message: `Set sticky for ${filteredposts.length} thread(s) to ${sticky}`,
message: __n('Set Sticky level for %s threads to %s', filteredposts.length, sticky),
action: '$set',
query: {
'sticky': stickyValue,

@ -18,9 +18,10 @@ module.exports = async (req, res, next) => {
const username = res.locals.user.username;
const ratelimit = await Ratelimits.incrmentQuota(username, '2fa', 50);
if (ratelimit > 100) {
const { __ } = res.locals;
return dynamicResponse(req, res, 429, 'message', {
'title': res.locals.__('Ratelimited'),
'message': res.locals.__('Please wait before generating another 2FA QR code.'),
'title': __('Ratelimited'),
'message': __('Please wait before generating another 2FA QR code.'),
});
}

Loading…
Cancel
Save