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'
15 } from '../../initializers'
16 import { isUserUsernameValid } from './users'
17 import { isArray, exists } from './misc'
18 import { VideoInstance } from '../../models'
19 import { logger } from '../../helpers'
20 import { VideoRateType } from '../../../shared'
22 const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
23 const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
24 const VIDEO_EVENTS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_EVENTS
26 function isVideoCategoryValid (value: number) {
27 return VIDEO_CATEGORIES[value] !== undefined
30 // Maybe we don't know the remote category, but that doesn't matter
31 function isRemoteVideoCategoryValid (value: string) {
32 return validator.isInt('' + value)
35 function isVideoLicenceValid (value: number) {
36 return VIDEO_LICENCES[value] !== undefined
39 // Maybe we don't know the remote licence, but that doesn't matter
40 function isRemoteVideoLicenceValid (value: string) {
41 return validator.isInt('' + value)
44 function isVideoLanguageValid (value: number) {
45 return value === null || VIDEO_LANGUAGES[value] !== undefined
48 // Maybe we don't know the remote language, but that doesn't matter
49 function isRemoteVideoLanguageValid (value: string) {
50 return validator.isInt('' + value)
53 function isVideoNSFWValid (value: any) {
54 return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value))
57 function isVideoTruncatedDescriptionValid (value: string) {
58 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.TRUNCATED_DESCRIPTION)
61 function isVideoDescriptionValid (value: string) {
62 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION)
65 function isVideoDurationValid (value: string) {
66 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
69 function isVideoNameValid (value: string) {
70 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
73 function isVideoTagsValid (tags: string[]) {
74 return isArray(tags) &&
75 validator.isInt(tags.length.toString(), VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
77 return exists(tag) && validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
81 function isVideoThumbnailValid (value: string) {
82 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL)
85 function isVideoThumbnailDataValid (value: string) {
86 return exists(value) && validator.isByteLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL_DATA)
89 function isVideoAbuseReasonValid (value: string) {
90 return exists(value) && validator.isLength(value, VIDEO_ABUSES_CONSTRAINTS_FIELDS.REASON)
93 function isVideoAbuseReporterUsernameValid (value: string) {
94 return isUserUsernameValid(value)
97 function isVideoViewsValid (value: string) {
98 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.VIEWS)
101 function isVideoLikesValid (value: string) {
102 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.LIKES)
105 function isVideoDislikesValid (value: string) {
106 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DISLIKES)
109 function isVideoEventCountValid (value: string) {
110 return exists(value) && validator.isInt(value + '', VIDEO_EVENTS_CONSTRAINTS_FIELDS.COUNT)
113 function isVideoRatingTypeValid (value: string) {
114 return values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1
117 function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
119 if (!files) return false
120 if (isArray(files)) return false
122 // Should have videofile file
123 const videofile = files['videofile']
124 if (!videofile || videofile.length === 0) return false
126 // The file should exist
127 const file = videofile[0]
128 if (!file || !file.originalname) return false
130 return new RegExp('^video/(webm|mp4|ogg)$', 'i').test(file.mimetype)
133 function isVideoFileSizeValid (value: string) {
134 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE)
137 function isVideoFileResolutionValid (value: string) {
138 return exists(value) && validator.isInt(value + '')
141 function isVideoFileExtnameValid (value: string) {
142 return VIDEOS_CONSTRAINTS_FIELDS.EXTNAME.indexOf(value) !== -1
145 function isVideoFileInfoHashValid (value: string) {
146 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.INFO_HASH)
149 function checkVideoExists (id: string, res: express.Response, callback: () => void) {
150 let promise: Promise<VideoInstance>
151 if (validator.isInt(id)) {
152 promise = db.Video.loadAndPopulateAuthorAndPodAndTags(+id)
154 promise = db.Video.loadByUUIDAndPopulateAuthorAndPodAndTags(id)
157 promise.then(video => {
159 return res.status(404)
160 .json({ error: 'Video not found' })
164 res.locals.video = video
168 logger.error('Error in video request validator.', err)
169 return res.sendStatus(500)
173 // ---------------------------------------------------------------------------
176 isVideoCategoryValid,
178 isVideoLanguageValid,
180 isVideoTruncatedDescriptionValid,
181 isVideoDescriptionValid,
182 isVideoDurationValid,
183 isVideoFileInfoHashValid,
186 isVideoThumbnailValid,
187 isVideoThumbnailDataValid,
188 isVideoFileExtnameValid,
189 isVideoAbuseReasonValid,
190 isVideoAbuseReporterUsernameValid,
194 isVideoRatingTypeValid,
195 isVideoDislikesValid,
196 isVideoEventCountValid,
197 isVideoFileSizeValid,
198 isVideoFileResolutionValid,
200 isRemoteVideoCategoryValid,
201 isRemoteVideoLicenceValid,
202 isRemoteVideoLanguageValid