Upgrade express validator to v4
authorChocobozzz <florian.bigard@gmail.com>
Fri, 15 Sep 2017 10:17:08 +0000 (12:17 +0200)
committerChocobozzz <florian.bigard@gmail.com>
Fri, 15 Sep 2017 10:17:08 +0000 (12:17 +0200)
19 files changed:
client/package.json
client/src/index.html
client/yarn.lock
package.json
server.ts
server/helpers/custom-validators/misc.ts
server/helpers/custom-validators/pods.ts
server/helpers/custom-validators/remote/videos.ts
server/helpers/custom-validators/users.ts
server/helpers/custom-validators/videos.ts
server/middlewares/validators/pagination.ts
server/middlewares/validators/pods.ts
server/middlewares/validators/remote/signature.ts
server/middlewares/validators/remote/videos.ts
server/middlewares/validators/sort.ts
server/middlewares/validators/users.ts
server/middlewares/validators/utils.ts
server/middlewares/validators/videos.ts
yarn.lock

index 8a82a294e66241ffc1c4b5120e3052c89aa23107..6fb1da425d8f0511e5915b27a2eee0b481de1bd9 100644 (file)
@@ -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",
index 4346775b1a0c097f7423a9af30b0d0066e2732e6..91ed04d177bd6b0d6c285590bb3a512d910a201a 100644 (file)
@@ -8,7 +8,7 @@
     <meta name="description" content="PeerTube, a decentralized video streaming platform using P2P (BitTorrent) directly in the web browser" />
 
     <!-- The following comment is used by the server to prerender OpenGraph tags -->
-    <!-- opengraph tags -->
+    <!-- open graph tags -->
     <!-- Do not remove it! -->
 
     <link rel="icon" type="image/png" href="/client/assets/favicon.png" />
index b61da863660b00001bd73ba404580e775428a697..011ecce681e6f5f1234e7900f5fb5f116e6198ab 100644 (file)
@@ -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:
index 9b38838e43b823e5199630c7018e3dae7bc879cd..8ef05f1f9cc581d2907bd6dcbd2da69b428baf79 100644 (file)
@@ -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",
index 80bf118c010aa582e9f2c02e2036df7226051b12..3f2d27718187c0e001ced9ffc8832a5af76b351a 100644 (file)
--- 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 -----------
 
index 8d215a416bc899c6cbf122b7fad5f603f2dbc512..60fcdd5bb4f2c712d402795d75939e3a84cd8a54 100644 (file)
@@ -14,10 +14,3 @@ export {
   exists,
   isArray
 }
-
-declare module 'express-validator' {
-  export interface Validator {
-    exists,
-    isArray
-  }
-}
index 844bfdf7833b4a56758e83baeb3c123eaaa00583..d5021bf38dbf5b8f553af001b87e5fe06a59128e 100644 (file)
@@ -32,10 +32,3 @@ export {
   isEachUniqueHostValid,
   isHostValid
 }
-
-declare module 'express-validator' {
-  export interface Validator {
-    isEachUniqueHostValid
-    isHostValid
-  }
-}
index e5c76f3cacf98206b243a015eca716705b765eae..e261e05a8f6d23983a6b18bbe8a9148a1e7c7852 100644 (file)
@@ -102,14 +102,6 @@ export {
   isEachRemoteRequestVideosEventsValid
 }
 
-declare module 'express-validator' {
-  export interface Validator {
-    isEachRemoteRequestVideosValid,
-    isEachRemoteRequestVideosQaduValid,
-    isEachRemoteRequestVideosEventsValid
-  }
-}
-
 // ---------------------------------------------------------------------------
 
 function isCommonVideoAttributesValid (video: any) {
index 805437efa2896b0c44f24d5933b208ba4fa816df..c180eccda34db4468d7676ea43acf701eb84b170 100644 (file)
@@ -39,13 +39,3 @@ export {
   isUserUsernameValid,
   isUserDisplayNSFWValid
 }
-
-declare module 'express-validator' {
-  export interface Validator {
-    isUserPasswordValid,
-    isUserRoleValid,
-    isUserUsernameValid,
-    isUserDisplayNSFWValid,
-    isUserVideoQuotaValid
-  }
-}
index 1d27e47fc392a57c4a04057c16ac8569cfc43cba..2eb021ae7ba4e096ee0a0fcc60c57f9275b9f6f0 100644 (file)
@@ -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
-  }
-}
index cca8295ffddc731bc309c3e189fb58210b9fffb0..a5a542cdfe0f3fcf4ace19f879fbd6403750d406 100644 (file)
@@ -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)
+  }
+]
 
 // ---------------------------------------------------------------------------
 
index 3a0f56f6a7d783a253775874b436d96138799f61..ab7702e781721438e1c328f600fdbf631db6b57e 100644 (file)
@@ -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)
+        })
+    })
+  }
+]
 
 // ---------------------------------------------------------------------------
 
index eb5c196ebd6c67236e1771eef885a375a26552a1..d3937b5150c425a80e36743297c68122e9395d3d 100644 (file)
@@ -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)
+  }
+]
 
 // ---------------------------------------------------------------------------
 
index 2037c0085e98b9cf71f2e44b673c6e9bdc3b84f5..e4682a60b5a9a7fb103cc3037cc1ae9a7faae0ea 100644 (file)
@@ -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)
+  }
+]
 
 // ---------------------------------------------------------------------------
 
index 3baee9fb3df437236e675b0d4223f2fe61c26721..71b18acb01b99ba83576dfe5391e996dcc6022dd 100644 (file)
@@ -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[]) {
index 15c07c6936f01903d5d6d8dfd2542b7a70c89fe2..ab9d0938cefd60a70897d17feaafc6d0d72671e2 100644 (file)
@@ -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<VideoInstance>
+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<VideoInstance>
 
-        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()
+    })
+  }
+]
 
 // ---------------------------------------------------------------------------
 
index 0424d59429f6e914fa7f855db71afcb1af4519cb..8845f83995be3536abd9c5f3f1b05be5b6f0e3bf 100644 (file)
@@ -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()
index 213b4c46b93f9159c9bc10f8db5e863c4cecc60a..bc8b7e5413b2c515a401653da76772a127dacf45 100644 (file)
@@ -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)
+      })
     })
-  })
-}
+  }
+]
 
 // ---------------------------------------------------------------------------
 
index d6fe0afadb3a6fda31d4a79c2b0d270b4e81f4d1..9356ed43ff00c8ad7ffb6c72955334bcc3c5c36a 100644 (file)
--- 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"