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