From 65fcc3119c334b75dd13bcfdebf186afdc580a8f Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 15 May 2017 22:22:03 +0200 Subject: First typescript iteration --- server/middlewares/validators/index.js | 21 --- server/middlewares/validators/index.ts | 6 + server/middlewares/validators/pagination.js | 21 --- server/middlewares/validators/pagination.ts | 17 ++ server/middlewares/validators/pods.js | 67 ------- server/middlewares/validators/pods.ts | 63 +++++++ server/middlewares/validators/remote/index.js | 13 -- server/middlewares/validators/remote/index.ts | 2 + server/middlewares/validators/remote/signature.js | 21 --- server/middlewares/validators/remote/signature.ts | 17 ++ server/middlewares/validators/remote/videos.js | 37 ---- server/middlewares/validators/remote/videos.ts | 34 ++++ server/middlewares/validators/sort.js | 48 ----- server/middlewares/validators/sort.ts | 44 +++++ server/middlewares/validators/users.js | 88 ---------- server/middlewares/validators/users.ts | 84 +++++++++ server/middlewares/validators/utils.js | 25 --- server/middlewares/validators/utils.ts | 21 +++ server/middlewares/validators/videos.js | 204 ---------------------- server/middlewares/validators/videos.ts | 199 +++++++++++++++++++++ 20 files changed, 487 insertions(+), 545 deletions(-) delete mode 100644 server/middlewares/validators/index.js create mode 100644 server/middlewares/validators/index.ts delete mode 100644 server/middlewares/validators/pagination.js create mode 100644 server/middlewares/validators/pagination.ts delete mode 100644 server/middlewares/validators/pods.js create mode 100644 server/middlewares/validators/pods.ts delete mode 100644 server/middlewares/validators/remote/index.js create mode 100644 server/middlewares/validators/remote/index.ts delete mode 100644 server/middlewares/validators/remote/signature.js create mode 100644 server/middlewares/validators/remote/signature.ts delete mode 100644 server/middlewares/validators/remote/videos.js create mode 100644 server/middlewares/validators/remote/videos.ts delete mode 100644 server/middlewares/validators/sort.js create mode 100644 server/middlewares/validators/sort.ts delete mode 100644 server/middlewares/validators/users.js create mode 100644 server/middlewares/validators/users.ts delete mode 100644 server/middlewares/validators/utils.js create mode 100644 server/middlewares/validators/utils.ts delete mode 100644 server/middlewares/validators/videos.js create mode 100644 server/middlewares/validators/videos.ts (limited to 'server/middlewares/validators') diff --git a/server/middlewares/validators/index.js b/server/middlewares/validators/index.js deleted file mode 100644 index 6c3a9c2b4..000000000 --- a/server/middlewares/validators/index.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict' - -const paginationValidators = require('./pagination') -const podsValidators = require('./pods') -const remoteValidators = require('./remote') -const sortValidators = require('./sort') -const usersValidators = require('./users') -const videosValidators = require('./videos') - -const validators = { - pagination: paginationValidators, - pods: podsValidators, - remote: remoteValidators, - sort: sortValidators, - users: usersValidators, - videos: videosValidators -} - -// --------------------------------------------------------------------------- - -module.exports = validators diff --git a/server/middlewares/validators/index.ts b/server/middlewares/validators/index.ts new file mode 100644 index 000000000..42ba465ec --- /dev/null +++ b/server/middlewares/validators/index.ts @@ -0,0 +1,6 @@ +export * from './remote' +export * from './pagination' +export * from './pods' +export * from './sort' +export * from './users' +export * from './videos' diff --git a/server/middlewares/validators/pagination.js b/server/middlewares/validators/pagination.js deleted file mode 100644 index 16682696e..000000000 --- a/server/middlewares/validators/pagination.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict' - -const checkErrors = require('./utils').checkErrors -const logger = require('../../helpers/logger') - -const validatorsPagination = { - pagination -} - -function pagination (req, res, next) { - req.checkQuery('start', 'Should have a number start').optional().isInt() - req.checkQuery('count', 'Should have a number count').optional().isInt() - - logger.debug('Checking pagination parameters', { parameters: req.query }) - - checkErrors(req, res, next) -} - -// --------------------------------------------------------------------------- - -module.exports = validatorsPagination diff --git a/server/middlewares/validators/pagination.ts b/server/middlewares/validators/pagination.ts new file mode 100644 index 000000000..de719c05b --- /dev/null +++ b/server/middlewares/validators/pagination.ts @@ -0,0 +1,17 @@ +import { checkErrors } from './utils' +import { logger } from '../../helpers' + +function paginationValidator (req, res, next) { + req.checkQuery('start', 'Should have a number start').optional().isInt() + req.checkQuery('count', 'Should have a number count').optional().isInt() + + logger.debug('Checking pagination parameters', { parameters: req.query }) + + checkErrors(req, res, next) +} + +// --------------------------------------------------------------------------- + +export { + paginationValidator +} diff --git a/server/middlewares/validators/pods.js b/server/middlewares/validators/pods.js deleted file mode 100644 index 0bf4b1844..000000000 --- a/server/middlewares/validators/pods.js +++ /dev/null @@ -1,67 +0,0 @@ -'use strict' - -const checkErrors = require('./utils').checkErrors -const constants = require('../../initializers/constants') -const db = require('../../initializers/database') -const friends = require('../../lib/friends') -const logger = require('../../helpers/logger') -const utils = require('../../helpers/utils') - -const validatorsPod = { - makeFriends, - podsAdd -} - -function makeFriends (req, res, next) { - // Force https if the administrator wants to make friends - if (utils.isTestInstance() === false && constants.CONFIG.WEBSERVER.SCHEME === 'http') { - return res.status(400).send('Cannot make friends with a non HTTPS webserver.') - } - - req.checkBody('hosts', 'Should have an array of unique hosts').isEachUniqueHostValid() - - logger.debug('Checking makeFriends parameters', { parameters: req.body }) - - checkErrors(req, res, function () { - friends.hasFriends(function (err, hasFriends) { - if (err) { - logger.error('Cannot know if we have friends.', { error: err }) - res.sendStatus(500) - } - - if (hasFriends === true) { - // We need to quit our friends before make new ones - return res.sendStatus(409) - } - - return next() - }) - }) -} - -function podsAdd (req, res, next) { - req.checkBody('host', 'Should have a host').isHostValid() - req.checkBody('email', 'Should have an email').isEmail() - req.checkBody('publicKey', 'Should have a public key').notEmpty() - logger.debug('Checking podsAdd parameters', { parameters: req.body }) - - checkErrors(req, res, function () { - db.Pod.loadByHost(req.body.host, function (err, pod) { - if (err) { - logger.error('Cannot load pod by host.', { error: err }) - res.sendStatus(500) - } - - // Pod with this host already exists - if (pod) { - return res.sendStatus(409) - } - - return next() - }) - }) -} - -// --------------------------------------------------------------------------- - -module.exports = validatorsPod diff --git a/server/middlewares/validators/pods.ts b/server/middlewares/validators/pods.ts new file mode 100644 index 000000000..fbfd268d0 --- /dev/null +++ b/server/middlewares/validators/pods.ts @@ -0,0 +1,63 @@ +const db = require('../../initializers/database') +import { checkErrors } from './utils' +import { logger } from '../../helpers' +import { CONFIG } from '../../initializers' +import { hasFriends } from '../../lib' +import { isTestInstance } from '../../helpers' + +function makeFriendsValidator (req, res, next) { + // Force https if the administrator wants to make friends + if (isTestInstance() === false && CONFIG.WEBSERVER.SCHEME === 'http') { + return res.status(400).send('Cannot make friends with a non HTTPS webserver.') + } + + req.checkBody('hosts', 'Should have an array of unique hosts').isEachUniqueHostValid() + + logger.debug('Checking makeFriends parameters', { parameters: req.body }) + + checkErrors(req, res, function () { + hasFriends(function (err, heHasFriends) { + if (err) { + logger.error('Cannot know if we have friends.', { error: err }) + res.sendStatus(500) + } + + if (heHasFriends === true) { + // We need to quit our friends before make new ones + return res.sendStatus(409) + } + + return next() + }) + }) +} + +function podsAddValidator (req, res, next) { + req.checkBody('host', 'Should have a host').isHostValid() + req.checkBody('email', 'Should have an email').isEmail() + req.checkBody('publicKey', 'Should have a public key').notEmpty() + logger.debug('Checking podsAdd parameters', { parameters: req.body }) + + checkErrors(req, res, function () { + db.Pod.loadByHost(req.body.host, function (err, pod) { + if (err) { + logger.error('Cannot load pod by host.', { error: err }) + res.sendStatus(500) + } + + // Pod with this host already exists + if (pod) { + return res.sendStatus(409) + } + + return next() + }) + }) +} + +// --------------------------------------------------------------------------- + +export { + makeFriendsValidator, + podsAddValidator +} diff --git a/server/middlewares/validators/remote/index.js b/server/middlewares/validators/remote/index.js deleted file mode 100644 index 022a2fe50..000000000 --- a/server/middlewares/validators/remote/index.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict' - -const remoteSignatureValidators = require('./signature') -const remoteVideosValidators = require('./videos') - -const validators = { - signature: remoteSignatureValidators, - videos: remoteVideosValidators -} - -// --------------------------------------------------------------------------- - -module.exports = validators diff --git a/server/middlewares/validators/remote/index.ts b/server/middlewares/validators/remote/index.ts new file mode 100644 index 000000000..d0d7740b1 --- /dev/null +++ b/server/middlewares/validators/remote/index.ts @@ -0,0 +1,2 @@ +export * from './signature' +export * from './videos' diff --git a/server/middlewares/validators/remote/signature.js b/server/middlewares/validators/remote/signature.js deleted file mode 100644 index 002232c05..000000000 --- a/server/middlewares/validators/remote/signature.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict' - -const checkErrors = require('../utils').checkErrors -const logger = require('../../../helpers/logger') - -const validatorsRemoteSignature = { - signature -} - -function signature (req, res, next) { - req.checkBody('signature.host', 'Should have a signature host').isURL() - req.checkBody('signature.signature', 'Should have a signature').notEmpty() - - logger.debug('Checking signature parameters', { parameters: { signature: req.body.signature } }) - - checkErrors(req, res, next) -} - -// --------------------------------------------------------------------------- - -module.exports = validatorsRemoteSignature diff --git a/server/middlewares/validators/remote/signature.ts b/server/middlewares/validators/remote/signature.ts new file mode 100644 index 000000000..6e3ebe7db --- /dev/null +++ b/server/middlewares/validators/remote/signature.ts @@ -0,0 +1,17 @@ +import { logger } from '../../../helpers' +import { checkErrors } from '../utils' + +function signatureValidator (req, res, next) { + req.checkBody('signature.host', 'Should have a signature host').isURL() + req.checkBody('signature.signature', 'Should have a signature').notEmpty() + + logger.debug('Checking signature parameters', { parameters: { signature: req.body.signature } }) + + checkErrors(req, res, next) +} + +// --------------------------------------------------------------------------- + +export { + signatureValidator +} diff --git a/server/middlewares/validators/remote/videos.js b/server/middlewares/validators/remote/videos.js deleted file mode 100644 index f2c6cba5e..000000000 --- a/server/middlewares/validators/remote/videos.js +++ /dev/null @@ -1,37 +0,0 @@ -'use strict' - -const checkErrors = require('../utils').checkErrors -const logger = require('../../../helpers/logger') - -const validatorsRemoteVideos = { - remoteVideos, - remoteQaduVideos, - remoteEventsVideos -} - -function remoteVideos (req, res, next) { - req.checkBody('data').isEachRemoteRequestVideosValid() - - logger.debug('Checking remoteVideos parameters', { parameters: req.body }) - - checkErrors(req, res, next) -} - -function remoteQaduVideos (req, res, next) { - req.checkBody('data').isEachRemoteRequestVideosQaduValid() - - logger.debug('Checking remoteQaduVideos parameters', { parameters: req.body }) - - checkErrors(req, res, next) -} - -function remoteEventsVideos (req, res, next) { - req.checkBody('data').isEachRemoteRequestVideosEventsValid() - - logger.debug('Checking remoteEventsVideos parameters', { parameters: req.body }) - - checkErrors(req, res, next) -} -// --------------------------------------------------------------------------- - -module.exports = validatorsRemoteVideos diff --git a/server/middlewares/validators/remote/videos.ts b/server/middlewares/validators/remote/videos.ts new file mode 100644 index 000000000..3380c29e2 --- /dev/null +++ b/server/middlewares/validators/remote/videos.ts @@ -0,0 +1,34 @@ +import { logger } from '../../../helpers' +import { checkErrors } from '../utils' + +function remoteVideosValidator (req, res, next) { + req.checkBody('data').isEachRemoteRequestVideosValid() + + logger.debug('Checking remoteVideos parameters', { parameters: req.body }) + + checkErrors(req, res, next) +} + +function remoteQaduVideosValidator (req, res, next) { + req.checkBody('data').isEachRemoteRequestVideosQaduValid() + + logger.debug('Checking remoteQaduVideos parameters', { parameters: req.body }) + + checkErrors(req, res, next) +} + +function remoteEventsVideosValidator (req, res, next) { + req.checkBody('data').isEachRemoteRequestVideosEventsValid() + + logger.debug('Checking remoteEventsVideos parameters', { parameters: req.body }) + + checkErrors(req, res, next) +} + +// --------------------------------------------------------------------------- + +export { + remoteVideosValidator, + remoteQaduVideosValidator, + remoteEventsVideosValidator +} diff --git a/server/middlewares/validators/sort.js b/server/middlewares/validators/sort.js deleted file mode 100644 index 017d266e6..000000000 --- a/server/middlewares/validators/sort.js +++ /dev/null @@ -1,48 +0,0 @@ -'use strict' - -const checkErrors = require('./utils').checkErrors -const constants = require('../../initializers/constants') -const logger = require('../../helpers/logger') - -const validatorsSort = { - usersSort, - videoAbusesSort, - videosSort -} - -// Initialize constants here for better performances -const SORTABLE_USERS_COLUMNS = createSortableColumns(constants.SORTABLE_COLUMNS.USERS) -const SORTABLE_VIDEO_ABUSES_COLUMNS = createSortableColumns(constants.SORTABLE_COLUMNS.VIDEO_ABUSES) -const SORTABLE_VIDEOS_COLUMNS = createSortableColumns(constants.SORTABLE_COLUMNS.VIDEOS) - -function usersSort (req, res, next) { - checkSort(req, res, next, SORTABLE_USERS_COLUMNS) -} - -function videoAbusesSort (req, res, next) { - checkSort(req, res, next, SORTABLE_VIDEO_ABUSES_COLUMNS) -} - -function videosSort (req, res, next) { - checkSort(req, res, next, SORTABLE_VIDEOS_COLUMNS) -} - -// --------------------------------------------------------------------------- - -module.exports = validatorsSort - -// --------------------------------------------------------------------------- - -function checkSort (req, res, next, sortableColumns) { - req.checkQuery('sort', 'Should have correct sortable column').optional().isIn(sortableColumns) - - logger.debug('Checking sort parameters', { parameters: req.query }) - - checkErrors(req, res, next) -} - -function createSortableColumns (sortableColumns) { - const sortableColumnDesc = sortableColumns.map(sortableColumn => '-' + sortableColumn) - - return sortableColumns.concat(sortableColumnDesc) -} diff --git a/server/middlewares/validators/sort.ts b/server/middlewares/validators/sort.ts new file mode 100644 index 000000000..ebc7333c7 --- /dev/null +++ b/server/middlewares/validators/sort.ts @@ -0,0 +1,44 @@ +import { checkErrors } from './utils' +import { logger } from '../../helpers' +import { SORTABLE_COLUMNS } from '../../initializers' + +// Initialize constants here for better performances +const SORTABLE_USERS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.USERS) +const SORTABLE_VIDEO_ABUSES_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEO_ABUSES) +const SORTABLE_VIDEOS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEOS) + +function usersSortValidator (req, res, next) { + checkSort(req, res, next, SORTABLE_USERS_COLUMNS) +} + +function videoAbusesSortValidator (req, res, next) { + checkSort(req, res, next, SORTABLE_VIDEO_ABUSES_COLUMNS) +} + +function videosSortValidator (req, res, next) { + checkSort(req, res, next, SORTABLE_VIDEOS_COLUMNS) +} + +// --------------------------------------------------------------------------- + +export { + usersSortValidator, + videoAbusesSortValidator, + videosSortValidator +} + +// --------------------------------------------------------------------------- + +function checkSort (req, res, next, sortableColumns) { + req.checkQuery('sort', 'Should have correct sortable column').optional().isIn(sortableColumns) + + logger.debug('Checking sort parameters', { parameters: req.query }) + + checkErrors(req, res, next) +} + +function createSortableColumns (sortableColumns) { + const sortableColumnDesc = sortableColumns.map(sortableColumn => '-' + sortableColumn) + + return sortableColumns.concat(sortableColumnDesc) +} diff --git a/server/middlewares/validators/users.js b/server/middlewares/validators/users.js deleted file mode 100644 index 1e7a64793..000000000 --- a/server/middlewares/validators/users.js +++ /dev/null @@ -1,88 +0,0 @@ -'use strict' - -const checkErrors = require('./utils').checkErrors -const db = require('../../initializers/database') -const logger = require('../../helpers/logger') - -const validatorsUsers = { - usersAdd, - usersRemove, - usersUpdate, - usersVideoRating -} - -function usersAdd (req, res, next) { - req.checkBody('username', 'Should have a valid username').isUserUsernameValid() - req.checkBody('password', 'Should have a valid password').isUserPasswordValid() - req.checkBody('email', 'Should have a valid email').isEmail() - - logger.debug('Checking usersAdd parameters', { parameters: req.body }) - - checkErrors(req, res, function () { - db.User.loadByUsernameOrEmail(req.body.username, req.body.email, function (err, user) { - if (err) { - logger.error('Error in usersAdd request validator.', { error: err }) - return res.sendStatus(500) - } - - if (user) return res.status(409).send('User already exists.') - - next() - }) - }) -} - -function usersRemove (req, res, next) { - req.checkParams('id', 'Should have a valid id').notEmpty().isInt() - - logger.debug('Checking usersRemove parameters', { parameters: req.params }) - - checkErrors(req, res, function () { - db.User.loadById(req.params.id, function (err, user) { - if (err) { - logger.error('Error in usersRemove request validator.', { error: err }) - return res.sendStatus(500) - } - - if (!user) return res.status(404).send('User not found') - - if (user.username === 'root') return res.status(400).send('Cannot remove the root user') - - next() - }) - }) -} - -function usersUpdate (req, res, next) { - req.checkParams('id', 'Should have a valid id').notEmpty().isInt() - // Add old password verification - req.checkBody('password', 'Should have a valid password').optional().isUserPasswordValid() - req.checkBody('displayNSFW', 'Should have a valid display Not Safe For Work attribute').optional().isUserDisplayNSFWValid() - - logger.debug('Checking usersUpdate parameters', { parameters: req.body }) - - checkErrors(req, res, next) -} - -function usersVideoRating (req, res, next) { - req.checkParams('videoId', 'Should have a valid video id').notEmpty().isUUID(4) - - logger.debug('Checking usersVideoRating parameters', { parameters: req.params }) - - checkErrors(req, res, function () { - db.Video.load(req.params.videoId, function (err, video) { - if (err) { - logger.error('Error in user request validator.', { error: err }) - return res.sendStatus(500) - } - - if (!video) return res.status(404).send('Video not found') - - next() - }) - }) -} - -// --------------------------------------------------------------------------- - -module.exports = validatorsUsers diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts new file mode 100644 index 000000000..a9149fe1b --- /dev/null +++ b/server/middlewares/validators/users.ts @@ -0,0 +1,84 @@ +const db = require('../../initializers/database') +import { checkErrors } from './utils' +import { logger } from '../../helpers' + +function usersAddValidator (req, res, next) { + req.checkBody('username', 'Should have a valid username').isUserUsernameValid() + req.checkBody('password', 'Should have a valid password').isUserPasswordValid() + req.checkBody('email', 'Should have a valid email').isEmail() + + logger.debug('Checking usersAdd parameters', { parameters: req.body }) + + checkErrors(req, res, function () { + db.User.loadByUsernameOrEmail(req.body.username, req.body.email, function (err, user) { + if (err) { + logger.error('Error in usersAdd request validator.', { error: err }) + return res.sendStatus(500) + } + + if (user) return res.status(409).send('User already exists.') + + next() + }) + }) +} + +function usersRemoveValidator (req, res, next) { + req.checkParams('id', 'Should have a valid id').notEmpty().isInt() + + logger.debug('Checking usersRemove parameters', { parameters: req.params }) + + checkErrors(req, res, function () { + db.User.loadById(req.params.id, function (err, user) { + if (err) { + logger.error('Error in usersRemove request validator.', { error: err }) + return res.sendStatus(500) + } + + if (!user) return res.status(404).send('User not found') + + if (user.username === 'root') return res.status(400).send('Cannot remove the root user') + + next() + }) + }) +} + +function usersUpdateValidator (req, res, next) { + req.checkParams('id', 'Should have a valid id').notEmpty().isInt() + // Add old password verification + req.checkBody('password', 'Should have a valid password').optional().isUserPasswordValid() + req.checkBody('displayNSFW', 'Should have a valid display Not Safe For Work attribute').optional().isUserDisplayNSFWValid() + + logger.debug('Checking usersUpdate parameters', { parameters: req.body }) + + checkErrors(req, res, next) +} + +function usersVideoRatingValidator (req, res, next) { + req.checkParams('videoId', 'Should have a valid video id').notEmpty().isUUID(4) + + logger.debug('Checking usersVideoRating parameters', { parameters: req.params }) + + checkErrors(req, res, function () { + db.Video.load(req.params.videoId, function (err, video) { + if (err) { + logger.error('Error in user request validator.', { error: err }) + return res.sendStatus(500) + } + + if (!video) return res.status(404).send('Video not found') + + next() + }) + }) +} + +// --------------------------------------------------------------------------- + +export { + usersAddValidator, + usersRemoveValidator, + usersUpdateValidator, + usersVideoRatingValidator +} diff --git a/server/middlewares/validators/utils.js b/server/middlewares/validators/utils.js deleted file mode 100644 index 3741b84c6..000000000 --- a/server/middlewares/validators/utils.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict' - -const util = require('util') - -const logger = require('../../helpers/logger') - -const validatorsUtils = { - checkErrors -} - -function checkErrors (req, res, next, statusCode) { - if (statusCode === undefined) statusCode = 400 - const errors = req.validationErrors() - - if (errors) { - logger.warn('Incorrect request parameters', { path: req.originalUrl, err: errors }) - return res.status(statusCode).send('There have been validation errors: ' + util.inspect(errors)) - } - - return next() -} - -// --------------------------------------------------------------------------- - -module.exports = validatorsUtils diff --git a/server/middlewares/validators/utils.ts b/server/middlewares/validators/utils.ts new file mode 100644 index 000000000..710e65529 --- /dev/null +++ b/server/middlewares/validators/utils.ts @@ -0,0 +1,21 @@ +import { inspect } from 'util' + +import { logger } from '../../helpers' + +function checkErrors (req, res, next, statusCode?) { + if (statusCode === undefined) statusCode = 400 + const errors = req.validationErrors() + + if (errors) { + logger.warn('Incorrect request parameters', { path: req.originalUrl, err: errors }) + return res.status(statusCode).send('There have been validation errors: ' + inspect(errors)) + } + + return next() +} + +// --------------------------------------------------------------------------- + +export { + checkErrors +} diff --git a/server/middlewares/validators/videos.js b/server/middlewares/validators/videos.js deleted file mode 100644 index f18ca1597..000000000 --- a/server/middlewares/validators/videos.js +++ /dev/null @@ -1,204 +0,0 @@ -'use strict' - -const checkErrors = require('./utils').checkErrors -const constants = require('../../initializers/constants') -const customVideosValidators = require('../../helpers/custom-validators').videos -const db = require('../../initializers/database') -const logger = require('../../helpers/logger') - -const validatorsVideos = { - videosAdd, - videosUpdate, - videosGet, - videosRemove, - videosSearch, - - videoAbuseReport, - - videoRate, - - videosBlacklist -} - -function videosAdd (req, res, next) { - req.checkBody('videofile', 'Should have a valid file').isVideoFile(req.files) - req.checkBody('name', 'Should have a valid name').isVideoNameValid() - req.checkBody('category', 'Should have a valid category').isVideoCategoryValid() - req.checkBody('licence', 'Should have a valid licence').isVideoLicenceValid() - req.checkBody('language', 'Should have a valid language').optional().isVideoLanguageValid() - req.checkBody('nsfw', 'Should have a valid NSFW attribute').isVideoNSFWValid() - req.checkBody('description', 'Should have a valid description').isVideoDescriptionValid() - req.checkBody('tags', 'Should have correct tags').optional().isVideoTagsValid() - - logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files }) - - checkErrors(req, res, function () { - const videoFile = req.files.videofile[0] - - db.Video.getDurationFromFile(videoFile.path, function (err, duration) { - if (err) { - return res.status(400).send('Cannot retrieve metadata of the file.') - } - - if (!customVideosValidators.isVideoDurationValid(duration)) { - return res.status(400).send('Duration of the video file is too big (max: ' + constants.CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).') - } - - videoFile.duration = duration - next() - }) - }) -} - -function videosUpdate (req, res, next) { - req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4) - req.checkBody('name', 'Should have a valid name').optional().isVideoNameValid() - req.checkBody('category', 'Should have a valid category').optional().isVideoCategoryValid() - req.checkBody('licence', 'Should have a valid licence').optional().isVideoLicenceValid() - req.checkBody('language', 'Should have a valid language').optional().isVideoLanguageValid() - req.checkBody('nsfw', 'Should have a valid NSFW attribute').optional().isVideoNSFWValid() - req.checkBody('description', 'Should have a valid description').optional().isVideoDescriptionValid() - req.checkBody('tags', 'Should have correct tags').optional().isVideoTagsValid() - - logger.debug('Checking videosUpdate parameters', { parameters: req.body }) - - checkErrors(req, res, function () { - checkVideoExists(req.params.id, res, function () { - // We need to make additional checks - if (res.locals.video.isOwned() === false) { - return res.status(403).send('Cannot update video of another pod') - } - - if (res.locals.video.Author.userId !== res.locals.oauth.token.User.id) { - return res.status(403).send('Cannot update video of another user') - } - - next() - }) - }) -} - -function videosGet (req, res, next) { - req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4) - - logger.debug('Checking videosGet parameters', { parameters: req.params }) - - checkErrors(req, res, function () { - checkVideoExists(req.params.id, res, next) - }) -} - -function videosRemove (req, res, next) { - req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4) - - logger.debug('Checking videosRemove parameters', { parameters: req.params }) - - checkErrors(req, res, function () { - checkVideoExists(req.params.id, res, function () { - // We need to make additional checks - - // Check if the user who did the request is able to delete the video - checkUserCanDeleteVideo(res.locals.oauth.token.User.id, res, function () { - next() - }) - }) - }) -} - -function videosSearch (req, res, next) { - const searchableColumns = constants.SEARCHABLE_COLUMNS.VIDEOS - req.checkParams('value', 'Should have a valid search').notEmpty() - req.checkQuery('field', 'Should have correct searchable column').optional().isIn(searchableColumns) - - logger.debug('Checking videosSearch parameters', { parameters: req.params }) - - checkErrors(req, res, next) -} - -function videoAbuseReport (req, res, next) { - req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4) - req.checkBody('reason', 'Should have a valid reason').isVideoAbuseReasonValid() - - logger.debug('Checking videoAbuseReport parameters', { parameters: req.body }) - - checkErrors(req, res, function () { - checkVideoExists(req.params.id, res, next) - }) -} - -function videoRate (req, res, next) { - req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4) - req.checkBody('rating', 'Should have a valid rate type').isVideoRatingTypeValid() - - logger.debug('Checking videoRate parameters', { parameters: req.body }) - - checkErrors(req, res, function () { - checkVideoExists(req.params.id, res, next) - }) -} - -function videosBlacklist (req, res, next) { - req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4) - - logger.debug('Checking videosBlacklist parameters', { parameters: req.params }) - - checkErrors(req, res, function () { - checkVideoExists(req.params.id, res, function () { - checkVideoIsBlacklistable(req, res, next) - }) - }) -} - -// --------------------------------------------------------------------------- - -module.exports = validatorsVideos - -// --------------------------------------------------------------------------- - -function checkVideoExists (id, res, callback) { - db.Video.loadAndPopulateAuthorAndPodAndTags(id, function (err, video) { - if (err) { - logger.error('Error in video request validator.', { error: err }) - return res.sendStatus(500) - } - - if (!video) return res.status(404).send('Video not found') - - res.locals.video = video - callback() - }) -} - -function checkUserCanDeleteVideo (userId, res, callback) { - // Retrieve the user who did the request - db.User.loadById(userId, function (err, user) { - if (err) { - logger.error('Error in video request validator.', { error: err }) - return res.sendStatus(500) - } - - // Check if the user can delete the video - // The user can delete it if s/he is an admin - // Or if s/he is the video's author - if (user.isAdmin() === false) { - if (res.locals.video.isOwned() === false) { - return res.status(403).send('Cannot remove video of another pod') - } - - if (res.locals.video.Author.userId !== res.locals.oauth.token.User.id) { - return res.status(403).send('Cannot remove video of another user') - } - } - - // If we reach this comment, we can delete the video - callback() - }) -} - -function checkVideoIsBlacklistable (req, res, callback) { - if (res.locals.video.isOwned() === true) { - return res.status(403).send('Cannot blacklist a local video') - } - - callback() -} diff --git a/server/middlewares/validators/videos.ts b/server/middlewares/validators/videos.ts new file mode 100644 index 000000000..5a49cf73c --- /dev/null +++ b/server/middlewares/validators/videos.ts @@ -0,0 +1,199 @@ +const db = require('../../initializers/database') +import { checkErrors } from './utils' +import { CONSTRAINTS_FIELDS, SEARCHABLE_COLUMNS } from '../../initializers' +import { logger, isVideoDurationValid } from '../../helpers' + +function videosAddValidator (req, res, next) { + req.checkBody('videofile', 'Should have a valid file').isVideoFile(req.files) + req.checkBody('name', 'Should have a valid name').isVideoNameValid() + req.checkBody('category', 'Should have a valid category').isVideoCategoryValid() + req.checkBody('licence', 'Should have a valid licence').isVideoLicenceValid() + req.checkBody('language', 'Should have a valid language').optional().isVideoLanguageValid() + req.checkBody('nsfw', 'Should have a valid NSFW attribute').isVideoNSFWValid() + req.checkBody('description', 'Should have a valid description').isVideoDescriptionValid() + req.checkBody('tags', 'Should have correct tags').optional().isVideoTagsValid() + + logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files }) + + checkErrors(req, res, function () { + const videoFile = req.files.videofile[0] + + db.Video.getDurationFromFile(videoFile.path, function (err, duration) { + if (err) { + return res.status(400).send('Cannot retrieve metadata of the file.') + } + + if (!isVideoDurationValid(duration)) { + return res.status(400).send('Duration of the video file is too big (max: ' + CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).') + } + + videoFile.duration = duration + next() + }) + }) +} + +function videosUpdateValidator (req, res, next) { + req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4) + req.checkBody('name', 'Should have a valid name').optional().isVideoNameValid() + req.checkBody('category', 'Should have a valid category').optional().isVideoCategoryValid() + req.checkBody('licence', 'Should have a valid licence').optional().isVideoLicenceValid() + req.checkBody('language', 'Should have a valid language').optional().isVideoLanguageValid() + req.checkBody('nsfw', 'Should have a valid NSFW attribute').optional().isVideoNSFWValid() + req.checkBody('description', 'Should have a valid description').optional().isVideoDescriptionValid() + req.checkBody('tags', 'Should have correct tags').optional().isVideoTagsValid() + + logger.debug('Checking videosUpdate parameters', { parameters: req.body }) + + checkErrors(req, res, function () { + checkVideoExists(req.params.id, res, function () { + // We need to make additional checks + if (res.locals.video.isOwned() === false) { + return res.status(403).send('Cannot update video of another pod') + } + + if (res.locals.video.Author.userId !== res.locals.oauth.token.User.id) { + return res.status(403).send('Cannot update video of another user') + } + + next() + }) + }) +} + +function videosGetValidator (req, res, next) { + req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4) + + logger.debug('Checking videosGet parameters', { parameters: req.params }) + + checkErrors(req, res, function () { + checkVideoExists(req.params.id, res, next) + }) +} + +function videosRemoveValidator (req, res, next) { + req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4) + + logger.debug('Checking videosRemove parameters', { parameters: req.params }) + + checkErrors(req, res, function () { + checkVideoExists(req.params.id, res, function () { + // We need to make additional checks + + // Check if the user who did the request is able to delete the video + checkUserCanDeleteVideo(res.locals.oauth.token.User.id, res, function () { + next() + }) + }) + }) +} + +function videosSearchValidator (req, res, next) { + const searchableColumns = SEARCHABLE_COLUMNS.VIDEOS + req.checkParams('value', 'Should have a valid search').notEmpty() + req.checkQuery('field', 'Should have correct searchable column').optional().isIn(searchableColumns) + + logger.debug('Checking videosSearch parameters', { parameters: req.params }) + + checkErrors(req, res, next) +} + +function videoAbuseReportValidator (req, res, next) { + req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4) + req.checkBody('reason', 'Should have a valid reason').isVideoAbuseReasonValid() + + logger.debug('Checking videoAbuseReport parameters', { parameters: req.body }) + + checkErrors(req, res, function () { + checkVideoExists(req.params.id, res, next) + }) +} + +function videoRateValidator (req, res, next) { + req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4) + req.checkBody('rating', 'Should have a valid rate type').isVideoRatingTypeValid() + + logger.debug('Checking videoRate parameters', { parameters: req.body }) + + checkErrors(req, res, function () { + checkVideoExists(req.params.id, res, next) + }) +} + +function videosBlacklistValidator (req, res, next) { + req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4) + + logger.debug('Checking videosBlacklist parameters', { parameters: req.params }) + + checkErrors(req, res, function () { + checkVideoExists(req.params.id, res, function () { + checkVideoIsBlacklistable(req, res, next) + }) + }) +} + +// --------------------------------------------------------------------------- + +export { + videosAddValidator, + videosUpdateValidator, + videosGetValidator, + videosRemoveValidator, + videosSearchValidator, + + videoAbuseReportValidator, + + videoRateValidator, + + videosBlacklistValidator +} + +// --------------------------------------------------------------------------- + +function checkVideoExists (id, res, callback) { + db.Video.loadAndPopulateAuthorAndPodAndTags(id, function (err, video) { + if (err) { + logger.error('Error in video request validator.', { error: err }) + return res.sendStatus(500) + } + + if (!video) return res.status(404).send('Video not found') + + res.locals.video = video + callback() + }) +} + +function checkUserCanDeleteVideo (userId, res, callback) { + // Retrieve the user who did the request + db.User.loadById(userId, function (err, user) { + if (err) { + logger.error('Error in video request validator.', { error: err }) + return res.sendStatus(500) + } + + // Check if the user can delete the video + // The user can delete it if s/he is an admin + // Or if s/he is the video's author + if (user.isAdmin() === false) { + if (res.locals.video.isOwned() === false) { + return res.status(403).send('Cannot remove video of another pod') + } + + if (res.locals.video.Author.userId !== res.locals.oauth.token.User.id) { + return res.status(403).send('Cannot remove video of another user') + } + } + + // If we reach this comment, we can delete the video + callback() + }) +} + +function checkVideoIsBlacklistable (req, res, callback) { + if (res.locals.video.isOwned() === true) { + return res.status(403).send('Cannot blacklist a local video') + } + + callback() +} -- cgit v1.2.3