diff options
Diffstat (limited to 'server/helpers')
-rw-r--r-- | server/helpers/custom-validators/misc.ts | 27 | ||||
-rw-r--r-- | server/helpers/custom-validators/users.ts | 26 | ||||
-rw-r--r-- | server/helpers/custom-validators/videos.ts | 29 | ||||
-rw-r--r-- | server/helpers/image-utils.ts | 21 | ||||
-rw-r--r-- | server/helpers/utils.ts | 18 |
5 files changed, 85 insertions, 36 deletions
diff --git a/server/helpers/custom-validators/misc.ts b/server/helpers/custom-validators/misc.ts index 3903884ea..8a270b777 100644 --- a/server/helpers/custom-validators/misc.ts +++ b/server/helpers/custom-validators/misc.ts | |||
@@ -1,3 +1,4 @@ | |||
1 | import 'multer' | ||
1 | import * as validator from 'validator' | 2 | import * as validator from 'validator' |
2 | 3 | ||
3 | function exists (value: any) { | 4 | function exists (value: any) { |
@@ -28,6 +29,29 @@ function isBooleanValid (value: string) { | |||
28 | return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value)) | 29 | return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value)) |
29 | } | 30 | } |
30 | 31 | ||
32 | function isFileValid ( | ||
33 | files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], | ||
34 | mimeTypeRegex: string, | ||
35 | field: string, | ||
36 | optional = false | ||
37 | ) { | ||
38 | // Should have files | ||
39 | if (!files) return optional | ||
40 | if (isArray(files)) return optional | ||
41 | |||
42 | // Should have a file | ||
43 | const fileArray = files[ field ] | ||
44 | if (!fileArray || fileArray.length === 0) { | ||
45 | return optional | ||
46 | } | ||
47 | |||
48 | // The file should exist | ||
49 | const file = fileArray[ 0 ] | ||
50 | if (!file || !file.originalname) return false | ||
51 | |||
52 | return new RegExp(`^${mimeTypeRegex}$`, 'i').test(file.mimetype) | ||
53 | } | ||
54 | |||
31 | // --------------------------------------------------------------------------- | 55 | // --------------------------------------------------------------------------- |
32 | 56 | ||
33 | export { | 57 | export { |
@@ -37,5 +61,6 @@ export { | |||
37 | isUUIDValid, | 61 | isUUIDValid, |
38 | isIdOrUUIDValid, | 62 | isIdOrUUIDValid, |
39 | isDateValid, | 63 | isDateValid, |
40 | isBooleanValid | 64 | isBooleanValid, |
65 | isFileValid | ||
41 | } | 66 | } |
diff --git a/server/helpers/custom-validators/users.ts b/server/helpers/custom-validators/users.ts index 6ed60c1c4..e805313f8 100644 --- a/server/helpers/custom-validators/users.ts +++ b/server/helpers/custom-validators/users.ts | |||
@@ -1,9 +1,9 @@ | |||
1 | import * as validator from 'validator' | ||
2 | import 'express-validator' | 1 | import 'express-validator' |
3 | 2 | import * as validator from 'validator' | |
4 | import { exists, isArray } from './misc' | ||
5 | import { CONSTRAINTS_FIELDS } from '../../initializers' | ||
6 | import { UserRole } from '../../../shared' | 3 | import { UserRole } from '../../../shared' |
4 | import { CONSTRAINTS_FIELDS } from '../../initializers' | ||
5 | |||
6 | import { exists, isFileValid } from './misc' | ||
7 | 7 | ||
8 | const USERS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.USERS | 8 | const USERS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.USERS |
9 | 9 | ||
@@ -37,20 +37,12 @@ function isUserRoleValid (value: any) { | |||
37 | return exists(value) && validator.isInt('' + value) && UserRole[value] !== undefined | 37 | return exists(value) && validator.isInt('' + value) && UserRole[value] !== undefined |
38 | } | 38 | } |
39 | 39 | ||
40 | const avatarMimeTypes = CONSTRAINTS_FIELDS.ACTORS.AVATAR.EXTNAME | ||
41 | .map(v => v.replace('.', '')) | ||
42 | .join('|') | ||
43 | const avatarMimeTypesRegex = `image/(${avatarMimeTypes})` | ||
40 | function isAvatarFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) { | 44 | function isAvatarFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) { |
41 | // Should have files | 45 | return isFileValid(files, avatarMimeTypesRegex, 'avatarfile') |
42 | if (!files) return false | ||
43 | if (isArray(files)) return false | ||
44 | |||
45 | // Should have videofile file | ||
46 | const avatarfile = files['avatarfile'] | ||
47 | if (!avatarfile || avatarfile.length === 0) return false | ||
48 | |||
49 | // The file should exist | ||
50 | const file = avatarfile[0] | ||
51 | if (!file || !file.originalname) return false | ||
52 | |||
53 | return new RegExp('^image/(png|jpeg)$', 'i').test(file.mimetype) | ||
54 | } | 46 | } |
55 | 47 | ||
56 | // --------------------------------------------------------------------------- | 48 | // --------------------------------------------------------------------------- |
diff --git a/server/helpers/custom-validators/videos.ts b/server/helpers/custom-validators/videos.ts index 0e8a2aab2..8ef3a3c64 100644 --- a/server/helpers/custom-validators/videos.ts +++ b/server/helpers/custom-validators/videos.ts | |||
@@ -8,12 +8,12 @@ import { | |||
8 | CONSTRAINTS_FIELDS, | 8 | CONSTRAINTS_FIELDS, |
9 | VIDEO_CATEGORIES, | 9 | VIDEO_CATEGORIES, |
10 | VIDEO_LANGUAGES, | 10 | VIDEO_LANGUAGES, |
11 | VIDEO_LICENCES, | 11 | VIDEO_LICENCES, VIDEO_MIMETYPE_EXT, |
12 | VIDEO_PRIVACIES, | 12 | VIDEO_PRIVACIES, |
13 | VIDEO_RATE_TYPES | 13 | VIDEO_RATE_TYPES |
14 | } from '../../initializers' | 14 | } from '../../initializers' |
15 | import { VideoModel } from '../../models/video/video' | 15 | import { VideoModel } from '../../models/video/video' |
16 | import { exists, isArray } from './misc' | 16 | import { exists, isArray, isFileValid } from './misc' |
17 | 17 | ||
18 | const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS | 18 | const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS |
19 | const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES | 19 | const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES |
@@ -68,20 +68,18 @@ function isVideoRatingTypeValid (value: string) { | |||
68 | return value === 'none' || values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1 | 68 | return value === 'none' || values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1 |
69 | } | 69 | } |
70 | 70 | ||
71 | const videoFileTypes = Object.keys(VIDEO_MIMETYPE_EXT).map(m => `(${m})`) | ||
72 | const videoFileTypesRegex = videoFileTypes.join('|') | ||
71 | function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) { | 73 | function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) { |
72 | // Should have files | 74 | return isFileValid(files, videoFileTypesRegex, 'videofile') |
73 | if (!files) return false | 75 | } |
74 | if (isArray(files)) return false | ||
75 | |||
76 | // Should have videofile file | ||
77 | const videofile = files['videofile'] | ||
78 | if (!videofile || videofile.length === 0) return false | ||
79 | |||
80 | // The file should exist | ||
81 | const file = videofile[0] | ||
82 | if (!file || !file.originalname) return false | ||
83 | 76 | ||
84 | return new RegExp('^video/(webm|mp4|ogg)$', 'i').test(file.mimetype) | 77 | const videoImageTypes = CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME |
78 | .map(v => v.replace('.', '')) | ||
79 | .join('|') | ||
80 | const videoImageTypesRegex = `image/(${videoImageTypes})` | ||
81 | function isVideoImage (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], field: string) { | ||
82 | return isFileValid(files, videoImageTypesRegex, field, true) | ||
85 | } | 83 | } |
86 | 84 | ||
87 | function isVideoPrivacyValid (value: string) { | 85 | function isVideoPrivacyValid (value: string) { |
@@ -141,5 +139,6 @@ export { | |||
141 | isVideoPrivacyValid, | 139 | isVideoPrivacyValid, |
142 | isVideoFileResolutionValid, | 140 | isVideoFileResolutionValid, |
143 | isVideoFileSizeValid, | 141 | isVideoFileSizeValid, |
144 | isVideoExist | 142 | isVideoExist, |
143 | isVideoImage | ||
145 | } | 144 | } |
diff --git a/server/helpers/image-utils.ts b/server/helpers/image-utils.ts new file mode 100644 index 000000000..ba57b5812 --- /dev/null +++ b/server/helpers/image-utils.ts | |||
@@ -0,0 +1,21 @@ | |||
1 | import 'multer' | ||
2 | import * as sharp from 'sharp' | ||
3 | import { unlinkPromise } from './core-utils' | ||
4 | |||
5 | async function processImage ( | ||
6 | physicalFile: Express.Multer.File, | ||
7 | destination: string, | ||
8 | newSize: { width: number, height: number } | ||
9 | ) { | ||
10 | await sharp(physicalFile.path) | ||
11 | .resize(newSize.width, newSize.height) | ||
12 | .toFile(destination) | ||
13 | |||
14 | await unlinkPromise(physicalFile.path) | ||
15 | } | ||
16 | |||
17 | // --------------------------------------------------------------------------- | ||
18 | |||
19 | export { | ||
20 | processImage | ||
21 | } | ||
diff --git a/server/helpers/utils.ts b/server/helpers/utils.ts index 79c3b5858..3b618360b 100644 --- a/server/helpers/utils.ts +++ b/server/helpers/utils.ts | |||
@@ -27,10 +27,14 @@ function badRequest (req: express.Request, res: express.Response, next: express. | |||
27 | return res.type('json').status(400).end() | 27 | return res.type('json').status(400).end() |
28 | } | 28 | } |
29 | 29 | ||
30 | function createReqFiles (fieldName: string, storageDir: string, mimeTypes: { [ id: string ]: string }) { | 30 | function createReqFiles ( |
31 | fieldNames: string[], | ||
32 | mimeTypes: { [ id: string ]: string }, | ||
33 | destinations: { [ fieldName: string ]: string } | ||
34 | ) { | ||
31 | const storage = multer.diskStorage({ | 35 | const storage = multer.diskStorage({ |
32 | destination: (req, file, cb) => { | 36 | destination: (req, file, cb) => { |
33 | cb(null, storageDir) | 37 | cb(null, destinations[file.fieldname]) |
34 | }, | 38 | }, |
35 | 39 | ||
36 | filename: async (req, file, cb) => { | 40 | filename: async (req, file, cb) => { |
@@ -48,7 +52,15 @@ function createReqFiles (fieldName: string, storageDir: string, mimeTypes: { [ i | |||
48 | } | 52 | } |
49 | }) | 53 | }) |
50 | 54 | ||
51 | return multer({ storage }).fields([{ name: fieldName, maxCount: 1 }]) | 55 | const fields = [] |
56 | for (const fieldName of fieldNames) { | ||
57 | fields.push({ | ||
58 | name: fieldName, | ||
59 | maxCount: 1 | ||
60 | }) | ||
61 | } | ||
62 | |||
63 | return multer({ storage }).fields(fields) | ||
52 | } | 64 | } |
53 | 65 | ||
54 | async function generateRandomString (size: number) { | 66 | async function generateRandomString (size: number) { |