Fix lint
[oweals/peertube.git] / server / helpers / custom-validators / videos.ts
1 import * as Promise from 'bluebird'
2 import * as express from 'express'
3 import 'express-validator'
4 import { values } from 'lodash'
5 import 'multer'
6 import * as validator from 'validator'
7 import { VideoRateType } from '../../../shared'
8 import { logger } from '../../helpers'
9 import {
10   CONSTRAINTS_FIELDS,
11   database as db,
12   VIDEO_CATEGORIES,
13   VIDEO_LANGUAGES,
14   VIDEO_LICENCES,
15   VIDEO_PRIVACIES,
16   VIDEO_RATE_TYPES
17 } from '../../initializers'
18 import { VideoInstance } from '../../models'
19 import { isActivityPubUrlValid } from './activitypub/misc'
20 import { exists, isArray } from './misc'
21
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
25
26 function isVideoCategoryValid (value: number) {
27   return VIDEO_CATEGORIES[value] !== undefined
28 }
29
30 // Maybe we don't know the remote category, but that doesn't matter
31 function isRemoteVideoCategoryValid (value: string) {
32   return validator.isInt('' + value)
33 }
34
35 function isVideoUrlValid (value: string) {
36   return isActivityPubUrlValid(value)
37 }
38
39 function isVideoLicenceValid (value: number) {
40   return VIDEO_LICENCES[value] !== undefined
41 }
42
43 function isVideoPrivacyValid (value: string) {
44   return VIDEO_PRIVACIES[value] !== undefined
45 }
46
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)
50 }
51
52 // Maybe we don't know the remote licence, but that doesn't matter
53 function isRemoteVideoLicenceValid (value: string) {
54   return validator.isInt('' + value)
55 }
56
57 function isVideoLanguageValid (value: number) {
58   return value === null || VIDEO_LANGUAGES[value] !== undefined
59 }
60
61 // Maybe we don't know the remote language, but that doesn't matter
62 function isRemoteVideoLanguageValid (value: string) {
63   return validator.isInt('' + value)
64 }
65
66 function isVideoNSFWValid (value: any) {
67   return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value))
68 }
69
70 function isVideoDurationValid (value: string) {
71   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
72 }
73
74 function isVideoTruncatedDescriptionValid (value: string) {
75   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.TRUNCATED_DESCRIPTION)
76 }
77
78 function isVideoDescriptionValid (value: string) {
79   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION)
80 }
81
82 function isVideoNameValid (value: string) {
83   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
84 }
85
86 function isVideoTagValid (tag: string) {
87   return exists(tag) && validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
88 }
89
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))
94 }
95
96 function isVideoThumbnailValid (value: string) {
97   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL)
98 }
99
100 function isVideoThumbnailDataValid (value: string) {
101   return exists(value) && validator.isByteLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL_DATA)
102 }
103
104 function isVideoAbuseReasonValid (value: string) {
105   return exists(value) && validator.isLength(value, VIDEO_ABUSES_CONSTRAINTS_FIELDS.REASON)
106 }
107
108 function isVideoViewsValid (value: string) {
109   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.VIEWS)
110 }
111
112 function isVideoLikesValid (value: string) {
113   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.LIKES)
114 }
115
116 function isVideoDislikesValid (value: string) {
117   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DISLIKES)
118 }
119
120 function isVideoEventCountValid (value: string) {
121   return exists(value) && validator.isInt(value + '', VIDEO_EVENTS_CONSTRAINTS_FIELDS.COUNT)
122 }
123
124 function isVideoRatingTypeValid (value: string) {
125   return values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1
126 }
127
128 function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
129   // Should have files
130   if (!files) return false
131   if (isArray(files)) return false
132
133   // Should have videofile file
134   const videofile = files['videofile']
135   if (!videofile || videofile.length === 0) return false
136
137   // The file should exist
138   const file = videofile[0]
139   if (!file || !file.originalname) return false
140
141   return new RegExp('^video/(webm|mp4|ogg)$', 'i').test(file.mimetype)
142 }
143
144 function isVideoFileSizeValid (value: string) {
145   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE)
146 }
147
148 function isVideoFileResolutionValid (value: string) {
149   return exists(value) && validator.isInt(value + '')
150 }
151
152 function isVideoFileExtnameValid (value: string) {
153   return VIDEOS_CONSTRAINTS_FIELDS.EXTNAME.indexOf(value) !== -1
154 }
155
156 function isVideoFileInfoHashValid (value: string) {
157   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.INFO_HASH)
158 }
159
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)
164   } else { // UUID
165     promise = db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(id)
166   }
167
168   promise.then(video => {
169     if (!video) {
170       return res.status(404)
171                 .json({ error: 'Video not found' })
172                 .end()
173     }
174
175     res.locals.video = video
176     callback()
177   })
178   .catch(err => {
179     logger.error('Error in video request validator.', err)
180     return res.sendStatus(500)
181   })
182 }
183
184 // ---------------------------------------------------------------------------
185
186 export {
187   isVideoCategoryValid,
188   isVideoLicenceValid,
189   isVideoLanguageValid,
190   isVideoNSFWValid,
191   isVideoTruncatedDescriptionValid,
192   isVideoDescriptionValid,
193   isVideoFileInfoHashValid,
194   isVideoNameValid,
195   isVideoTagsValid,
196   isVideoThumbnailValid,
197   isVideoThumbnailDataValid,
198   isVideoFileExtnameValid,
199   isVideoAbuseReasonValid,
200   isVideoFile,
201   isVideoViewsValid,
202   isVideoLikesValid,
203   isVideoRatingTypeValid,
204   isVideoDislikesValid,
205   isVideoEventCountValid,
206   isVideoFileSizeValid,
207   isVideoPrivacyValid,
208   isRemoteVideoPrivacyValid,
209   isVideoDurationValid,
210   isVideoFileResolutionValid,
211   checkVideoExists,
212   isVideoTagValid,
213   isRemoteVideoCategoryValid,
214   isRemoteVideoLicenceValid,
215   isVideoUrlValid,
216   isRemoteVideoLanguageValid
217 }