]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/middlewares/validators/users.ts
Add avatar max size limit
[github/Chocobozzz/PeerTube.git] / server / middlewares / validators / users.ts
index ab9d0938cefd60a70897d17feaafc6d0d72671e2..7de3e442ccec31cbabe8ccc295adfc45982eabc7 100644 (file)
@@ -1,34 +1,33 @@
-import { body, param } from 'express-validator/check'
-import 'express-validator'
 import * as express from 'express'
-import * as Promise from 'bluebird'
-import * as validator from 'validator'
-
-import { database as db } from '../../initializers/database'
-import { checkErrors } from './utils'
+import 'express-validator'
+import { body, param } from 'express-validator/check'
+import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc'
 import {
-  isSignupAllowed,
-  logger,
-  isUserUsernameValid,
-  isUserPasswordValid,
-  isUserVideoQuotaValid,
-  isUserDisplayNSFWValid,
-  isVideoIdOrUUIDValid
-} from '../../helpers'
-import { UserInstance, VideoInstance } from '../../models'
+  isAvatarFile, isUserAutoPlayVideoValid, isUserDisplayNSFWValid, isUserPasswordValid, isUserRoleValid, isUserUsernameValid,
+  isUserVideoQuotaValid
+} from '../../helpers/custom-validators/users'
+import { isVideoExist } from '../../helpers/custom-validators/videos'
+import { logger } from '../../helpers/logger'
+import { isSignupAllowed } from '../../helpers/utils'
+import { CONSTRAINTS_FIELDS } from '../../initializers'
+import { UserModel } from '../../models/account/user'
+import { areValidationErrors } from './utils'
+import Multer = require('multer')
 
 const usersAddValidator = [
-  body('username').custom(isUserUsernameValid).withMessage('Should have a valid username'),
+  body('username').custom(isUserUsernameValid).withMessage('Should have a valid username (lowercase alphanumeric characters)'),
   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'),
+  body('role').custom(isUserRoleValid).withMessage('Should have a valid role'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (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)
-    })
+    if (areValidationErrors(req, res)) return
+    if (!await checkUserNameOrEmailDoesNotAlreadyExist(req.body.username, req.body.email, res)) return
+
+    return next()
   }
 ]
 
@@ -37,37 +36,33 @@ const usersRegisterValidator = [
   body('password').custom(isUserPasswordValid).withMessage('Should have a valid password'),
   body('email').isEmail().withMessage('Should have a valid email'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (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)
-    })
+    if (areValidationErrors(req, res)) return
+    if (!await checkUserNameOrEmailDoesNotAlreadyExist(req.body.username, req.body.email, res)) return
+
+    return next()
   }
 ]
 
 const usersRemoveValidator = [
   param('id').isInt().not().isEmpty().withMessage('Should have a valid id'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (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)
-        }
-
-        if (user.username === 'root') {
-          return res.status(400)
-                    .send({ error: 'Cannot remove the root user' })
-                    .end()
-        }
-
-        return next()
-      })
-    })
+    if (areValidationErrors(req, res)) return
+    if (!await checkUserIdExist(req.params.id, res)) return
+
+    const user = res.locals.user
+    if (user.username === 'root') {
+      return res.status(400)
+                .send({ error: 'Cannot remove the root user' })
+                .end()
+    }
+
+    return next()
   }
 ]
 
@@ -75,13 +70,15 @@ 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'),
+  body('role').optional().custom(isUserRoleValid).withMessage('Should have a valid role'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (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)
-    })
+    if (areValidationErrors(req, res)) return
+    if (!await checkUserIdExist(req.params.id, res)) return
+
+    return next()
   }
 ]
 
@@ -89,69 +86,77 @@ 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'),
+  body('autoPlayVideo').optional().custom(isUserAutoPlayVideoValid).withMessage('Should have a valid automatically plays video 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)
+    if (areValidationErrors(req, res)) return
+
+    return next()
+  }
+]
+
+const usersUpdateMyAvatarValidator = [
+  body('avatarfile').custom((value, { req }) => isAvatarFile(req.files)).withMessage(
+    'This file is not supported. Please, make sure it is of the following type : '
+    + CONSTRAINTS_FIELDS.ACTORS.AVATAR.EXTNAME.join(', ')
+  ),
+
+  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+    logger.debug('Checking usersUpdateMyAvatarValidator parameters', { parameters: req.body })
+
+    if (areValidationErrors(req, res)) return
+
+    const imageFile = req.files['avatarfile'][0] as Express.Multer.File
+    if (imageFile.size > CONSTRAINTS_FIELDS.ACTORS.AVATAR.FILE_SIZE.max) {
+      res.status(400)
+        .send({ error: `The size of the avatar is too big (>${CONSTRAINTS_FIELDS.ACTORS.AVATAR.FILE_SIZE.max}).` })
+        .end()
+      return
+    }
+
+    return 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)
-    })
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
+    logger.debug('Checking usersGet parameters', { parameters: req.body })
+
+    if (areValidationErrors(req, res)) return
+    if (!await checkUserIdExist(req.params.id, res)) return
+
+    return next()
   }
 ]
 
 const usersVideoRatingValidator = [
-  param('videoId').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'),
+  param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking usersVideoRating parameters', { parameters: req.params })
 
-    checkErrors(req, res, () => {
-      let videoPromise: Promise<VideoInstance>
-
-      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)
-        })
-    })
+    if (areValidationErrors(req, res)) return
+    if (!await isVideoExist(req.params.videoId, res)) return
+
+    return next()
   }
 ]
 
 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()
-    })
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
+    const allowed = await isSignupAllowed()
+    if (allowed === false) {
+      return res.status(403)
+                .send({ error: 'User registration is not enabled or user limit is reached.' })
+                .end()
+    }
+
+    return next()
   }
 ]
 
@@ -165,42 +170,36 @@ export {
   usersUpdateMeValidator,
   usersVideoRatingValidator,
   ensureUserRegistrationAllowed,
-  usersGetValidator
+  usersGetValidator,
+  usersUpdateMyAvatarValidator
 }
 
 // ---------------------------------------------------------------------------
 
-function checkUserExists (id: number, res: express.Response, callback: (err: Error, user: UserInstance) => void) {
-  db.User.loadById(id)
-    .then(user => {
-      if (!user) {
-        return res.status(404)
-                  .send({ error: 'User not found' })
-                  .end()
-      }
-
-      res.locals.user = user
-      return callback(null, user)
-    })
-    .catch(err => {
-      logger.error('Error in user request validator.', err)
-      return res.sendStatus(500)
-    })
+async function checkUserIdExist (id: number, res: express.Response) {
+  const user = await UserModel.loadById(id)
+
+  if (!user) {
+    res.status(404)
+              .send({ error: 'User not found' })
+              .end()
+
+    return false
+  }
+
+  res.locals.user = user
+  return true
 }
 
-function checkUserDoesNotAlreadyExist (username: string, email: string, res: express.Response, callback: () => void) {
-  db.User.loadByUsernameOrEmail(username, email)
-      .then(user => {
-        if (user) {
-          return res.status(409)
-                    .send({ error: 'User already exists.' })
-                    .end()
-        }
-
-        return callback()
-      })
-      .catch(err => {
-        logger.error('Error in usersAdd request validator.', err)
-        return res.sendStatus(500)
-      })
+async function checkUserNameOrEmailDoesNotAlreadyExist (username: string, email: string, res: express.Response) {
+  const user = await UserModel.loadByUsernameOrEmail(username, email)
+
+  if (user) {
+    res.status(409)
+              .send({ error: 'User with this username of email already exists.' })
+              .end()
+    return false
+  }
+
+  return true
 }