From b60e5f38daf77e720a27aa86d3b482c58906a03a Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 15 Sep 2017 12:17:08 +0200 Subject: Upgrade express validator to v4 --- server/helpers/custom-validators/misc.ts | 7 - server/helpers/custom-validators/pods.ts | 7 - server/helpers/custom-validators/remote/videos.ts | 8 - server/helpers/custom-validators/users.ts | 10 - server/helpers/custom-validators/videos.ts | 36 +-- server/middlewares/validators/pagination.ts | 16 +- server/middlewares/validators/pods.ts | 155 ++++++------ server/middlewares/validators/remote/signature.ts | 18 +- server/middlewares/validators/remote/videos.ts | 45 ++-- server/middlewares/validators/sort.ts | 28 +-- server/middlewares/validators/users.ts | 219 +++++++++------- server/middlewares/validators/utils.ts | 11 +- server/middlewares/validators/videos.ts | 294 ++++++++++++---------- 13 files changed, 430 insertions(+), 424 deletions(-) (limited to 'server') diff --git a/server/helpers/custom-validators/misc.ts b/server/helpers/custom-validators/misc.ts index 8d215a416..60fcdd5bb 100644 --- a/server/helpers/custom-validators/misc.ts +++ b/server/helpers/custom-validators/misc.ts @@ -14,10 +14,3 @@ export { exists, isArray } - -declare module 'express-validator' { - export interface Validator { - exists, - isArray - } -} diff --git a/server/helpers/custom-validators/pods.ts b/server/helpers/custom-validators/pods.ts index 844bfdf78..d5021bf38 100644 --- a/server/helpers/custom-validators/pods.ts +++ b/server/helpers/custom-validators/pods.ts @@ -32,10 +32,3 @@ export { isEachUniqueHostValid, isHostValid } - -declare module 'express-validator' { - export interface Validator { - isEachUniqueHostValid - isHostValid - } -} diff --git a/server/helpers/custom-validators/remote/videos.ts b/server/helpers/custom-validators/remote/videos.ts index e5c76f3ca..e261e05a8 100644 --- a/server/helpers/custom-validators/remote/videos.ts +++ b/server/helpers/custom-validators/remote/videos.ts @@ -102,14 +102,6 @@ export { isEachRemoteRequestVideosEventsValid } -declare module 'express-validator' { - export interface Validator { - isEachRemoteRequestVideosValid, - isEachRemoteRequestVideosQaduValid, - isEachRemoteRequestVideosEventsValid - } -} - // --------------------------------------------------------------------------- function isCommonVideoAttributesValid (video: any) { diff --git a/server/helpers/custom-validators/users.ts b/server/helpers/custom-validators/users.ts index 805437efa..c180eccda 100644 --- a/server/helpers/custom-validators/users.ts +++ b/server/helpers/custom-validators/users.ts @@ -39,13 +39,3 @@ export { isUserUsernameValid, isUserDisplayNSFWValid } - -declare module 'express-validator' { - export interface Validator { - isUserPasswordValid, - isUserRoleValid, - isUserUsernameValid, - isUserDisplayNSFWValid, - isUserVideoQuotaValid - } -} diff --git a/server/helpers/custom-validators/videos.ts b/server/helpers/custom-validators/videos.ts index 1d27e47fc..2eb021ae7 100644 --- a/server/helpers/custom-validators/videos.ts +++ b/server/helpers/custom-validators/videos.ts @@ -107,12 +107,13 @@ function isVideoRatingTypeValid (value: string) { return values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1 } -function isVideoFile (value: string, files: { [ fieldname: string ]: Express.Multer.File[] }) { +function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) { // Should have files if (!files) return false + if (isArray(files)) return false // Should have videofile file - const videofile = files.videofile + const videofile = files['videofile'] if (!videofile || videofile.length === 0) return false // The file should exist @@ -168,34 +169,3 @@ export { isVideoFileSizeValid, isVideoFileResolutionValid } - -declare module 'express-validator' { - export interface Validator { - isVideoIdOrUUIDValid, - isVideoAuthorValid, - isVideoDateValid, - isVideoCategoryValid, - isVideoLicenceValid, - isVideoLanguageValid, - isVideoNSFWValid, - isVideoDescriptionValid, - isVideoDurationValid, - isVideoInfoHashValid, - isVideoNameValid, - isVideoTagsValid, - isVideoThumbnailValid, - isVideoThumbnailDataValid, - isVideoExtnameValid, - isVideoUUIDValid, - isVideoAbuseReasonValid, - isVideoAbuseReporterUsernameValid, - isVideoFile, - isVideoViewsValid, - isVideoLikesValid, - isVideoRatingTypeValid, - isVideoDislikesValid, - isVideoEventCountValid, - isVideoFileSizeValid, - isVideoFileResolutionValid - } -} diff --git a/server/middlewares/validators/pagination.ts b/server/middlewares/validators/pagination.ts index cca8295ff..a5a542cdf 100644 --- a/server/middlewares/validators/pagination.ts +++ b/server/middlewares/validators/pagination.ts @@ -1,17 +1,19 @@ -import 'express-validator' +import { query } from 'express-validator/check' import * as express from 'express' import { checkErrors } from './utils' import { logger } from '../../helpers' -function paginationValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - req.checkQuery('start', 'Should have a number start').optional().isInt() - req.checkQuery('count', 'Should have a number count').optional().isInt() +const paginationValidator = [ + query('start').optional().isInt().withMessage('Should have a number start'), + query('count').optional().isInt().withMessage('Should have a number count'), - logger.debug('Checking pagination parameters', { parameters: req.query }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking pagination parameters', { parameters: req.query }) - checkErrors(req, res, next) -} + checkErrors(req, res, next) + } +] // --------------------------------------------------------------------------- diff --git a/server/middlewares/validators/pods.ts b/server/middlewares/validators/pods.ts index 3a0f56f6a..ab7702e78 100644 --- a/server/middlewares/validators/pods.ts +++ b/server/middlewares/validators/pods.ts @@ -1,89 +1,96 @@ -import 'express-validator' +import { body, param } from 'express-validator/check' import * as express from 'express' import { database as db } from '../../initializers/database' import { checkErrors } from './utils' -import { logger } from '../../helpers' +import { logger, isEachUniqueHostValid, isHostValid } from '../../helpers' import { CONFIG } from '../../initializers' import { hasFriends } from '../../lib' import { isTestInstance } from '../../helpers' -function makeFriendsValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - // Force https if the administrator wants to make friends - if (isTestInstance() === false && CONFIG.WEBSERVER.SCHEME === 'http') { - return res.status(400) - .json({ - error: 'Cannot make friends with a non HTTPS web server.' - }) - .end() +const makeFriendsValidator = [ + body('hosts').custom(isEachUniqueHostValid).withMessage('Should have an array of unique hosts'), + + (req: express.Request, res: express.Response, next: express.NextFunction) => { + // Force https if the administrator wants to make friends + if (isTestInstance() === false && CONFIG.WEBSERVER.SCHEME === 'http') { + return res.status(400) + .json({ + error: 'Cannot make friends with a non HTTPS web server.' + }) + .end() + } + + logger.debug('Checking makeFriends parameters', { parameters: req.body }) + + checkErrors(req, res, () => { + hasFriends() + .then(heHasFriends => { + if (heHasFriends === true) { + // We need to quit our friends before make new ones + return res.sendStatus(409) + } + + return next() + }) + .catch(err => { + logger.error('Cannot know if we have friends.', err) + res.sendStatus(500) + }) + }) } +] - req.checkBody('hosts', 'Should have an array of unique hosts').isEachUniqueHostValid() - - logger.debug('Checking makeFriends parameters', { parameters: req.body }) - - checkErrors(req, res, () => { - hasFriends() - .then(heHasFriends => { - if (heHasFriends === true) { - // We need to quit our friends before make new ones - return res.sendStatus(409) - } - - return next() - }) - .catch(err => { - logger.error('Cannot know if we have friends.', err) - res.sendStatus(500) - }) - }) -} +const podsAddValidator = [ + body('host').custom(isHostValid).withMessage('Should have a host'), + body('email').isEmail().withMessage('Should have an email'), + body('publicKey').not().isEmpty().withMessage('Should have a public key'), -function podsAddValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - req.checkBody('host', 'Should have a host').isHostValid() - req.checkBody('email', 'Should have an email').isEmail() - req.checkBody('publicKey', 'Should have a public key').notEmpty() - logger.debug('Checking podsAdd parameters', { parameters: req.body }) - - checkErrors(req, res, () => { - db.Pod.loadByHost(req.body.host) - .then(pod => { - // Pod with this host already exists - if (pod) { - return res.sendStatus(409) - } - - return next() - }) - .catch(err => { - logger.error('Cannot load pod by host.', err) - res.sendStatus(500) - }) - }) -} + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking podsAdd parameters', { parameters: req.body }) -function podRemoveValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - req.checkParams('id', 'Should have a valid id').notEmpty().isNumeric() - - logger.debug('Checking podRemoveValidator parameters', { parameters: req.params }) - - checkErrors(req, res, function () { - db.Pod.load(req.params.id) - .then(pod => { - if (!pod) { - logger.error('Cannot find pod %d.', req.params.id) - return res.sendStatus(404) - } - - res.locals.pod = pod - return next() - }) - .catch(err => { - logger.error('Cannot load pod %d.', req.params.id, err) - res.sendStatus(500) - }) - }) -} + checkErrors(req, res, () => { + db.Pod.loadByHost(req.body.host) + .then(pod => { + // Pod with this host already exists + if (pod) { + return res.sendStatus(409) + } + + return next() + }) + .catch(err => { + logger.error('Cannot load pod by host.', err) + res.sendStatus(500) + }) + }) + } +] + +const podRemoveValidator = [ + param('id').isNumeric().not().isEmpty().withMessage('Should have a valid id'), + + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking podRemoveValidator parameters', { parameters: req.params }) + + checkErrors(req, res, () => { + db.Pod.load(req.params.id) + .then(pod => { + if (!pod) { + logger.error('Cannot find pod %d.', req.params.id) + return res.sendStatus(404) + } + + res.locals.pod = pod + return next() + }) + .catch(err => { + logger.error('Cannot load pod %d.', req.params.id, err) + res.sendStatus(500) + }) + }) + } +] // --------------------------------------------------------------------------- diff --git a/server/middlewares/validators/remote/signature.ts b/server/middlewares/validators/remote/signature.ts index eb5c196eb..d3937b515 100644 --- a/server/middlewares/validators/remote/signature.ts +++ b/server/middlewares/validators/remote/signature.ts @@ -1,17 +1,19 @@ -import 'express-validator' +import { body } from 'express-validator/check' import * as express from 'express' -import { logger } from '../../../helpers' +import { logger, isHostValid } from '../../../helpers' import { checkErrors } from '../utils' -function signatureValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - req.checkBody('signature.host', 'Should have a signature host').isURL() - req.checkBody('signature.signature', 'Should have a signature').notEmpty() +const signatureValidator = [ + body('signature.host').custom(isHostValid).withMessage('Should have a signature host'), + body('signature.signature').not().isEmpty().withMessage('Should have a signature'), - logger.debug('Checking signature parameters', { parameters: { signature: req.body.signature } }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking signature parameters', { parameters: { signature: req.body.signature } }) - checkErrors(req, res, next) -} + checkErrors(req, res, next) + } +] // --------------------------------------------------------------------------- diff --git a/server/middlewares/validators/remote/videos.ts b/server/middlewares/validators/remote/videos.ts index 2037c0085..e4682a60b 100644 --- a/server/middlewares/validators/remote/videos.ts +++ b/server/middlewares/validators/remote/videos.ts @@ -1,32 +1,43 @@ -import 'express-validator' +import { body } from 'express-validator/check' import * as express from 'express' -import { logger } from '../../../helpers' +import { + logger, + isEachRemoteRequestVideosValid, + isEachRemoteRequestVideosQaduValid, + isEachRemoteRequestVideosEventsValid +} from '../../../helpers' import { checkErrors } from '../utils' -function remoteVideosValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - req.checkBody('data').isEachRemoteRequestVideosValid() +const remoteVideosValidator = [ + body('data').custom(isEachRemoteRequestVideosValid), - logger.debug('Checking remoteVideos parameters', { parameters: req.body }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking remoteVideos parameters', { parameters: req.body }) - checkErrors(req, res, next) -} + checkErrors(req, res, next) + } +] -function remoteQaduVideosValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - req.checkBody('data').isEachRemoteRequestVideosQaduValid() +const remoteQaduVideosValidator = [ + body('data').custom(isEachRemoteRequestVideosQaduValid), - logger.debug('Checking remoteQaduVideos parameters', { parameters: req.body }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking remoteQaduVideos parameters', { parameters: req.body }) - checkErrors(req, res, next) -} + checkErrors(req, res, next) + } +] -function remoteEventsVideosValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - req.checkBody('data').isEachRemoteRequestVideosEventsValid() +const remoteEventsVideosValidator = [ + body('data').custom(isEachRemoteRequestVideosEventsValid), - logger.debug('Checking remoteEventsVideos parameters', { parameters: req.body }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking remoteEventsVideos parameters', { parameters: req.body }) - checkErrors(req, res, next) -} + checkErrors(req, res, next) + } +] // --------------------------------------------------------------------------- diff --git a/server/middlewares/validators/sort.ts b/server/middlewares/validators/sort.ts index 3baee9fb3..71b18acb0 100644 --- a/server/middlewares/validators/sort.ts +++ b/server/middlewares/validators/sort.ts @@ -1,4 +1,4 @@ -import 'express-validator' +import { query } from 'express-validator/check' import * as express from 'express' import { checkErrors } from './utils' @@ -10,17 +10,9 @@ const SORTABLE_USERS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.USERS) const SORTABLE_VIDEO_ABUSES_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEO_ABUSES) const SORTABLE_VIDEOS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEOS) -function usersSortValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - checkSort(req, res, next, SORTABLE_USERS_COLUMNS) -} - -function videoAbusesSortValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - checkSort(req, res, next, SORTABLE_VIDEO_ABUSES_COLUMNS) -} - -function videosSortValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - checkSort(req, res, next, SORTABLE_VIDEOS_COLUMNS) -} +const usersSortValidator = checkSort(SORTABLE_USERS_COLUMNS) +const videoAbusesSortValidator = checkSort(SORTABLE_VIDEO_ABUSES_COLUMNS) +const videosSortValidator = checkSort(SORTABLE_VIDEOS_COLUMNS) // --------------------------------------------------------------------------- @@ -32,12 +24,16 @@ export { // --------------------------------------------------------------------------- -function checkSort (req: express.Request, res: express.Response, next: express.NextFunction, sortableColumns: string[]) { - req.checkQuery('sort', 'Should have correct sortable column').optional().isIn(sortableColumns) +function checkSort (sortableColumns: string[]) { + return [ + query('sort').optional().isIn(sortableColumns).withMessage('Should have correct sortable column'), - logger.debug('Checking sort parameters', { parameters: req.query }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking sort parameters', { parameters: req.query }) - checkErrors(req, res, next) + checkErrors(req, res, next) + } + ] } function createSortableColumns (sortableColumns: string[]) { diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts index 15c07c693..ab9d0938c 100644 --- a/server/middlewares/validators/users.ts +++ b/server/middlewares/validators/users.ts @@ -1,3 +1,4 @@ +import { body, param } from 'express-validator/check' import 'express-validator' import * as express from 'express' import * as Promise from 'bluebird' @@ -5,130 +6,154 @@ import * as validator from 'validator' import { database as db } from '../../initializers/database' import { checkErrors } from './utils' -import { isSignupAllowed, logger } from '../../helpers' +import { + isSignupAllowed, + logger, + isUserUsernameValid, + isUserPasswordValid, + isUserVideoQuotaValid, + isUserDisplayNSFWValid, + isVideoIdOrUUIDValid +} from '../../helpers' import { UserInstance, VideoInstance } from '../../models' -function usersAddValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - req.checkBody('username', 'Should have a valid username').isUserUsernameValid() - req.checkBody('password', 'Should have a valid password').isUserPasswordValid() - req.checkBody('email', 'Should have a valid email').isEmail() - req.checkBody('videoQuota', 'Should have a valid user quota').isUserVideoQuotaValid() +const usersAddValidator = [ + body('username').custom(isUserUsernameValid).withMessage('Should have a valid username'), + body('password').custom(isUserPasswordValid).withMessage('Should have a valid password'), + body('email').isEmail().withMessage('Should have a valid email'), + body('videoQuota').custom(isUserVideoQuotaValid).withMessage('Should have a valid user quota'), - logger.debug('Checking usersAdd parameters', { parameters: req.body }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking usersAdd parameters', { parameters: req.body }) - checkErrors(req, res, () => { - checkUserDoesNotAlreadyExist(req.body.username, req.body.email, res, next) - }) -} + checkErrors(req, res, () => { + checkUserDoesNotAlreadyExist(req.body.username, req.body.email, res, next) + }) + } +] -function usersRegisterValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - req.checkBody('username', 'Should have a valid username').isUserUsernameValid() - req.checkBody('password', 'Should have a valid password').isUserPasswordValid() - req.checkBody('email', 'Should have a valid email').isEmail() +const usersRegisterValidator = [ + body('username').custom(isUserUsernameValid).withMessage('Should have a valid username'), + body('password').custom(isUserPasswordValid).withMessage('Should have a valid password'), + body('email').isEmail().withMessage('Should have a valid email'), - logger.debug('Checking usersRegister parameters', { parameters: req.body }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking usersRegister parameters', { parameters: req.body }) - checkErrors(req, res, () => { - checkUserDoesNotAlreadyExist(req.body.username, req.body.email, res, next) - }) -} + checkErrors(req, res, () => { + checkUserDoesNotAlreadyExist(req.body.username, req.body.email, res, next) + }) + } +] -function usersRemoveValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - req.checkParams('id', 'Should have a valid id').notEmpty().isInt() +const usersRemoveValidator = [ + param('id').isInt().not().isEmpty().withMessage('Should have a valid id'), - logger.debug('Checking usersRemove parameters', { parameters: req.params }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking usersRemove parameters', { parameters: req.params }) - checkErrors(req, res, () => { - checkUserExists(req.params.id, res, (err, user) => { - if (err) { - logger.error('Error in usersRemoveValidator.', err) - return res.sendStatus(500) - } + checkErrors(req, res, () => { + checkUserExists(req.params.id, res, (err, user) => { + if (err) { + logger.error('Error in usersRemoveValidator.', err) + return res.sendStatus(500) + } - if (user.username === 'root') { - return res.status(400) - .send({ error: 'Cannot remove the root user' }) - .end() - } + if (user.username === 'root') { + return res.status(400) + .send({ error: 'Cannot remove the root user' }) + .end() + } - return next() + return next() + }) }) - }) -} + } +] -function usersUpdateValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - req.checkParams('id', 'Should have a valid id').notEmpty().isInt() - req.checkBody('email', 'Should have a valid email attribute').optional().isEmail() - req.checkBody('videoQuota', 'Should have a valid user quota').optional().isUserVideoQuotaValid() +const usersUpdateValidator = [ + param('id').isInt().not().isEmpty().withMessage('Should have a valid id'), + body('email').optional().isEmail().withMessage('Should have a valid email attribute'), + body('videoQuota').optional().custom(isUserVideoQuotaValid).withMessage('Should have a valid user quota'), - logger.debug('Checking usersUpdate parameters', { parameters: req.body }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking usersUpdate parameters', { parameters: req.body }) - checkErrors(req, res, () => { - checkUserExists(req.params.id, res, next) - }) -} + checkErrors(req, res, () => { + checkUserExists(req.params.id, res, next) + }) + } +] -function usersUpdateMeValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - // Add old password verification - req.checkBody('password', 'Should have a valid password').optional().isUserPasswordValid() - req.checkBody('email', 'Should have a valid email attribute').optional().isEmail() - req.checkBody('displayNSFW', 'Should have a valid display Not Safe For Work attribute').optional().isUserDisplayNSFWValid() +const usersUpdateMeValidator = [ + body('password').optional().custom(isUserPasswordValid).withMessage('Should have a valid password'), + body('email').optional().isEmail().withMessage('Should have a valid email attribute'), + body('displayNSFW').optional().custom(isUserDisplayNSFWValid).withMessage('Should have a valid display Not Safe For Work attribute'), - logger.debug('Checking usersUpdateMe parameters', { parameters: req.body }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + // TODO: Add old password verification + logger.debug('Checking usersUpdateMe parameters', { parameters: req.body }) - checkErrors(req, res, next) -} + checkErrors(req, res, next) + } +] -function usersGetValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - req.checkParams('id', 'Should have a valid id').notEmpty().isInt() +const usersGetValidator = [ + param('id').isInt().not().isEmpty().withMessage('Should have a valid id'), - checkErrors(req, res, () => { - checkUserExists(req.params.id, res, next) - }) -} - -function usersVideoRatingValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - req.checkParams('videoId', 'Should have a valid video id').notEmpty().isVideoIdOrUUIDValid() - - logger.debug('Checking usersVideoRating parameters', { parameters: req.params }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + checkErrors(req, res, () => { + checkUserExists(req.params.id, res, next) + }) + } +] - checkErrors(req, res, () => { - let videoPromise: Promise +const usersVideoRatingValidator = [ + param('videoId').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'), - if (validator.isUUID(req.params.videoId)) { - videoPromise = db.Video.loadByUUID(req.params.videoId) - } else { - videoPromise = db.Video.load(req.params.videoId) - } + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking usersVideoRating parameters', { parameters: req.params }) - videoPromise - .then(video => { - if (!video) { - return res.status(404) - .json({ error: 'Video not found' }) - .end() - } + checkErrors(req, res, () => { + let videoPromise: Promise - return next() - }) - .catch(err => { - logger.error('Error in user request validator.', err) - return res.sendStatus(500) - }) - }) -} + if (validator.isUUID(req.params.videoId)) { + videoPromise = db.Video.loadByUUID(req.params.videoId) + } else { + videoPromise = db.Video.load(req.params.videoId) + } -function ensureUserRegistrationAllowed (req: express.Request, res: express.Response, next: express.NextFunction) { - isSignupAllowed().then(allowed => { - if (allowed === false) { - return res.status(403) - .send({ error: 'User registration is not enabled or user limit is reached.' }) - .end() - } + videoPromise + .then(video => { + if (!video) { + return res.status(404) + .json({ error: 'Video not found' }) + .end() + } + + return next() + }) + .catch(err => { + logger.error('Error in user request validator.', err) + return res.sendStatus(500) + }) + }) + } +] + +const ensureUserRegistrationAllowed = [ + (req: express.Request, res: express.Response, next: express.NextFunction) => { + isSignupAllowed().then(allowed => { + if (allowed === false) { + return res.status(403) + .send({ error: 'User registration is not enabled or user limit is reached.' }) + .end() + } - return next() - }) -} + return next() + }) + } +] // --------------------------------------------------------------------------- diff --git a/server/middlewares/validators/utils.ts b/server/middlewares/validators/utils.ts index 0424d5942..8845f8399 100644 --- a/server/middlewares/validators/utils.ts +++ b/server/middlewares/validators/utils.ts @@ -1,15 +1,14 @@ -import 'express-validator' +import { validationResult } from 'express-validator/check' import * as express from 'express' -import { inspect } from 'util' import { logger } from '../../helpers' function checkErrors (req: express.Request, res: express.Response, next: express.NextFunction, statusCode = 400) { - const errors = req.validationErrors() + const errors = validationResult(req) - if (errors) { - logger.warn('Incorrect request parameters', { path: req.originalUrl, err: errors }) - return res.status(statusCode).send('There have been validation errors: ' + inspect(errors)) + if (!errors.isEmpty()) { + logger.warn('Incorrect request parameters', { path: req.originalUrl, err: errors.mapped() }) + return res.status(statusCode).json({ errors: errors.mapped() }) } return next() diff --git a/server/middlewares/validators/videos.ts b/server/middlewares/validators/videos.ts index 213b4c46b..bc8b7e541 100644 --- a/server/middlewares/validators/videos.ts +++ b/server/middlewares/validators/videos.ts @@ -1,4 +1,4 @@ -import 'express-validator' +import { body, param, query } from 'express-validator/check' import * as express from 'express' import * as Promise from 'bluebird' import * as validator from 'validator' @@ -6,172 +6,198 @@ import * as validator from 'validator' import { database as db } from '../../initializers/database' import { checkErrors } from './utils' import { CONSTRAINTS_FIELDS, SEARCHABLE_COLUMNS } from '../../initializers' -import { logger, isVideoDurationValid } from '../../helpers' +import { + logger, + isVideoDurationValid, + isVideoFile, + isVideoNameValid, + isVideoCategoryValid, + isVideoLicenceValid, + isVideoDescriptionValid, + isVideoLanguageValid, + isVideoTagsValid, + isVideoNSFWValid, + isVideoIdOrUUIDValid, + isVideoAbuseReasonValid, + isVideoRatingTypeValid +} from '../../helpers' import { VideoInstance } from '../../models' -function videosAddValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - // FIXME: Don't write an error message, it seems there is a bug with express-validator - // 'Should have a valid file' - req.checkBody('videofile').isVideoFile(req.files) - req.checkBody('name', 'Should have a valid name').isVideoNameValid() - req.checkBody('category', 'Should have a valid category').isVideoCategoryValid() - req.checkBody('licence', 'Should have a valid licence').isVideoLicenceValid() - req.checkBody('language', 'Should have a valid language').optional().isVideoLanguageValid() - req.checkBody('nsfw', 'Should have a valid NSFW attribute').isVideoNSFWValid() - req.checkBody('description', 'Should have a valid description').isVideoDescriptionValid() - req.checkBody('tags', 'Should have correct tags').optional().isVideoTagsValid() - - logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files }) - - checkErrors(req, res, () => { - const videoFile: Express.Multer.File = req.files['videofile'][0] - const user = res.locals.oauth.token.User - - user.isAbleToUploadVideo(videoFile) - .then(isAble => { - if (isAble === false) { - res.status(403) - .json({ error: 'The user video quota is exceeded with this video.' }) - .end() +const videosAddValidator = [ + body('videofile').custom((value, { req }) => isVideoFile(req.files)).withMessage('Should have a valid file'), + body('name').custom(isVideoNameValid).withMessage('Should have a valid name'), + body('category').custom(isVideoCategoryValid).withMessage('Should have a valid category'), + body('licence').custom(isVideoLicenceValid).withMessage('Should have a valid licence'), + body('language').optional().custom(isVideoLanguageValid).withMessage('Should have a valid language'), + body('nsfw').custom(isVideoNSFWValid).withMessage('Should have a valid NSFW attribute'), + body('description').custom(isVideoDescriptionValid).withMessage('Should have a valid description'), + body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'), + + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files }) + + checkErrors(req, res, () => { + const videoFile: Express.Multer.File = req.files['videofile'][0] + const user = res.locals.oauth.token.User + + user.isAbleToUploadVideo(videoFile) + .then(isAble => { + if (isAble === false) { + res.status(403) + .json({ error: 'The user video quota is exceeded with this video.' }) + .end() + + return undefined + } + + return db.Video.getDurationFromFile(videoFile.path) + .catch(err => { + logger.error('Invalid input file in videosAddValidator.', err) + res.status(400) + .json({ error: 'Invalid input file.' }) + .end() + + return undefined + }) + }) + .then(duration => { + // Previous test failed, abort + if (duration === undefined) return + + if (!isVideoDurationValid('' + duration)) { + return res.status(400) + .json({ + error: 'Duration of the video file is too big (max: ' + CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).' + }) + .end() + } + + videoFile['duration'] = duration + next() + }) + .catch(err => { + logger.error('Error in video add validator', err) + res.sendStatus(500) return undefined + }) + }) + } +] + +const videosUpdateValidator = [ + param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), + body('name').optional().custom(isVideoNameValid).withMessage('Should have a valid name'), + body('category').optional().custom(isVideoCategoryValid).withMessage('Should have a valid category'), + body('licence').optional().custom(isVideoLicenceValid).withMessage('Should have a valid licence'), + body('language').optional().custom(isVideoLanguageValid).withMessage('Should have a valid language'), + body('nsfw').optional().custom(isVideoNSFWValid).withMessage('Should have a valid NSFW attribute'), + body('description').optional().custom(isVideoDescriptionValid).withMessage('Should have a valid description'), + body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'), + + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking videosUpdate parameters', { parameters: req.body }) + + checkErrors(req, res, () => { + checkVideoExists(req.params.id, res, () => { + // We need to make additional checks + if (res.locals.video.isOwned() === false) { + return res.status(403) + .json({ error: 'Cannot update video of another pod' }) + .end() } - return db.Video.getDurationFromFile(videoFile.path) - .catch(err => { - logger.error('Invalid input file in videosAddValidator.', err) - res.status(400) - .json({ error: 'Invalid input file.' }) - .end() - - return undefined - }) - }) - .then(duration => { - // Previous test failed, abort - if (duration === undefined) return - - if (!isVideoDurationValid('' + duration)) { - return res.status(400) - .json({ - error: 'Duration of the video file is too big (max: ' + CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).' - }) + if (res.locals.video.Author.userId !== res.locals.oauth.token.User.id) { + return res.status(403) + .json({ error: 'Cannot update video of another user' }) .end() } - videoFile['duration'] = duration next() }) - .catch(err => { - logger.error('Error in video add validator', err) - res.sendStatus(500) - - return undefined - }) - - }) -} - -function videosUpdateValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() - req.checkBody('name', 'Should have a valid name').optional().isVideoNameValid() - req.checkBody('category', 'Should have a valid category').optional().isVideoCategoryValid() - req.checkBody('licence', 'Should have a valid licence').optional().isVideoLicenceValid() - req.checkBody('language', 'Should have a valid language').optional().isVideoLanguageValid() - req.checkBody('nsfw', 'Should have a valid NSFW attribute').optional().isVideoNSFWValid() - req.checkBody('description', 'Should have a valid description').optional().isVideoDescriptionValid() - req.checkBody('tags', 'Should have correct tags').optional().isVideoTagsValid() - - logger.debug('Checking videosUpdate parameters', { parameters: req.body }) - - checkErrors(req, res, () => { - checkVideoExists(req.params.id, res, () => { - // We need to make additional checks - if (res.locals.video.isOwned() === false) { - return res.status(403) - .json({ error: 'Cannot update video of another pod' }) - .end() - } - - if (res.locals.video.Author.userId !== res.locals.oauth.token.User.id) { - return res.status(403) - .json({ error: 'Cannot update video of another user' }) - .end() - } - - next() }) - }) -} + } +] -function videosGetValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() +const videosGetValidator = [ + param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), - logger.debug('Checking videosGet parameters', { parameters: req.params }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking videosGet parameters', { parameters: req.params }) - checkErrors(req, res, () => { - checkVideoExists(req.params.id, res, next) - }) -} + checkErrors(req, res, () => { + checkVideoExists(req.params.id, res, next) + }) + } +] -function videosRemoveValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() +const videosRemoveValidator = [ + param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), - logger.debug('Checking videosRemove parameters', { parameters: req.params }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking videosRemove parameters', { parameters: req.params }) - checkErrors(req, res, () => { - checkVideoExists(req.params.id, res, () => { - // Check if the user who did the request is able to delete the video - checkUserCanDeleteVideo(res.locals.oauth.token.User.id, res, () => { - next() + checkErrors(req, res, () => { + checkVideoExists(req.params.id, res, () => { + // Check if the user who did the request is able to delete the video + checkUserCanDeleteVideo(res.locals.oauth.token.User.id, res, () => { + next() + }) }) }) - }) -} + } +] -function videosSearchValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - const searchableColumns = SEARCHABLE_COLUMNS.VIDEOS - req.checkParams('value', 'Should have a valid search').notEmpty() - req.checkQuery('field', 'Should have correct searchable column').optional().isIn(searchableColumns) +const videosSearchValidator = [ + param('value').not().isEmpty().withMessage('Should have a valid search'), + query('field').optional().isIn(SEARCHABLE_COLUMNS.VIDEOS).withMessage('Should have correct searchable column'), - logger.debug('Checking videosSearch parameters', { parameters: req.params }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking videosSearch parameters', { parameters: req.params }) - checkErrors(req, res, next) -} + checkErrors(req, res, next) + } +] -function videoAbuseReportValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() - req.checkBody('reason', 'Should have a valid reason').isVideoAbuseReasonValid() +const videoAbuseReportValidator = [ + param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), + body('reason').custom(isVideoAbuseReasonValid).withMessage('Should have a valid reason'), - logger.debug('Checking videoAbuseReport parameters', { parameters: req.body }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking videoAbuseReport parameters', { parameters: req.body }) - checkErrors(req, res, () => { - checkVideoExists(req.params.id, res, next) - }) -} + checkErrors(req, res, () => { + checkVideoExists(req.params.id, res, next) + }) + } +] -function videoRateValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() - req.checkBody('rating', 'Should have a valid rate type').isVideoRatingTypeValid() +const videoRateValidator = [ + param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), + body('rating').custom(isVideoRatingTypeValid).withMessage('Should have a valid rate type'), - logger.debug('Checking videoRate parameters', { parameters: req.body }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking videoRate parameters', { parameters: req.body }) - checkErrors(req, res, () => { - checkVideoExists(req.params.id, res, next) - }) -} + checkErrors(req, res, () => { + checkVideoExists(req.params.id, res, next) + }) + } +] -function videosBlacklistValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() +const videosBlacklistValidator = [ + param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), - logger.debug('Checking videosBlacklist parameters', { parameters: req.params }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking videosBlacklist parameters', { parameters: req.params }) - checkErrors(req, res, () => { - checkVideoExists(req.params.id, res, () => { - checkVideoIsBlacklistable(req, res, next) + checkErrors(req, res, () => { + checkVideoExists(req.params.id, res, () => { + checkVideoIsBlacklistable(req, res, next) + }) }) - }) -} + } +] // --------------------------------------------------------------------------- -- cgit v1.2.3