]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/middlewares/validators/videos/videos.ts
Add banners support
[github/Chocobozzz/PeerTube.git] / server / middlewares / validators / videos / videos.ts
index 9834f714bd6cdbd6eb0b7e6b0a46c22e0ba13066..4d31d3dcb076e6cd4a1644fe2b9719ca519e1b38 100644 (file)
@@ -2,12 +2,16 @@ import * as express from 'express'
 import { body, param, query, ValidationChain } from 'express-validator'
 import { isAbleToUploadVideo } from '@server/lib/user'
 import { getServerActor } from '@server/models/application/application'
-import { MVideoFullLight } from '@server/types/models'
+import { ExpressPromiseHandler } from '@server/types/express'
+import { MVideoWithRights } from '@server/types/models'
 import { ServerErrorCode, UserRight, VideoChangeOwnershipStatus, VideoPrivacy } from '../../../../shared'
+import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
 import { VideoChangeOwnershipAccept } from '../../../../shared/models/videos/video-change-ownership-accept.model'
 import {
+  exists,
   isBooleanValid,
   isDateValid,
+  isFileFieldValid,
   isIdOrUUIDValid,
   isIdValid,
   isUUIDValid,
@@ -22,7 +26,8 @@ import {
   isScheduleVideoUpdatePrivacyValid,
   isVideoCategoryValid,
   isVideoDescriptionValid,
-  isVideoFile,
+  isVideoFileMimeTypeValid,
+  isVideoFileSizeValid,
   isVideoFilterValid,
   isVideoImage,
   isVideoLanguageValid,
@@ -49,17 +54,17 @@ import { isLocalVideoAccepted } from '../../../lib/moderation'
 import { Hooks } from '../../../lib/plugins/hooks'
 import { AccountModel } from '../../../models/account/account'
 import { VideoModel } from '../../../models/video/video'
-import { authenticatePromiseIfNeeded } from '../../oauth'
+import { authenticatePromiseIfNeeded } from '../../auth'
 import { areValidationErrors } from '../utils'
-import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
 
 const videosAddValidator = getCommonVideoEditAttributes().concat([
   body('videofile')
-    .custom((value, { req }) => isVideoFile(req.files)).withMessage(
-      'This file is not supported or too large. Please, make sure it is of the following type: ' +
-      CONSTRAINTS_FIELDS.VIDEOS.EXTNAME.join(', ')
-    ),
-  body('name').custom(isVideoNameValid).withMessage('Should have a valid name'),
+    .custom((value, { req }) => isFileFieldValid(req.files, 'videofile'))
+    .withMessage('Should have a file'),
+  body('name')
+    .trim()
+    .custom(isVideoNameValid)
+    .withMessage('Should have a valid name'),
   body('channelId')
     .customSanitizer(toIntOrNull)
     .custom(isIdValid).withMessage('Should have correct video channel id'),
@@ -75,8 +80,27 @@ const videosAddValidator = getCommonVideoEditAttributes().concat([
 
     if (!await doesVideoChannelOfAccountExist(req.body.channelId, user, res)) return cleanUpReqFiles(req)
 
+    if (!isVideoFileMimeTypeValid(req.files)) {
+      res.status(HttpStatusCode.UNSUPPORTED_MEDIA_TYPE_415)
+         .json({
+           error: 'This file is not supported. Please, make sure it is of the following type: ' +
+                  CONSTRAINTS_FIELDS.VIDEOS.EXTNAME.join(', ')
+         })
+
+      return cleanUpReqFiles(req)
+    }
+
+    if (!isVideoFileSizeValid(videoFile.size.toString())) {
+      res.status(HttpStatusCode.PAYLOAD_TOO_LARGE_413)
+         .json({
+           error: 'This file is too large.'
+         })
+
+      return cleanUpReqFiles(req)
+    }
+
     if (await isAbleToUploadVideo(user.id, videoFile.size) === false) {
-      res.status(HttpStatusCode.FORBIDDEN_403)
+      res.status(HttpStatusCode.PAYLOAD_TOO_LARGE_413)
          .json({ error: 'The user video quota is exceeded with this video.' })
 
       return cleanUpReqFiles(req)
@@ -88,8 +112,8 @@ const videosAddValidator = getCommonVideoEditAttributes().concat([
       duration = await getDurationFromVideoFile(videoFile.path)
     } catch (err) {
       logger.error('Invalid input file in videosAddValidator.', { err })
-      res.status(HttpStatusCode.BAD_REQUEST_400)
-         .json({ error: 'Invalid input file.' })
+      res.status(HttpStatusCode.UNPROCESSABLE_ENTITY_422)
+         .json({ error: 'Video file unreadable.' })
 
       return cleanUpReqFiles(req)
     }
@@ -106,6 +130,7 @@ const videosUpdateValidator = getCommonVideoEditAttributes().concat([
   param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
   body('name')
     .optional()
+    .trim()
     .custom(isVideoNameValid).withMessage('Should have a valid name'),
   body('channelId')
     .optional()
@@ -172,17 +197,16 @@ const videosCustomGetValidator = (
       // Controllers does not need to check video rights
       if (fetchType === 'only-immutable-attributes') return next()
 
-      const video = getVideoWithAttributes(res)
-      const videoAll = video as MVideoFullLight
+      const video = getVideoWithAttributes(res) as MVideoWithRights
 
       // Video private or blacklisted
-      if (videoAll.requiresAuth()) {
+      if (video.requiresAuth()) {
         await authenticatePromiseIfNeeded(req, res, authenticateInQuery)
 
         const user = res.locals.oauth ? res.locals.oauth.token.User : null
 
         // Only the owner or a user that have blacklist rights can see the video
-        if (!user || !user.canGetVideo(videoAll)) {
+        if (!user || !user.canGetVideo(video)) {
           return res.status(HttpStatusCode.FORBIDDEN_403)
                     .json({ error: 'Cannot get this private/internal or blacklisted video.' })
         }
@@ -295,7 +319,7 @@ const videosAcceptChangeOwnershipValidator = [
     const videoChangeOwnership = res.locals.videoChangeOwnership
     const isAble = await isAbleToUploadVideo(user.id, videoChangeOwnership.Video.getMaxQualityFile().size)
     if (isAble === false) {
-      res.status(HttpStatusCode.FORBIDDEN_403)
+      res.status(HttpStatusCode.PAYLOAD_TOO_LARGE_413)
         .json({ error: 'The user video quota is exceeded with this video.' })
 
       return
@@ -389,7 +413,7 @@ function getCommonVideoEditAttributes () {
       .optional()
       .customSanitizer(toIntOrNull)
       .custom(isScheduleVideoUpdatePrivacyValid).withMessage('Should have correct schedule update privacy')
-  ] as (ValidationChain | express.Handler)[]
+  ] as (ValidationChain | ExpressPromiseHandler)[]
 }
 
 const commonVideosFiltersValidator = [
@@ -423,6 +447,9 @@ const commonVideosFiltersValidator = [
     .optional()
     .customSanitizer(toBooleanOrNull)
     .custom(isBooleanValid).withMessage('Should have a valid skip count boolean'),
+  query('search')
+    .optional()
+    .custom(exists).withMessage('Should have a valid search'),
 
   (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking commons video filters query', { parameters: req.query })