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