From 40e87e9ecc54e3513fb586928330a7855eb192c6 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 12 Jul 2018 19:02:00 +0200 Subject: Implement captions/subtitles --- server/middlewares/validators/video-captions.ts | 70 +++++++++++++++++++++++++ server/middlewares/validators/videos.ts | 36 +++---------- 2 files changed, 76 insertions(+), 30 deletions(-) create mode 100644 server/middlewares/validators/video-captions.ts (limited to 'server/middlewares') diff --git a/server/middlewares/validators/video-captions.ts b/server/middlewares/validators/video-captions.ts new file mode 100644 index 000000000..b6d92d380 --- /dev/null +++ b/server/middlewares/validators/video-captions.ts @@ -0,0 +1,70 @@ +import * as express from 'express' +import { areValidationErrors } from './utils' +import { checkUserCanManageVideo, isVideoExist } from '../../helpers/custom-validators/videos' +import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc' +import { body, param } from 'express-validator/check' +import { CONSTRAINTS_FIELDS } from '../../initializers' +import { UserRight } from '../../../shared' +import { logger } from '../../helpers/logger' +import { isVideoCaptionExist, isVideoCaptionFile, isVideoCaptionLanguageValid } from '../../helpers/custom-validators/video-captions' + +const addVideoCaptionValidator = [ + param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'), + param('captionLanguage').custom(isVideoCaptionLanguageValid).not().isEmpty().withMessage('Should have a valid caption language'), + body('captionfile') + .custom((value, { req }) => isVideoCaptionFile(req.files, 'captionfile')).withMessage( + 'This caption file is not supported or too large. Please, make sure it is of the following type : ' + + CONSTRAINTS_FIELDS.VIDEO_CAPTIONS.CAPTION_FILE.EXTNAME.join(', ') + ), + + async (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking addVideoCaption parameters', { parameters: req.body }) + + if (areValidationErrors(req, res)) return + if (!await isVideoExist(req.params.videoId, res)) return + + // Check if the user who did the request is able to update the video + const user = res.locals.oauth.token.User + if (!checkUserCanManageVideo(user, res.locals.video, UserRight.UPDATE_ANY_VIDEO, res)) return + + return next() + } +] + +const deleteVideoCaptionValidator = [ + param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'), + param('captionLanguage').custom(isVideoCaptionLanguageValid).not().isEmpty().withMessage('Should have a valid caption language'), + + async (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking deleteVideoCaption parameters', { parameters: req.params }) + + if (areValidationErrors(req, res)) return + if (!await isVideoExist(req.params.videoId, res)) return + if (!await isVideoCaptionExist(res.locals.video, req.params.captionLanguage, res)) return + + // Check if the user who did the request is able to update the video + const user = res.locals.oauth.token.User + if (!checkUserCanManageVideo(user, res.locals.video, UserRight.UPDATE_ANY_VIDEO, res)) return + + return next() + } +] + +const listVideoCaptionsValidator = [ + param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'), + + async (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking listVideoCaptions parameters', { parameters: req.params }) + + if (areValidationErrors(req, res)) return + if (!await isVideoExist(req.params.videoId, res)) return + + return next() + } +] + +export { + addVideoCaptionValidator, + listVideoCaptionsValidator, + deleteVideoCaptionValidator +} diff --git a/server/middlewares/validators/videos.ts b/server/middlewares/validators/videos.ts index 59d65d5a4..899def6fc 100644 --- a/server/middlewares/validators/videos.ts +++ b/server/middlewares/validators/videos.ts @@ -12,6 +12,7 @@ import { toValueOrNull } from '../../helpers/custom-validators/misc' import { + checkUserCanManageVideo, isScheduleVideoUpdatePrivacyValid, isVideoAbuseReasonValid, isVideoCategoryValid, @@ -31,8 +32,6 @@ import { import { getDurationFromVideoFile } from '../../helpers/ffmpeg-utils' import { logger } from '../../helpers/logger' import { CONSTRAINTS_FIELDS } from '../../initializers' -import { UserModel } from '../../models/account/user' -import { VideoModel } from '../../models/video/video' import { VideoShareModel } from '../../models/video/video-share' import { authenticate } from '../oauth' import { areValidationErrors } from './utils' @@ -40,17 +39,17 @@ import { areValidationErrors } from './utils' const videosAddValidator = [ body('videofile') .custom((value, { req }) => isVideoFile(req.files)).withMessage( - 'This file is not supported or too large. Please, make sure it is of the following type : ' + 'This file is not supported or too large. Please, make sure it is of the following type: ' + CONSTRAINTS_FIELDS.VIDEOS.EXTNAME.join(', ') ), body('thumbnailfile') .custom((value, { req }) => isVideoImage(req.files, 'thumbnailfile')).withMessage( - 'This thumbnail file is not supported or too large. Please, make sure it is of the following type : ' + 'This thumbnail file is not supported or too large. Please, make sure it is of the following type: ' + CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME.join(', ') ), body('previewfile') .custom((value, { req }) => isVideoImage(req.files, 'previewfile')).withMessage( - 'This preview file is not supported or too large. Please, make sure it is of the following type : ' + 'This preview file is not supported or too large. Please, make sure it is of the following type: ' + CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME.join(', ') ), body('name').custom(isVideoNameValid).withMessage('Should have a valid name'), @@ -152,12 +151,12 @@ const videosUpdateValidator = [ param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), body('thumbnailfile') .custom((value, { req }) => isVideoImage(req.files, 'thumbnailfile')).withMessage( - 'This thumbnail file is not supported or too large. Please, make sure it is of the following type : ' + 'This thumbnail file is not supported or too large. Please, make sure it is of the following type: ' + CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME.join(', ') ), body('previewfile') .custom((value, { req }) => isVideoImage(req.files, 'previewfile')).withMessage( - 'This preview file is not supported or too large. Please, make sure it is of the following type : ' + 'This preview file is not supported or too large. Please, make sure it is of the following type: ' + CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME.join(', ') ), body('name') @@ -373,29 +372,6 @@ export { // --------------------------------------------------------------------------- -function checkUserCanManageVideo (user: UserModel, video: VideoModel, right: UserRight, res: express.Response) { - // Retrieve the user who did the request - if (video.isOwned() === false) { - res.status(403) - .json({ error: 'Cannot manage a video of another server.' }) - .end() - return false - } - - // Check if the user can delete the video - // The user can delete it if he has the right - // Or if s/he is the video's account - const account = video.VideoChannel.Account - if (user.hasRight(right) === false && account.userId !== user.id) { - res.status(403) - .json({ error: 'Cannot manage a video of another user.' }) - .end() - return false - } - - return true -} - function areErrorsInVideoImageFiles (req: express.Request, res: express.Response) { // Files are optional if (!req.files) return false -- cgit v1.2.3