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