Server: reorganize express validators
authorChocobozzz <florian.bigard@gmail.com>
Sun, 31 Jul 2016 18:58:43 +0000 (20:58 +0200)
committerChocobozzz <florian.bigard@gmail.com>
Sun, 31 Jul 2016 18:58:43 +0000 (20:58 +0200)
server.js
server/helpers/custom-validators.js [deleted file]
server/helpers/custom-validators/index.js [new file with mode: 0644]
server/helpers/custom-validators/misc.js [new file with mode: 0644]
server/helpers/custom-validators/users.js [new file with mode: 0644]
server/helpers/custom-validators/videos.js [new file with mode: 0644]
server/initializers/constants.js
server/middlewares/validators/videos.js
server/models/video.js

index b2eeeff70edcd6494f3cd23e30ad5a8a3e6cfeaf..d38c5830f3f0ac565fbfdbe4b5554c98dc7c2bad 100644 (file)
--- a/server.js
+++ b/server.js
@@ -53,7 +53,7 @@ app.use(bodyParser.json())
 app.use(bodyParser.urlencoded({ extended: false }))
 // Validate some params for the API
 app.use(expressValidator({
-  customValidators: customValidators
+  customValidators: Object.assign({}, customValidators.misc, customValidators.users, customValidators.videos)
 }))
 
 // ----------- Views, routes and static files -----------
diff --git a/server/helpers/custom-validators.js b/server/helpers/custom-validators.js
deleted file mode 100644 (file)
index b666644..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-'use strict'
-
-const validator = require('express-validator').validator
-
-const constants = require('../initializers/constants')
-const VIDEOS_CONSTRAINTS_FIELDS = constants.VIDEOS_CONSTRAINTS_FIELDS
-
-const customValidators = {
-  exists: exists,
-  isEachRemoteVideosValid: isEachRemoteVideosValid,
-  isArray: isArray,
-  isVideoAuthorValid: isVideoAuthorValid,
-  isVideoDateValid: isVideoDateValid,
-  isVideoDescriptionValid: isVideoDescriptionValid,
-  isVideoDurationValid: isVideoDurationValid,
-  isVideoMagnetUriValid: isVideoMagnetUriValid,
-  isVideoNameValid: isVideoNameValid,
-  isVideoPodUrlValid: isVideoPodUrlValid,
-  isVideoTagsValid: isVideoTagsValid,
-  isVideoThumbnailValid: isVideoThumbnailValid,
-  isVideoThumbnail64Valid: isVideoThumbnail64Valid
-}
-
-function exists (value) {
-  return value !== undefined && value !== null
-}
-
-function isEachRemoteVideosValid (requests) {
-  return requests.every(function (request) {
-    const video = request.data
-    return (
-      isRequestTypeAddValid(request.type) &&
-      isVideoAuthorValid(video.author) &&
-      isVideoDateValid(video.createdDate) &&
-      isVideoDescriptionValid(video.description) &&
-      isVideoDurationValid(video.duration) &&
-      isVideoMagnetUriValid(video.magnetUri) &&
-      isVideoNameValid(video.name) &&
-      isVideoPodUrlValid(video.podUrl) &&
-      isVideoTagsValid(video.tags) &&
-      isVideoThumbnail64Valid(video.thumbnailBase64)
-    ) ||
-    (
-      isRequestTypeRemoveValid(request.type) &&
-      isVideoNameValid(video.name) &&
-      isVideoMagnetUriValid(video.magnetUri)
-    )
-  })
-}
-
-function isArray (value) {
-  return Array.isArray(value)
-}
-
-function isRequestTypeAddValid (value) {
-  return value === 'add'
-}
-
-function isRequestTypeRemoveValid (value) {
-  return value === 'remove'
-}
-
-function isVideoAuthorValid (value) {
-  return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.AUTHOR)
-}
-
-function isVideoDateValid (value) {
-  return validator.isDate(value)
-}
-
-function isVideoDescriptionValid (value) {
-  return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION)
-}
-
-function isVideoDurationValid (value) {
-  return validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
-}
-
-function isVideoMagnetUriValid (value) {
-  return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.MAGNET_URI)
-}
-
-function isVideoNameValid (value) {
-  return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
-}
-
-function isVideoPodUrlValid (value) {
-  // TODO: set options (TLD...)
-  return validator.isURL(value)
-}
-
-function isVideoTagsValid (tags) {
-  return isArray(tags) &&
-         validator.isInt(tags.length, VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
-         tags.every(function (tag) {
-           return validator.isAlphanumeric(tag) &&
-                  validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
-         })
-}
-
-function isVideoThumbnailValid (value) {
-  return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL)
-}
-
-function isVideoThumbnail64Valid (value) {
-  return validator.isBase64(value) &&
-         validator.isByteLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL64)
-}
-
-// ---------------------------------------------------------------------------
-
-module.exports = customValidators
-
-// ---------------------------------------------------------------------------
diff --git a/server/helpers/custom-validators/index.js b/server/helpers/custom-validators/index.js
new file mode 100644 (file)
index 0000000..ab30668
--- /dev/null
@@ -0,0 +1,15 @@
+'use strict'
+
+const miscValidators = require('./misc')
+const usersValidators = require('./users')
+const videosValidators = require('./videos')
+
+const validators = {
+  misc: miscValidators,
+  users: usersValidators,
+  videos: videosValidators
+}
+
+// ---------------------------------------------------------------------------
+
+module.exports = validators
diff --git a/server/helpers/custom-validators/misc.js b/server/helpers/custom-validators/misc.js
new file mode 100644 (file)
index 0000000..782ae3d
--- /dev/null
@@ -0,0 +1,18 @@
+'use strict'
+
+const miscValidators = {
+  exists: exists,
+  isArray: isArray
+}
+
+function exists (value) {
+  return value !== undefined && value !== null
+}
+
+function isArray (value) {
+  return Array.isArray(value)
+}
+
+// ---------------------------------------------------------------------------
+
+module.exports = miscValidators
diff --git a/server/helpers/custom-validators/users.js b/server/helpers/custom-validators/users.js
new file mode 100644 (file)
index 0000000..41e00d0
--- /dev/null
@@ -0,0 +1,18 @@
+'use strict'
+
+const validator = require('express-validator').validator
+
+const constants = require('../../initializers/constants')
+const USERS_CONSTRAINTS_FIELDS = constants.CONSTRAINTS_FIELDS.USERS
+
+const usersValidators = {
+  isUserUsernameValid: isUserUsernameValid
+}
+
+function isUserUsernameValid (value) {
+  return validator.isLength(value, USERS_CONSTRAINTS_FIELDS.USERNAME)
+}
+
+// ---------------------------------------------------------------------------
+
+module.exports = usersValidators
diff --git a/server/helpers/custom-validators/videos.js b/server/helpers/custom-validators/videos.js
new file mode 100644 (file)
index 0000000..39a19cb
--- /dev/null
@@ -0,0 +1,106 @@
+'use strict'
+
+const validator = require('express-validator').validator
+
+const constants = require('../../initializers/constants')
+const usersValidators = require('./users')
+const miscValidators = require('./misc')
+const VIDEOS_CONSTRAINTS_FIELDS = constants.CONSTRAINTS_FIELDS.VIDEOS
+
+const videosValidators = {
+  isEachRemoteVideosValid: isEachRemoteVideosValid,
+  isVideoAuthorValid: isVideoAuthorValid,
+  isVideoDateValid: isVideoDateValid,
+  isVideoDescriptionValid: isVideoDescriptionValid,
+  isVideoDurationValid: isVideoDurationValid,
+  isVideoMagnetUriValid: isVideoMagnetUriValid,
+  isVideoNameValid: isVideoNameValid,
+  isVideoPodUrlValid: isVideoPodUrlValid,
+  isVideoTagsValid: isVideoTagsValid,
+  isVideoThumbnailValid: isVideoThumbnailValid,
+  isVideoThumbnail64Valid: isVideoThumbnail64Valid
+}
+
+function isEachRemoteVideosValid (requests) {
+  return requests.every(function (request) {
+    const video = request.data
+    return (
+      isRequestTypeAddValid(request.type) &&
+      isVideoAuthorValid(video.author) &&
+      isVideoDateValid(video.createdDate) &&
+      isVideoDescriptionValid(video.description) &&
+      isVideoDurationValid(video.duration) &&
+      isVideoMagnetUriValid(video.magnetUri) &&
+      isVideoNameValid(video.name) &&
+      isVideoPodUrlValid(video.podUrl) &&
+      isVideoTagsValid(video.tags) &&
+      isVideoThumbnail64Valid(video.thumbnailBase64)
+    ) ||
+    (
+      isRequestTypeRemoveValid(request.type) &&
+      isVideoNameValid(video.name) &&
+      isVideoMagnetUriValid(video.magnetUri)
+    )
+  })
+}
+
+function isVideoAuthorValid (value) {
+  return usersValidators.isUserUsernameValid(usersValidators)
+}
+
+function isVideoDateValid (value) {
+  return validator.isDate(value)
+}
+
+function isVideoDescriptionValid (value) {
+  return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION)
+}
+
+function isVideoDurationValid (value) {
+  return validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
+}
+
+function isVideoMagnetUriValid (value) {
+  return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.MAGNET_URI)
+}
+
+function isVideoNameValid (value) {
+  return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
+}
+
+function isVideoPodUrlValid (value) {
+  // TODO: set options (TLD...)
+  return validator.isURL(value)
+}
+
+function isVideoTagsValid (tags) {
+  return miscValidators.isArray(tags) &&
+         validator.isInt(tags.length, VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
+         tags.every(function (tag) {
+           return validator.isAlphanumeric(tag) &&
+                  validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
+         })
+}
+
+function isVideoThumbnailValid (value) {
+  return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL)
+}
+
+function isVideoThumbnail64Valid (value) {
+  return validator.isBase64(value) &&
+         validator.isByteLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL64)
+}
+
+// ---------------------------------------------------------------------------
+
+module.exports = videosValidators
+
+// ---------------------------------------------------------------------------
+
+function isRequestTypeAddValid (value) {
+  return value === 'add'
+}
+
+function isRequestTypeRemoveValid (value) {
+  return value === 'remove'
+}
index 467816f2cd539501d70a372df5cb9c829e471633..5f4aeccc66e3d3682e923b5f92ec7a4aeca7867c 100644 (file)
@@ -3,6 +3,23 @@
 // API version of our pod
 const API_VERSION = 'v1'
 
+const CONSTRAINTS_FIELDS = {
+  USERS: {
+    USERNAME: { min: 3, max: 20 }, // Length
+    PASSWORD: { min: 6, max: 255 } // Length
+  },
+  VIDEOS: {
+    NAME: { min: 3, max: 50 }, // Length
+    DESCRIPTION: { min: 3, max: 250 }, // Length
+    MAGNET_URI: { min: 10 }, // Length
+    DURATION: { min: 1, max: 7200 }, // Number
+    TAGS: { min: 1, max: 3 }, // Number of total tags
+    TAG: { min: 2, max: 10 }, // Length
+    THUMBNAIL: { min: 2, max: 30 },
+    THUMBNAIL64: { min: 0, max: 20000 } // Bytes
+  }
+}
+
 // Score a pod has when we create it as a friend
 const FRIEND_SCORE = {
   BASE: 100,
@@ -55,29 +72,18 @@ const THUMBNAILS_SIZE = '200x110'
 // Path for access to thumbnails with express router
 const THUMBNAILS_STATIC_PATH = '/static/thumbnails'
 
-const VIDEOS_CONSTRAINTS_FIELDS = {
-  NAME: { min: 3, max: 50 }, // Length
-  DESCRIPTION: { min: 3, max: 250 }, // Length
-  MAGNET_URI: { min: 10 }, // Length
-  DURATION: { min: 1, max: 7200 }, // Number
-  AUTHOR: { min: 3, max: 20 }, // Length
-  TAGS: { min: 1, max: 3 }, // Number of total tags
-  TAG: { min: 2, max: 10 }, // Length
-  THUMBNAIL: { min: 2, max: 30 },
-  THUMBNAIL64: { min: 0, max: 20000 } // Bytes
-}
-
 // Special constants for a test instance
 if (isTestInstance() === true) {
   FRIEND_SCORE.BASE = 20
   INTERVAL = 10000
-  VIDEOS_CONSTRAINTS_FIELDS.DURATION.max = 14
+  CONSTRAINTS_FIELDS.VIDEOS.DURATION.max = 14
 }
 
 // ---------------------------------------------------------------------------
 
 module.exports = {
   API_VERSION: API_VERSION,
+  CONSTRAINTS_FIELDS: CONSTRAINTS_FIELDS,
   FRIEND_SCORE: FRIEND_SCORE,
   INTERVAL: INTERVAL,
   OAUTH_LIFETIME: OAUTH_LIFETIME,
@@ -90,8 +96,7 @@ module.exports = {
   SEEDS_IN_PARALLEL: SEEDS_IN_PARALLEL,
   SORTABLE_COLUMNS: SORTABLE_COLUMNS,
   THUMBNAILS_SIZE: THUMBNAILS_SIZE,
-  THUMBNAILS_STATIC_PATH: THUMBNAILS_STATIC_PATH,
-  VIDEOS_CONSTRAINTS_FIELDS: VIDEOS_CONSTRAINTS_FIELDS
+  THUMBNAILS_STATIC_PATH: THUMBNAILS_STATIC_PATH
 }
 
 // ---------------------------------------------------------------------------
index 3e2af06fb0c253e45c6746f041764e16bbf212fb..422f3642fa17bbd3cdbdd6687a0c69736757516d 100644 (file)
@@ -4,7 +4,7 @@ const mongoose = require('mongoose')
 
 const checkErrors = require('./utils').checkErrors
 const constants = require('../../initializers/constants')
-const customValidators = require('../../helpers/custom-validators')
+const customVideosValidators = require('../../helpers/custom-validators').videos
 const logger = require('../../helpers/logger')
 
 const Video = mongoose.model('Video')
@@ -33,8 +33,8 @@ function videosAdd (req, res, next) {
         return res.status(400).send('Cannot retrieve metadata of the file.')
       }
 
-      if (!customValidators.isVideoDurationValid(duration)) {
-        return res.status(400).send('Duration of the video file is too big (max: ' + constants.VIDEOS_CONSTRAINTS_FIELDS.DURATION.max + 's).')
+      if (!customVideosValidators.isVideoDurationValid(duration)) {
+        return res.status(400).send('Duration of the video file is too big (max: ' + constants.CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).')
       }
 
       videoFile.duration = duration
index 396aa505d5e1e1efd1e02b43646eb06ab15694ac..acb8353c2891b411e2b2e3fb64a32ec7bd1a033b 100644 (file)
@@ -9,7 +9,7 @@ const pathUtils = require('path')
 const mongoose = require('mongoose')
 
 const constants = require('../initializers/constants')
-const customValidators = require('../helpers/custom-validators')
+const customVideosValidators = require('../helpers/custom-validators').videos
 const logger = require('../helpers/logger')
 const utils = require('../helpers/utils')
 const webtorrent = require('../lib/webtorrent')
@@ -39,18 +39,18 @@ const VideoSchema = mongoose.Schema({
   }
 })
 
-VideoSchema.path('name').validate(customValidators.isVideoNameValid)
-VideoSchema.path('description').validate(customValidators.isVideoDescriptionValid)
-VideoSchema.path('magnetUri').validate(customValidators.isVideoMagnetUriValid)
-VideoSchema.path('podUrl').validate(customValidators.isVideoPodUrlValid)
-VideoSchema.path('author').validate(customValidators.isVideoAuthorValid)
-VideoSchema.path('duration').validate(customValidators.isVideoDurationValid)
+VideoSchema.path('name').validate(customVideosValidators.isVideoNameValid)
+VideoSchema.path('description').validate(customVideosValidators.isVideoDescriptionValid)
+VideoSchema.path('magnetUri').validate(customVideosValidators.isVideoMagnetUriValid)
+VideoSchema.path('podUrl').validate(customVideosValidators.isVideoPodUrlValid)
+VideoSchema.path('author').validate(customVideosValidators.isVideoAuthorValid)
+VideoSchema.path('duration').validate(customVideosValidators.isVideoDurationValid)
 // The tumbnail can be the path or the data in base 64
 // The pre save hook will convert the base 64 data in a file on disk and replace the thumbnail key by the filename
 VideoSchema.path('thumbnail').validate(function (value) {
-  return customValidators.isVideoThumbnailValid(value) || customValidators.isVideoThumbnail64Valid(value)
+  return customVideosValidators.isVideoThumbnailValid(value) || customVideosValidators.isVideoThumbnail64Valid(value)
 })
-VideoSchema.path('tags').validate(customValidators.isVideoTagsValid)
+VideoSchema.path('tags').validate(customVideosValidators.isVideoTagsValid)
 
 VideoSchema.methods = {
   isOwned: isOwned,