1 import { values } from 'lodash'
2 import * as validator from 'validator'
3 import * as Promise from 'bluebird'
4 import * as express from 'express'
5 import 'express-validator'
16 } from '../../initializers'
17 import { isUserUsernameValid } from './users'
18 import { isArray, exists } from './misc'
19 import { VideoInstance } from '../../models'
20 import { logger } from '../../helpers'
21 import { VideoRateType } from '../../../shared'
23 const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
24 const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
25 const VIDEO_EVENTS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_EVENTS
27 function isVideoCategoryValid (value: number) {
28 return VIDEO_CATEGORIES[value] !== undefined
31 // Maybe we don't know the remote category, but that doesn't matter
32 function isRemoteVideoCategoryValid (value: string) {
33 return validator.isInt('' + value)
36 function isVideoLicenceValid (value: number) {
37 return VIDEO_LICENCES[value] !== undefined
40 function isVideoPrivacyValid (value: string) {
41 return VIDEO_PRIVACIES[value] !== undefined
44 // Maybe we don't know the remote privacy setting, but that doesn't matter
45 function isRemoteVideoPrivacyValid (value: string) {
46 return validator.isInt('' + value)
49 // Maybe we don't know the remote licence, but that doesn't matter
50 function isRemoteVideoLicenceValid (value: string) {
51 return validator.isInt('' + value)
54 function isVideoLanguageValid (value: number) {
55 return value === null || VIDEO_LANGUAGES[value] !== undefined
58 // Maybe we don't know the remote language, but that doesn't matter
59 function isRemoteVideoLanguageValid (value: string) {
60 return validator.isInt('' + value)
63 function isVideoNSFWValid (value: any) {
64 return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value))
67 function isVideoTruncatedDescriptionValid (value: string) {
68 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.TRUNCATED_DESCRIPTION)
71 function isVideoDescriptionValid (value: string) {
72 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION)
75 function isVideoDurationValid (value: string) {
76 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
79 function isVideoNameValid (value: string) {
80 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
83 function isVideoTagsValid (tags: string[]) {
84 return isArray(tags) &&
85 validator.isInt(tags.length.toString(), VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
87 return exists(tag) && validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
91 function isVideoThumbnailValid (value: string) {
92 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL)
95 function isVideoThumbnailDataValid (value: string) {
96 return exists(value) && validator.isByteLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL_DATA)
99 function isVideoAbuseReasonValid (value: string) {
100 return exists(value) && validator.isLength(value, VIDEO_ABUSES_CONSTRAINTS_FIELDS.REASON)
103 function isVideoAbuseReporterUsernameValid (value: string) {
104 return isUserUsernameValid(value)
107 function isVideoViewsValid (value: string) {
108 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.VIEWS)
111 function isVideoLikesValid (value: string) {
112 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.LIKES)
115 function isVideoDislikesValid (value: string) {
116 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DISLIKES)
119 function isVideoEventCountValid (value: string) {
120 return exists(value) && validator.isInt(value + '', VIDEO_EVENTS_CONSTRAINTS_FIELDS.COUNT)
123 function isVideoRatingTypeValid (value: string) {
124 return values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1
127 function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
129 if (!files) return false
130 if (isArray(files)) return false
132 // Should have videofile file
133 const videofile = files['videofile']
134 if (!videofile || videofile.length === 0) return false
136 // The file should exist
137 const file = videofile[0]
138 if (!file || !file.originalname) return false
140 return new RegExp('^video/(webm|mp4|ogg)$', 'i').test(file.mimetype)
143 function isVideoFileSizeValid (value: string) {
144 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE)
147 function isVideoFileResolutionValid (value: string) {
148 return exists(value) && validator.isInt(value + '')
151 function isVideoFileExtnameValid (value: string) {
152 return VIDEOS_CONSTRAINTS_FIELDS.EXTNAME.indexOf(value) !== -1
155 function isVideoFileInfoHashValid (value: string) {
156 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.INFO_HASH)
159 function checkVideoExists (id: string, res: express.Response, callback: () => void) {
160 let promise: Promise<VideoInstance>
161 if (validator.isInt(id)) {
162 promise = db.Video.loadAndPopulateAuthorAndPodAndTags(+id)
164 promise = db.Video.loadByUUIDAndPopulateAuthorAndPodAndTags(id)
167 promise.then(video => {
169 return res.status(404)
170 .json({ error: 'Video not found' })
174 res.locals.video = video
178 logger.error('Error in video request validator.', err)
179 return res.sendStatus(500)
183 // ---------------------------------------------------------------------------
186 isVideoCategoryValid,
188 isVideoLanguageValid,
190 isVideoTruncatedDescriptionValid,
191 isVideoDescriptionValid,
192 isVideoDurationValid,
193 isVideoFileInfoHashValid,
196 isVideoThumbnailValid,
197 isVideoThumbnailDataValid,
198 isVideoFileExtnameValid,
199 isVideoAbuseReasonValid,
200 isVideoAbuseReporterUsernameValid,
204 isVideoRatingTypeValid,
205 isVideoDislikesValid,
206 isVideoEventCountValid,
207 isVideoFileSizeValid,
209 isRemoteVideoPrivacyValid,
210 isVideoFileResolutionValid,
212 isRemoteVideoCategoryValid,
213 isRemoteVideoLicenceValid,
214 isRemoteVideoLanguageValid