Update dependencies
[oweals/peertube.git] / server / helpers / custom-validators / videos.ts
1 import { values } from 'lodash'
2 import validator from 'validator'
3 import { VideoFilter, VideoPrivacy, VideoRateType } from '../../../shared'
4 import {
5   CONSTRAINTS_FIELDS,
6   MIMETYPES,
7   VIDEO_CATEGORIES,
8   VIDEO_LICENCES,
9   VIDEO_PRIVACIES,
10   VIDEO_RATE_TYPES,
11   VIDEO_STATES
12 } from '../../initializers/constants'
13 import { exists, isArray, isDateValid, isFileValid } from './misc'
14 import * as magnetUtil from 'magnet-uri'
15
16 const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
17
18 function isVideoFilterValid (filter: VideoFilter) {
19   return filter === 'local' || filter === 'all-local'
20 }
21
22 function isVideoCategoryValid (value: any) {
23   return value === null || VIDEO_CATEGORIES[value] !== undefined
24 }
25
26 function isVideoStateValid (value: any) {
27   return exists(value) && VIDEO_STATES[value] !== undefined
28 }
29
30 function isVideoLicenceValid (value: any) {
31   return value === null || VIDEO_LICENCES[value] !== undefined
32 }
33
34 function isVideoLanguageValid (value: any) {
35   return value === null ||
36     (typeof value === 'string' && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.LANGUAGE))
37 }
38
39 function isVideoDurationValid (value: string) {
40   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
41 }
42
43 function isVideoTruncatedDescriptionValid (value: string) {
44   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.TRUNCATED_DESCRIPTION)
45 }
46
47 function isVideoDescriptionValid (value: string) {
48   return value === null || (exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION))
49 }
50
51 function isVideoSupportValid (value: string) {
52   return value === null || (exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.SUPPORT))
53 }
54
55 function isVideoNameValid (value: string) {
56   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
57 }
58
59 function isVideoTagValid (tag: string) {
60   return exists(tag) && validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
61 }
62
63 function isVideoTagsValid (tags: string[]) {
64   return tags === null || (
65     isArray(tags) &&
66     validator.isInt(tags.length.toString(), VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
67     tags.every(tag => isVideoTagValid(tag))
68   )
69 }
70
71 function isVideoViewsValid (value: string) {
72   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.VIEWS)
73 }
74
75 function isVideoRatingTypeValid (value: string) {
76   return value === 'none' || values(VIDEO_RATE_TYPES).includes(value as VideoRateType)
77 }
78
79 function isVideoFileExtnameValid (value: string) {
80   return exists(value) && MIMETYPES.VIDEO.EXT_MIMETYPE[value] !== undefined
81 }
82
83 function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
84   const videoFileTypesRegex = Object.keys(MIMETYPES.VIDEO.MIMETYPE_EXT)
85                                     .map(m => `(${m})`)
86                                     .join('|')
87
88   return isFileValid(files, videoFileTypesRegex, 'videofile', null)
89 }
90
91 const videoImageTypes = CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME
92                                           .map(v => v.replace('.', ''))
93                                           .join('|')
94 const videoImageTypesRegex = `image/(${videoImageTypes})`
95
96 function isVideoImage (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], field: string) {
97   return isFileValid(files, videoImageTypesRegex, field, CONSTRAINTS_FIELDS.VIDEOS.IMAGE.FILE_SIZE.max, true)
98 }
99
100 function isVideoPrivacyValid (value: number) {
101   return VIDEO_PRIVACIES[value] !== undefined
102 }
103
104 function isScheduleVideoUpdatePrivacyValid (value: number) {
105   return value === VideoPrivacy.UNLISTED || value === VideoPrivacy.PUBLIC || value === VideoPrivacy.INTERNAL
106 }
107
108 function isVideoOriginallyPublishedAtValid (value: string | null) {
109   return value === null || isDateValid(value)
110 }
111
112 function isVideoFileInfoHashValid (value: string | null | undefined) {
113   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.INFO_HASH)
114 }
115
116 function isVideoFileResolutionValid (value: string) {
117   return exists(value) && validator.isInt(value + '')
118 }
119
120 function isVideoFPSResolutionValid (value: string) {
121   return value === null || validator.isInt(value + '')
122 }
123
124 function isVideoFileSizeValid (value: string) {
125   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE)
126 }
127
128 function isVideoMagnetUriValid (value: string) {
129   if (!exists(value)) return false
130
131   const parsed = magnetUtil.decode(value)
132   return parsed && isVideoFileInfoHashValid(parsed.infoHash)
133 }
134
135 // ---------------------------------------------------------------------------
136
137 export {
138   isVideoCategoryValid,
139   isVideoLicenceValid,
140   isVideoLanguageValid,
141   isVideoTruncatedDescriptionValid,
142   isVideoDescriptionValid,
143   isVideoFileInfoHashValid,
144   isVideoNameValid,
145   isVideoTagsValid,
146   isVideoFPSResolutionValid,
147   isScheduleVideoUpdatePrivacyValid,
148   isVideoOriginallyPublishedAtValid,
149   isVideoFile,
150   isVideoMagnetUriValid,
151   isVideoStateValid,
152   isVideoViewsValid,
153   isVideoRatingTypeValid,
154   isVideoFileExtnameValid,
155   isVideoDurationValid,
156   isVideoTagValid,
157   isVideoPrivacyValid,
158   isVideoFileResolutionValid,
159   isVideoFileSizeValid,
160   isVideoImage,
161   isVideoSupportValid,
162   isVideoFilterValid
163 }