import * as express from 'express'
-import { body, param, query, ValidationChain } from 'express-validator/check'
+import { body, param, query, ValidationChain } from 'express-validator'
import { UserRight, VideoPlaylistCreate, VideoPlaylistUpdate } from '../../../../shared'
import { logger } from '../../../helpers/logger'
-import { UserModel } from '../../../models/account/user'
import { areValidationErrors } from '../utils'
import { isVideoImage } from '../../../helpers/custom-validators/videos'
import { CONSTRAINTS_FIELDS } from '../../../initializers/constants'
-import { isArrayOf, isIdOrUUIDValid, isIdValid, isUUIDValid, toIntArray, toValueOrNull } from '../../../helpers/custom-validators/misc'
+import {
+ isArrayOf,
+ isIdOrUUIDValid,
+ isIdValid,
+ isUUIDValid,
+ toIntArray,
+ toIntOrNull,
+ toValueOrNull
+} from '../../../helpers/custom-validators/misc'
import {
isVideoPlaylistDescriptionValid,
isVideoPlaylistNameValid,
isVideoPlaylistTimestampValid,
isVideoPlaylistTypeValid
} from '../../../helpers/custom-validators/video-playlists'
-import { VideoPlaylistModel } from '../../../models/video/video-playlist'
import { cleanUpReqFiles } from '../../../helpers/express-utils'
import { VideoPlaylistElementModel } from '../../../models/video/video-playlist-element'
import { authenticatePromiseIfNeeded } from '../../oauth'
import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model'
import { VideoPlaylistType } from '../../../../shared/models/videos/playlist/video-playlist-type.model'
-import { doesVideoChannelIdExist, doesVideoExist, doesVideoPlaylistExist } from '../../../helpers/middlewares'
+import { doesVideoChannelIdExist, doesVideoExist, doesVideoPlaylistExist, VideoPlaylistFetchType } from '../../../helpers/middlewares'
+import { MVideoPlaylist } from '../../../types/models/video/video-playlist'
+import { MUserAccountId } from '@server/types/models'
const videoPlaylistsAddValidator = getCommonPlaylistEditAttributes().concat([
body('displayName')
if (!await doesVideoPlaylistExist(req.params.playlistId, res, 'all')) return cleanUpReqFiles(req)
- const videoPlaylist = res.locals.videoPlaylist
+ const videoPlaylist = getPlaylist(res)
- if (!checkUserCanManageVideoPlaylist(res.locals.oauth.token.User, res.locals.videoPlaylist, UserRight.REMOVE_ANY_VIDEO_PLAYLIST, res)) {
+ if (!checkUserCanManageVideoPlaylist(res.locals.oauth.token.User, videoPlaylist, UserRight.REMOVE_ANY_VIDEO_PLAYLIST, res)) {
return cleanUpReqFiles(req)
}
if (!await doesVideoPlaylistExist(req.params.playlistId, res)) return
- const videoPlaylist = res.locals.videoPlaylist
+ const videoPlaylist = getPlaylist(res)
if (videoPlaylist.type === VideoPlaylistType.WATCH_LATER) {
return res.status(400)
.json({ error: 'Cannot delete a watch later playlist.' })
}
- if (!checkUserCanManageVideoPlaylist(res.locals.oauth.token.User, res.locals.videoPlaylist, UserRight.REMOVE_ANY_VIDEO_PLAYLIST, res)) {
+ if (!checkUserCanManageVideoPlaylist(res.locals.oauth.token.User, videoPlaylist, UserRight.REMOVE_ANY_VIDEO_PLAYLIST, res)) {
return
}
}
]
-const videoPlaylistsGetValidator = [
- param('playlistId')
- .custom(isIdOrUUIDValid).withMessage('Should have a valid playlist id/uuid'),
+const videoPlaylistsGetValidator = (fetchType: VideoPlaylistFetchType) => {
+ return [
+ param('playlistId')
+ .custom(isIdOrUUIDValid).withMessage('Should have a valid playlist id/uuid'),
- async (req: express.Request, res: express.Response, next: express.NextFunction) => {
- logger.debug('Checking videoPlaylistsGetValidator parameters', { parameters: req.params })
+ async (req: express.Request, res: express.Response, next: express.NextFunction) => {
+ logger.debug('Checking videoPlaylistsGetValidator parameters', { parameters: req.params })
- if (areValidationErrors(req, res)) return
+ if (areValidationErrors(req, res)) return
- if (!await doesVideoPlaylistExist(req.params.playlistId, res)) return
+ if (!await doesVideoPlaylistExist(req.params.playlistId, res, fetchType)) return
- const videoPlaylist = res.locals.videoPlaylist
+ const videoPlaylist = res.locals.videoPlaylistFull || res.locals.videoPlaylistSummary
- // Video is unlisted, check we used the uuid to fetch it
- if (videoPlaylist.privacy === VideoPlaylistPrivacy.UNLISTED) {
- if (isUUIDValid(req.params.playlistId)) return next()
+ // Video is unlisted, check we used the uuid to fetch it
+ if (videoPlaylist.privacy === VideoPlaylistPrivacy.UNLISTED) {
+ if (isUUIDValid(req.params.playlistId)) return next()
- return res.status(404).end()
- }
+ return res.status(404).end()
+ }
+
+ if (videoPlaylist.privacy === VideoPlaylistPrivacy.PRIVATE) {
+ await authenticatePromiseIfNeeded(req, res)
- if (videoPlaylist.privacy === VideoPlaylistPrivacy.PRIVATE) {
- await authenticatePromiseIfNeeded(req, res)
+ const user = res.locals.oauth ? res.locals.oauth.token.User : null
- const user = res.locals.oauth ? res.locals.oauth.token.User : null
+ if (
+ !user ||
+ (videoPlaylist.OwnerAccount.id !== user.Account.id && !user.hasRight(UserRight.UPDATE_ANY_VIDEO_PLAYLIST))
+ ) {
+ return res.status(403)
+ .json({ error: 'Cannot get this private video playlist.' })
+ }
- if (
- !user ||
- (videoPlaylist.OwnerAccount.id !== user.Account.id && !user.hasRight(UserRight.UPDATE_ANY_VIDEO_PLAYLIST))
- ) {
- return res.status(403)
- .json({ error: 'Cannot get this private video playlist.' })
+ return next()
}
return next()
}
+ ]
+}
+
+const videoPlaylistsSearchValidator = [
+ query('search').optional().not().isEmpty().withMessage('Should have a valid search'),
+
+ (req: express.Request, res: express.Response, next: express.NextFunction) => {
+ logger.debug('Checking videoPlaylists search query', { parameters: req.query })
+
+ if (areValidationErrors(req, res)) return
return next()
}
if (!await doesVideoPlaylistExist(req.params.playlistId, res, 'all')) return
if (!await doesVideoExist(req.body.videoId, res, 'only-video')) return
- const videoPlaylist = res.locals.videoPlaylist
- const video = res.locals.video
-
- const videoPlaylistElement = await VideoPlaylistElementModel.loadByPlaylistAndVideo(videoPlaylist.id, video.id)
- if (videoPlaylistElement) {
- res.status(409)
- .json({ error: 'This video in this playlist already exists' })
- .end()
+ const videoPlaylist = getPlaylist(res)
- return
- }
-
- if (!checkUserCanManageVideoPlaylist(res.locals.oauth.token.User, res.locals.videoPlaylist, UserRight.UPDATE_ANY_VIDEO_PLAYLIST, res)) {
+ if (!checkUserCanManageVideoPlaylist(res.locals.oauth.token.User, videoPlaylist, UserRight.UPDATE_ANY_VIDEO_PLAYLIST, res)) {
return
}
const videoPlaylistsUpdateOrRemoveVideoValidator = [
param('playlistId')
.custom(isIdOrUUIDValid).withMessage('Should have a valid playlist id/uuid'),
- param('videoId')
- .custom(isIdOrUUIDValid).withMessage('Should have an video id/uuid'),
+ param('playlistElementId')
+ .custom(isIdValid).withMessage('Should have an element id/uuid'),
body('startTimestamp')
.optional()
.custom(isVideoPlaylistTimestampValid).withMessage('Should have a valid start timestamp'),
if (areValidationErrors(req, res)) return
if (!await doesVideoPlaylistExist(req.params.playlistId, res, 'all')) return
- if (!await doesVideoExist(req.params.videoId, res, 'id')) return
- const videoPlaylist = res.locals.videoPlaylist
- const video = res.locals.video
+ const videoPlaylist = getPlaylist(res)
- const videoPlaylistElement = await VideoPlaylistElementModel.loadByPlaylistAndVideo(videoPlaylist.id, video.id)
+ const videoPlaylistElement = await VideoPlaylistElementModel.loadById(req.params.playlistElementId)
if (!videoPlaylistElement) {
res.status(404)
.json({ error: 'Video playlist element not found' })
const videoPlaylistElementAPGetValidator = [
param('playlistId')
.custom(isIdOrUUIDValid).withMessage('Should have a valid playlist id/uuid'),
- param('videoId')
- .custom(isIdOrUUIDValid).withMessage('Should have an video id/uuid'),
+ param('playlistElementId')
+ .custom(isIdValid).withMessage('Should have an playlist element id'),
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
logger.debug('Checking videoPlaylistElementAPGetValidator parameters', { parameters: req.params })
if (areValidationErrors(req, res)) return
- const videoPlaylistElement = await VideoPlaylistElementModel.loadByPlaylistAndVideoForAP(req.params.playlistId, req.params.videoId)
+ const playlistElementId = parseInt(req.params.playlistElementId + '', 10)
+ const playlistId = req.params.playlistId
+
+ const videoPlaylistElement = await VideoPlaylistElementModel.loadByPlaylistAndElementIdForAP(playlistId, playlistElementId)
if (!videoPlaylistElement) {
res.status(404)
.json({ error: 'Video playlist element not found' })
return res.status(403).end()
}
- res.locals.videoPlaylistElement = videoPlaylistElement
+ res.locals.videoPlaylistElementAP = videoPlaylistElement
return next()
}
if (!await doesVideoPlaylistExist(req.params.playlistId, res, 'all')) return
- const videoPlaylist = res.locals.videoPlaylist
+ const videoPlaylist = getPlaylist(res)
if (!checkUserCanManageVideoPlaylist(res.locals.oauth.token.User, videoPlaylist, UserRight.UPDATE_ANY_VIDEO_PLAYLIST, res)) return
const nextPosition = await VideoPlaylistElementModel.getNextPositionOf(videoPlaylist.id)
videoPlaylistsUpdateValidator,
videoPlaylistsDeleteValidator,
videoPlaylistsGetValidator,
+ videoPlaylistsSearchValidator,
videoPlaylistsAddVideoValidator,
videoPlaylistsUpdateOrRemoveVideoValidator,
function getCommonPlaylistEditAttributes () {
return [
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: '
- + CONSTRAINTS_FIELDS.VIDEO_PLAYLISTS.IMAGE.EXTNAME.join(', ')
- ),
+ .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: ' +
+ CONSTRAINTS_FIELDS.VIDEO_PLAYLISTS.IMAGE.EXTNAME.join(', ')
+ ),
body('description')
.optional()
.custom(isVideoPlaylistDescriptionValid).withMessage('Should have a valid description'),
body('privacy')
.optional()
- .toInt()
+ .customSanitizer(toIntOrNull)
.custom(isVideoPlaylistPrivacyValid).withMessage('Should have correct playlist privacy'),
body('videoChannelId')
.optional()
- .customSanitizer(toValueOrNull)
- .toInt()
+ .customSanitizer(toIntOrNull)
] as (ValidationChain | express.Handler)[]
}
-function checkUserCanManageVideoPlaylist (user: UserModel, videoPlaylist: VideoPlaylistModel, right: UserRight, res: express.Response) {
+function checkUserCanManageVideoPlaylist (user: MUserAccountId, videoPlaylist: MVideoPlaylist, right: UserRight, res: express.Response) {
if (videoPlaylist.isOwned() === false) {
res.status(403)
.json({ error: 'Cannot manage video playlist of another server.' })
return true
}
+
+function getPlaylist (res: express.Response) {
+ return res.locals.videoPlaylistFull || res.locals.videoPlaylistSummary
+}