]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/helpers/custom-validators/misc.ts
f8f168149e9cfeb7078e40d43eb725896ee74bc4
[github/Chocobozzz/PeerTube.git] / server / helpers / custom-validators / misc.ts
1 import 'multer'
2 import { UploadFilesForCheck } from 'express'
3 import { sep } from 'path'
4 import validator from 'validator'
5 import { isShortUUID, shortToUUID } from '../uuid'
6
7 function exists (value: any) {
8 return value !== undefined && value !== null
9 }
10
11 function isSafePath (p: string) {
12 return exists(p) &&
13 (p + '').split(sep).every(part => {
14 return [ '..' ].includes(part) === false
15 })
16 }
17
18 function isArray (value: any): value is any[] {
19 return Array.isArray(value)
20 }
21
22 function isNotEmptyIntArray (value: any) {
23 return Array.isArray(value) && value.every(v => validator.isInt('' + v)) && value.length !== 0
24 }
25
26 function isArrayOf (value: any, validator: (value: any) => boolean) {
27 return isArray(value) && value.every(v => validator(v))
28 }
29
30 function isDateValid (value: string) {
31 return exists(value) && validator.isISO8601(value)
32 }
33
34 function isIdValid (value: string) {
35 return exists(value) && validator.isInt('' + value)
36 }
37
38 function isUUIDValid (value: string) {
39 return exists(value) && validator.isUUID('' + value, 4)
40 }
41
42 function areUUIDsValid (values: string[]) {
43 return isArray(values) && values.every(v => isUUIDValid(v))
44 }
45
46 function isIdOrUUIDValid (value: string) {
47 return isIdValid(value) || isUUIDValid(value)
48 }
49
50 function isBooleanValid (value: any) {
51 return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value))
52 }
53
54 function isIntOrNull (value: any) {
55 return value === null || validator.isInt('' + value)
56 }
57
58 // ---------------------------------------------------------------------------
59
60 function isFileFieldValid (
61 files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[],
62 field: string,
63 optional = false
64 ) {
65 // Should have files
66 if (!files) return optional
67 if (isArray(files)) return optional
68
69 // Should have a file
70 const fileArray = files[field]
71 if (!fileArray || fileArray.length === 0) {
72 return optional
73 }
74
75 // The file should exist
76 const file = fileArray[0]
77 if (!file || !file.originalname) return false
78 return file
79 }
80
81 function isFileMimeTypeValid (
82 files: UploadFilesForCheck,
83 mimeTypeRegex: string,
84 field: string,
85 optional = false
86 ) {
87 // Should have files
88 if (!files) return optional
89 if (isArray(files)) return optional
90
91 // Should have a file
92 const fileArray = files[field]
93 if (!fileArray || fileArray.length === 0) {
94 return optional
95 }
96
97 // The file should exist
98 const file = fileArray[0]
99 if (!file || !file.originalname) return false
100
101 return new RegExp(`^${mimeTypeRegex}$`, 'i').test(file.mimetype)
102 }
103
104 function isFileValid (
105 files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[],
106 mimeTypeRegex: string,
107 field: string,
108 maxSize: number | null,
109 optional = false
110 ) {
111 // Should have files
112 if (!files) return optional
113 if (isArray(files)) return optional
114
115 // Should have a file
116 const fileArray = files[field]
117 if (!fileArray || fileArray.length === 0) {
118 return optional
119 }
120
121 // The file should exist
122 const file = fileArray[0]
123 if (!file || !file.originalname) return false
124
125 // Check size
126 if ((maxSize !== null) && file.size > maxSize) return false
127
128 return new RegExp(`^${mimeTypeRegex}$`, 'i').test(file.mimetype)
129 }
130
131 // ---------------------------------------------------------------------------
132
133 function toCompleteUUID (value: string) {
134 if (isShortUUID(value)) return shortToUUID(value)
135
136 return value
137 }
138
139 function toCompleteUUIDs (values: string[]) {
140 return values.map(v => toCompleteUUID(v))
141 }
142
143 function toIntOrNull (value: string) {
144 const v = toValueOrNull(value)
145
146 if (v === null || v === undefined) return v
147 if (typeof v === 'number') return v
148
149 return validator.toInt('' + v)
150 }
151
152 function toBooleanOrNull (value: any) {
153 const v = toValueOrNull(value)
154
155 if (v === null || v === undefined) return v
156 if (typeof v === 'boolean') return v
157
158 return validator.toBoolean('' + v)
159 }
160
161 function toValueOrNull (value: string) {
162 if (value === 'null') return null
163
164 return value
165 }
166
167 function toArray (value: any) {
168 if (value && isArray(value) === false) return [ value ]
169
170 return value
171 }
172
173 function toIntArray (value: any) {
174 if (!value) return []
175 if (isArray(value) === false) return [ validator.toInt(value) ]
176
177 return value.map(v => validator.toInt(v))
178 }
179
180 // ---------------------------------------------------------------------------
181
182 export {
183 exists,
184 isArrayOf,
185 isNotEmptyIntArray,
186 isArray,
187 isIntOrNull,
188 isIdValid,
189 isSafePath,
190 isUUIDValid,
191 toCompleteUUIDs,
192 toCompleteUUID,
193 isIdOrUUIDValid,
194 isDateValid,
195 toValueOrNull,
196 toBooleanOrNull,
197 isBooleanValid,
198 toIntOrNull,
199 areUUIDsValid,
200 toArray,
201 toIntArray,
202 isFileFieldValid,
203 isFileMimeTypeValid,
204 isFileValid
205 }