diff --git a/controllers/forms/addcustompage.js b/controllers/forms/addcustompage.js index 25afc5bd..a534f233 100644 --- a/controllers/forms/addcustompage.js +++ b/controllers/forms/addcustompage.js @@ -29,7 +29,7 @@ module.exports = { } return false; } , expected: true, error: '.html name must contain a-z 0-9 _ - only' }, - { result: !existsBody(req.body.message) || numberBody(res.locals.messageLength, 0, globalLimits.customPages.maxLength), expected: true, error: `Message must be ${globalLimits.customPages.maxLength} characters or less` }, + { result: numberBody(res.locals.messageLength, 0, globalLimits.customPages.maxLength), expected: true, error: `Message must be ${globalLimits.customPages.maxLength} characters or less` }, { result: lengthBody(req.body.title, 0, 50), expected: false, error: 'Title must be 50 characters or less' }, { result: lengthBody(req.body.page, 0, 50), expected: false, error: '.html name must be 50 characters or less' }, { result: async () => { diff --git a/controllers/forms/addnews.js b/controllers/forms/addnews.js index 8a95e8e1..0bcc7a26 100644 --- a/controllers/forms/addnews.js +++ b/controllers/forms/addnews.js @@ -2,6 +2,7 @@ const addNews = require(__dirname+'/../../models/forms/addnews.js') , dynamicResponse = require(__dirname+'/../../helpers/dynamic.js') + , config = require(__dirname+'/../../config.js') , paramConverter = require(__dirname+'/../../helpers/paramconverter.js') , { checkSchema, lengthBody, numberBody, minmaxBody, numberBodyVariable, inArrayBody, arrayInBody, existsBody } = require(__dirname+'/../../helpers/schema.js'); @@ -20,7 +21,7 @@ module.exports = { const errors = await checkSchema([ { result: existsBody(req.body.message), expected: true, error: 'Missing message' }, { result: existsBody(req.body.title), expected: true, error: 'Missing title' }, - { result: lengthBody(req.body.message, 0, globalLimits.fieldLength.message), expected: false, error: `Message must be ${globalLimits.fieldLength.message} characters or less` }, + { result: numberBody(res.locals.messageLength, 0, globalLimits.fieldLength.message), expected: true, error: `Message must be ${globalLimits.fieldLength.message} characters or less` }, { result: lengthBody(req.body.title, 0, 50), expected: false, error: 'Title must be 50 characters or less' }, ]); diff --git a/controllers/forms/appeal.js b/controllers/forms/appeal.js index 1c66c43e..7879c77c 100644 --- a/controllers/forms/appeal.js +++ b/controllers/forms/appeal.js @@ -23,7 +23,7 @@ module.exports = { const errors = await checkSchema([ { result: existsBody(req.body.message), expected: true, error: 'Appeals must include a message' }, - { result: numberBody(res.locals.messageLength, 1, globalLimits.fieldLength.message), expected: true, error: `Appeal message must be ${globalLimits.fieldLength.message} characters or less` }, + { result: numberBody(res.locals.messageLength, 0, globalLimits.fieldLength.message), expected: true, error: `Appeal message must be ${globalLimits.fieldLength.message} characters or less` }, ]); //should appeals really be based off message field length global limit? minor. if (errors.length > 0) { diff --git a/controllers/forms/changepassword.js b/controllers/forms/changepassword.js index 4743b497..7aaee366 100644 --- a/controllers/forms/changepassword.js +++ b/controllers/forms/changepassword.js @@ -16,13 +16,13 @@ module.exports = { const errors = await checkSchema([ { result: existsBody(req.body.username), expected: true, error: 'Missing username' }, - { result: lengthBody(req.body.username, 1, 50), expected: false, error: 'Username must be 50 characters or less' }, + { result: lengthBody(req.body.username, 0, 50), expected: false, error: 'Username must be 50 characters or less' }, { result: existsBody(req.body.password), expected: true, error: 'Missing password' }, - { result: lengthBody(req.body.password, 1, 50), expected: false, error: 'Password must be 50 characters or less' }, + { result: lengthBody(req.body.password, 0, 50), expected: false, error: 'Password must be 50 characters or less' }, { result: existsBody(req.body.newpassword), expected: true, error: 'Missing new password' }, - { result: lengthBody(req.body.newpassword, 1, 100), expected: false, error: 'New pasword must be 100 characters or less' }, + { result: lengthBody(req.body.newpassword, 0, 100), expected: false, error: 'New pasword must be 100 characters or less' }, { result: existsBody(req.body.newpasswordconfirm), expected: true, error: 'Missing new password confirmation' }, - { result: lengthBody(req.body.newpasswordconfirm, 1, 100), expected: false, error: 'New password confirmation must be 100 characters or less' }, + { result: lengthBody(req.body.newpasswordconfirm, 0, 100), expected: false, error: 'New password confirmation must be 100 characters or less' }, { result: (req.body.newpassword === req.body.newpasswordconfirm), expected: true, error: 'New password and password confirmation must match' }, ]); diff --git a/controllers/forms/create.js b/controllers/forms/create.js index 8d89983b..24e79b2b 100644 --- a/controllers/forms/create.js +++ b/controllers/forms/create.js @@ -21,11 +21,11 @@ module.exports = { const errors = await checkSchema([ { result: (enableUserBoardCreation === true), blocking: true, permLevel: 1, expected: true, error: 'User board creation is currently disabled' }, { result: existsBody(req.body.uri), expected: true, error: 'Missing URI' }, - { result: lengthBody(req.body.uri, 1, globalLimits.fieldLength.uri), expected: false, error: `URI must be ${globalLimits.fieldLength.uri} characters or less` }, + { result: lengthBody(req.body.uri, 0, globalLimits.fieldLength.uri), expected: false, error: `URI must be ${globalLimits.fieldLength.uri} characters or less` }, { result: existsBody(req.body.name), expected: true, error: 'Missing name' }, - { result: lengthBody(req.body.name, 1, globalLimits.fieldLength.boardname), expected: false, error: `Name must be ${globalLimits.fieldLength.boardname} characters or less` }, + { result: lengthBody(req.body.name, 0, globalLimits.fieldLength.boardname), expected: false, error: `Name must be ${globalLimits.fieldLength.boardname} characters or less` }, { result: alphaNumericRegex.test(req.body.uri), expected: true, error: 'URI must contain a-z 0-9 only' }, - { result: existsBody(req.body.description), expected: true, error: `Description must be ${globalLimits.fieldLength.description} characters or less` }, + { result: lengthBody(req.body.name, 0, globalLimits.fieldLength.description), expected: false, error: `Description must be ${globalLimits.fieldLength.description} characters or less` }, ], res.locals.permLevel); if (errors.length > 0) { diff --git a/controllers/forms/editnews.js b/controllers/forms/editnews.js index bf566710..d7b3f082 100644 --- a/controllers/forms/editnews.js +++ b/controllers/forms/editnews.js @@ -19,9 +19,9 @@ module.exports = { const errors = await checkSchema([ { result: existsBody(req.body.news_id), expected: true, error: 'Missing news id' }, { result: existsBody(req.body.message), expected: true, error: 'Missing message' }, - { result: numberBody(res.locals.messageLength, 1, 10000), expected: true, error: 'Message must be 10000 characters or less' }, + { result: numberBody(res.locals.messageLength, 0, 10000), expected: true, error: 'Message must be 10000 characters or less' }, { result: existsBody(req.body.title), expected: true, error: 'Missing title' }, - { result: lengthBody(req.body.title, 1, 50), expected: false, error: 'Title must be 50 characters or less' }, + { result: lengthBody(req.body.title, 0, 50), expected: false, error: 'Title must be 50 characters or less' }, ]); if (errors.length > 0) { diff --git a/controllers/forms/globalactions.js b/controllers/forms/globalactions.js index 4b6657e6..043dd802 100644 --- a/controllers/forms/globalactions.js +++ b/controllers/forms/globalactions.js @@ -22,9 +22,9 @@ module.exports = { controller: async (req, res, next) => { const { globalLimits } = config.get; - + res.locals.actions = actionChecker(req); - + const errors = await checkSchema([ { result: lengthBody(req.body.globalcheckedposts, 1), expected: false, blocking: true, error: 'Must select at least one post' }, { result: lengthBody(res.locals.actions.validActions, 1), expected: false, blocking: true, error: 'No actions selected' }, diff --git a/controllers/forms/login.js b/controllers/forms/login.js index e7540afb..855c758c 100644 --- a/controllers/forms/login.js +++ b/controllers/forms/login.js @@ -17,8 +17,8 @@ module.exports = { const errors = await checkSchema([ { result: existsBody(req.body.username), expected: true, error: 'Missing username' }, { result: existsBody(req.body.password), expected: true, error: 'Missing password' }, - { result: lengthBody(req.body.username, 1, 50), expected: false, error: 'Username must be 1-50 characters' }, - { result: lengthBody(req.body.password, 1, 100), expected: false, error: 'Password must be 1-100 characters' }, + { result: lengthBody(req.body.username, 0, 50), expected: false, error: 'Username must be 1-50 characters' }, + { result: lengthBody(req.body.password, 0, 100), expected: false, error: 'Password must be 1-100 characters' }, ]); if (errors.length > 0) { diff --git a/controllers/forms/makepost.js b/controllers/forms/makepost.js index aa1d5984..5d675dbe 100644 --- a/controllers/forms/makepost.js +++ b/controllers/forms/makepost.js @@ -22,7 +22,7 @@ module.exports = { controller: async (req, res, next) => { const { pruneImmediately, globalLimits, disableAnonymizerFilePosting } = config.get; - + const hasNoMandatoryFile = globalLimits.postFiles.max !== 0 && res.locals.board.settings.maxFiles !== 0 && res.locals.numFiles === 0; //maybe add more duplicates here? diff --git a/controllers/forms/register.js b/controllers/forms/register.js index 0ca4c8cd..09dd7943 100644 --- a/controllers/forms/register.js +++ b/controllers/forms/register.js @@ -21,12 +21,12 @@ module.exports = { const errors = await checkSchema([ { result: (enableUserAccountCreation === true), blocking: true, permLevel: 1, expected: true, error: 'Account creation is currently disabled' }, { result: existsBody(req.body.username), expected: true, error: 'Missing username' }, - { result: lengthBody(req.body.username, 1, 50), expected: false, error: 'Username must be 50 characters or less' }, + { result: lengthBody(req.body.username, 0, 50), expected: false, error: 'Username must be 50 characters or less' }, { result: alphaNumericRegex.test(req.body.username), expected: true, error: 'Username must contain a-z 0-9 only'}, { result: existsBody(req.body.password), expected: true, error: 'Missing password' }, - { result: lengthBody(req.body.password, 1, 50), expected: false, error: 'Password must be 50 characters or less' }, + { result: lengthBody(req.body.password, 0, 50), expected: false, error: 'Password must be 50 characters or less' }, { result: existsBody(req.body.passwordconfirm), expected: true, error: 'Missing password confirmation' }, - { result: lengthBody(req.body.passwordconfirm, 1, 100), expected: false, error: 'Password confirmation must be 100 characters or less' }, + { result: lengthBody(req.body.passwordconfirm, 0, 100), expected: false, error: 'Password confirmation must be 100 characters or less' }, { result: (req.body.password === req.body.passwordconfirm), expected: true, error: 'Password and password confirmation must match' }, ], res.locals.permLevel); diff --git a/controllers/forms/resign.js b/controllers/forms/resign.js index e98723f0..be73b890 100644 --- a/controllers/forms/resign.js +++ b/controllers/forms/resign.js @@ -18,7 +18,7 @@ module.exports = { const errors = await checkSchema([ { result: existsBody(req.body.confirm), expected: true, error: 'Missing confirmation' }, - { result: lengthBody(req.body.board, 1), expected: true, error: 'You did not select a board' }, + { result: existsBody(req.body.board), expected: true, error: 'You did not select a board' }, { result: alphaNumericRegex.test(req.body.board), expected: true, error: 'URI must contain a-z 0-9 only' }, { result: async () => { res.locals.board = await Boards.findOne(req.body.board); diff --git a/controllers/forms/transfer.js b/controllers/forms/transfer.js index c7d0fa23..527bf417 100644 --- a/controllers/forms/transfer.js +++ b/controllers/forms/transfer.js @@ -17,7 +17,7 @@ module.exports = { const errors = await checkSchema([ { result: existsBody(req.body.username), expected: true, error: 'Missing new owner username' }, - { result: lengthBody(req.body.username, 1, 50), expected: true, error: 'New owner username must be 50 characters or less' }, + { result: lengthBody(req.body.username, 0, 50), expected: true, error: 'New owner username must be 50 characters or less' }, { result: (req.body.username === res.locals.board.owner), expected: false, error: 'New owner must be different from current owner' }, { result: alphaNumericRegex.test(req.body.username), expected: true, error: 'New owner username must contain a-z 0-9 only' }, ]); diff --git a/controllers/pages.js b/controllers/pages.js index 8966b2a2..b86f2dc1 100644 --- a/controllers/pages.js +++ b/controllers/pages.js @@ -25,7 +25,7 @@ const express = require('express') captcha, thread, modlog, modloglist, account, boardlist, customPage } = require(__dirname+'/../models/pages/') , threadParamConverter = paramConverter({ processThreadIdParam: true }) , logParamConverter = paramConverter({ processDateParam: true }) - , newsParamConverter = paramConverter({ objectIdFields: ['newsid'] }); + , newsParamConverter = paramConverter({ objectIdParams: ['newsid'] }); //homepage router.get('/index.html', home); diff --git a/helpers/paramconverter.js b/helpers/paramconverter.js index 7b102663..e8650a3e 100644 --- a/helpers/paramconverter.js +++ b/helpers/paramconverter.js @@ -12,6 +12,7 @@ const defaultOptions = { allowedArrays: [], //helpers/checks/captcha.js already does this for captcha numberFields: [], numberArrays: [], + objectIdParams: [], objectIdFields: [], objectIdArrays: [], processThreadIdParam: false, @@ -26,9 +27,9 @@ module.exports = (options) => { return (req, res, next) => { - const { timeFields, trimFields, allowedArrays, - processThreadIdParam, processDateParam, processMessageLength, - numberFields, numberArrays, objectIdFields, objectIdArrays } = options; + const { timeFields, trimFields, allowedArrays, processThreadIdParam, + processDateParam, processMessageLength, numberFields, numberArrays, + objectIdParams, objectIdFields, objectIdArrays } = options; /* check all body fields, body-parser prevents this array being too big, so no worry. whitelist for fields that can be arrays, and convert singular of those fields to 1 length array */ @@ -109,6 +110,12 @@ module.exports = (options) => { req.body[field] = ObjectId(req.body[field]); } } + for (let i = 0; i < objectIdParams.length; i++) { + const field = objectIdParams[i]; + if (req.params[field]) { + req.params[field] = ObjectId(req.params[field]); + } + } for (let i = 0; i < objectIdArrays.length; i++) { const field = objectIdArrays[i]; if (req.body[field]) { @@ -145,8 +152,8 @@ module.exports = (options) => { /* normalise message length check for CRLF vs just LF, because String.length depending on browser wont count CRLF as 2 characters, so user gets "message too long" at the right length. Maybe will add another array for these in future */ - if (processMessageLength && req.body.message) { - res.locals.messageLength = req.body.message.replace(/\r\n/igm, '\n').length; + if (processMessageLength) { + res.locals.messageLength = req.body.message ? req.body.message.replace(/\r\n/igm, '\n').length : 0; } next();