Improve create import file job
[oweals/peertube.git] / server / helpers / custom-validators / videos.ts
1 import { Response } from 'express'
2 import 'express-validator'
3 import { values } from 'lodash'
4 import 'multer'
5 import * as validator from 'validator'
6 import { UserRight, VideoRateType } from '../../../shared'
7 import {
8   CONSTRAINTS_FIELDS,
9   VIDEO_CATEGORIES,
10   VIDEO_LICENCES,
11   VIDEO_MIMETYPE_EXT,
12   VIDEO_PRIVACIES,
13   VIDEO_RATE_TYPES
14 } from '../../initializers'
15 import { VideoModel } from '../../models/video/video'
16 import { exists, isArray, isFileValid } from './misc'
17 import { VideoChannelModel } from '../../models/video/video-channel'
18 import { UserModel } from '../../models/account/user'
19
20 const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
21 const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
22
23 function isVideoCategoryValid (value: any) {
24   return value === null || VIDEO_CATEGORIES[value] !== undefined
25 }
26
27 function isVideoLicenceValid (value: any) {
28   return value === null || VIDEO_LICENCES[value] !== undefined
29 }
30
31 function isVideoLanguageValid (value: any) {
32   return value === null ||
33     (typeof value === 'string' && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.LANGUAGE))
34 }
35
36 function isVideoDurationValid (value: string) {
37   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
38 }
39
40 function isVideoTruncatedDescriptionValid (value: string) {
41   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.TRUNCATED_DESCRIPTION)
42 }
43
44 function isVideoDescriptionValid (value: string) {
45   return value === null || (exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION))
46 }
47
48 function isVideoSupportValid (value: string) {
49   return value === null || (exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.SUPPORT))
50 }
51
52 function isVideoNameValid (value: string) {
53   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
54 }
55
56 function isVideoTagValid (tag: string) {
57   return exists(tag) && validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
58 }
59
60 function isVideoTagsValid (tags: string[]) {
61   return tags === null || (
62     isArray(tags) &&
63     validator.isInt(tags.length.toString(), VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
64     tags.every(tag => isVideoTagValid(tag))
65   )
66 }
67
68 function isVideoAbuseReasonValid (value: string) {
69   return exists(value) && validator.isLength(value, VIDEO_ABUSES_CONSTRAINTS_FIELDS.REASON)
70 }
71
72 function isVideoViewsValid (value: string) {
73   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.VIEWS)
74 }
75
76 function isVideoRatingTypeValid (value: string) {
77   return value === 'none' || values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1
78 }
79
80 const videoFileTypes = Object.keys(VIDEO_MIMETYPE_EXT).map(m => `(${m})`)
81 const videoFileTypesRegex = videoFileTypes.join('|')
82 function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
83   return isFileValid(files, videoFileTypesRegex, 'videofile')
84 }
85
86 const videoImageTypes = CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME
87   .map(v => v.replace('.', ''))
88   .join('|')
89 const videoImageTypesRegex = `image/(${videoImageTypes})`
90 function isVideoImage (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], field: string) {
91   return isFileValid(files, videoImageTypesRegex, field, true)
92 }
93
94 function isVideoPrivacyValid (value: string) {
95   return validator.isInt(value + '') && VIDEO_PRIVACIES[value] !== undefined
96 }
97
98 function isVideoFileInfoHashValid (value: string) {
99   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.INFO_HASH)
100 }
101
102 function isVideoFileResolutionValid (value: string) {
103   return exists(value) && validator.isInt(value + '')
104 }
105
106 function isVideoFileSizeValid (value: string) {
107   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE)
108 }
109
110 async function isVideoExist (id: string, res: Response) {
111   let video: VideoModel
112
113   if (validator.isInt(id)) {
114     video = await VideoModel.loadAndPopulateAccountAndServerAndTags(+id)
115   } else { // UUID
116     video = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(id)
117   }
118
119   if (!video) {
120     res.status(404)
121       .json({ error: 'Video not found' })
122       .end()
123
124     return false
125   }
126
127   res.locals.video = video
128   return true
129 }
130
131 async function isVideoChannelOfAccountExist (channelId: number, user: UserModel, res: Response) {
132   if (user.hasRight(UserRight.UPDATE_ANY_VIDEO) === true) {
133     const videoChannel = await VideoChannelModel.loadAndPopulateAccount(channelId)
134     if (!videoChannel) {
135       res.status(400)
136          .json({ error: 'Unknown video video channel on this instance.' })
137          .end()
138
139       return false
140     }
141
142     res.locals.videoChannel = videoChannel
143     return true
144   }
145
146   const videoChannel = await VideoChannelModel.loadByIdAndAccount(channelId, user.Account.id)
147   if (!videoChannel) {
148     res.status(400)
149        .json({ error: 'Unknown video video channel for this account.' })
150        .end()
151
152     return false
153   }
154
155   res.locals.videoChannel = videoChannel
156   return true
157 }
158
159 // ---------------------------------------------------------------------------
160
161 export {
162   isVideoCategoryValid,
163   isVideoLicenceValid,
164   isVideoLanguageValid,
165   isVideoTruncatedDescriptionValid,
166   isVideoDescriptionValid,
167   isVideoFileInfoHashValid,
168   isVideoNameValid,
169   isVideoTagsValid,
170   isVideoAbuseReasonValid,
171   isVideoFile,
172   isVideoViewsValid,
173   isVideoRatingTypeValid,
174   isVideoDurationValid,
175   isVideoTagValid,
176   isVideoPrivacyValid,
177   isVideoFileResolutionValid,
178   isVideoFileSizeValid,
179   isVideoExist,
180   isVideoImage,
181   isVideoChannelOfAccountExist,
182   isVideoSupportValid
183 }