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