From b60e5f38daf77e720a27aa86d3b482c58906a03a Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 15 Sep 2017 12:17:08 +0200 Subject: [PATCH] Upgrade express validator to v4 --- client/package.json | 2 +- client/src/index.html | 2 +- client/yarn.lock | 91 +++-- package.json | 2 +- server.ts | 11 +- server/helpers/custom-validators/misc.ts | 7 - server/helpers/custom-validators/pods.ts | 7 - .../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 | 145 ++++---- .../validators/remote/signature.ts | 18 +- .../middlewares/validators/remote/videos.ts | 45 ++- server/middlewares/validators/sort.ts | 28 +- server/middlewares/validators/users.ts | 235 +++++++------ server/middlewares/validators/utils.ts | 11 +- server/middlewares/validators/videos.ts | 320 ++++++++++-------- yarn.lock | 20 +- 19 files changed, 517 insertions(+), 497 deletions(-) diff --git a/client/package.json b/client/package.json index 8a82a294e..6fb1da425 100644 --- a/client/package.json +++ b/client/package.json @@ -62,7 +62,7 @@ "json-loader": "^0.5.4", "ng-router-loader": "^2.0.0", "ngc-webpack": "3.2.2", - "ngx-bootstrap": "1.9.1", + "ngx-bootstrap": "1.9.3", "ngx-chips": "1.5.3", "node-sass": "^4.1.1", "normalize.css": "^7.0.0", diff --git a/client/src/index.html b/client/src/index.html index 4346775b1..91ed04d17 100644 --- a/client/src/index.html +++ b/client/src/index.html @@ -8,7 +8,7 @@ - + diff --git a/client/yarn.lock b/client/yarn.lock index b61da8636..011ecce68 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -370,6 +370,13 @@ array-flatten@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.1.tgz#426bb9da84090c1838d812c8150af20a8331e296" +array-includes@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.7.0" + array-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -1560,8 +1567,8 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" codelyzer@^3.0.0-beta.4: - version "3.1.2" - resolved "https://registry.yarnpkg.com/codelyzer/-/codelyzer-3.1.2.tgz#9ff1f041fb9b5ee5dbeb45ba866dfaf04983af04" + version "3.2.0" + resolved "https://registry.yarnpkg.com/codelyzer/-/codelyzer-3.2.0.tgz#68eb0a67771ea73006b517053c3035c1838abf14" dependencies: app-root-path "^2.0.1" css-selector-tokenizer "^0.7.0" @@ -1735,10 +1742,14 @@ copy-webpack-plugin@^4.0.0: minimatch "^3.0.0" node-dir "^0.1.10" -core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0: +core-js@^2.4.0, core-js@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.0.tgz#569c050918be6486b3837552028ae0466b717086" +core-js@^2.4.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b" + core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -1830,8 +1841,8 @@ css-color-names@0.0.4: resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" css-loader@^0.28.4: - version "0.28.5" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.5.tgz#dd02bb91b94545710212ef7f6aaa66663113d754" + version "0.28.7" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.7.tgz#5f2ee989dd32edd907717f953317656160999c1b" dependencies: babel-code-frame "^6.11.0" css-selector-tokenizer "^0.7.0" @@ -1992,6 +2003,13 @@ deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" +default-gateway@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-2.0.2.tgz#e365db05c50a4643cc1990c6178228c540a0b910" + dependencies: + execa "^0.7.0" + ip-regex "^2.1.0" + define-properties@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" @@ -3361,11 +3379,12 @@ inquirer@^0.12.0: strip-ansi "^3.0.0" through "^2.3.6" -internal-ip@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-1.2.0.tgz#ae9fbf93b984878785d50a8de1b356956058cf5c" +internal-ip@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-2.0.2.tgz#bed2b35491e8b42aee087de7614e870908ee80f2" dependencies: - meow "^3.3.0" + default-gateway "^2.0.2" + ipaddr.js "^1.5.1" interpret@^1.0.0: version "1.0.3" @@ -3385,6 +3404,10 @@ invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" +ip-regex@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" + ip-set@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/ip-set/-/ip-set-1.0.1.tgz#633b66d0bd6c8d0de968d053263c9120d3b6727e" @@ -3399,7 +3422,7 @@ ipaddr.js@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.4.0.tgz#296aca878a821816e5b85d0a285a99bcff4582f0" -"ipaddr.js@>= 0.1.5", ipaddr.js@^1.0.1: +"ipaddr.js@>= 0.1.5", ipaddr.js@^1.0.1, ipaddr.js@^1.5.1: version "1.5.2" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.5.2.tgz#d4b505bde9946987ccf0fc58d9010ff9607e3fa0" @@ -3624,6 +3647,10 @@ is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" @@ -4205,7 +4232,7 @@ memory-fs@^0.4.0, memory-fs@~0.4.1: errno "^0.1.3" readable-stream "^2.0.1" -meow@^3.3.0, meow@^3.7.0: +meow@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" dependencies: @@ -4452,9 +4479,9 @@ ngc-webpack@3.2.2: source-map "^0.5.6" ts-node "^3.2.0" -ngx-bootstrap@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ngx-bootstrap/-/ngx-bootstrap-1.9.1.tgz#09ed06d908f5f3bb23f821a0fb452e9a17d7665b" +ngx-bootstrap@1.9.3: + version "1.9.3" + resolved "https://registry.yarnpkg.com/ngx-bootstrap/-/ngx-bootstrap-1.9.3.tgz#28e75d14fb1beaee609383d7694de4eb3ba03b26" ngx-chips@1.5.3: version "1.5.3" @@ -4740,12 +4767,11 @@ opener@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8" -opn@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/opn/-/opn-4.0.2.tgz#7abc22e644dff63b0a96d5ab7f2790c0f01abc95" +opn@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.1.0.tgz#72ce2306a17dbea58ff1041853352b4a8fc77519" dependencies: - object-assign "^4.0.1" - pinkie-promise "^2.0.0" + is-wsl "^1.1.0" optimize-js-plugin@0.0.4: version "0.0.4" @@ -6480,7 +6506,7 @@ supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" -supports-color@^3.1.1, supports-color@^3.2.3: +supports-color@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" dependencies: @@ -7029,8 +7055,8 @@ video.js@^5.19.2: xhr "2.2.2" video.js@^6.2.0: - version "6.2.7" - resolved "https://registry.yarnpkg.com/video.js/-/video.js-6.2.7.tgz#3baa4bdffd58b4c4ab723dbcde5b10349f59957d" + version "6.2.8" + resolved "https://registry.yarnpkg.com/video.js/-/video.js-6.2.8.tgz#e449710bf8513f607456293ae1da97559a94fb97" dependencies: babel-runtime "^6.9.2" global "4.3.2" @@ -7132,10 +7158,11 @@ webpack-dev-middleware@^1.11.0: time-stamp "^2.0.0" webpack-dev-server@^2.4.5: - version "2.7.1" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.7.1.tgz#21580f5a08cd065c71144cf6f61c345bca59a8b8" + version "2.8.2" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.8.2.tgz#abd61f410778cc4c843d7cebbf41465b1ab7734c" dependencies: ansi-html "0.0.7" + array-includes "^3.0.3" bonjour "^3.5.0" chokidar "^1.6.0" compression "^1.5.2" @@ -7144,20 +7171,20 @@ webpack-dev-server@^2.4.5: express "^4.13.3" html-entities "^1.2.0" http-proxy-middleware "~0.17.4" - internal-ip "^1.2.0" + internal-ip "^2.0.2" ip "^1.1.5" loglevel "^1.4.1" - opn "4.0.2" + opn "^5.1.0" portfinder "^1.0.9" selfsigned "^1.9.1" serve-index "^1.7.2" sockjs "0.3.18" sockjs-client "1.1.4" spdy "^3.4.1" - strip-ansi "^3.0.0" - supports-color "^3.1.1" + strip-ansi "^3.0.1" + supports-color "^4.2.1" webpack-dev-middleware "^1.11.0" - yargs "^6.0.0" + yargs "^6.6.0" webpack-dll-bundles-plugin@^1.0.0-beta.5: version "1.0.0-beta.5" @@ -7195,8 +7222,8 @@ webpack-sources@^1.0.1: source-map "~0.5.3" webpack@^3.3.0: - version "3.5.5" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.5.5.tgz#3226f09fc8b3e435ff781e7af34f82b68b26996c" + version "3.5.6" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.5.6.tgz#a492fb6c1ed7f573816f90e00c8fbb5a20cc5c36" dependencies: acorn "^5.0.0" acorn-dynamic-import "^2.0.0" @@ -7427,7 +7454,7 @@ yargs@^4.8.1: y18n "^3.2.1" yargs-parser "^2.4.1" -yargs@^6.0.0: +yargs@^6.6.0: version "6.6.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208" dependencies: diff --git a/package.json b/package.json index 9b38838e4..8ef05f1f9 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "create-torrent": "^3.24.5", "express": "^4.12.4", "express-oauth-server": "^2.0.0", - "express-validator": "^3.1.0", + "express-validator": "^4.1.1", "fluent-ffmpeg": "^2.1.0", "js-yaml": "^3.5.4", "lodash": "^4.11.1", diff --git a/server.ts b/server.ts index 80bf118c0..3f2d27718 100644 --- a/server.ts +++ b/server.ts @@ -7,16 +7,14 @@ if (isTestInstance()) { // ----------- Node modules ----------- import * as bodyParser from 'body-parser' import * as express from 'express' -// FIXME: cannot import express-validator -const expressValidator = require('express-validator') import * as http from 'http' import * as morgan from 'morgan' import * as path from 'path' -import * as bittorrentTracker from 'bittorrent-tracker' +import * as bitTorrentTracker from 'bittorrent-tracker' import * as cors from 'cors' import { Server as WebSocketServer } from 'ws' -const TrackerServer = bittorrentTracker.Server +const TrackerServer = bitTorrentTracker.Server process.title = 'peertube' @@ -49,7 +47,6 @@ db.init(false).then(() => onDatabaseInitDone()) // ----------- PeerTube modules ----------- import { migrate, installApplication } from './server/initializers' import { JobScheduler, activateSchedulers, VideosPreviewCache } from './server/lib' -import * as customValidators from './server/helpers/custom-validators' import { apiRouter, clientsRouter, staticRouter } from './server/controllers' // ----------- Command line ----------- @@ -81,10 +78,6 @@ app.use(morgan('combined', { // For body requests app.use(bodyParser.json({ limit: '500kb' })) app.use(bodyParser.urlencoded({ extended: false })) -// Validate some params for the API -app.use(expressValidator({ - customValidators: customValidators -})) // ----------- Views, routes and static files ----------- 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() +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'), - logger.debug('Checking makeFriends parameters', { parameters: req.body }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking podsAdd 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) - } + 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 know if we have friends.', err) - res.sendStatus(500) - }) - }) -} + return next() + }) + .catch(err => { + logger.error('Cannot load pod by host.', err) + res.sendStatus(500) + }) + }) + } +] -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 }) +const podRemoveValidator = [ + param('id').isNumeric().not().isEmpty().withMessage('Should have a valid id'), - checkErrors(req, res, () => { - db.Pod.loadByHost(req.body.host) - .then(pod => { - // Pod with this host already exists - if (pod) { - return res.sendStatus(409) - } + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking podRemoveValidator parameters', { parameters: req.params }) - return next() - }) - .catch(err => { - logger.error('Cannot load pod by host.', err) - res.sendStatus(500) - }) - }) -} + 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) + } -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) - }) - }) -} + 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) - }) -} - -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() - - logger.debug('Checking usersRegister parameters', { parameters: req.body }) - - 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() - - 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) - } - - if (user.username === 'root') { - return res.status(400) - .send({ error: 'Cannot remove the root user' }) - .end() - } - - return next() + checkErrors(req, res, () => { + checkUserDoesNotAlreadyExist(req.body.username, req.body.email, res, 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 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 usersUpdate parameters', { parameters: req.body }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking usersRegister parameters', { parameters: req.body }) - checkErrors(req, res, () => { - checkUserExists(req.params.id, res, next) - }) -} + checkErrors(req, res, () => { + checkUserDoesNotAlreadyExist(req.body.username, req.body.email, 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 usersRemoveValidator = [ + param('id').isInt().not().isEmpty().withMessage('Should have a valid id'), - logger.debug('Checking usersUpdateMe parameters', { parameters: req.body }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking usersRemove parameters', { parameters: req.params }) - checkErrors(req, res, next) -} + checkErrors(req, res, () => { + checkUserExists(req.params.id, res, (err, user) => { + if (err) { + logger.error('Error in usersRemoveValidator.', err) + return res.sendStatus(500) + } -function usersGetValidator (req: express.Request, res: express.Response, next: express.NextFunction) { - req.checkParams('id', 'Should have a valid id').notEmpty().isInt() - - 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 }) - - checkErrors(req, res, () => { - let videoPromise: Promise - - if (validator.isUUID(req.params.videoId)) { - videoPromise = db.Video.loadByUUID(req.params.videoId) - } else { - videoPromise = db.Video.load(req.params.videoId) - } - - videoPromise - .then(video => { - if (!video) { - return res.status(404) - .json({ error: 'Video not found' }) + if (user.username === 'root') { + return res.status(400) + .send({ error: 'Cannot remove the root user' }) .end() } return next() }) - .catch(err => { - logger.error('Error in user request validator.', err) - return res.sendStatus(500) - }) - }) -} + }) + } +] -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() - } +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'), - return next() - }) -} + (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) + }) + } +] + +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'), + + (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) + } +] + +const usersGetValidator = [ + param('id').isInt().not().isEmpty().withMessage('Should have a valid id'), + + (req: express.Request, res: express.Response, next: express.NextFunction) => { + checkErrors(req, res, () => { + checkUserExists(req.params.id, res, next) + }) + } +] + +const usersVideoRatingValidator = [ + param('videoId').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'), + + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking usersVideoRating parameters', { parameters: req.params }) + + checkErrors(req, res, () => { + let videoPromise: Promise + + if (validator.isUUID(req.params.videoId)) { + videoPromise = db.Video.loadByUUID(req.params.videoId) + } else { + videoPromise = db.Video.load(req.params.videoId) + } + + 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() + }) + } +] // --------------------------------------------------------------------------- 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() +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'), - logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files }) + (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 + 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.' }) + 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 - }) - }) - .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).' - }) + 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() } - videoFile['duration'] = duration - next() - }) - .catch(err => { - logger.error('Error in video add validator', err) - res.sendStatus(500) + 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() + } - 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() - - logger.debug('Checking videosGet parameters', { parameters: req.params }) - - 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() - - 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() }) }) - }) -} + } +] -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 videosGetValidator = [ + param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), - logger.debug('Checking videosSearch parameters', { parameters: req.params }) + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking videosGet parameters', { parameters: req.params }) - 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() - - logger.debug('Checking videoAbuseReport parameters', { parameters: req.body }) - - 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() - - logger.debug('Checking videoRate parameters', { parameters: req.body }) - - 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() - - 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, next) }) - }) -} + } +] + +const videosRemoveValidator = [ + param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), + + (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() + }) + }) + }) + } +] + +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'), + + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking videosSearch parameters', { parameters: req.params }) + + checkErrors(req, res, next) + } +] + +const videoAbuseReportValidator = [ + param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), + body('reason').custom(isVideoAbuseReasonValid).withMessage('Should have a valid reason'), + + (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) + }) + } +] + +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'), + + (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) + }) + } +] + +const videosBlacklistValidator = [ + param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), + + (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) + }) + }) + } +] // --------------------------------------------------------------------------- diff --git a/yarn.lock b/yarn.lock index d6fe0afad..9356ed43f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16,7 +16,7 @@ dependencies: "@types/node" "*" -"@types/bluebird@*", "@types/bluebird@^3.4.0": +"@types/bluebird@*": version "3.5.8" resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.8.tgz#242a83379f06c90f96acf6d1aeab3af6faebdb98" @@ -513,7 +513,7 @@ block-stream@*: dependencies: inherits "~2.0.0" -bluebird@3.5.0, bluebird@^3.0.5, bluebird@^3.4.0, bluebird@^3.4.6, bluebird@^3.5.0: +bluebird@3.5.0, bluebird@^3.0.5, bluebird@^3.4.6, bluebird@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c" @@ -1364,15 +1364,13 @@ express-oauth-server@^2.0.0: express "^4.13.3" oauth2-server "3.0.0" -express-validator@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/express-validator/-/express-validator-3.2.1.tgz#45603e7eee693185c2198fbdebd414925ffd3524" +express-validator@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/express-validator/-/express-validator-4.1.1.tgz#539d49262778eaac170fcd55ef6a3245196cb9d9" dependencies: - "@types/bluebird" "^3.4.0" "@types/express" "~4.0.34" - bluebird "^3.4.0" lodash "^4.16.0" - validator "~6.2.0" + validator "~8.1.0" express@^4.12.4, express@^4.13.3: version "4.15.4" @@ -3979,14 +3977,10 @@ v8flags@^3.0.0: dependencies: user-home "^1.1.1" -validator@^8.0.0, validator@^8.1.0: +validator@^8.0.0, validator@^8.1.0, validator@~8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/validator/-/validator-8.1.0.tgz#89cf6b512ff71eba886afd8d10d47f8dc800eac0" -validator@~6.2.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/validator/-/validator-6.2.1.tgz#bc575b78d15beb2e338a665ba9530c7f409ef667" - vary@^1, vary@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.1.tgz#67535ebb694c1d52257457984665323f587e8d37"