aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/middlewares
diff options
context:
space:
mode:
Diffstat (limited to 'server/middlewares')
-rw-r--r--server/middlewares/validators/pagination.ts16
-rw-r--r--server/middlewares/validators/pods.ts155
-rw-r--r--server/middlewares/validators/remote/signature.ts18
-rw-r--r--server/middlewares/validators/remote/videos.ts45
-rw-r--r--server/middlewares/validators/sort.ts28
-rw-r--r--server/middlewares/validators/users.ts219
-rw-r--r--server/middlewares/validators/utils.ts11
-rw-r--r--server/middlewares/validators/videos.ts294
8 files changed, 427 insertions, 359 deletions
diff --git a/server/middlewares/validators/pagination.ts b/server/middlewares/validators/pagination.ts
index cca8295ff..a5a542cdf 100644
--- a/server/middlewares/validators/pagination.ts
+++ b/server/middlewares/validators/pagination.ts
@@ -1,17 +1,19 @@
1import 'express-validator' 1import { query } from 'express-validator/check'
2import * as express from 'express' 2import * as express from 'express'
3 3
4import { checkErrors } from './utils' 4import { checkErrors } from './utils'
5import { logger } from '../../helpers' 5import { logger } from '../../helpers'
6 6
7function paginationValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 7const paginationValidator = [
8 req.checkQuery('start', 'Should have a number start').optional().isInt() 8 query('start').optional().isInt().withMessage('Should have a number start'),
9 req.checkQuery('count', 'Should have a number count').optional().isInt() 9 query('count').optional().isInt().withMessage('Should have a number count'),
10 10
11 logger.debug('Checking pagination parameters', { parameters: req.query }) 11 (req: express.Request, res: express.Response, next: express.NextFunction) => {
12 logger.debug('Checking pagination parameters', { parameters: req.query })
12 13
13 checkErrors(req, res, next) 14 checkErrors(req, res, next)
14} 15 }
16]
15 17
16// --------------------------------------------------------------------------- 18// ---------------------------------------------------------------------------
17 19
diff --git a/server/middlewares/validators/pods.ts b/server/middlewares/validators/pods.ts
index 3a0f56f6a..ab7702e78 100644
--- a/server/middlewares/validators/pods.ts
+++ b/server/middlewares/validators/pods.ts
@@ -1,89 +1,96 @@
1import 'express-validator' 1import { body, param } from 'express-validator/check'
2import * as express from 'express' 2import * as express from 'express'
3 3
4import { database as db } from '../../initializers/database' 4import { database as db } from '../../initializers/database'
5import { checkErrors } from './utils' 5import { checkErrors } from './utils'
6import { logger } from '../../helpers' 6import { logger, isEachUniqueHostValid, isHostValid } from '../../helpers'
7import { CONFIG } from '../../initializers' 7import { CONFIG } from '../../initializers'
8import { hasFriends } from '../../lib' 8import { hasFriends } from '../../lib'
9import { isTestInstance } from '../../helpers' 9import { isTestInstance } from '../../helpers'
10 10
11function makeFriendsValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 11const makeFriendsValidator = [
12 // Force https if the administrator wants to make friends 12 body('hosts').custom(isEachUniqueHostValid).withMessage('Should have an array of unique hosts'),
13 if (isTestInstance() === false && CONFIG.WEBSERVER.SCHEME === 'http') { 13
14 return res.status(400) 14 (req: express.Request, res: express.Response, next: express.NextFunction) => {
15 .json({ 15 // Force https if the administrator wants to make friends
16 error: 'Cannot make friends with a non HTTPS web server.' 16 if (isTestInstance() === false && CONFIG.WEBSERVER.SCHEME === 'http') {
17 }) 17 return res.status(400)
18 .end() 18 .json({
19 error: 'Cannot make friends with a non HTTPS web server.'
20 })
21 .end()
22 }
23
24 logger.debug('Checking makeFriends parameters', { parameters: req.body })
25
26 checkErrors(req, res, () => {
27 hasFriends()
28 .then(heHasFriends => {
29 if (heHasFriends === true) {
30 // We need to quit our friends before make new ones
31 return res.sendStatus(409)
32 }
33
34 return next()
35 })
36 .catch(err => {
37 logger.error('Cannot know if we have friends.', err)
38 res.sendStatus(500)
39 })
40 })
19 } 41 }
42]
20 43
21 req.checkBody('hosts', 'Should have an array of unique hosts').isEachUniqueHostValid() 44const podsAddValidator = [
22 45 body('host').custom(isHostValid).withMessage('Should have a host'),
23 logger.debug('Checking makeFriends parameters', { parameters: req.body }) 46 body('email').isEmail().withMessage('Should have an email'),
24 47 body('publicKey').not().isEmpty().withMessage('Should have a public key'),
25 checkErrors(req, res, () => {
26 hasFriends()
27 .then(heHasFriends => {
28 if (heHasFriends === true) {
29 // We need to quit our friends before make new ones
30 return res.sendStatus(409)
31 }
32
33 return next()
34 })
35 .catch(err => {
36 logger.error('Cannot know if we have friends.', err)
37 res.sendStatus(500)
38 })
39 })
40}
41 48
42function podsAddValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 49 (req: express.Request, res: express.Response, next: express.NextFunction) => {
43 req.checkBody('host', 'Should have a host').isHostValid() 50 logger.debug('Checking podsAdd parameters', { parameters: req.body })
44 req.checkBody('email', 'Should have an email').isEmail()
45 req.checkBody('publicKey', 'Should have a public key').notEmpty()
46 logger.debug('Checking podsAdd parameters', { parameters: req.body })
47
48 checkErrors(req, res, () => {
49 db.Pod.loadByHost(req.body.host)
50 .then(pod => {
51 // Pod with this host already exists
52 if (pod) {
53 return res.sendStatus(409)
54 }
55
56 return next()
57 })
58 .catch(err => {
59 logger.error('Cannot load pod by host.', err)
60 res.sendStatus(500)
61 })
62 })
63}
64 51
65function podRemoveValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 52 checkErrors(req, res, () => {
66 req.checkParams('id', 'Should have a valid id').notEmpty().isNumeric() 53 db.Pod.loadByHost(req.body.host)
67 54 .then(pod => {
68 logger.debug('Checking podRemoveValidator parameters', { parameters: req.params }) 55 // Pod with this host already exists
69 56 if (pod) {
70 checkErrors(req, res, function () { 57 return res.sendStatus(409)
71 db.Pod.load(req.params.id) 58 }
72 .then(pod => { 59
73 if (!pod) { 60 return next()
74 logger.error('Cannot find pod %d.', req.params.id) 61 })
75 return res.sendStatus(404) 62 .catch(err => {
76 } 63 logger.error('Cannot load pod by host.', err)
77 64 res.sendStatus(500)
78 res.locals.pod = pod 65 })
79 return next() 66 })
80 }) 67 }
81 .catch(err => { 68]
82 logger.error('Cannot load pod %d.', req.params.id, err) 69
83 res.sendStatus(500) 70const podRemoveValidator = [
84 }) 71 param('id').isNumeric().not().isEmpty().withMessage('Should have a valid id'),
85 }) 72
86} 73 (req: express.Request, res: express.Response, next: express.NextFunction) => {
74 logger.debug('Checking podRemoveValidator parameters', { parameters: req.params })
75
76 checkErrors(req, res, () => {
77 db.Pod.load(req.params.id)
78 .then(pod => {
79 if (!pod) {
80 logger.error('Cannot find pod %d.', req.params.id)
81 return res.sendStatus(404)
82 }
83
84 res.locals.pod = pod
85 return next()
86 })
87 .catch(err => {
88 logger.error('Cannot load pod %d.', req.params.id, err)
89 res.sendStatus(500)
90 })
91 })
92 }
93]
87 94
88// --------------------------------------------------------------------------- 95// ---------------------------------------------------------------------------
89 96
diff --git a/server/middlewares/validators/remote/signature.ts b/server/middlewares/validators/remote/signature.ts
index eb5c196eb..d3937b515 100644
--- a/server/middlewares/validators/remote/signature.ts
+++ b/server/middlewares/validators/remote/signature.ts
@@ -1,17 +1,19 @@
1import 'express-validator' 1import { body } from 'express-validator/check'
2import * as express from 'express' 2import * as express from 'express'
3 3
4import { logger } from '../../../helpers' 4import { logger, isHostValid } from '../../../helpers'
5import { checkErrors } from '../utils' 5import { checkErrors } from '../utils'
6 6
7function signatureValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 7const signatureValidator = [
8 req.checkBody('signature.host', 'Should have a signature host').isURL() 8 body('signature.host').custom(isHostValid).withMessage('Should have a signature host'),
9 req.checkBody('signature.signature', 'Should have a signature').notEmpty() 9 body('signature.signature').not().isEmpty().withMessage('Should have a signature'),
10 10
11 logger.debug('Checking signature parameters', { parameters: { signature: req.body.signature } }) 11 (req: express.Request, res: express.Response, next: express.NextFunction) => {
12 logger.debug('Checking signature parameters', { parameters: { signature: req.body.signature } })
12 13
13 checkErrors(req, res, next) 14 checkErrors(req, res, next)
14} 15 }
16]
15 17
16// --------------------------------------------------------------------------- 18// ---------------------------------------------------------------------------
17 19
diff --git a/server/middlewares/validators/remote/videos.ts b/server/middlewares/validators/remote/videos.ts
index 2037c0085..e4682a60b 100644
--- a/server/middlewares/validators/remote/videos.ts
+++ b/server/middlewares/validators/remote/videos.ts
@@ -1,32 +1,43 @@
1import 'express-validator' 1import { body } from 'express-validator/check'
2import * as express from 'express' 2import * as express from 'express'
3 3
4import { logger } from '../../../helpers' 4import {
5 logger,
6 isEachRemoteRequestVideosValid,
7 isEachRemoteRequestVideosQaduValid,
8 isEachRemoteRequestVideosEventsValid
9} from '../../../helpers'
5import { checkErrors } from '../utils' 10import { checkErrors } from '../utils'
6 11
7function remoteVideosValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 12const remoteVideosValidator = [
8 req.checkBody('data').isEachRemoteRequestVideosValid() 13 body('data').custom(isEachRemoteRequestVideosValid),
9 14
10 logger.debug('Checking remoteVideos parameters', { parameters: req.body }) 15 (req: express.Request, res: express.Response, next: express.NextFunction) => {
16 logger.debug('Checking remoteVideos parameters', { parameters: req.body })
11 17
12 checkErrors(req, res, next) 18 checkErrors(req, res, next)
13} 19 }
20]
14 21
15function remoteQaduVideosValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 22const remoteQaduVideosValidator = [
16 req.checkBody('data').isEachRemoteRequestVideosQaduValid() 23 body('data').custom(isEachRemoteRequestVideosQaduValid),
17 24
18 logger.debug('Checking remoteQaduVideos parameters', { parameters: req.body }) 25 (req: express.Request, res: express.Response, next: express.NextFunction) => {
26 logger.debug('Checking remoteQaduVideos parameters', { parameters: req.body })
19 27
20 checkErrors(req, res, next) 28 checkErrors(req, res, next)
21} 29 }
30]
22 31
23function remoteEventsVideosValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 32const remoteEventsVideosValidator = [
24 req.checkBody('data').isEachRemoteRequestVideosEventsValid() 33 body('data').custom(isEachRemoteRequestVideosEventsValid),
25 34
26 logger.debug('Checking remoteEventsVideos parameters', { parameters: req.body }) 35 (req: express.Request, res: express.Response, next: express.NextFunction) => {
36 logger.debug('Checking remoteEventsVideos parameters', { parameters: req.body })
27 37
28 checkErrors(req, res, next) 38 checkErrors(req, res, next)
29} 39 }
40]
30 41
31// --------------------------------------------------------------------------- 42// ---------------------------------------------------------------------------
32 43
diff --git a/server/middlewares/validators/sort.ts b/server/middlewares/validators/sort.ts
index 3baee9fb3..71b18acb0 100644
--- a/server/middlewares/validators/sort.ts
+++ b/server/middlewares/validators/sort.ts
@@ -1,4 +1,4 @@
1import 'express-validator' 1import { query } from 'express-validator/check'
2import * as express from 'express' 2import * as express from 'express'
3 3
4import { checkErrors } from './utils' 4import { checkErrors } from './utils'
@@ -10,17 +10,9 @@ const SORTABLE_USERS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.USERS)
10const SORTABLE_VIDEO_ABUSES_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEO_ABUSES) 10const SORTABLE_VIDEO_ABUSES_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEO_ABUSES)
11const SORTABLE_VIDEOS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEOS) 11const SORTABLE_VIDEOS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEOS)
12 12
13function usersSortValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 13const usersSortValidator = checkSort(SORTABLE_USERS_COLUMNS)
14 checkSort(req, res, next, SORTABLE_USERS_COLUMNS) 14const videoAbusesSortValidator = checkSort(SORTABLE_VIDEO_ABUSES_COLUMNS)
15} 15const videosSortValidator = checkSort(SORTABLE_VIDEOS_COLUMNS)
16
17function videoAbusesSortValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
18 checkSort(req, res, next, SORTABLE_VIDEO_ABUSES_COLUMNS)
19}
20
21function videosSortValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
22 checkSort(req, res, next, SORTABLE_VIDEOS_COLUMNS)
23}
24 16
25// --------------------------------------------------------------------------- 17// ---------------------------------------------------------------------------
26 18
@@ -32,12 +24,16 @@ export {
32 24
33// --------------------------------------------------------------------------- 25// ---------------------------------------------------------------------------
34 26
35function checkSort (req: express.Request, res: express.Response, next: express.NextFunction, sortableColumns: string[]) { 27function checkSort (sortableColumns: string[]) {
36 req.checkQuery('sort', 'Should have correct sortable column').optional().isIn(sortableColumns) 28 return [
29 query('sort').optional().isIn(sortableColumns).withMessage('Should have correct sortable column'),
37 30
38 logger.debug('Checking sort parameters', { parameters: req.query }) 31 (req: express.Request, res: express.Response, next: express.NextFunction) => {
32 logger.debug('Checking sort parameters', { parameters: req.query })
39 33
40 checkErrors(req, res, next) 34 checkErrors(req, res, next)
35 }
36 ]
41} 37}
42 38
43function createSortableColumns (sortableColumns: string[]) { 39function createSortableColumns (sortableColumns: string[]) {
diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts
index 15c07c693..ab9d0938c 100644
--- a/server/middlewares/validators/users.ts
+++ b/server/middlewares/validators/users.ts
@@ -1,3 +1,4 @@
1import { body, param } from 'express-validator/check'
1import 'express-validator' 2import 'express-validator'
2import * as express from 'express' 3import * as express from 'express'
3import * as Promise from 'bluebird' 4import * as Promise from 'bluebird'
@@ -5,130 +6,154 @@ import * as validator from 'validator'
5 6
6import { database as db } from '../../initializers/database' 7import { database as db } from '../../initializers/database'
7import { checkErrors } from './utils' 8import { checkErrors } from './utils'
8import { isSignupAllowed, logger } from '../../helpers' 9import {
10 isSignupAllowed,
11 logger,
12 isUserUsernameValid,
13 isUserPasswordValid,
14 isUserVideoQuotaValid,
15 isUserDisplayNSFWValid,
16 isVideoIdOrUUIDValid
17} from '../../helpers'
9import { UserInstance, VideoInstance } from '../../models' 18import { UserInstance, VideoInstance } from '../../models'
10 19
11function usersAddValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 20const usersAddValidator = [
12 req.checkBody('username', 'Should have a valid username').isUserUsernameValid() 21 body('username').custom(isUserUsernameValid).withMessage('Should have a valid username'),
13 req.checkBody('password', 'Should have a valid password').isUserPasswordValid() 22 body('password').custom(isUserPasswordValid).withMessage('Should have a valid password'),
14 req.checkBody('email', 'Should have a valid email').isEmail() 23 body('email').isEmail().withMessage('Should have a valid email'),
15 req.checkBody('videoQuota', 'Should have a valid user quota').isUserVideoQuotaValid() 24 body('videoQuota').custom(isUserVideoQuotaValid).withMessage('Should have a valid user quota'),
16 25
17 logger.debug('Checking usersAdd parameters', { parameters: req.body }) 26 (req: express.Request, res: express.Response, next: express.NextFunction) => {
27 logger.debug('Checking usersAdd parameters', { parameters: req.body })
18 28
19 checkErrors(req, res, () => { 29 checkErrors(req, res, () => {
20 checkUserDoesNotAlreadyExist(req.body.username, req.body.email, res, next) 30 checkUserDoesNotAlreadyExist(req.body.username, req.body.email, res, next)
21 }) 31 })
22} 32 }
33]
23 34
24function usersRegisterValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 35const usersRegisterValidator = [
25 req.checkBody('username', 'Should have a valid username').isUserUsernameValid() 36 body('username').custom(isUserUsernameValid).withMessage('Should have a valid username'),
26 req.checkBody('password', 'Should have a valid password').isUserPasswordValid() 37 body('password').custom(isUserPasswordValid).withMessage('Should have a valid password'),
27 req.checkBody('email', 'Should have a valid email').isEmail() 38 body('email').isEmail().withMessage('Should have a valid email'),
28 39
29 logger.debug('Checking usersRegister parameters', { parameters: req.body }) 40 (req: express.Request, res: express.Response, next: express.NextFunction) => {
41 logger.debug('Checking usersRegister parameters', { parameters: req.body })
30 42
31 checkErrors(req, res, () => { 43 checkErrors(req, res, () => {
32 checkUserDoesNotAlreadyExist(req.body.username, req.body.email, res, next) 44 checkUserDoesNotAlreadyExist(req.body.username, req.body.email, res, next)
33 }) 45 })
34} 46 }
47]
35 48
36function usersRemoveValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 49const usersRemoveValidator = [
37 req.checkParams('id', 'Should have a valid id').notEmpty().isInt() 50 param('id').isInt().not().isEmpty().withMessage('Should have a valid id'),
38 51
39 logger.debug('Checking usersRemove parameters', { parameters: req.params }) 52 (req: express.Request, res: express.Response, next: express.NextFunction) => {
53 logger.debug('Checking usersRemove parameters', { parameters: req.params })
40 54
41 checkErrors(req, res, () => { 55 checkErrors(req, res, () => {
42 checkUserExists(req.params.id, res, (err, user) => { 56 checkUserExists(req.params.id, res, (err, user) => {
43 if (err) { 57 if (err) {
44 logger.error('Error in usersRemoveValidator.', err) 58 logger.error('Error in usersRemoveValidator.', err)
45 return res.sendStatus(500) 59 return res.sendStatus(500)
46 } 60 }
47 61
48 if (user.username === 'root') { 62 if (user.username === 'root') {
49 return res.status(400) 63 return res.status(400)
50 .send({ error: 'Cannot remove the root user' }) 64 .send({ error: 'Cannot remove the root user' })
51 .end() 65 .end()
52 } 66 }
53 67
54 return next() 68 return next()
69 })
55 }) 70 })
56 }) 71 }
57} 72]
58 73
59function usersUpdateValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 74const usersUpdateValidator = [
60 req.checkParams('id', 'Should have a valid id').notEmpty().isInt() 75 param('id').isInt().not().isEmpty().withMessage('Should have a valid id'),
61 req.checkBody('email', 'Should have a valid email attribute').optional().isEmail() 76 body('email').optional().isEmail().withMessage('Should have a valid email attribute'),
62 req.checkBody('videoQuota', 'Should have a valid user quota').optional().isUserVideoQuotaValid() 77 body('videoQuota').optional().custom(isUserVideoQuotaValid).withMessage('Should have a valid user quota'),
63 78
64 logger.debug('Checking usersUpdate parameters', { parameters: req.body }) 79 (req: express.Request, res: express.Response, next: express.NextFunction) => {
80 logger.debug('Checking usersUpdate parameters', { parameters: req.body })
65 81
66 checkErrors(req, res, () => { 82 checkErrors(req, res, () => {
67 checkUserExists(req.params.id, res, next) 83 checkUserExists(req.params.id, res, next)
68 }) 84 })
69} 85 }
86]
70 87
71function usersUpdateMeValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 88const usersUpdateMeValidator = [
72 // Add old password verification 89 body('password').optional().custom(isUserPasswordValid).withMessage('Should have a valid password'),
73 req.checkBody('password', 'Should have a valid password').optional().isUserPasswordValid() 90 body('email').optional().isEmail().withMessage('Should have a valid email attribute'),
74 req.checkBody('email', 'Should have a valid email attribute').optional().isEmail() 91 body('displayNSFW').optional().custom(isUserDisplayNSFWValid).withMessage('Should have a valid display Not Safe For Work attribute'),
75 req.checkBody('displayNSFW', 'Should have a valid display Not Safe For Work attribute').optional().isUserDisplayNSFWValid()
76 92
77 logger.debug('Checking usersUpdateMe parameters', { parameters: req.body }) 93 (req: express.Request, res: express.Response, next: express.NextFunction) => {
94 // TODO: Add old password verification
95 logger.debug('Checking usersUpdateMe parameters', { parameters: req.body })
78 96
79 checkErrors(req, res, next) 97 checkErrors(req, res, next)
80} 98 }
99]
81 100
82function usersGetValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 101const usersGetValidator = [
83 req.checkParams('id', 'Should have a valid id').notEmpty().isInt() 102 param('id').isInt().not().isEmpty().withMessage('Should have a valid id'),
84 103
85 checkErrors(req, res, () => { 104 (req: express.Request, res: express.Response, next: express.NextFunction) => {
86 checkUserExists(req.params.id, res, next) 105 checkErrors(req, res, () => {
87 }) 106 checkUserExists(req.params.id, res, next)
88} 107 })
89 108 }
90function usersVideoRatingValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 109]
91 req.checkParams('videoId', 'Should have a valid video id').notEmpty().isVideoIdOrUUIDValid()
92
93 logger.debug('Checking usersVideoRating parameters', { parameters: req.params })
94 110
95 checkErrors(req, res, () => { 111const usersVideoRatingValidator = [
96 let videoPromise: Promise<VideoInstance> 112 param('videoId').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'),
97 113
98 if (validator.isUUID(req.params.videoId)) { 114 (req: express.Request, res: express.Response, next: express.NextFunction) => {
99 videoPromise = db.Video.loadByUUID(req.params.videoId) 115 logger.debug('Checking usersVideoRating parameters', { parameters: req.params })
100 } else {
101 videoPromise = db.Video.load(req.params.videoId)
102 }
103 116
104 videoPromise 117 checkErrors(req, res, () => {
105 .then(video => { 118 let videoPromise: Promise<VideoInstance>
106 if (!video) {
107 return res.status(404)
108 .json({ error: 'Video not found' })
109 .end()
110 }
111 119
112 return next() 120 if (validator.isUUID(req.params.videoId)) {
113 }) 121 videoPromise = db.Video.loadByUUID(req.params.videoId)
114 .catch(err => { 122 } else {
115 logger.error('Error in user request validator.', err) 123 videoPromise = db.Video.load(req.params.videoId)
116 return res.sendStatus(500) 124 }
117 })
118 })
119}
120 125
121function ensureUserRegistrationAllowed (req: express.Request, res: express.Response, next: express.NextFunction) { 126 videoPromise
122 isSignupAllowed().then(allowed => { 127 .then(video => {
123 if (allowed === false) { 128 if (!video) {
124 return res.status(403) 129 return res.status(404)
125 .send({ error: 'User registration is not enabled or user limit is reached.' }) 130 .json({ error: 'Video not found' })
126 .end() 131 .end()
127 } 132 }
133
134 return next()
135 })
136 .catch(err => {
137 logger.error('Error in user request validator.', err)
138 return res.sendStatus(500)
139 })
140 })
141 }
142]
143
144const ensureUserRegistrationAllowed = [
145 (req: express.Request, res: express.Response, next: express.NextFunction) => {
146 isSignupAllowed().then(allowed => {
147 if (allowed === false) {
148 return res.status(403)
149 .send({ error: 'User registration is not enabled or user limit is reached.' })
150 .end()
151 }
128 152
129 return next() 153 return next()
130 }) 154 })
131} 155 }
156]
132 157
133// --------------------------------------------------------------------------- 158// ---------------------------------------------------------------------------
134 159
diff --git a/server/middlewares/validators/utils.ts b/server/middlewares/validators/utils.ts
index 0424d5942..8845f8399 100644
--- a/server/middlewares/validators/utils.ts
+++ b/server/middlewares/validators/utils.ts
@@ -1,15 +1,14 @@
1import 'express-validator' 1import { validationResult } from 'express-validator/check'
2import * as express from 'express' 2import * as express from 'express'
3import { inspect } from 'util'
4 3
5import { logger } from '../../helpers' 4import { logger } from '../../helpers'
6 5
7function checkErrors (req: express.Request, res: express.Response, next: express.NextFunction, statusCode = 400) { 6function checkErrors (req: express.Request, res: express.Response, next: express.NextFunction, statusCode = 400) {
8 const errors = req.validationErrors() 7 const errors = validationResult(req)
9 8
10 if (errors) { 9 if (!errors.isEmpty()) {
11 logger.warn('Incorrect request parameters', { path: req.originalUrl, err: errors }) 10 logger.warn('Incorrect request parameters', { path: req.originalUrl, err: errors.mapped() })
12 return res.status(statusCode).send('There have been validation errors: ' + inspect(errors)) 11 return res.status(statusCode).json({ errors: errors.mapped() })
13 } 12 }
14 13
15 return next() 14 return next()
diff --git a/server/middlewares/validators/videos.ts b/server/middlewares/validators/videos.ts
index 213b4c46b..bc8b7e541 100644
--- a/server/middlewares/validators/videos.ts
+++ b/server/middlewares/validators/videos.ts
@@ -1,4 +1,4 @@
1import 'express-validator' 1import { body, param, query } from 'express-validator/check'
2import * as express from 'express' 2import * as express from 'express'
3import * as Promise from 'bluebird' 3import * as Promise from 'bluebird'
4import * as validator from 'validator' 4import * as validator from 'validator'
@@ -6,172 +6,198 @@ import * as validator from 'validator'
6import { database as db } from '../../initializers/database' 6import { database as db } from '../../initializers/database'
7import { checkErrors } from './utils' 7import { checkErrors } from './utils'
8import { CONSTRAINTS_FIELDS, SEARCHABLE_COLUMNS } from '../../initializers' 8import { CONSTRAINTS_FIELDS, SEARCHABLE_COLUMNS } from '../../initializers'
9import { logger, isVideoDurationValid } from '../../helpers' 9import {
10 logger,
11 isVideoDurationValid,
12 isVideoFile,
13 isVideoNameValid,
14 isVideoCategoryValid,
15 isVideoLicenceValid,
16 isVideoDescriptionValid,
17 isVideoLanguageValid,
18 isVideoTagsValid,
19 isVideoNSFWValid,
20 isVideoIdOrUUIDValid,
21 isVideoAbuseReasonValid,
22 isVideoRatingTypeValid
23} from '../../helpers'
10import { VideoInstance } from '../../models' 24import { VideoInstance } from '../../models'
11 25
12function videosAddValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 26const videosAddValidator = [
13 // FIXME: Don't write an error message, it seems there is a bug with express-validator 27 body('videofile').custom((value, { req }) => isVideoFile(req.files)).withMessage('Should have a valid file'),
14 // 'Should have a valid file' 28 body('name').custom(isVideoNameValid).withMessage('Should have a valid name'),
15 req.checkBody('videofile').isVideoFile(req.files) 29 body('category').custom(isVideoCategoryValid).withMessage('Should have a valid category'),
16 req.checkBody('name', 'Should have a valid name').isVideoNameValid() 30 body('licence').custom(isVideoLicenceValid).withMessage('Should have a valid licence'),
17 req.checkBody('category', 'Should have a valid category').isVideoCategoryValid() 31 body('language').optional().custom(isVideoLanguageValid).withMessage('Should have a valid language'),
18 req.checkBody('licence', 'Should have a valid licence').isVideoLicenceValid() 32 body('nsfw').custom(isVideoNSFWValid).withMessage('Should have a valid NSFW attribute'),
19 req.checkBody('language', 'Should have a valid language').optional().isVideoLanguageValid() 33 body('description').custom(isVideoDescriptionValid).withMessage('Should have a valid description'),
20 req.checkBody('nsfw', 'Should have a valid NSFW attribute').isVideoNSFWValid() 34 body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'),
21 req.checkBody('description', 'Should have a valid description').isVideoDescriptionValid() 35
22 req.checkBody('tags', 'Should have correct tags').optional().isVideoTagsValid() 36 (req: express.Request, res: express.Response, next: express.NextFunction) => {
23 37 logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files })
24 logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files }) 38
25 39 checkErrors(req, res, () => {
26 checkErrors(req, res, () => { 40 const videoFile: Express.Multer.File = req.files['videofile'][0]
27 const videoFile: Express.Multer.File = req.files['videofile'][0] 41 const user = res.locals.oauth.token.User
28 const user = res.locals.oauth.token.User 42
29 43 user.isAbleToUploadVideo(videoFile)
30 user.isAbleToUploadVideo(videoFile) 44 .then(isAble => {
31 .then(isAble => { 45 if (isAble === false) {
32 if (isAble === false) { 46 res.status(403)
33 res.status(403) 47 .json({ error: 'The user video quota is exceeded with this video.' })
34 .json({ error: 'The user video quota is exceeded with this video.' }) 48 .end()
35 .end() 49
50 return undefined
51 }
52
53 return db.Video.getDurationFromFile(videoFile.path)
54 .catch(err => {
55 logger.error('Invalid input file in videosAddValidator.', err)
56 res.status(400)
57 .json({ error: 'Invalid input file.' })
58 .end()
59
60 return undefined
61 })
62 })
63 .then(duration => {
64 // Previous test failed, abort
65 if (duration === undefined) return
66
67 if (!isVideoDurationValid('' + duration)) {
68 return res.status(400)
69 .json({
70 error: 'Duration of the video file is too big (max: ' + CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).'
71 })
72 .end()
73 }
74
75 videoFile['duration'] = duration
76 next()
77 })
78 .catch(err => {
79 logger.error('Error in video add validator', err)
80 res.sendStatus(500)
36 81
37 return undefined 82 return undefined
83 })
84 })
85 }
86]
87
88const videosUpdateValidator = [
89 param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
90 body('name').optional().custom(isVideoNameValid).withMessage('Should have a valid name'),
91 body('category').optional().custom(isVideoCategoryValid).withMessage('Should have a valid category'),
92 body('licence').optional().custom(isVideoLicenceValid).withMessage('Should have a valid licence'),
93 body('language').optional().custom(isVideoLanguageValid).withMessage('Should have a valid language'),
94 body('nsfw').optional().custom(isVideoNSFWValid).withMessage('Should have a valid NSFW attribute'),
95 body('description').optional().custom(isVideoDescriptionValid).withMessage('Should have a valid description'),
96 body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'),
97
98 (req: express.Request, res: express.Response, next: express.NextFunction) => {
99 logger.debug('Checking videosUpdate parameters', { parameters: req.body })
100
101 checkErrors(req, res, () => {
102 checkVideoExists(req.params.id, res, () => {
103 // We need to make additional checks
104 if (res.locals.video.isOwned() === false) {
105 return res.status(403)
106 .json({ error: 'Cannot update video of another pod' })
107 .end()
38 } 108 }
39 109
40 return db.Video.getDurationFromFile(videoFile.path) 110 if (res.locals.video.Author.userId !== res.locals.oauth.token.User.id) {
41 .catch(err => { 111 return res.status(403)
42 logger.error('Invalid input file in videosAddValidator.', err) 112 .json({ error: 'Cannot update video of another user' })
43 res.status(400)
44 .json({ error: 'Invalid input file.' })
45 .end()
46
47 return undefined
48 })
49 })
50 .then(duration => {
51 // Previous test failed, abort
52 if (duration === undefined) return
53
54 if (!isVideoDurationValid('' + duration)) {
55 return res.status(400)
56 .json({
57 error: 'Duration of the video file is too big (max: ' + CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).'
58 })
59 .end() 113 .end()
60 } 114 }
61 115
62 videoFile['duration'] = duration
63 next() 116 next()
64 }) 117 })
65 .catch(err => {
66 logger.error('Error in video add validator', err)
67 res.sendStatus(500)
68
69 return undefined
70 })
71
72 })
73}
74
75function videosUpdateValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
76 req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid()
77 req.checkBody('name', 'Should have a valid name').optional().isVideoNameValid()
78 req.checkBody('category', 'Should have a valid category').optional().isVideoCategoryValid()
79 req.checkBody('licence', 'Should have a valid licence').optional().isVideoLicenceValid()
80 req.checkBody('language', 'Should have a valid language').optional().isVideoLanguageValid()
81 req.checkBody('nsfw', 'Should have a valid NSFW attribute').optional().isVideoNSFWValid()
82 req.checkBody('description', 'Should have a valid description').optional().isVideoDescriptionValid()
83 req.checkBody('tags', 'Should have correct tags').optional().isVideoTagsValid()
84
85 logger.debug('Checking videosUpdate parameters', { parameters: req.body })
86
87 checkErrors(req, res, () => {
88 checkVideoExists(req.params.id, res, () => {
89 // We need to make additional checks
90 if (res.locals.video.isOwned() === false) {
91 return res.status(403)
92 .json({ error: 'Cannot update video of another pod' })
93 .end()
94 }
95
96 if (res.locals.video.Author.userId !== res.locals.oauth.token.User.id) {
97 return res.status(403)
98 .json({ error: 'Cannot update video of another user' })
99 .end()
100 }
101
102 next()
103 }) 118 })
104 }) 119 }
105} 120]
106 121
107function videosGetValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 122const videosGetValidator = [
108 req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() 123 param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
109 124
110 logger.debug('Checking videosGet parameters', { parameters: req.params }) 125 (req: express.Request, res: express.Response, next: express.NextFunction) => {
126 logger.debug('Checking videosGet parameters', { parameters: req.params })
111 127
112 checkErrors(req, res, () => { 128 checkErrors(req, res, () => {
113 checkVideoExists(req.params.id, res, next) 129 checkVideoExists(req.params.id, res, next)
114 }) 130 })
115} 131 }
132]
116 133
117function videosRemoveValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 134const videosRemoveValidator = [
118 req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() 135 param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
119 136
120 logger.debug('Checking videosRemove parameters', { parameters: req.params }) 137 (req: express.Request, res: express.Response, next: express.NextFunction) => {
138 logger.debug('Checking videosRemove parameters', { parameters: req.params })
121 139
122 checkErrors(req, res, () => { 140 checkErrors(req, res, () => {
123 checkVideoExists(req.params.id, res, () => { 141 checkVideoExists(req.params.id, res, () => {
124 // Check if the user who did the request is able to delete the video 142 // Check if the user who did the request is able to delete the video
125 checkUserCanDeleteVideo(res.locals.oauth.token.User.id, res, () => { 143 checkUserCanDeleteVideo(res.locals.oauth.token.User.id, res, () => {
126 next() 144 next()
145 })
127 }) 146 })
128 }) 147 })
129 }) 148 }
130} 149]
131 150
132function videosSearchValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 151const videosSearchValidator = [
133 const searchableColumns = SEARCHABLE_COLUMNS.VIDEOS 152 param('value').not().isEmpty().withMessage('Should have a valid search'),
134 req.checkParams('value', 'Should have a valid search').notEmpty() 153 query('field').optional().isIn(SEARCHABLE_COLUMNS.VIDEOS).withMessage('Should have correct searchable column'),
135 req.checkQuery('field', 'Should have correct searchable column').optional().isIn(searchableColumns)
136 154
137 logger.debug('Checking videosSearch parameters', { parameters: req.params }) 155 (req: express.Request, res: express.Response, next: express.NextFunction) => {
156 logger.debug('Checking videosSearch parameters', { parameters: req.params })
138 157
139 checkErrors(req, res, next) 158 checkErrors(req, res, next)
140} 159 }
160]
141 161
142function videoAbuseReportValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 162const videoAbuseReportValidator = [
143 req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() 163 param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
144 req.checkBody('reason', 'Should have a valid reason').isVideoAbuseReasonValid() 164 body('reason').custom(isVideoAbuseReasonValid).withMessage('Should have a valid reason'),
145 165
146 logger.debug('Checking videoAbuseReport parameters', { parameters: req.body }) 166 (req: express.Request, res: express.Response, next: express.NextFunction) => {
167 logger.debug('Checking videoAbuseReport parameters', { parameters: req.body })
147 168
148 checkErrors(req, res, () => { 169 checkErrors(req, res, () => {
149 checkVideoExists(req.params.id, res, next) 170 checkVideoExists(req.params.id, res, next)
150 }) 171 })
151} 172 }
173]
152 174
153function videoRateValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 175const videoRateValidator = [
154 req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() 176 param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
155 req.checkBody('rating', 'Should have a valid rate type').isVideoRatingTypeValid() 177 body('rating').custom(isVideoRatingTypeValid).withMessage('Should have a valid rate type'),
156 178
157 logger.debug('Checking videoRate parameters', { parameters: req.body }) 179 (req: express.Request, res: express.Response, next: express.NextFunction) => {
180 logger.debug('Checking videoRate parameters', { parameters: req.body })
158 181
159 checkErrors(req, res, () => { 182 checkErrors(req, res, () => {
160 checkVideoExists(req.params.id, res, next) 183 checkVideoExists(req.params.id, res, next)
161 }) 184 })
162} 185 }
186]
163 187
164function videosBlacklistValidator (req: express.Request, res: express.Response, next: express.NextFunction) { 188const videosBlacklistValidator = [
165 req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() 189 param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
166 190
167 logger.debug('Checking videosBlacklist parameters', { parameters: req.params }) 191 (req: express.Request, res: express.Response, next: express.NextFunction) => {
192 logger.debug('Checking videosBlacklist parameters', { parameters: req.params })
168 193
169 checkErrors(req, res, () => { 194 checkErrors(req, res, () => {
170 checkVideoExists(req.params.id, res, () => { 195 checkVideoExists(req.params.id, res, () => {
171 checkVideoIsBlacklistable(req, res, next) 196 checkVideoIsBlacklistable(req, res, next)
197 })
172 }) 198 })
173 }) 199 }
174} 200]
175 201
176// --------------------------------------------------------------------------- 202// ---------------------------------------------------------------------------
177 203