]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/helpers/custom-validators/misc.ts
Add TMP persistent directory
[github/Chocobozzz/PeerTube.git] / server / helpers / custom-validators / misc.ts
CommitLineData
ac81d1a0 1import 'multer'
f6d6e7f8 2import { UploadFilesForCheck } from 'express'
345da516 3import { sep } from 'path'
f6d6e7f8 4import validator from 'validator'
0628157f 5import { isShortUUID, shortToUUID } from '@shared/extra-utils'
fdbda9e3 6
69818c93 7function exists (value: any) {
e4c55619
C
8 return value !== undefined && value !== null
9}
10
345da516
C
11function isSafePath (p: string) {
12 return exists(p) &&
13 (p + '').split(sep).every(part => {
f023a19c 14 return [ '..' ].includes(part) === false
345da516
C
15 })
16}
17
0c9668f7
C
18function isSafeFilename (filename: string, extension: string) {
19 return typeof filename === 'string' && !!filename.match(new RegExp(`^[a-z0-9-]+\\.${extension}$`))
20}
21
d7ce9dca
C
22function isSafePeerTubeFilenameWithoutExtension (filename: string) {
23 return filename.match(/^[a-z0-9-]+$/)
24}
25
c158a5fa 26function isArray (value: any): value is any[] {
e4c55619
C
27 return Array.isArray(value)
28}
29
2f1548fd
C
30function isNotEmptyIntArray (value: any) {
31 return Array.isArray(value) && value.every(v => validator.isInt('' + v)) && value.length !== 0
cef534ed
C
32}
33
b033851f
C
34function isNotEmptyStringArray (value: any) {
35 return Array.isArray(value) && value.every(v => typeof v === 'string' && v.length !== 0) && value.length !== 0
36}
37
09209296
C
38function isArrayOf (value: any, validator: (value: any) => boolean) {
39 return isArray(value) && value.every(v => validator(v))
40}
41
72c7248b
C
42function isDateValid (value: string) {
43 return exists(value) && validator.isISO8601(value)
44}
45
46function isIdValid (value: string) {
47 return exists(value) && validator.isInt('' + value)
48}
49
50function isUUIDValid (value: string) {
51 return exists(value) && validator.isUUID('' + value, 4)
52}
53
fbd67e7f
C
54function areUUIDsValid (values: string[]) {
55 return isArray(values) && values.every(v => isUUIDValid(v))
56}
57
72c7248b
C
58function isIdOrUUIDValid (value: string) {
59 return isIdValid(value) || isUUIDValid(value)
60}
61
360329cc 62function isBooleanValid (value: any) {
47564bbe
C
63 return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value))
64}
65
fb719404
C
66function isIntOrNull (value: any) {
67 return value === null || validator.isInt('' + value)
68}
69
d4a8e7a6 70// ---------------------------------------------------------------------------
f0a39880 71
c729caf6
C
72function isFileValid (options: {
73 files: UploadFilesForCheck
f2eb23cd 74
c729caf6
C
75 maxSize: number | null
76 mimeTypeRegex: string | null
f2eb23cd 77
c729caf6 78 field?: string
f2eb23cd 79
c729caf6
C
80 optional?: boolean // Default false
81}) {
82 const { files, mimeTypeRegex, field, maxSize, optional = false } = options
f2eb23cd 83
ac81d1a0
C
84 // Should have files
85 if (!files) return optional
ac81d1a0 86
c729caf6
C
87 const fileArray = isArray(files)
88 ? files
89 : files[field]
90
91 if (!fileArray || !isArray(fileArray) || fileArray.length === 0) {
ac81d1a0
C
92 return optional
93 }
94
c729caf6 95 // The file exists
a1587156 96 const file = fileArray[0]
99b75748 97 if (!file?.originalname) return false
ac81d1a0 98
0c237b19 99 // Check size
c1e791ba 100 if ((maxSize !== null) && file.size > maxSize) return false
0c237b19 101
c729caf6
C
102 if (mimeTypeRegex === null) return true
103
104 return checkMimetypeRegex(file.mimetype, mimeTypeRegex)
105}
106
107function checkMimetypeRegex (fileMimeType: string, mimeTypeRegex: string) {
108 return new RegExp(`^${mimeTypeRegex}$`, 'i').test(fileMimeType)
ac81d1a0
C
109}
110
e4c55619
C
111// ---------------------------------------------------------------------------
112
d4a8e7a6 113function toCompleteUUID (value: string) {
ded68a97
C
114 if (isShortUUID(value)) {
115 try {
116 return shortToUUID(value)
117 } catch {
118 return null
119 }
120 }
d4a8e7a6
C
121
122 return value
123}
124
fbd67e7f
C
125function toCompleteUUIDs (values: string[]) {
126 return values.map(v => toCompleteUUID(v))
127}
128
d4a8e7a6
C
129function toIntOrNull (value: string) {
130 const v = toValueOrNull(value)
131
132 if (v === null || v === undefined) return v
133 if (typeof v === 'number') return v
134
135 return validator.toInt('' + v)
136}
137
138function toBooleanOrNull (value: any) {
139 const v = toValueOrNull(value)
140
141 if (v === null || v === undefined) return v
142 if (typeof v === 'boolean') return v
143
144 return validator.toBoolean('' + v)
145}
146
147function toValueOrNull (value: string) {
148 if (value === 'null') return null
149
150 return value
151}
152
d4a8e7a6
C
153function toIntArray (value: any) {
154 if (!value) return []
155 if (isArray(value) === false) return [ validator.toInt(value) ]
156
157 return value.map(v => validator.toInt(v))
158}
159
160// ---------------------------------------------------------------------------
161
65fcc311
C
162export {
163 exists,
09209296 164 isArrayOf,
2f1548fd 165 isNotEmptyIntArray,
72c7248b 166 isArray,
fb719404 167 isIntOrNull,
72c7248b 168 isIdValid,
345da516 169 isSafePath,
b033851f 170 isNotEmptyStringArray,
72c7248b 171 isUUIDValid,
fbd67e7f 172 toCompleteUUIDs,
d4a8e7a6 173 toCompleteUUID,
72c7248b 174 isIdOrUUIDValid,
47564bbe 175 isDateValid,
2efd32f6 176 toValueOrNull,
c8861d5d 177 toBooleanOrNull,
ac81d1a0 178 isBooleanValid,
360329cc 179 toIntOrNull,
fbd67e7f 180 areUUIDsValid,
f0a39880 181 toIntArray,
c729caf6 182 isFileValid,
d7ce9dca 183 isSafePeerTubeFilenameWithoutExtension,
0c9668f7 184 isSafeFilename,
c729caf6 185 checkMimetypeRegex
65fcc311 186}