Change how we handle resolution
[oweals/peertube.git] / server / helpers / custom-validators / videos.ts
1 import { values } from 'lodash'
2 import * as validator from 'validator'
3 import 'express-validator'
4 import 'multer'
5
6 import {
7   CONSTRAINTS_FIELDS,
8   VIDEO_CATEGORIES,
9   VIDEO_LICENCES,
10   VIDEO_LANGUAGES,
11   VIDEO_RATE_TYPES
12 } from '../../initializers'
13 import { isUserUsernameValid } from './users'
14 import { isArray, exists } from './misc'
15 import { VideoRateType } from '../../../shared'
16
17 const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
18 const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
19 const VIDEO_EVENTS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_EVENTS
20
21 function isVideoIdOrUUIDValid (value: string) {
22   return validator.isInt(value) || isVideoUUIDValid(value)
23 }
24
25 function isVideoAuthorValid (value: string) {
26   return isUserUsernameValid(value)
27 }
28
29 function isVideoDateValid (value: string) {
30   return exists(value) && validator.isISO8601(value)
31 }
32
33 function isVideoCategoryValid (value: number) {
34   return VIDEO_CATEGORIES[value] !== undefined
35 }
36
37 function isVideoLicenceValid (value: number) {
38   return VIDEO_LICENCES[value] !== undefined
39 }
40
41 function isVideoLanguageValid (value: number) {
42   return value === null || VIDEO_LANGUAGES[value] !== undefined
43 }
44
45 function isVideoNSFWValid (value: any) {
46   return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value))
47 }
48
49 function isVideoDescriptionValid (value: string) {
50   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION)
51 }
52
53 function isVideoDurationValid (value: string) {
54   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
55 }
56
57 function isVideoNameValid (value: string) {
58   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
59 }
60
61 function isVideoTagsValid (tags: string[]) {
62   return isArray(tags) &&
63          validator.isInt(tags.length.toString(), VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
64          tags.every(tag => {
65            return exists(tag) && validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
66          })
67 }
68
69 function isVideoThumbnailValid (value: string) {
70   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL)
71 }
72
73 function isVideoThumbnailDataValid (value: string) {
74   return exists(value) && validator.isByteLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL_DATA)
75 }
76
77 function isVideoUUIDValid (value: string) {
78   return exists(value) && validator.isUUID('' + value, 4)
79 }
80
81 function isVideoAbuseReasonValid (value: string) {
82   return exists(value) && validator.isLength(value, VIDEO_ABUSES_CONSTRAINTS_FIELDS.REASON)
83 }
84
85 function isVideoAbuseReporterUsernameValid (value: string) {
86   return isUserUsernameValid(value)
87 }
88
89 function isVideoViewsValid (value: string) {
90   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.VIEWS)
91 }
92
93 function isVideoLikesValid (value: string) {
94   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.LIKES)
95 }
96
97 function isVideoDislikesValid (value: string) {
98   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DISLIKES)
99 }
100
101 function isVideoEventCountValid (value: string) {
102   return exists(value) && validator.isInt(value + '', VIDEO_EVENTS_CONSTRAINTS_FIELDS.COUNT)
103 }
104
105 function isVideoRatingTypeValid (value: string) {
106   return values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1
107 }
108
109 function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
110   // Should have files
111   if (!files) return false
112   if (isArray(files)) return false
113
114   // Should have videofile file
115   const videofile = files['videofile']
116   if (!videofile || videofile.length === 0) return false
117
118   // The file should exist
119   const file = videofile[0]
120   if (!file || !file.originalname) return false
121
122   return new RegExp('^video/(webm|mp4|ogg)$', 'i').test(file.mimetype)
123 }
124
125 function isVideoFileSizeValid (value: string) {
126   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE)
127 }
128
129 function isVideoFileResolutionValid (value: string) {
130   return exists(value) && validator.isInt(value + '')
131 }
132
133 function isVideoFileExtnameValid (value: string) {
134   return VIDEOS_CONSTRAINTS_FIELDS.EXTNAME.indexOf(value) !== -1
135 }
136
137 function isVideoFileInfoHashValid (value: string) {
138   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.INFO_HASH)
139 }
140
141 // ---------------------------------------------------------------------------
142
143 export {
144   isVideoIdOrUUIDValid,
145   isVideoAuthorValid,
146   isVideoDateValid,
147   isVideoCategoryValid,
148   isVideoLicenceValid,
149   isVideoLanguageValid,
150   isVideoNSFWValid,
151   isVideoDescriptionValid,
152   isVideoDurationValid,
153   isVideoFileInfoHashValid,
154   isVideoNameValid,
155   isVideoTagsValid,
156   isVideoThumbnailValid,
157   isVideoThumbnailDataValid,
158   isVideoFileExtnameValid,
159   isVideoUUIDValid,
160   isVideoAbuseReasonValid,
161   isVideoAbuseReporterUsernameValid,
162   isVideoFile,
163   isVideoViewsValid,
164   isVideoLikesValid,
165   isVideoRatingTypeValid,
166   isVideoDislikesValid,
167   isVideoEventCountValid,
168   isVideoFileSizeValid,
169   isVideoFileResolutionValid
170 }