Compare commits

...

2 Commits

Author SHA1 Message Date
Phillip Thelen
6092cba1ea upgrade express and express-validator 2025-09-18 14:30:09 +02:00
Phillip Thelen
0b4adbbf07 update rimraf 2025-09-18 14:19:46 +02:00
38 changed files with 359 additions and 335 deletions

View File

@@ -1,12 +1,13 @@
import gulp from 'gulp';
import clean from 'rimraf';
import { rimraf as clean } from 'rimraf';
import apidoc from 'apidoc';
const APIDOC_DEST_PATH = './apidoc/html';
const APIDOC_SRC_PATH = './website/server';
const APIDOC_CONFIG_PATH = './apidoc/apidoc.json';
gulp.task('apidoc:clean', done => {
clean(APIDOC_DEST_PATH, done);
clean.sync(APIDOC_DEST_PATH);
done();
});
gulp.task('apidoc', gulp.series('apidoc:clean', done => {

View File

@@ -6,7 +6,7 @@ import babel from 'gulp-babel';
import os from 'os';
import fs from 'fs';
import spawn from 'cross-spawn'; // eslint-disable-line import/no-extraneous-dependencies
import clean from 'rimraf';
import { rimraf as clean } from 'rimraf';
gulp.task('build:babel:server', () => gulp.src('website/server/**/*.js')
.pipe(babel())

View File

@@ -1,6 +1,6 @@
import gulp from 'gulp';
import spritesmith from 'gulp.spritesmith';
import clean from 'rimraf';
import { rimraf as clean } from 'rimraf';
import mergeStream from 'merge-stream';
import { sync } from 'glob';
@@ -109,7 +109,8 @@ gulp.task('sprites:main', async () => {
});
gulp.task('sprites:clean', done => {
clean(`${IMG_DIST_PATH}spritesmith*,${CSS_DIST_PATH}spritesmith*}`, done);
clean.sync(`${IMG_DIST_PATH}spritesmith*,${CSS_DIST_PATH}spritesmith*}`);
done();
});
gulp.task('sprites:compile', gulp.series('sprites:clean', 'sprites:main', done => done()));

View File

@@ -29,9 +29,9 @@
"eslint": "^8.55.0",
"eslint-config-habitrpg": "^6.2.3",
"eslint-plugin-mocha": "^5.0.0",
"express": "^4.21.1",
"express": "5.1.0",
"express-basic-auth": "^1.2.1",
"express-validator": "^5.2.0",
"express-validator": "7.2.1",
"firebase-admin": "^12.1.1",
"glob": "^8.1.0",
"got": "^11.8.6",
@@ -66,8 +66,8 @@
"rate-limiter-flexible": "^2.4.2",
"redis": "^3.1.2",
"remove-markdown": "^0.5.0",
"rimraf": "^3.0.2",
"short-uuid": "^4.2.2",
"rimraf": "6.0.1",
"sinon": "^15.2.0",
"stripe": "^12.18.0",
"superagent": "^8.1.2",

View File

@@ -3,6 +3,7 @@ import moment from 'moment';
import pick from 'lodash/pick';
import sortBy from 'lodash/sortBy';
import nconf from 'nconf';
import { body , validationResult } from 'express-validator';
import {
authWithHeaders,
} from '../../middlewares/auth';
@@ -87,8 +88,8 @@ api.loginLocal = {
errorMessage: res.t('missingPassword'),
},
});
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
req.sanitizeBody('username').trim();
req.sanitizeBody('password').trim();
@@ -216,8 +217,8 @@ api.updateUsername = {
},
});
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const newUsername = req.body.username;
@@ -307,7 +308,7 @@ api.updatePassword = {
},
});
const validationErrors = req.validationErrors();
const validationErrors = validationResult(req).array();
if (validationErrors) {
throw validationErrors;
@@ -353,8 +354,8 @@ api.resetPassword = {
notEmpty: { errorMessage: res.t('missingEmail') },
},
});
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const email = req.body.email.toLowerCase();
let user = await User.findOne(
@@ -419,12 +420,12 @@ api.updateEmail = {
if (!user.auth.local.email) throw new BadRequest(res.t('userHasNoLocalRegistration'));
req.checkBody('newEmail', res.t('newEmailRequired')).notEmpty().isEmail();
await body('newEmail', res.t('newEmailRequired')).notEmpty().isEmail().run(req)
if (user.auth.local.hashed_password) {
req.checkBody('password', res.t('missingPassword')).notEmpty();
await body('password', res.t('missingPassword')).notEmpty().run(req)
}
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const emailAlreadyInUse = await User.findOne({
'auth.local.email': req.body.newEmail.toLowerCase(),
@@ -485,8 +486,8 @@ api.resetPasswordSetNewOne = {
},
});
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { newPassword, confirmPassword } = req.body;

View File

@@ -4,6 +4,7 @@ import merge from 'lodash/merge';
import pick from 'lodash/pick';
import reduce from 'lodash/reduce';
import times from 'lodash/times';
import { body, param, query , validationResult } from 'express-validator';
import { authWithHeaders, authWithSession } from '../../middlewares/auth';
import { model as Challenge } from '../../models/challenge';
import bannedWords from '../../libs/bannedWords';
@@ -232,11 +233,11 @@ api.createChallenge = {
async handler (req, res) {
const { user } = res.locals;
req.checkBody('group', apiError('groupIdRequired')).notEmpty();
req.checkBody('summary', apiError('summaryLengthExceedsMax')).isLength({ max: MAX_SUMMARY_SIZE_FOR_CHALLENGES });
await body('group', apiError('groupIdRequired')).notEmpty().run(req)
await body('summary', apiError('summaryLengthExceedsMax')).isLength({ max: MAX_SUMMARY_SIZE_FOR_CHALLENGES }).run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const group = await Group.getGroup({
user, groupId: req.body.group, fields: basicGroupFields, optionalMembership: true,
@@ -328,10 +329,10 @@ api.joinChallenge = {
async handler (req, res) {
const { user } = res.locals;
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
await param('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID().run(req);
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const challenge = await Challenge.findOne({ _id: req.params.challengeId }).exec();
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
@@ -397,10 +398,10 @@ api.leaveChallenge = {
const { user } = res.locals;
const keep = req.body.keep === 'remove-all' ? 'remove-all' : 'keep-all';
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
await param('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID().run(req);
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const challenge = await Challenge.findOne({ _id: req.params.challengeId }).exec();
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
@@ -463,10 +464,10 @@ api.getUserChallenges = {
url: '/challenges/user',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkQuery('page').notEmpty().isInt({ min: 0 }, apiError('queryPageInteger'));
await query('page').notEmpty().isInt({ min: 0 }, apiError('queryPageInteger')).run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const CHALLENGES_PER_PAGE = 10;
const {
@@ -599,10 +600,10 @@ api.getGroupChallenges = {
const { user } = res.locals;
let { groupId } = req.params;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
await param('groupId', apiError('groupIdRequired')).notEmpty().run(req);
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
if (groupId === 'party') groupId = user.party._id;
if (groupId === 'habitrpg') groupId = TAVERN_ID;
@@ -661,10 +662,10 @@ api.getChallenge = {
url: '/challenges/:challengeId',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
await param('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID().run(req);
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { user } = res.locals;
const { challengeId } = req.params;
@@ -719,10 +720,10 @@ api.exportChallengeCsv = {
url: '/challenges/:challengeId/export/csv',
middlewares: [authWithSession],
async handler (req, res) {
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
await param('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID().run(req);
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { user } = res.locals;
const { challengeId } = req.params;
@@ -836,11 +837,11 @@ api.updateChallenge = {
url: '/challenges/:challengeId',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
req.checkBody('summary', apiError('summaryLengthExceedsMax')).isLength({ max: MAX_SUMMARY_SIZE_FOR_CHALLENGES });
await param('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID().run(req);
await body('summary', apiError('summaryLengthExceedsMax')).isLength({ max: MAX_SUMMARY_SIZE_FOR_CHALLENGES }).run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { user } = res.locals;
const { challengeId } = req.params;
@@ -883,10 +884,10 @@ api.deleteChallenge = {
async handler (req, res) {
const { user } = res.locals;
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
await param('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID().run(req);
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const challenge = await Challenge.findOne({ _id: req.params.challengeId }).exec();
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
@@ -931,11 +932,11 @@ api.selectChallengeWinner = {
async handler (req, res) {
const { user } = res.locals;
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
req.checkParams('winnerId', res.t('winnerIdRequired')).notEmpty().isUUID();
await param('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID().run(req);
await param('winnerId', res.t('winnerIdRequired')).notEmpty().isUUID().run(req);
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const challenge = await Challenge.findOne({ _id: req.params.challengeId }).exec();
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
@@ -992,10 +993,10 @@ api.cloneChallenge = {
async handler (req, res) {
const { user } = res.locals;
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
await param('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID().run(req);
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const challengeToClone = await Challenge.findOne({ _id: req.params.challengeId }).exec();
if (!challengeToClone) throw new NotFound(res.t('challengeNotFound'));
@@ -1061,10 +1062,10 @@ api.flagChallenge = {
async handler (req, res) {
const { user } = res.locals;
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
await param('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID().run(req);
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const challenge = await Challenge.findOne({ _id: req.params.challengeId }).exec();
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
@@ -1094,10 +1095,10 @@ api.clearFlagsChallenge = {
async handler (req, res) {
const { user } = res.locals;
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
await param('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID().run(req);
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
if (!user.hasPermission('moderator')) {
throw new NotAuthorized(res.t('messageGroupChatAdminClearFlagCount'));

View File

@@ -1,5 +1,6 @@
import _ from 'lodash';
import couponCode from 'coupon-code';
import { param, query , validationResult } from 'express-validator';
import csvStringify from '../../libs/csvStringify';
import {
authWithHeaders,
@@ -72,11 +73,11 @@ api.generateCoupons = {
url: '/coupons/generate/:event',
middlewares: [authWithHeaders(), ensurePermission('coupons')],
async handler (req, res) {
req.checkParams('event', apiError('eventRequired')).notEmpty();
req.checkQuery('count', apiError('countRequired')).notEmpty().isNumeric();
await param('event', apiError('eventRequired')).notEmpty().run(req)
await query('count', apiError('countRequired')).notEmpty().isNumeric().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const coupons = await Coupon.generate(req.params.event, req.query.count);
res.respond(200, coupons);
@@ -122,10 +123,10 @@ api.validateCoupon = {
optional: true,
})],
async handler (req, res) {
req.checkParams('code', res.t('couponCodeRequired')).notEmpty();
await param('code', res.t('couponCodeRequired')).notEmpty().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
let valid = false;
const code = couponCode.validate(req.params.code);

View File

@@ -9,6 +9,7 @@ import pick from 'lodash/pick';
import uniqBy from 'lodash/uniqBy';
import nconf from 'nconf';
import moment from 'moment';
import { body, param, query , validationResult } from 'express-validator';
import { authWithHeaders } from '../../middlewares/auth';
import {
model as Group,
@@ -132,10 +133,10 @@ api.createGroup = {
const group = new Group(Group.sanitize(req.body));
group.leader = user._id;
req.checkBody('summary', apiError('summaryLengthExceedsMax')).isLength({ max: MAX_SUMMARY_SIZE_FOR_GUILDS });
await body('summary', apiError('summaryLengthExceedsMax')).isLength({ max: MAX_SUMMARY_SIZE_FOR_GUILDS }).run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
if (group.type === 'guild') {
if (!user.hasPermission('fullAccess')) {
@@ -206,10 +207,10 @@ api.createGroupPlan = {
const { user } = res.locals;
const group = new Group(Group.sanitize(req.body.groupToCreate));
req.checkBody('paymentType', res.t('paymentTypeRequired')).notEmpty();
req.checkBody('summary', apiError('summaryLengthExceedsMax')).isLength({ max: MAX_SUMMARY_SIZE_FOR_GUILDS });
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
await body('paymentType', res.t('paymentTypeRequired')).notEmpty().run(req)
await body('summary', apiError('summaryLengthExceedsMax')).isLength({ max: MAX_SUMMARY_SIZE_FOR_GUILDS }).run(req)
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
// @TODO: Change message
if (group.privacy !== 'private') throw new NotAuthorized(res.t('partyMustbePrivate'));
@@ -321,13 +322,13 @@ api.getGroups = {
async handler (req, res) {
const { user } = res.locals;
req.checkQuery('type', res.t('groupTypesRequired')).notEmpty();
await query('type', res.t('groupTypesRequired')).notEmpty().run(req)
// pagination options, can only be used with public guilds
req.checkQuery('paginate').optional().isIn(['true', 'false'], apiError('guildsPaginateBooleanString'));
req.checkQuery('page').optional().isInt({ min: 0 }, apiError('queryPageInteger'));
await query('paginate').optional().isIn(['true', 'false'], apiError('guildsPaginateBooleanString')).run(req)
await query('page').optional().isInt({ min: 0 }, apiError('queryPageInteger')).run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const types = req.query.type.split(',');
@@ -419,10 +420,10 @@ api.getGroup = {
async handler (req, res) {
const { user } = res.locals;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
await param('groupId', apiError('groupIdRequired')).notEmpty().run(req);
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { groupId } = req.params;
const group = await Group.getGroup({ user, groupId, populateLeader: false });
@@ -481,11 +482,11 @@ api.updateGroup = {
async handler (req, res) {
const { user } = res.locals;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
req.checkBody('summary', apiError('summaryLengthExceedsMax')).isLength({ max: MAX_SUMMARY_SIZE_FOR_GUILDS });
await param('groupId', apiError('groupIdRequired')).notEmpty().run(req);
await body('summary', apiError('summaryLengthExceedsMax')).isLength({ max: MAX_SUMMARY_SIZE_FOR_GUILDS }).run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const optionalMembership = Boolean(user.hasPermission('moderator'));
const group = await Group.getGroup({ user, groupId: req.params.groupId, optionalMembership });
@@ -567,10 +568,10 @@ api.joinGroup = {
const { user } = res.locals;
let inviter;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); // .isUUID(); can't be used because it would block 'habitrpg' or 'party'
await param('groupId', apiError('groupIdRequired')).notEmpty().run(req); // .isUUID(); can't be used because it would block 'habitrpg' or 'party'
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
// Works even if the user is not yet a member of the group
// Do not fetch chat and work even if the user is not yet a member of the group
@@ -760,10 +761,10 @@ api.rejectGroupInvite = {
async handler (req, res) {
const { user } = res.locals;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); // .isUUID(); can't be used because it would block 'habitrpg' or 'party'
await param('groupId', apiError('groupIdRequired')).notEmpty().run(req); // .isUUID(); can't be used because it would block 'habitrpg' or 'party'
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { groupId } = req.params;
let isUserInvited = false;
@@ -831,13 +832,13 @@ api.leaveGroup = {
middlewares: [authWithHeaders()],
async handler (req, res) {
const { user } = res.locals;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
await param('groupId', apiError('groupIdRequired')).notEmpty().run(req);
// When removing the user from challenges, should we keep the tasks?
req.checkQuery('keep', apiError('keepOrRemoveAll')).optional().isIn(['keep-all', 'remove-all']);
req.checkBody('keepChallenges', apiError('groupRemainOrLeaveChallenges')).optional().isIn(['remain-in-challenges', 'leave-challenges']);
await query('keep', apiError('keepOrRemoveAll')).optional().isIn(['keep-all', 'remove-all']).run(req)
await body('keepChallenges', apiError('groupRemainOrLeaveChallenges')).optional().isIn(['remain-in-challenges', 'leave-challenges']).run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { groupId } = req.params;
await leaveGroup({
@@ -899,11 +900,11 @@ api.removeGroupMember = {
async handler (req, res) {
const { user } = res.locals;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
req.checkParams('memberId', res.t('userIdRequired')).notEmpty().isUUID();
await param('groupId', apiError('groupIdRequired')).notEmpty().run(req);
await param('memberId', res.t('userIdRequired')).notEmpty().isUUID().run(req);
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const optionalMembership = Boolean(user.hasPermission('moderator'));
const group = await Group.getGroup({
user, groupId: req.params.groupId, optionalMembership, fields: '-chat',
@@ -1105,12 +1106,12 @@ api.inviteToGroup = {
if (user.flags.chatRevoked) throw new NotAuthorized(res.t('chatPrivilegesRevoked'));
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
await param('groupId', apiError('groupIdRequired')).notEmpty().run(req);
if (user.invitesSent >= MAX_EMAIL_INVITES_BY_USER) throw new NotAuthorized(res.t('inviteLimitReached', { techAssistanceEmail: TECH_ASSISTANCE_EMAIL }));
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const group = await Group.getGroup({ user, groupId: req.params.groupId, fields: '-chat' });
if (!group) throw new NotFound(res.t('groupNotFound'));
@@ -1182,11 +1183,11 @@ api.addGroupManager = {
const { user } = res.locals;
const { managerId } = req.body;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); // .isUUID(); can't be used because it would block 'habitrpg' or 'party'
req.checkBody('managerId', apiError('managerIdRequired')).notEmpty();
await param('groupId', apiError('groupIdRequired')).notEmpty().run(req); // .isUUID(); can't be used because it would block 'habitrpg' or 'party'
await body('managerId', apiError('managerIdRequired')).notEmpty().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const newManager = await User.findById(managerId, 'guilds party').exec();
const groupFields = basicGroupFields.concat(' managers');
@@ -1232,11 +1233,11 @@ api.removeGroupManager = {
const { user } = res.locals;
const { managerId } = req.body;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); // .isUUID(); can't be used because it would block 'habitrpg' or 'party'
req.checkBody('managerId', apiError('managerIdRequired')).notEmpty();
await param('groupId', apiError('groupIdRequired')).notEmpty().run(req); // .isUUID(); can't be used because it would block 'habitrpg' or 'party'
await body('managerId', apiError('managerIdRequired')).notEmpty().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const groupFields = basicGroupFields.concat(' managers');
const group = await Group.getGroup({ user, groupId: req.params.groupId, fields: groupFields });
@@ -1323,7 +1324,7 @@ api.getLookingForParty = {
const USERS_PER_PAGE = 30;
const { user } = res.locals;
req.checkQuery('page').optional().isInt({ min: 0 }, apiError('queryPageInteger'));
await query('page').optional().isInt({ min: 0 }, apiError('queryPageInteger')).run(req)
const PAGE = req.query.page || 0;
const PAGE_START = USERS_PER_PAGE * PAGE;

View File

@@ -1,5 +1,6 @@
import _ from 'lodash';
import validator from 'validator';
import { query, param , validationResult } from 'express-validator';
import { authWithHeaders } from '../../middlewares/auth';
import { ensurePermission } from '../../middlewares/ensureAccessRight';
import { model as User } from '../../models/user';
@@ -73,10 +74,10 @@ api.getPatrons = {
url: '/hall/patrons',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkQuery('page').optional().isInt({ min: 0 }, apiError('queryPageInteger'));
await query('page').optional().isInt({ min: 0 }, apiError('queryPageInteger')).run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const page = req.query.page ? Number(req.query.page) : 0;
const perPage = 50;
@@ -177,10 +178,10 @@ api.getHero = {
url: '/hall/heroes/:heroId',
middlewares: [authWithHeaders(), ensurePermission('userSupport')],
async handler (req, res) {
req.checkParams('heroId', res.t('heroIdRequired')).notEmpty();
await param('heroId', res.t('heroIdRequired')).notEmpty().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { heroId } = req.params;
@@ -263,10 +264,10 @@ api.updateHero = {
const { heroId } = req.params;
const updateData = req.body;
req.checkParams('heroId', res.t('heroIdRequired')).notEmpty().isUUID();
await param('heroId', res.t('heroIdRequired')).notEmpty().isUUID().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const hero = await User.findById(heroId).exec();
if (!hero) throw new NotFound(res.t('userWithIDNotFound', { userId: heroId }));
@@ -555,10 +556,10 @@ api.getHeroParty = { // @TODO XXX add tests
url: '/hall/heroes/party/:groupId',
middlewares: [authWithHeaders(), ensurePermission('userSupport')],
async handler (req, res) {
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty().isUUID();
await param('groupId', apiError('groupIdRequired')).notEmpty().isUUID().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { groupId } = req.params;
@@ -597,10 +598,10 @@ api.getHeroGroupPlans = {
url: '/hall/heroes/:heroId/group-plans',
middlewares: [authWithHeaders(), ensurePermission('userSupport')],
async handler (req, res) {
req.checkParams('heroId', res.t('heroIdRequired')).notEmpty();
await param('heroId', res.t('heroIdRequired')).notEmpty().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { heroId } = req.params;

View File

@@ -1,5 +1,6 @@
import escapeRegExp from 'lodash/escapeRegExp';
import pick from 'lodash/pick';
import { body, param, query as checkQuery , validationResult } from 'express-validator';
import { authWithHeaders } from '../../middlewares/auth';
import {
model as User,
@@ -103,10 +104,10 @@ api.getMember = {
url: '/members/:memberId',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID();
await param('memberId', res.t('memberIdRequired')).notEmpty().isUUID().run(req);
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { memberId } = req.params;
@@ -132,10 +133,10 @@ api.getMemberByUsername = {
url: '/members/username/:username',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkParams('username', res.t('invalidReqParams')).notEmpty();
await param('username', res.t('invalidReqParams')).notEmpty().run(req);
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
let username = req.params.username.toLowerCase();
if (username[0] === '@') username = username.slice(1, username.length);
@@ -261,10 +262,10 @@ api.getMemberAchievements = {
url: '/members/:memberId/achievements',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID();
await param('memberId', res.t('memberIdRequired')).notEmpty().isUUID().run(req);
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { memberId } = req.params;
@@ -292,13 +293,13 @@ function _getMembersForItem (type) {
}
return async function handleGetMembersForItem (req, res) {
req.checkParams('groupId', res.t('groupIdRequired')).notEmpty();
req.checkQuery('lastId').optional().notEmpty().isUUID();
await param('groupId', res.t('groupIdRequired')).notEmpty().run(req);
await checkQuery('lastId').optional().notEmpty().isUUID().run(req)
// Allow an arbitrary number of results (up to 60)
req.checkQuery('limit', res.t('groupIdRequired')).optional().notEmpty().isInt({ min: 1, max: 60 });
await checkQuery('limit', res.t('groupIdRequired')).optional().notEmpty().isInt({ min: 1, max: 60 }).run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { groupId } = req.params;
const { lastId } = req.query;
@@ -566,11 +567,11 @@ api.getChallengeMemberProgress = {
url: '/challenges/:challengeId/members/:memberId',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID();
await param('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID().run(req);
await param('memberId', res.t('memberIdRequired')).notEmpty().isUUID().run(req);
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { user } = res.locals;
const { challengeId } = req.params;
@@ -627,11 +628,11 @@ api.getObjectionsToInteraction = {
url: '/members/:toUserId/objections/:interaction',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkParams('toUserId', res.t('toUserIDRequired')).notEmpty().isUUID();
req.checkParams('interaction', res.t('interactionRequired')).notEmpty().isIn(KNOWN_INTERACTIONS);
await param('toUserId', res.t('toUserIDRequired')).notEmpty().isUUID().run(req);
await param('interaction', res.t('interactionRequired')).notEmpty().isIn(KNOWN_INTERACTIONS).run(req);
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const sender = res.locals.user;
const receiver = await User.findById(req.params.toUserId).exec();
@@ -662,11 +663,11 @@ api.transferGems = {
url: '/members/transfer-gems',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkBody('toUserId', res.t('toUserIDRequired')).notEmpty().isUUID();
req.checkBody('gemAmount', res.t('gemAmountRequired')).notEmpty().isInt();
await body('toUserId', res.t('toUserIDRequired')).notEmpty().isUUID().run(req)
await body('gemAmount', res.t('gemAmountRequired')).notEmpty().isInt().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const sender = res.locals.user;
const receiver = await User.findById(req.body.toUserId).exec();
@@ -815,9 +816,9 @@ api.clearUserFlags = {
const { user } = res.locals;
const { memberId } = req.params;
req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID();
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
await param('memberId', res.t('memberIdRequired')).notEmpty().isUUID().run(req);
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
if (!user.hasPermission('moderator')) {
throw new BadRequest('Only a moderator may clear reports from a profile.');

View File

@@ -1,4 +1,5 @@
import mongoose from 'mongoose';
import { param , validationResult } from 'express-validator';
const api = {};
@@ -36,10 +37,10 @@ api.getModelPaths = {
method: 'GET',
url: '/models/:model/paths',
async handler (req, res) {
req.checkParams('model', res.t('modelNotFound')).notEmpty().isIn(allModels);
await param('model', res.t('modelNotFound')).notEmpty().isIn(allModels).run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
let { model } = req.params;
// tasks models are lowercase, the others have the first letter uppercase (User, Group)

View File

@@ -1,3 +1,4 @@
import { body, param , validationResult } from 'express-validator';
import { authWithHeaders } from '../../middlewares/auth';
import {
NotFound,
@@ -25,11 +26,11 @@ api.addPushDevice = {
async handler (req, res) {
const { user } = res.locals;
req.checkBody('regId', res.t('regIdRequired')).notEmpty();
req.checkBody('type', res.t('typeRequired')).notEmpty().isIn(['ios', 'android']);
await body('regId', res.t('regIdRequired')).notEmpty().run(req)
await body('type', res.t('typeRequired')).notEmpty().isIn(['ios', 'android']).run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { pushDevices } = user;
@@ -75,10 +76,10 @@ api.removePushDevice = {
async handler (req, res) {
const { user } = res.locals;
req.checkParams('regId', res.t('regIdRequired')).notEmpty();
await param('regId', res.t('regIdRequired')).notEmpty().run(req);
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { regId } = req.params;

View File

@@ -2,6 +2,7 @@ import each from 'lodash/each';
import every from 'lodash/every';
import isBoolean from 'lodash/isBoolean';
import pick from 'lodash/pick';
import { param , validationResult } from 'express-validator';
import { authWithHeaders } from '../../middlewares/auth';
import { getAnalyticsServiceByEnvironment } from '../../libs/analyticsService';
import {
@@ -68,10 +69,10 @@ api.inviteToQuest = {
const { questKey } = req.params;
const quest = questScrolls[questKey];
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
await param('groupId', apiError('groupIdRequired')).notEmpty().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const group = await Group.getGroup({ user, groupId: req.params.groupId, fields: basicGroupFields.concat(' quest chat') });
@@ -202,10 +203,10 @@ api.acceptQuest = {
async handler (req, res) {
const { user } = res.locals;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
await param('groupId', apiError('groupIdRequired')).notEmpty().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const group = await Group.getGroup({ user, groupId: req.params.groupId, fields: basicGroupFields.concat(' quest chat') });
@@ -267,10 +268,10 @@ api.rejectQuest = {
async handler (req, res) {
const { user } = res.locals;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
await param('groupId', apiError('groupIdRequired')).notEmpty().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const group = await Group.getGroup({ user, groupId: req.params.groupId, fields: basicGroupFields.concat(' quest chat') });
if (!group) throw new NotFound(res.t('groupNotFound'));
@@ -335,10 +336,10 @@ api.forceStart = {
async handler (req, res) {
const { user } = res.locals;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
await param('groupId', apiError('groupIdRequired')).notEmpty().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const group = await Group.getGroup({ user, groupId: req.params.groupId, fields: basicGroupFields.concat(' quest chat') });
@@ -400,10 +401,10 @@ api.cancelQuest = {
const { user } = res.locals;
const { groupId } = req.params;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
await param('groupId', apiError('groupIdRequired')).notEmpty().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const group = await Group.getGroup({ user, groupId, fields: basicGroupFields.concat(' quest') });
@@ -475,10 +476,10 @@ api.abortQuest = {
const { user } = res.locals;
const { groupId } = req.params;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
await param('groupId', apiError('groupIdRequired')).notEmpty().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const group = await Group.getGroup({ user, groupId, fields: basicGroupFields.concat(' quest chat') });
@@ -549,10 +550,10 @@ api.leaveQuest = {
const { user } = res.locals;
const { groupId } = req.params;
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
await param('groupId', apiError('groupIdRequired')).notEmpty().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const group = await Group.getGroup({ user, groupId, fields: basicGroupFields.concat(' quest') });

View File

@@ -2,6 +2,7 @@ import assign from 'lodash/assign';
import find from 'lodash/find';
import merge from 'lodash/merge';
import pick from 'lodash/pick';
import { param, query , validationResult } from 'express-validator'
import moment from 'moment';
import { authWithHeaders } from '../../middlewares/auth';
import {
@@ -310,9 +311,9 @@ api.createChallengeTasks = {
url: '/tasks/challenge/:challengeId',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
await param('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID().run(req)
const reqValidationErrors = req.validationErrors();
const reqValidationErrors = validationResult(req).array();
if (reqValidationErrors) throw reqValidationErrors;
const { user } = res.locals;
@@ -394,10 +395,10 @@ api.getUserTasks = {
async handler (req, res) {
const types = Tasks.tasksTypes.map(type => `${type}s`);
types.push('completedTodos', '_allCompletedTodos'); // _allCompletedTodos is currently in BETA and is likely to be removed in future
req.checkQuery('type', res.t('invalidTasksTypeExtra')).optional().isIn(types);
await query('type', res.t('invalidTasksTypeExtra')).optional().isIn(types).run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { user } = res.locals;
const { dueDate } = req.query;
@@ -447,12 +448,12 @@ api.getChallengeTasks = {
url: '/tasks/challenge/:challengeId',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
await param('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID().run(req)
const types = Tasks.tasksTypes.map(type => `${type}s`);
req.checkQuery('type', res.t('invalidTasksType')).optional().isIn(types);
await query('type', res.t('invalidTasksType')).optional().isIn(types).run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { user } = res.locals;
const { challengeId } = req.params;
@@ -602,10 +603,10 @@ api.updateTask = {
async handler (req, res) {
const { user } = res.locals;
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
await param('taskId', apiError('taskIdRequired')).notEmpty().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { taskId } = req.params;
const task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
@@ -805,11 +806,11 @@ api.moveTask = {
url: '/tasks/:taskId/move/to/:position',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
req.checkParams('position', res.t('positionRequired')).notEmpty().isNumeric();
await param('taskId', apiError('taskIdRequired')).notEmpty().run(req)
await param('position', res.t('positionRequired')).notEmpty().isNumeric().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { user } = res.locals;
const { taskId } = req.params;
@@ -908,10 +909,10 @@ api.addChecklistItem = {
async handler (req, res) {
const { user } = res.locals;
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
await param('taskId', apiError('taskIdRequired')).notEmpty().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { taskId } = req.params;
const task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
@@ -957,11 +958,11 @@ api.scoreCheckListItem = {
async handler (req, res) {
const { user } = res.locals;
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
req.checkParams('itemId', res.t('itemIdRequired')).notEmpty().isUUID();
await param('taskId', apiError('taskIdRequired')).notEmpty().run(req)
await param('itemId', res.t('itemIdRequired')).notEmpty().isUUID().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { taskId } = req.params;
const task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
@@ -1018,11 +1019,11 @@ api.updateChecklistItem = {
async handler (req, res) {
const { user } = res.locals;
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
req.checkParams('itemId', res.t('itemIdRequired')).notEmpty().isUUID();
await param('taskId', apiError('taskIdRequired')).notEmpty().run(req)
await param('itemId', res.t('itemIdRequired')).notEmpty().isUUID().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { taskId } = req.params;
const task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
@@ -1079,11 +1080,11 @@ api.removeChecklistItem = {
async handler (req, res) {
const { user } = res.locals;
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
req.checkParams('itemId', res.t('itemIdRequired')).notEmpty().isUUID();
await param('taskId', apiError('taskIdRequired')).notEmpty().run(req)
await param('itemId', res.t('itemIdRequired')).notEmpty().isUUID().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { taskId } = req.params;
const task = await Tasks.Task.findByIdOrAlias(taskId, user._id);
@@ -1141,12 +1142,12 @@ api.addTagToTask = {
async handler (req, res) {
const { user } = res.locals;
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
await param('taskId', apiError('taskIdRequired')).notEmpty().run(req)
const userTags = user.tags.map(tag => tag.id);
req.checkParams('tagId', res.t('tagIdRequired')).notEmpty().isUUID().isIn(userTags);
await param('tagId', res.t('tagIdRequired')).notEmpty().isUUID().isIn(userTags).run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { taskId } = req.params;
const task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id });
@@ -1198,11 +1199,11 @@ api.removeTagFromTask = {
async handler (req, res) {
const { user } = res.locals;
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
req.checkParams('tagId', res.t('tagIdRequired')).notEmpty().isUUID();
await param('taskId', apiError('taskIdRequired')).notEmpty().run(req)
await param('tagId', res.t('tagIdRequired')).notEmpty().isUUID().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { taskId } = req.params;
const task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id });
@@ -1243,11 +1244,11 @@ api.unlinkAllTasks = {
url: '/tasks/unlink-all/:challengeId',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
req.checkQuery('keep', apiError('keepOrRemoveAll')).notEmpty().isIn(['keep-all', 'remove-all']);
await param('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID().run(req)
await query('keep', apiError('keepOrRemoveAll')).notEmpty().isIn(['keep-all', 'remove-all']).run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { user } = res.locals;
const { keep } = req.query;
@@ -1309,11 +1310,11 @@ api.unlinkOneTask = {
url: '/tasks/unlink-one/:taskId',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty().isUUID();
req.checkQuery('keep', apiError('keepOrRemove')).notEmpty().isIn(['keep', 'remove']);
await param('taskId', apiError('taskIdRequired')).notEmpty().isUUID().run(req)
await query('keep', apiError('keepOrRemove')).notEmpty().isIn(['keep', 'remove']).run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { user } = res.locals;
const { keep } = req.query;

View File

@@ -1,5 +1,6 @@
import pick from 'lodash/pick';
import isUUID from 'validator/lib/isUUID';
import { param , query , validationResult } from 'express-validator';
import { authWithHeaders } from '../../../middlewares/auth';
import * as Tasks from '../../../models/task';
import { model as Group } from '../../../models/group';
@@ -45,9 +46,9 @@ api.createGroupTasks = {
url: '/tasks/group/:groupId',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty().isUUID();
await param('groupId', apiError('groupIdRequired')).notEmpty().isUUID().run(req)
const reqValidationErrors = req.validationErrors();
const reqValidationErrors = validationResult(req).array();
if (reqValidationErrors) throw reqValidationErrors;
const { user } = res.locals;
@@ -92,11 +93,11 @@ api.getGroupTasks = {
url: '/tasks/group/:groupId',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty().isUUID();
req.checkQuery('type', res.t('invalidTasksType')).optional().isIn(types);
await param('groupId', apiError('groupIdRequired')).notEmpty().isUUID().run(req)
await query('type', res.t('invalidTasksType')).optional().isIn(types).run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { user } = res.locals;
@@ -132,10 +133,10 @@ api.groupMoveTask = {
url: '/group-tasks/:taskId/move/to/:position',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty();
req.checkParams('position', res.t('positionRequired')).notEmpty().isNumeric();
await param('taskId', apiError('taskIdRequired')).notEmpty().run(req)
await param('position', res.t('positionRequired')).notEmpty().isNumeric().run(req)
const reqValidationErrors = req.validationErrors();
const reqValidationErrors = validationResult(req).array();
if (reqValidationErrors) throw reqValidationErrors;
const { user } = res.locals;
@@ -203,9 +204,9 @@ api.assignTask = {
url: '/tasks/:taskId/assign',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty().isUUID();
await param('taskId', apiError('taskIdRequired')).notEmpty().isUUID().run(req)
const reqValidationErrors = req.validationErrors();
const reqValidationErrors = validationResult(req).array();
if (reqValidationErrors) throw reqValidationErrors;
const { user } = res.locals;
@@ -280,10 +281,10 @@ api.unassignTask = {
url: '/tasks/:taskId/unassign/:assignedUserId',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty().isUUID();
req.checkParams('assignedUserId', res.t('userIdRequired')).notEmpty().isUUID();
await param('taskId', apiError('taskIdRequired')).notEmpty().isUUID().run(req)
await param('assignedUserId', res.t('userIdRequired')).notEmpty().isUUID().run(req)
const reqValidationErrors = req.validationErrors();
const reqValidationErrors = validationResult(req).array();
if (reqValidationErrors) throw reqValidationErrors;
const { user } = res.locals;
@@ -337,10 +338,10 @@ api.taskNeedsWork = {
url: '/tasks/:taskId/needs-work/:userId',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkParams('taskId', apiError('taskIdRequired')).notEmpty().isUUID();
req.checkParams('userId', res.t('userIdRequired')).notEmpty().isUUID();
await param('taskId', apiError('taskIdRequired')).notEmpty().isUUID().run(req)
await param('userId', res.t('userIdRequired')).notEmpty().isUUID().run(req)
const reqValidationErrors = req.validationErrors();
const reqValidationErrors = validationResult(req).array();
if (reqValidationErrors) throw reqValidationErrors;
const { user } = res.locals;

View File

@@ -4,6 +4,7 @@ import isFunction from 'lodash/isFunction';
import pick from 'lodash/pick';
import nconf from 'nconf';
import get from 'lodash/get';
import { param , validationResult } from 'express-validator';
import { authWithHeaders } from '../../middlewares/auth';
import common from '../../../common';
import {
@@ -1735,11 +1736,11 @@ api.movePinnedItem = {
url: '/user/move-pinned-item/:path/move/to/:position',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkParams('path', res.t('taskIdRequired')).notEmpty();
req.checkParams('position', res.t('positionRequired')).notEmpty().isNumeric();
await param('path', res.t('taskIdRequired')).notEmpty().run(req)
await param('position', res.t('positionRequired')).notEmpty().isNumeric().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { user } = res.locals;
const { path } = req.params;

View File

@@ -1,5 +1,6 @@
import validator from 'validator';
import merge from 'lodash/merge';
import { param , validationResult } from 'express-validator';
import uniqBy from 'lodash/uniqBy';
import { v4 as uuid } from 'uuid';
import { authWithHeaders } from '../../middlewares/auth';
@@ -41,10 +42,10 @@ api.searchHero = {
url: '/admin/search/:userIdentifier',
middlewares: [authWithHeaders(), ensurePermission('userSupport')],
async handler (req, res) {
req.checkParams('userIdentifier', res.t('userIdentifierRequired')).notEmpty();
await param('userIdentifier', res.t('userIdentifierRequired')).notEmpty().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { userIdentifier } = req.params;
@@ -109,10 +110,10 @@ api.getUserHistory = {
url: '/admin/user/:userId/history',
middlewares: [authWithHeaders(), ensurePermission('userSupport')],
async handler (req, res) {
req.checkParams('userId', res.t('heroIdRequired')).notEmpty().isUUID();
await param('userId', res.t('heroIdRequired')).notEmpty().isUUID().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { userId } = req.params;
@@ -161,10 +162,10 @@ api.updateBlocker = {
url: '/admin/blockers/:blockerId',
middlewares: [authWithHeaders(), ensurePermission('accessControl')],
async handler (req, res) {
req.checkParams('blockerId', res.t('blockerIdRequired')).notEmpty().isUUID();
await param('blockerId', res.t('blockerIdRequired')).notEmpty().isUUID().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const blocker = await Blocker.findById(req.params.blockerId).exec();
if (!blocker) throw new NotFound(res.t('blockerNotFound'));
@@ -181,10 +182,10 @@ api.deleteBlocker = {
url: '/admin/blockers/:blockerId',
middlewares: [authWithHeaders(), ensurePermission('accessControl')],
async handler (req, res) {
req.checkParams('blockerId', res.t('blockerIdRequired')).notEmpty().isUUID();
await param('blockerId', res.t('blockerIdRequired')).notEmpty().isUUID().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const blocker = await Blocker.findById(req.params.blockerId).exec();
if (!blocker) throw new NotFound(res.t('blockerNotFound'));

View File

@@ -21,8 +21,8 @@ api.verifyUsername = {
},
});
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { user } = res.locals;
const chosenUsername = req.body.username;
@@ -105,8 +105,8 @@ api.checkEmail = {
},
});
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const lowercaseEmail = req.body.email.toLowerCase();
if (isRestrictedEmailDomain(lowercaseEmail)) {

View File

@@ -1,4 +1,5 @@
import _ from 'lodash';
import { query , validationResult } from 'express-validator';
import { langCodes } from '../../libs/i18n';
import { apiError } from '../../libs/apiError';
import common from '../../../common';
@@ -57,10 +58,10 @@ api.faq = {
method: 'GET',
url: '/faq',
async handler (req, res) {
req.checkQuery('platform').optional().isIn(['web', 'android', 'ios'], apiError('invalidPlatform'));
await query('platform').optional().isIn(['web', 'android', 'ios'], apiError('invalidPlatform')).run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const proposedLang = req.query.language && req.query.language.toString();
const language = langCodes.includes(proposedLang) ? proposedLang : 'en';

View File

@@ -1,3 +1,4 @@
import { param , validationResult } from 'express-validator';
import { authWithHeaders } from '../../middlewares/auth';
import { apiError } from '../../libs/apiError';
import { NotFound } from '../../libs/errors';
@@ -38,10 +39,10 @@ api.deleteMessage = {
middlewares: [authWithHeaders()],
url: '/inbox/messages/:messageId',
async handler (req, res) {
req.checkParams('messageId', apiError('messageIdRequired')).notEmpty().isUUID();
await param('messageId', apiError('messageIdRequired')).notEmpty().isUUID().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { messageId } = req.params;
const { user } = res.locals;
@@ -216,10 +217,10 @@ api.likePrivateMessage = {
url: '/inbox/like-private-message/:uniqueMessageId',
middlewares: [authWithHeaders()],
async handler (req, res) {
req.checkParams('uniqueMessageId', apiError('messageIdRequired')).notEmpty();
await param('uniqueMessageId', apiError('messageIdRequired')).notEmpty().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { user } = res.locals;
const { uniqueMessageId } = req.params;

View File

@@ -1,4 +1,5 @@
import { sendJob } from '../../libs/worker';
import { param , validationResult } from 'express-validator';
import { authWithHeaders } from '../../middlewares/auth';
import { ensurePermission } from '../../middlewares/ensureAccessRight';
import { TransactionModel as Transaction } from '../../models/transaction';
@@ -16,9 +17,9 @@ api.purchaseHistory = {
middlewares: [authWithHeaders(), ensurePermission('userSupport')],
url: '/members/:memberId/purchase-history',
async handler (req, res) {
req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID();
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
await param('memberId', res.t('memberIdRequired')).notEmpty().isUUID().run(req)
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
let transactions = await Transaction
.find({ userId: req.params.memberId })
.sort({ createdAt: -1 })

View File

@@ -1,4 +1,5 @@
import _ from 'lodash';
import { param , validationResult } from 'express-validator';
import { authWithHeaders } from '../../middlewares/auth';
import { apiError } from '../../libs/apiError';
import { model as NewsPost } from '../../models/newsPost';
@@ -110,7 +111,7 @@ api.getPost = {
})],
noLanguage: true,
async handler (req, res) {
req.checkParams('postId', apiError('postIdRequired')).notEmpty().isUUID();
await param('postId', apiError('postIdRequired')).notEmpty().isUUID().run(req)
const { user } = res.locals;
const newsPost = await NewsPost.findById(req.params.postId).exec();
@@ -148,9 +149,9 @@ api.updateNews = {
url: '/news/:postId',
middlewares: [authWithHeaders(), ensurePermission('news')],
async handler (req, res) {
req.checkParams('postId', apiError('postIdRequired')).notEmpty().isUUID();
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
await param('postId', apiError('postIdRequired')).notEmpty().isUUID().run(req)
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const newsPost = await NewsPost.findById(req.params.postId).exec();
if (!newsPost) throw new NotFound(res.t('newsPostNotFound'));
@@ -183,9 +184,9 @@ api.deleteNews = {
url: '/news/:postId',
middlewares: [authWithHeaders(), ensurePermission('news')],
async handler (req, res) {
req.checkParams('postId', apiError('postIdRequired')).notEmpty().isUUID();
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
await param('postId', apiError('postIdRequired')).notEmpty().isUUID().run(req)
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const newsPost = await NewsPost.findById(req.params.postId).exec();
if (!newsPost) throw new NotFound(res.t('newsPostNotFound'));

View File

@@ -252,8 +252,8 @@ api.verifyDisplayName = {
},
});
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const chosenDisplayName = req.body.displayName;

View File

@@ -177,10 +177,10 @@ api.exportUserAvatarHtml = {
async handler (/* req, res */) {
throw new NotFound('This API route is currently not available. See https://github.com/HabitRPG/habitica/issues/9489.');
/* req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID();
/* await param('memberId', res.t('memberIdRequired')).notEmpty().isUUID().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { memberId } = req.params;
@@ -215,10 +215,10 @@ api.exportUserAvatarPng = {
async handler (/* req, res */) {
throw new NotFound('This API route is currently not available. See https://github.com/HabitRPG/habitica/issues/9489.');
/* req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID();
/* await param('memberId', res.t('memberIdRequired')).notEmpty().isUUID().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { memberId } = req.params;

View File

@@ -13,8 +13,8 @@ async function emailUnsubscribe (req, res) {
notEmpty: { errorMessage: res.t('missingUnsubscriptionCode') },
},
});
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const data = JSON.parse(decrypt(req.query.code));

View File

@@ -110,8 +110,8 @@ async function registerLocal (req, res, { isV3 = false }) {
},
});
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const issues = verifyUsername(req.body.username, res);
if (issues.length > 0) throw new BadRequest(issues.join(' '));

View File

@@ -1,4 +1,5 @@
import _ from 'lodash';
import { param, query , validationResult } from 'express-validator';
import {
model as User,
publicFields as memberFields,
@@ -22,13 +23,13 @@ async function getMembersTasksForChallenge (members, challenge) {
}
export async function handleGetMembersForChallenge (req, res) {
req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
req.checkQuery('lastId').optional().notEmpty().isUUID();
await param('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID().run(req);
await query('lastId').optional().notEmpty().isUUID().run(req);
// Allow an arbitrary number of results (up to 60)
req.checkQuery('limit', res.t('groupIdRequired')).optional().notEmpty().isInt({ min: 1, max: 60 });
await query('limit', res.t('groupIdRequired')).optional().notEmpty().isInt({ min: 1, max: 60 }).run(req);
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const { challengeId } = req.params;
const { lastId } = req.query;

View File

@@ -1,5 +1,6 @@
import nconf from 'nconf';
import moment from 'moment';
import { param , validationResult } from 'express-validator';
import { getAuthorEmailFromMessage } from '../chat';
import ChatReporter from './chatReporter';
import {
@@ -23,11 +24,11 @@ export default class GroupChatReporter extends ChatReporter {
}
async validate () {
this.req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
this.req.checkParams('chatId', apiError('chatIdRequired')).notEmpty();
await param('groupId', apiError('groupIdRequired')).notEmpty().run(req)
await param('chatId', apiError('chatIdRequired')).notEmpty().run(req)
const validationErrors = this.req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = this.validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const group = await Group.getGroup({
user: this.user,

View File

@@ -1,3 +1,4 @@
import { param , validationResult } from 'express-validator';
import { model as User } from '../../models/user';
import ChatReporter from './chatReporter';
@@ -20,10 +21,10 @@ export default class InboxChatReporter extends ChatReporter {
}
async validate () {
this.req.checkParams('messageId', apiError('messageIdRequired')).notEmpty();
await param('messageId', apiError('messageIdRequired')).notEmpty().run(req)
const validationErrors = this.req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = this.validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
if (this.user.hasPermission('moderator') && this.req.query.userId) {
this.inboxUser = await User.findOne({ _id: this.req.query.userId }).exec();

View File

@@ -1,5 +1,6 @@
import { model as User } from '../../models/user';
import * as slack from '../slack';
import { param , validationResult } from 'express-validator';
import ChatReporter from './chatReporter';
import {
@@ -15,10 +16,10 @@ export default class ProfileReporter extends ChatReporter {
}
async validate () {
this.req.checkParams('memberId', this.res.t('memberIdRequired')).notEmpty().isUUID();
await param('memberId', this.res.t('memberIdRequired')).notEmpty().isUUID().run(req)
const validationErrors = this.req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = this.validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
const flaggedUser = await User.findOne(
{ _id: this.req.params.memberId },

View File

@@ -1,10 +1,11 @@
import { param , validationResult } from 'express-validator';
import { model as Coupon } from '../../models/coupon';
export async function enterCode (req, res, user) { // eslint-disable-line import/prefer-default-export, max-len
req.checkParams('code', res.t('couponCodeRequired')).notEmpty();
await param('code', res.t('couponCodeRequired')).notEmpty().run(req)
const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
const validationErrors = validationResult(req).array();
if (validationErrors && validationErrors.length > 0) throw validationErrors;
await Coupon.apply(user, req, req.params.code);
}

View File

@@ -1,3 +1,5 @@
import { query, validationResult } from 'express-validator';
import { model as User } from '../models/user';
import { chatModel as Chat } from '../models/message';
import * as Tasks from '../models/task';
@@ -157,9 +159,9 @@ async function castSpell (req, res, { isV3 = false }) {
const quantity = req.body.quantity || 1;
// optional because not required by all targetTypes, presence is checked later if necessary
req.checkQuery('targetId', res.t('targetIdUUID')).optional().isUUID();
await query('targetId', res.t('targetIdUUID')).optional().isUUID().run(req)
const reqValidationErrors = req.validationErrors();
const reqValidationErrors = validationResult(req).array();
if (reqValidationErrors) throw reqValidationErrors;
const klass = common.content.spells.special[spellId] ? 'special' : user.stats.class;

View File

@@ -97,7 +97,7 @@ async function createTasks (req, res, options = {}) {
// and task in parallel it could save the user/challenge/group
// with a tasksOrder that doens't match reality
const validationErrors = newTask.validateSync();
if (validationErrors) throw validationErrors;
if (validationErrors && validationErrors.length > 0) throw validationErrors;
// Otherwise update the user/challenge/group
if (!taskOrderToAdd[`${taskType}s`]) taskOrderToAdd[`${taskType}s`] = [];

View File

@@ -1,5 +1,4 @@
import express from 'express';
import expressValidator from 'express-validator';
import path from 'path';
import analytics from './analytics';
import setupBody from './setupBody';
@@ -16,7 +15,6 @@ const app = express();
// re-set the view options because they are not inherited from the top level app
setupExpress(app);
app.use(expressValidator());
app.use(analytics);
app.use(setupBody);

View File

@@ -27,11 +27,11 @@ export default function errorHandler (err, req, res, next) { // eslint-disable-l
}
// Handle errors by express-validator
if (Array.isArray(err) && err[0].param && err[0].msg) {
if (Array.isArray(err) && err.length >= 1 && err[0].path && err[0].msg) {
responseErr = new BadRequest(res.t('invalidReqParams'));
responseErr.errors = err.map(paramErr => ({
message: paramErr.msg,
param: paramErr.param,
param: paramErr.path,
value: paramErr.value,
}));
}
@@ -66,7 +66,7 @@ export default function errorHandler (err, req, res, next) { // eslint-disable-l
responseErr = new InternalServerError();
}
if (!err.skipLogging) {
if (!err.skipLogging && err instanceof Error) {
// log the error
logger.error(err, {
method: req.method,

View File

@@ -11,7 +11,7 @@ const router = express.Router(); // eslint-disable-line new-cap
const BASE_URL = nconf.get('BASE_URL');
router.all('*', (req, res, next) => {
router.all('*route', (req, res, next) => {
const error = new NotFound(`API v1 is no longer supported, please use API v3 instead (${BASE_URL}/apidoc).`);
return next(error);
});

View File

@@ -11,7 +11,7 @@ const router = express.Router(); // eslint-disable-line new-cap
const BASE_URL = nconf.get('BASE_URL');
router.all('*', (req, res, next) => {
router.all('*route', (req, res, next) => {
const error = new NotFound(`API v2 is no longer supported, please use API v3 instead (${BASE_URL}/apidoc).`);
return next(error);
});