1 import * as Promise from 'bluebird'
2 import * as express from 'express'
3 import 'express-validator'
4 import { values } from 'lodash'
6 import * as validator from 'validator'
7 import { VideoRateType } from '../../../shared'
8 import { logger } from '../../helpers'
17 } from '../../initializers'
18 import { VideoInstance } from '../../models'
19 import { isActivityPubUrlValid } from './activitypub/misc'
20 import { exists, isArray } from './misc'
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 isVideoUrlValid (value: string) {
36 return isActivityPubUrlValid(value)
39 function isVideoLicenceValid (value: number) {
40 return VIDEO_LICENCES[value] !== undefined
43 function isVideoPrivacyValid (value: string) {
44 return VIDEO_PRIVACIES[value] !== undefined
47 // Maybe we don't know the remote privacy setting, but that doesn't matter
48 function isRemoteVideoPrivacyValid (value: string) {
49 return validator.isInt('' + value)
52 // Maybe we don't know the remote licence, but that doesn't matter
53 function isRemoteVideoLicenceValid (value: string) {
54 return validator.isInt('' + value)
57 function isVideoLanguageValid (value: number) {
58 return value === null || VIDEO_LANGUAGES[value] !== undefined
61 // Maybe we don't know the remote language, but that doesn't matter
62 function isRemoteVideoLanguageValid (value: string) {
63 return validator.isInt('' + value)
66 function isVideoNSFWValid (value: any) {
67 return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value))
70 function isVideoDurationValid (value: string) {
71 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
74 function isVideoTruncatedDescriptionValid (value: string) {
75 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.TRUNCATED_DESCRIPTION)
78 function isVideoDescriptionValid (value: string) {
79 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION)
82 function isVideoNameValid (value: string) {
83 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
86 function isVideoTagValid (tag: string) {
87 return exists(tag) && validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
90 function isVideoTagsValid (tags: string[]) {
91 return isArray(tags) &&
92 validator.isInt(tags.length.toString(), VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
93 tags.every(tag => isVideoTagValid(tag))
96 function isVideoThumbnailValid (value: string) {
97 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL)
100 function isVideoThumbnailDataValid (value: string) {
101 return exists(value) && validator.isByteLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL_DATA)
104 function isVideoAbuseReasonValid (value: string) {
105 return exists(value) && validator.isLength(value, VIDEO_ABUSES_CONSTRAINTS_FIELDS.REASON)
108 function isVideoViewsValid (value: string) {
109 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.VIEWS)
112 function isVideoLikesValid (value: string) {
113 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.LIKES)
116 function isVideoDislikesValid (value: string) {
117 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DISLIKES)
120 function isVideoEventCountValid (value: string) {
121 return exists(value) && validator.isInt(value + '', VIDEO_EVENTS_CONSTRAINTS_FIELDS.COUNT)
124 function isVideoRatingTypeValid (value: string) {
125 return values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1
128 function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
130 if (!files) return false
131 if (isArray(files)) return false
133 // Should have videofile file
134 const videofile = files['videofile']
135 if (!videofile || videofile.length === 0) return false
137 // The file should exist
138 const file = videofile[0]
139 if (!file || !file.originalname) return false
141 return new RegExp('^video/(webm|mp4|ogg)$', 'i').test(file.mimetype)
144 function isVideoFileSizeValid (value: string) {
145 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE)
148 function isVideoFileResolutionValid (value: string) {
149 return exists(value) && validator.isInt(value + '')
152 function isVideoFileExtnameValid (value: string) {
153 return VIDEOS_CONSTRAINTS_FIELDS.EXTNAME.indexOf(value) !== -1
156 function isVideoFileInfoHashValid (value: string) {
157 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.INFO_HASH)
160 function checkVideoExists (id: string, res: express.Response, callback: () => void) {
161 let promise: Promise<VideoInstance>
162 if (validator.isInt(id)) {
163 promise = db.Video.loadAndPopulateAccountAndServerAndTags(+id)
165 promise = db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(id)
168 promise.then(video => {
170 return res.status(404)
171 .json({ error: 'Video not found' })
175 res.locals.video = video
179 logger.error('Error in video request validator.', err)
180 return res.sendStatus(500)
184 // ---------------------------------------------------------------------------
187 isVideoCategoryValid,
189 isVideoLanguageValid,
191 isVideoTruncatedDescriptionValid,
192 isVideoDescriptionValid,
193 isVideoFileInfoHashValid,
196 isVideoThumbnailValid,
197 isVideoThumbnailDataValid,
198 isVideoFileExtnameValid,
199 isVideoAbuseReasonValid,
203 isVideoRatingTypeValid,
204 isVideoDislikesValid,
205 isVideoEventCountValid,
206 isVideoFileSizeValid,
208 isRemoteVideoPrivacyValid,
209 isVideoDurationValid,
210 isVideoFileResolutionValid,
213 isRemoteVideoCategoryValid,
214 isRemoteVideoLicenceValid,
216 isRemoteVideoLanguageValid