aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/middlewares/validators
diff options
context:
space:
mode:
Diffstat (limited to 'server/middlewares/validators')
-rw-r--r--server/middlewares/validators/follows.ts3
-rw-r--r--server/middlewares/validators/redundancy.ts4
-rw-r--r--server/middlewares/validators/users.ts5
-rw-r--r--server/middlewares/validators/videos/video-abuses.ts4
-rw-r--r--server/middlewares/validators/videos/video-blacklist.ts6
-rw-r--r--server/middlewares/validators/videos/video-captions.ts6
-rw-r--r--server/middlewares/validators/videos/video-channels.ts5
-rw-r--r--server/middlewares/validators/videos/video-comments.ts40
-rw-r--r--server/middlewares/validators/videos/video-playlists.ts84
-rw-r--r--server/middlewares/validators/videos/video-shares.ts2
-rw-r--r--server/middlewares/validators/videos/videos.ts20
-rw-r--r--server/middlewares/validators/webfinger.ts3
12 files changed, 97 insertions, 85 deletions
diff --git a/server/middlewares/validators/follows.ts b/server/middlewares/validators/follows.ts
index c3d772297..788735663 100644
--- a/server/middlewares/validators/follows.ts
+++ b/server/middlewares/validators/follows.ts
@@ -10,6 +10,7 @@ import { areValidationErrors } from './utils'
10import { ActorModel } from '../../models/activitypub/actor' 10import { ActorModel } from '../../models/activitypub/actor'
11import { loadActorUrlOrGetFromWebfinger } from '../../helpers/webfinger' 11import { loadActorUrlOrGetFromWebfinger } from '../../helpers/webfinger'
12import { isValidActorHandle } from '../../helpers/custom-validators/activitypub/actor' 12import { isValidActorHandle } from '../../helpers/custom-validators/activitypub/actor'
13import { MActorFollowActorsDefault } from '@server/typings/models'
13 14
14const followValidator = [ 15const followValidator = [
15 body('hosts').custom(isEachUniqueHostValid).withMessage('Should have an array of unique hosts'), 16 body('hosts').custom(isEachUniqueHostValid).withMessage('Should have an array of unique hosts'),
@@ -65,7 +66,7 @@ const getFollowerValidator = [
65 66
66 if (areValidationErrors(req, res)) return 67 if (areValidationErrors(req, res)) return
67 68
68 let follow: ActorFollowModel 69 let follow: MActorFollowActorsDefault
69 try { 70 try {
70 const actorUrl = await loadActorUrlOrGetFromWebfinger(req.params.nameWithHost) 71 const actorUrl = await loadActorUrlOrGetFromWebfinger(req.params.nameWithHost)
71 const actor = await ActorModel.loadByUrl(actorUrl) 72 const actor = await ActorModel.loadByUrl(actorUrl)
diff --git a/server/middlewares/validators/redundancy.ts b/server/middlewares/validators/redundancy.ts
index 1fdac0e4e..e65d3b8d3 100644
--- a/server/middlewares/validators/redundancy.ts
+++ b/server/middlewares/validators/redundancy.ts
@@ -24,7 +24,7 @@ const videoFileRedundancyGetValidator = [
24 if (areValidationErrors(req, res)) return 24 if (areValidationErrors(req, res)) return
25 if (!await doesVideoExist(req.params.videoId, res)) return 25 if (!await doesVideoExist(req.params.videoId, res)) return
26 26
27 const video = res.locals.video 27 const video = res.locals.videoAll
28 const videoFile = video.VideoFiles.find(f => { 28 const videoFile = video.VideoFiles.find(f => {
29 return f.resolution === req.params.resolution && (!req.params.fps || f.fps === req.params.fps) 29 return f.resolution === req.params.resolution && (!req.params.fps || f.fps === req.params.fps)
30 }) 30 })
@@ -50,7 +50,7 @@ const videoPlaylistRedundancyGetValidator = [
50 if (areValidationErrors(req, res)) return 50 if (areValidationErrors(req, res)) return
51 if (!await doesVideoExist(req.params.videoId, res)) return 51 if (!await doesVideoExist(req.params.videoId, res)) return
52 52
53 const video = res.locals.video 53 const video = res.locals.videoAll
54 const videoStreamingPlaylist = video.VideoStreamingPlaylists.find(p => p === req.params.streamingPlaylistType) 54 const videoStreamingPlaylist = video.VideoStreamingPlaylists.find(p => p === req.params.streamingPlaylistType)
55 55
56 if (!videoStreamingPlaylist) return res.status(404).json({ error: 'Video playlist not found.' }) 56 if (!videoStreamingPlaylist) return res.status(404).json({ error: 'Video playlist not found.' })
diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts
index 16d297047..40dd0f0e9 100644
--- a/server/middlewares/validators/users.ts
+++ b/server/middlewares/validators/users.ts
@@ -2,7 +2,7 @@ import * as Bluebird from 'bluebird'
2import * as express from 'express' 2import * as express from 'express'
3import { body, param } from 'express-validator' 3import { body, param } from 'express-validator'
4import { omit } from 'lodash' 4import { omit } from 'lodash'
5import { isIdOrUUIDValid, toBooleanOrNull, toIntOrNull } from '../../helpers/custom-validators/misc' 5import { isIdOrUUIDValid, toBooleanOrNull } from '../../helpers/custom-validators/misc'
6import { 6import {
7 isUserAdminFlagsValid, 7 isUserAdminFlagsValid,
8 isUserAutoPlayVideoValid, 8 isUserAutoPlayVideoValid,
@@ -31,6 +31,7 @@ import { isThemeNameValid } from '../../helpers/custom-validators/plugins'
31import { isThemeRegistered } from '../../lib/plugins/theme-utils' 31import { isThemeRegistered } from '../../lib/plugins/theme-utils'
32import { doesVideoExist } from '../../helpers/middlewares' 32import { doesVideoExist } from '../../helpers/middlewares'
33import { UserRole } from '../../../shared/models/users' 33import { UserRole } from '../../../shared/models/users'
34import { MUserDefault } from '@server/typings/models'
34 35
35const usersAddValidator = [ 36const usersAddValidator = [
36 body('username').custom(isUserUsernameValid).withMessage('Should have a valid username (lowercase alphanumeric characters)'), 37 body('username').custom(isUserUsernameValid).withMessage('Should have a valid username (lowercase alphanumeric characters)'),
@@ -457,7 +458,7 @@ async function checkUserNameOrEmailDoesNotAlreadyExist (username: string, email:
457 return true 458 return true
458} 459}
459 460
460async function checkUserExist (finder: () => Bluebird<UserModel>, res: express.Response, abortResponse = true) { 461async function checkUserExist (finder: () => Bluebird<MUserDefault>, res: express.Response, abortResponse = true) {
461 const user = await finder() 462 const user = await finder()
462 463
463 if (!user) { 464 if (!user) {
diff --git a/server/middlewares/validators/videos/video-abuses.ts b/server/middlewares/validators/videos/video-abuses.ts
index e27d91bb1..a4aef4024 100644
--- a/server/middlewares/validators/videos/video-abuses.ts
+++ b/server/middlewares/validators/videos/video-abuses.ts
@@ -33,7 +33,7 @@ const videoAbuseGetValidator = [
33 33
34 if (areValidationErrors(req, res)) return 34 if (areValidationErrors(req, res)) return
35 if (!await doesVideoExist(req.params.videoId, res)) return 35 if (!await doesVideoExist(req.params.videoId, res)) return
36 if (!await doesVideoAbuseExist(req.params.id, res.locals.video.id, res)) return 36 if (!await doesVideoAbuseExist(req.params.id, res.locals.videoAll.id, res)) return
37 37
38 return next() 38 return next()
39 } 39 }
@@ -54,7 +54,7 @@ const videoAbuseUpdateValidator = [
54 54
55 if (areValidationErrors(req, res)) return 55 if (areValidationErrors(req, res)) return
56 if (!await doesVideoExist(req.params.videoId, res)) return 56 if (!await doesVideoExist(req.params.videoId, res)) return
57 if (!await doesVideoAbuseExist(req.params.id, res.locals.video.id, res)) return 57 if (!await doesVideoAbuseExist(req.params.id, res.locals.videoAll.id, res)) return
58 58
59 return next() 59 return next()
60 } 60 }
diff --git a/server/middlewares/validators/videos/video-blacklist.ts b/server/middlewares/validators/videos/video-blacklist.ts
index 3e8c5b30c..5440e57e7 100644
--- a/server/middlewares/validators/videos/video-blacklist.ts
+++ b/server/middlewares/validators/videos/video-blacklist.ts
@@ -14,7 +14,7 @@ const videosBlacklistRemoveValidator = [
14 14
15 if (areValidationErrors(req, res)) return 15 if (areValidationErrors(req, res)) return
16 if (!await doesVideoExist(req.params.videoId, res)) return 16 if (!await doesVideoExist(req.params.videoId, res)) return
17 if (!await doesVideoBlacklistExist(res.locals.video.id, res)) return 17 if (!await doesVideoBlacklistExist(res.locals.videoAll.id, res)) return
18 18
19 return next() 19 return next()
20 } 20 }
@@ -36,7 +36,7 @@ const videosBlacklistAddValidator = [
36 if (areValidationErrors(req, res)) return 36 if (areValidationErrors(req, res)) return
37 if (!await doesVideoExist(req.params.videoId, res)) return 37 if (!await doesVideoExist(req.params.videoId, res)) return
38 38
39 const video = res.locals.video 39 const video = res.locals.videoAll
40 if (req.body.unfederate === true && video.remote === true) { 40 if (req.body.unfederate === true && video.remote === true) {
41 return res 41 return res
42 .status(409) 42 .status(409)
@@ -59,7 +59,7 @@ const videosBlacklistUpdateValidator = [
59 59
60 if (areValidationErrors(req, res)) return 60 if (areValidationErrors(req, res)) return
61 if (!await doesVideoExist(req.params.videoId, res)) return 61 if (!await doesVideoExist(req.params.videoId, res)) return
62 if (!await doesVideoBlacklistExist(res.locals.video.id, res)) return 62 if (!await doesVideoBlacklistExist(res.locals.videoAll.id, res)) return
63 63
64 return next() 64 return next()
65 } 65 }
diff --git a/server/middlewares/validators/videos/video-captions.ts b/server/middlewares/validators/videos/video-captions.ts
index f5610222a..2fb1da5ce 100644
--- a/server/middlewares/validators/videos/video-captions.ts
+++ b/server/middlewares/validators/videos/video-captions.ts
@@ -26,7 +26,7 @@ const addVideoCaptionValidator = [
26 26
27 // Check if the user who did the request is able to update the video 27 // Check if the user who did the request is able to update the video
28 const user = res.locals.oauth.token.User 28 const user = res.locals.oauth.token.User
29 if (!checkUserCanManageVideo(user, res.locals.video, UserRight.UPDATE_ANY_VIDEO, res)) return cleanUpReqFiles(req) 29 if (!checkUserCanManageVideo(user, res.locals.videoAll, UserRight.UPDATE_ANY_VIDEO, res)) return cleanUpReqFiles(req)
30 30
31 return next() 31 return next()
32 } 32 }
@@ -41,11 +41,11 @@ const deleteVideoCaptionValidator = [
41 41
42 if (areValidationErrors(req, res)) return 42 if (areValidationErrors(req, res)) return
43 if (!await doesVideoExist(req.params.videoId, res)) return 43 if (!await doesVideoExist(req.params.videoId, res)) return
44 if (!await doesVideoCaptionExist(res.locals.video, req.params.captionLanguage, res)) return 44 if (!await doesVideoCaptionExist(res.locals.videoAll, req.params.captionLanguage, res)) return
45 45
46 // Check if the user who did the request is able to update the video 46 // Check if the user who did the request is able to update the video
47 const user = res.locals.oauth.token.User 47 const user = res.locals.oauth.token.User
48 if (!checkUserCanManageVideo(user, res.locals.video, UserRight.UPDATE_ANY_VIDEO, res)) return 48 if (!checkUserCanManageVideo(user, res.locals.videoAll, UserRight.UPDATE_ANY_VIDEO, res)) return
49 49
50 return next() 50 return next()
51 } 51 }
diff --git a/server/middlewares/validators/videos/video-channels.ts b/server/middlewares/validators/videos/video-channels.ts
index 3ee5064fc..a0df03f7e 100644
--- a/server/middlewares/validators/videos/video-channels.ts
+++ b/server/middlewares/validators/videos/video-channels.ts
@@ -7,13 +7,14 @@ import {
7 isVideoChannelSupportValid 7 isVideoChannelSupportValid
8} from '../../../helpers/custom-validators/video-channels' 8} from '../../../helpers/custom-validators/video-channels'
9import { logger } from '../../../helpers/logger' 9import { logger } from '../../../helpers/logger'
10import { UserModel } from '../../../models/account/user'
11import { VideoChannelModel } from '../../../models/video/video-channel' 10import { VideoChannelModel } from '../../../models/video/video-channel'
12import { areValidationErrors } from '../utils' 11import { areValidationErrors } from '../utils'
13import { isActorPreferredUsernameValid } from '../../../helpers/custom-validators/activitypub/actor' 12import { isActorPreferredUsernameValid } from '../../../helpers/custom-validators/activitypub/actor'
14import { ActorModel } from '../../../models/activitypub/actor' 13import { ActorModel } from '../../../models/activitypub/actor'
15import { isBooleanValid } from '../../../helpers/custom-validators/misc' 14import { isBooleanValid } from '../../../helpers/custom-validators/misc'
16import { doesLocalVideoChannelNameExist, doesVideoChannelNameWithHostExist } from '../../../helpers/middlewares' 15import { doesLocalVideoChannelNameExist, doesVideoChannelNameWithHostExist } from '../../../helpers/middlewares'
16import { MChannelActorAccountDefault } from '../../../typings/models/video'
17import { MUser } from '@server/typings/models'
17 18
18const videoChannelsAddValidator = [ 19const videoChannelsAddValidator = [
19 body('name').custom(isActorPreferredUsernameValid).withMessage('Should have a valid channel name'), 20 body('name').custom(isActorPreferredUsernameValid).withMessage('Should have a valid channel name'),
@@ -131,7 +132,7 @@ export {
131 132
132// --------------------------------------------------------------------------- 133// ---------------------------------------------------------------------------
133 134
134function checkUserCanDeleteVideoChannel (user: UserModel, videoChannel: VideoChannelModel, res: express.Response) { 135function checkUserCanDeleteVideoChannel (user: MUser, videoChannel: MChannelActorAccountDefault, res: express.Response) {
135 if (videoChannel.Actor.isOwned() === false) { 136 if (videoChannel.Actor.isOwned() === false) {
136 res.status(403) 137 res.status(403)
137 .json({ error: 'Cannot remove video channel of another server.' }) 138 .json({ error: 'Cannot remove video channel of another server.' })
diff --git a/server/middlewares/validators/videos/video-comments.ts b/server/middlewares/validators/videos/video-comments.ts
index 83a0c24b0..8adbb02ba 100644
--- a/server/middlewares/validators/videos/video-comments.ts
+++ b/server/middlewares/validators/videos/video-comments.ts
@@ -4,13 +4,13 @@ import { UserRight } from '../../../../shared'
4import { isIdOrUUIDValid, isIdValid } from '../../../helpers/custom-validators/misc' 4import { isIdOrUUIDValid, isIdValid } from '../../../helpers/custom-validators/misc'
5import { isValidVideoCommentText } from '../../../helpers/custom-validators/video-comments' 5import { isValidVideoCommentText } from '../../../helpers/custom-validators/video-comments'
6import { logger } from '../../../helpers/logger' 6import { logger } from '../../../helpers/logger'
7import { UserModel } from '../../../models/account/user'
8import { VideoModel } from '../../../models/video/video'
9import { VideoCommentModel } from '../../../models/video/video-comment' 7import { VideoCommentModel } from '../../../models/video/video-comment'
10import { areValidationErrors } from '../utils' 8import { areValidationErrors } from '../utils'
11import { Hooks } from '../../../lib/plugins/hooks' 9import { Hooks } from '../../../lib/plugins/hooks'
12import { isLocalVideoThreadAccepted, isLocalVideoCommentReplyAccepted, AcceptResult } from '../../../lib/moderation' 10import { AcceptResult, isLocalVideoCommentReplyAccepted, isLocalVideoThreadAccepted } from '../../../lib/moderation'
13import { doesVideoExist } from '../../../helpers/middlewares' 11import { doesVideoExist } from '../../../helpers/middlewares'
12import { MCommentOwner, MVideo, MVideoFullLight, MVideoId } from '../../../typings/models/video'
13import { MUser } from '@server/typings/models'
14 14
15const listVideoCommentThreadsValidator = [ 15const listVideoCommentThreadsValidator = [
16 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'), 16 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
@@ -34,7 +34,7 @@ const listVideoThreadCommentsValidator = [
34 34
35 if (areValidationErrors(req, res)) return 35 if (areValidationErrors(req, res)) return
36 if (!await doesVideoExist(req.params.videoId, res, 'only-video')) return 36 if (!await doesVideoExist(req.params.videoId, res, 'only-video')) return
37 if (!await doesVideoCommentThreadExist(req.params.threadId, res.locals.video, res)) return 37 if (!await doesVideoCommentThreadExist(req.params.threadId, res.locals.onlyVideo, res)) return
38 38
39 return next() 39 return next()
40 } 40 }
@@ -49,8 +49,8 @@ const addVideoCommentThreadValidator = [
49 49
50 if (areValidationErrors(req, res)) return 50 if (areValidationErrors(req, res)) return
51 if (!await doesVideoExist(req.params.videoId, res)) return 51 if (!await doesVideoExist(req.params.videoId, res)) return
52 if (!isVideoCommentsEnabled(res.locals.video, res)) return 52 if (!isVideoCommentsEnabled(res.locals.videoAll, res)) return
53 if (!await isVideoCommentAccepted(req, res, false)) return 53 if (!await isVideoCommentAccepted(req, res, res.locals.videoAll,false)) return
54 54
55 return next() 55 return next()
56 } 56 }
@@ -66,9 +66,9 @@ const addVideoCommentReplyValidator = [
66 66
67 if (areValidationErrors(req, res)) return 67 if (areValidationErrors(req, res)) return
68 if (!await doesVideoExist(req.params.videoId, res)) return 68 if (!await doesVideoExist(req.params.videoId, res)) return
69 if (!isVideoCommentsEnabled(res.locals.video, res)) return 69 if (!isVideoCommentsEnabled(res.locals.videoAll, res)) return
70 if (!await doesVideoCommentExist(req.params.commentId, res.locals.video, res)) return 70 if (!await doesVideoCommentExist(req.params.commentId, res.locals.videoAll, res)) return
71 if (!await isVideoCommentAccepted(req, res, true)) return 71 if (!await isVideoCommentAccepted(req, res, res.locals.videoAll, true)) return
72 72
73 return next() 73 return next()
74 } 74 }
@@ -83,7 +83,7 @@ const videoCommentGetValidator = [
83 83
84 if (areValidationErrors(req, res)) return 84 if (areValidationErrors(req, res)) return
85 if (!await doesVideoExist(req.params.videoId, res, 'id')) return 85 if (!await doesVideoExist(req.params.videoId, res, 'id')) return
86 if (!await doesVideoCommentExist(req.params.commentId, res.locals.video, res)) return 86 if (!await doesVideoCommentExist(req.params.commentId, res.locals.videoId, res)) return
87 87
88 return next() 88 return next()
89 } 89 }
@@ -98,10 +98,10 @@ const removeVideoCommentValidator = [
98 98
99 if (areValidationErrors(req, res)) return 99 if (areValidationErrors(req, res)) return
100 if (!await doesVideoExist(req.params.videoId, res)) return 100 if (!await doesVideoExist(req.params.videoId, res)) return
101 if (!await doesVideoCommentExist(req.params.commentId, res.locals.video, res)) return 101 if (!await doesVideoCommentExist(req.params.commentId, res.locals.videoAll, res)) return
102 102
103 // Check if the user who did the request is able to delete the video 103 // Check if the user who did the request is able to delete the video
104 if (!checkUserCanDeleteVideoComment(res.locals.oauth.token.User, res.locals.videoComment, res)) return 104 if (!checkUserCanDeleteVideoComment(res.locals.oauth.token.User, res.locals.videoCommentFull, res)) return
105 105
106 return next() 106 return next()
107 } 107 }
@@ -120,7 +120,7 @@ export {
120 120
121// --------------------------------------------------------------------------- 121// ---------------------------------------------------------------------------
122 122
123async function doesVideoCommentThreadExist (id: number, video: VideoModel, res: express.Response) { 123async function doesVideoCommentThreadExist (id: number, video: MVideoId, res: express.Response) {
124 const videoComment = await VideoCommentModel.loadById(id) 124 const videoComment = await VideoCommentModel.loadById(id)
125 125
126 if (!videoComment) { 126 if (!videoComment) {
@@ -151,7 +151,7 @@ async function doesVideoCommentThreadExist (id: number, video: VideoModel, res:
151 return true 151 return true
152} 152}
153 153
154async function doesVideoCommentExist (id: number, video: VideoModel, res: express.Response) { 154async function doesVideoCommentExist (id: number, video: MVideoId, res: express.Response) {
155 const videoComment = await VideoCommentModel.loadByIdAndPopulateVideoAndAccountAndReply(id) 155 const videoComment = await VideoCommentModel.loadByIdAndPopulateVideoAndAccountAndReply(id)
156 156
157 if (!videoComment) { 157 if (!videoComment) {
@@ -170,11 +170,11 @@ async function doesVideoCommentExist (id: number, video: VideoModel, res: expres
170 return false 170 return false
171 } 171 }
172 172
173 res.locals.videoComment = videoComment 173 res.locals.videoCommentFull = videoComment
174 return true 174 return true
175} 175}
176 176
177function isVideoCommentsEnabled (video: VideoModel, res: express.Response) { 177function isVideoCommentsEnabled (video: MVideo, res: express.Response) {
178 if (video.commentsEnabled !== true) { 178 if (video.commentsEnabled !== true) {
179 res.status(409) 179 res.status(409)
180 .json({ error: 'Video comments are disabled for this video.' }) 180 .json({ error: 'Video comments are disabled for this video.' })
@@ -186,7 +186,7 @@ function isVideoCommentsEnabled (video: VideoModel, res: express.Response) {
186 return true 186 return true
187} 187}
188 188
189function checkUserCanDeleteVideoComment (user: UserModel, videoComment: VideoCommentModel, res: express.Response) { 189function checkUserCanDeleteVideoComment (user: MUser, videoComment: MCommentOwner, res: express.Response) {
190 const account = videoComment.Account 190 const account = videoComment.Account
191 if (user.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT) === false && account.userId !== user.id) { 191 if (user.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT) === false && account.userId !== user.id) {
192 res.status(403) 192 res.status(403)
@@ -198,9 +198,9 @@ function checkUserCanDeleteVideoComment (user: UserModel, videoComment: VideoCom
198 return true 198 return true
199} 199}
200 200
201async function isVideoCommentAccepted (req: express.Request, res: express.Response, isReply: boolean) { 201async function isVideoCommentAccepted (req: express.Request, res: express.Response, video: MVideoFullLight, isReply: boolean) {
202 const acceptParameters = { 202 const acceptParameters = {
203 video: res.locals.video, 203 video,
204 commentBody: req.body, 204 commentBody: req.body,
205 user: res.locals.oauth.token.User 205 user: res.locals.oauth.token.User
206 } 206 }
@@ -208,7 +208,7 @@ async function isVideoCommentAccepted (req: express.Request, res: express.Respon
208 let acceptedResult: AcceptResult 208 let acceptedResult: AcceptResult
209 209
210 if (isReply) { 210 if (isReply) {
211 const acceptReplyParameters = Object.assign(acceptParameters, { parentComment: res.locals.videoComment }) 211 const acceptReplyParameters = Object.assign(acceptParameters, { parentComment: res.locals.videoCommentFull })
212 212
213 acceptedResult = await Hooks.wrapFun( 213 acceptedResult = await Hooks.wrapFun(
214 isLocalVideoCommentReplyAccepted, 214 isLocalVideoCommentReplyAccepted,
diff --git a/server/middlewares/validators/videos/video-playlists.ts b/server/middlewares/validators/videos/video-playlists.ts
index 5823795be..ca36d419a 100644
--- a/server/middlewares/validators/videos/video-playlists.ts
+++ b/server/middlewares/validators/videos/video-playlists.ts
@@ -2,7 +2,6 @@ import * as express from 'express'
2import { body, param, query, ValidationChain } from 'express-validator' 2import { body, param, query, ValidationChain } from 'express-validator'
3import { UserRight, VideoPlaylistCreate, VideoPlaylistUpdate } from '../../../../shared' 3import { UserRight, VideoPlaylistCreate, VideoPlaylistUpdate } from '../../../../shared'
4import { logger } from '../../../helpers/logger' 4import { logger } from '../../../helpers/logger'
5import { UserModel } from '../../../models/account/user'
6import { areValidationErrors } from '../utils' 5import { areValidationErrors } from '../utils'
7import { isVideoImage } from '../../../helpers/custom-validators/videos' 6import { isVideoImage } from '../../../helpers/custom-validators/videos'
8import { CONSTRAINTS_FIELDS } from '../../../initializers/constants' 7import { CONSTRAINTS_FIELDS } from '../../../initializers/constants'
@@ -22,13 +21,14 @@ import {
22 isVideoPlaylistTimestampValid, 21 isVideoPlaylistTimestampValid,
23 isVideoPlaylistTypeValid 22 isVideoPlaylistTypeValid
24} from '../../../helpers/custom-validators/video-playlists' 23} from '../../../helpers/custom-validators/video-playlists'
25import { VideoPlaylistModel } from '../../../models/video/video-playlist'
26import { cleanUpReqFiles } from '../../../helpers/express-utils' 24import { cleanUpReqFiles } from '../../../helpers/express-utils'
27import { VideoPlaylistElementModel } from '../../../models/video/video-playlist-element' 25import { VideoPlaylistElementModel } from '../../../models/video/video-playlist-element'
28import { authenticatePromiseIfNeeded } from '../../oauth' 26import { authenticatePromiseIfNeeded } from '../../oauth'
29import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model' 27import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model'
30import { VideoPlaylistType } from '../../../../shared/models/videos/playlist/video-playlist-type.model' 28import { VideoPlaylistType } from '../../../../shared/models/videos/playlist/video-playlist-type.model'
31import { doesVideoChannelIdExist, doesVideoExist, doesVideoPlaylistExist } from '../../../helpers/middlewares' 29import { doesVideoChannelIdExist, doesVideoExist, doesVideoPlaylistExist, VideoPlaylistFetchType } from '../../../helpers/middlewares'
30import { MVideoPlaylist } from '../../../typings/models/video/video-playlist'
31import { MUserAccountId } from '@server/typings/models'
32 32
33const videoPlaylistsAddValidator = getCommonPlaylistEditAttributes().concat([ 33const videoPlaylistsAddValidator = getCommonPlaylistEditAttributes().concat([
34 body('displayName') 34 body('displayName')
@@ -67,9 +67,9 @@ const videoPlaylistsUpdateValidator = getCommonPlaylistEditAttributes().concat([
67 67
68 if (!await doesVideoPlaylistExist(req.params.playlistId, res, 'all')) return cleanUpReqFiles(req) 68 if (!await doesVideoPlaylistExist(req.params.playlistId, res, 'all')) return cleanUpReqFiles(req)
69 69
70 const videoPlaylist = res.locals.videoPlaylist 70 const videoPlaylist = getPlaylist(res)
71 71
72 if (!checkUserCanManageVideoPlaylist(res.locals.oauth.token.User, res.locals.videoPlaylist, UserRight.REMOVE_ANY_VIDEO_PLAYLIST, res)) { 72 if (!checkUserCanManageVideoPlaylist(res.locals.oauth.token.User, videoPlaylist, UserRight.REMOVE_ANY_VIDEO_PLAYLIST, res)) {
73 return cleanUpReqFiles(req) 73 return cleanUpReqFiles(req)
74 } 74 }
75 75
@@ -110,13 +110,13 @@ const videoPlaylistsDeleteValidator = [
110 110
111 if (!await doesVideoPlaylistExist(req.params.playlistId, res)) return 111 if (!await doesVideoPlaylistExist(req.params.playlistId, res)) return
112 112
113 const videoPlaylist = res.locals.videoPlaylist 113 const videoPlaylist = getPlaylist(res)
114 if (videoPlaylist.type === VideoPlaylistType.WATCH_LATER) { 114 if (videoPlaylist.type === VideoPlaylistType.WATCH_LATER) {
115 return res.status(400) 115 return res.status(400)
116 .json({ error: 'Cannot delete a watch later playlist.' }) 116 .json({ error: 'Cannot delete a watch later playlist.' })
117 } 117 }
118 118
119 if (!checkUserCanManageVideoPlaylist(res.locals.oauth.token.User, res.locals.videoPlaylist, UserRight.REMOVE_ANY_VIDEO_PLAYLIST, res)) { 119 if (!checkUserCanManageVideoPlaylist(res.locals.oauth.token.User, videoPlaylist, UserRight.REMOVE_ANY_VIDEO_PLAYLIST, res)) {
120 return 120 return
121 } 121 }
122 122
@@ -124,45 +124,47 @@ const videoPlaylistsDeleteValidator = [
124 } 124 }
125] 125]
126 126
127const videoPlaylistsGetValidator = [ 127const videoPlaylistsGetValidator = (fetchType: VideoPlaylistFetchType) => {
128 param('playlistId') 128 return [
129 .custom(isIdOrUUIDValid).withMessage('Should have a valid playlist id/uuid'), 129 param('playlistId')
130 .custom(isIdOrUUIDValid).withMessage('Should have a valid playlist id/uuid'),
130 131
131 async (req: express.Request, res: express.Response, next: express.NextFunction) => { 132 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
132 logger.debug('Checking videoPlaylistsGetValidator parameters', { parameters: req.params }) 133 logger.debug('Checking videoPlaylistsGetValidator parameters', { parameters: req.params })
133 134
134 if (areValidationErrors(req, res)) return 135 if (areValidationErrors(req, res)) return
135 136
136 if (!await doesVideoPlaylistExist(req.params.playlistId, res)) return 137 if (!await doesVideoPlaylistExist(req.params.playlistId, res, fetchType)) return
137 138
138 const videoPlaylist = res.locals.videoPlaylist 139 const videoPlaylist = res.locals.videoPlaylistFull || res.locals.videoPlaylistSummary
139 140
140 // Video is unlisted, check we used the uuid to fetch it 141 // Video is unlisted, check we used the uuid to fetch it
141 if (videoPlaylist.privacy === VideoPlaylistPrivacy.UNLISTED) { 142 if (videoPlaylist.privacy === VideoPlaylistPrivacy.UNLISTED) {
142 if (isUUIDValid(req.params.playlistId)) return next() 143 if (isUUIDValid(req.params.playlistId)) return next()
143 144
144 return res.status(404).end() 145 return res.status(404).end()
145 } 146 }
146 147
147 if (videoPlaylist.privacy === VideoPlaylistPrivacy.PRIVATE) { 148 if (videoPlaylist.privacy === VideoPlaylistPrivacy.PRIVATE) {
148 await authenticatePromiseIfNeeded(req, res) 149 await authenticatePromiseIfNeeded(req, res)
149 150
150 const user = res.locals.oauth ? res.locals.oauth.token.User : null 151 const user = res.locals.oauth ? res.locals.oauth.token.User : null
151 152
152 if ( 153 if (
153 !user || 154 !user ||
154 (videoPlaylist.OwnerAccount.id !== user.Account.id && !user.hasRight(UserRight.UPDATE_ANY_VIDEO_PLAYLIST)) 155 (videoPlaylist.OwnerAccount.id !== user.Account.id && !user.hasRight(UserRight.UPDATE_ANY_VIDEO_PLAYLIST))
155 ) { 156 ) {
156 return res.status(403) 157 return res.status(403)
157 .json({ error: 'Cannot get this private video playlist.' }) 158 .json({ error: 'Cannot get this private video playlist.' })
159 }
160
161 return next()
158 } 162 }
159 163
160 return next() 164 return next()
161 } 165 }
162 166 ]
163 return next() 167}
164 }
165]
166 168
167const videoPlaylistsAddVideoValidator = [ 169const videoPlaylistsAddVideoValidator = [
168 param('playlistId') 170 param('playlistId')
@@ -184,8 +186,8 @@ const videoPlaylistsAddVideoValidator = [
184 if (!await doesVideoPlaylistExist(req.params.playlistId, res, 'all')) return 186 if (!await doesVideoPlaylistExist(req.params.playlistId, res, 'all')) return
185 if (!await doesVideoExist(req.body.videoId, res, 'only-video')) return 187 if (!await doesVideoExist(req.body.videoId, res, 'only-video')) return
186 188
187 const videoPlaylist = res.locals.videoPlaylist 189 const videoPlaylist = getPlaylist(res)
188 const video = res.locals.video 190 const video = res.locals.onlyVideo
189 191
190 const videoPlaylistElement = await VideoPlaylistElementModel.loadByPlaylistAndVideo(videoPlaylist.id, video.id) 192 const videoPlaylistElement = await VideoPlaylistElementModel.loadByPlaylistAndVideo(videoPlaylist.id, video.id)
191 if (videoPlaylistElement) { 193 if (videoPlaylistElement) {
@@ -196,7 +198,7 @@ const videoPlaylistsAddVideoValidator = [
196 return 198 return
197 } 199 }
198 200
199 if (!checkUserCanManageVideoPlaylist(res.locals.oauth.token.User, res.locals.videoPlaylist, UserRight.UPDATE_ANY_VIDEO_PLAYLIST, res)) { 201 if (!checkUserCanManageVideoPlaylist(res.locals.oauth.token.User, videoPlaylist, UserRight.UPDATE_ANY_VIDEO_PLAYLIST, res)) {
200 return 202 return
201 } 203 }
202 204
@@ -223,7 +225,7 @@ const videoPlaylistsUpdateOrRemoveVideoValidator = [
223 225
224 if (!await doesVideoPlaylistExist(req.params.playlistId, res, 'all')) return 226 if (!await doesVideoPlaylistExist(req.params.playlistId, res, 'all')) return
225 227
226 const videoPlaylist = res.locals.videoPlaylist 228 const videoPlaylist = getPlaylist(res)
227 229
228 const videoPlaylistElement = await VideoPlaylistElementModel.loadById(req.params.playlistElementId) 230 const videoPlaylistElement = await VideoPlaylistElementModel.loadById(req.params.playlistElementId)
229 if (!videoPlaylistElement) { 231 if (!videoPlaylistElement) {
@@ -289,7 +291,7 @@ const videoPlaylistsReorderVideosValidator = [
289 291
290 if (!await doesVideoPlaylistExist(req.params.playlistId, res, 'all')) return 292 if (!await doesVideoPlaylistExist(req.params.playlistId, res, 'all')) return
291 293
292 const videoPlaylist = res.locals.videoPlaylist 294 const videoPlaylist = getPlaylist(res)
293 if (!checkUserCanManageVideoPlaylist(res.locals.oauth.token.User, videoPlaylist, UserRight.UPDATE_ANY_VIDEO_PLAYLIST, res)) return 295 if (!checkUserCanManageVideoPlaylist(res.locals.oauth.token.User, videoPlaylist, UserRight.UPDATE_ANY_VIDEO_PLAYLIST, res)) return
294 296
295 const nextPosition = await VideoPlaylistElementModel.getNextPositionOf(videoPlaylist.id) 297 const nextPosition = await VideoPlaylistElementModel.getNextPositionOf(videoPlaylist.id)
@@ -388,7 +390,7 @@ function getCommonPlaylistEditAttributes () {
388 ] as (ValidationChain | express.Handler)[] 390 ] as (ValidationChain | express.Handler)[]
389} 391}
390 392
391function checkUserCanManageVideoPlaylist (user: UserModel, videoPlaylist: VideoPlaylistModel, right: UserRight, res: express.Response) { 393function checkUserCanManageVideoPlaylist (user: MUserAccountId, videoPlaylist: MVideoPlaylist, right: UserRight, res: express.Response) {
392 if (videoPlaylist.isOwned() === false) { 394 if (videoPlaylist.isOwned() === false) {
393 res.status(403) 395 res.status(403)
394 .json({ error: 'Cannot manage video playlist of another server.' }) 396 .json({ error: 'Cannot manage video playlist of another server.' })
@@ -410,3 +412,7 @@ function checkUserCanManageVideoPlaylist (user: UserModel, videoPlaylist: VideoP
410 412
411 return true 413 return true
412} 414}
415
416function getPlaylist (res: express.Response) {
417 return res.locals.videoPlaylistFull || res.locals.videoPlaylistSummary
418}
diff --git a/server/middlewares/validators/videos/video-shares.ts b/server/middlewares/validators/videos/video-shares.ts
index ace62be5c..20fc96243 100644
--- a/server/middlewares/validators/videos/video-shares.ts
+++ b/server/middlewares/validators/videos/video-shares.ts
@@ -16,7 +16,7 @@ const videosShareValidator = [
16 if (areValidationErrors(req, res)) return 16 if (areValidationErrors(req, res)) return
17 if (!await doesVideoExist(req.params.id, res)) return 17 if (!await doesVideoExist(req.params.id, res)) return
18 18
19 const video = res.locals.video 19 const video = res.locals.videoAll
20 20
21 const share = await VideoShareModel.load(req.params.actorId, video.id) 21 const share = await VideoShareModel.load(req.params.actorId, video.id)
22 if (!share) { 22 if (!share) {
diff --git a/server/middlewares/validators/videos/videos.ts b/server/middlewares/validators/videos/videos.ts
index af06f3c62..a194d14b3 100644
--- a/server/middlewares/validators/videos/videos.ts
+++ b/server/middlewares/validators/videos/videos.ts
@@ -37,13 +37,14 @@ import { VideoModel } from '../../../models/video/video'
37import { checkUserCanTerminateOwnershipChange, doesChangeVideoOwnershipExist } from '../../../helpers/custom-validators/video-ownership' 37import { checkUserCanTerminateOwnershipChange, doesChangeVideoOwnershipExist } from '../../../helpers/custom-validators/video-ownership'
38import { VideoChangeOwnershipAccept } from '../../../../shared/models/videos/video-change-ownership-accept.model' 38import { VideoChangeOwnershipAccept } from '../../../../shared/models/videos/video-change-ownership-accept.model'
39import { AccountModel } from '../../../models/account/account' 39import { AccountModel } from '../../../models/account/account'
40import { VideoFetchType } from '../../../helpers/video'
41import { isNSFWQueryValid, isNumberArray, isStringArray } from '../../../helpers/custom-validators/search' 40import { isNSFWQueryValid, isNumberArray, isStringArray } from '../../../helpers/custom-validators/search'
42import { getServerActor } from '../../../helpers/utils' 41import { getServerActor } from '../../../helpers/utils'
43import { CONFIG } from '../../../initializers/config' 42import { CONFIG } from '../../../initializers/config'
44import { isLocalVideoAccepted } from '../../../lib/moderation' 43import { isLocalVideoAccepted } from '../../../lib/moderation'
45import { Hooks } from '../../../lib/plugins/hooks' 44import { Hooks } from '../../../lib/plugins/hooks'
46import { checkUserCanManageVideo, doesVideoChannelOfAccountExist, doesVideoExist } from '../../../helpers/middlewares' 45import { checkUserCanManageVideo, doesVideoChannelOfAccountExist, doesVideoExist } from '../../../helpers/middlewares'
46import { MVideoFullLight } from '@server/typings/models'
47import { getVideo } from '../../../helpers/video'
47 48
48const videosAddValidator = getCommonVideoEditAttributes().concat([ 49const videosAddValidator = getCommonVideoEditAttributes().concat([
49 body('videofile') 50 body('videofile')
@@ -113,7 +114,7 @@ const videosUpdateValidator = getCommonVideoEditAttributes().concat([
113 114
114 // Check if the user who did the request is able to update the video 115 // Check if the user who did the request is able to update the video
115 const user = res.locals.oauth.token.User 116 const user = res.locals.oauth.token.User
116 if (!checkUserCanManageVideo(user, res.locals.video, UserRight.UPDATE_ANY_VIDEO, res)) return cleanUpReqFiles(req) 117 if (!checkUserCanManageVideo(user, res.locals.videoAll, UserRight.UPDATE_ANY_VIDEO, res)) return cleanUpReqFiles(req)
117 118
118 if (req.body.channelId && !await doesVideoChannelOfAccountExist(req.body.channelId, user, res)) return cleanUpReqFiles(req) 119 if (req.body.channelId && !await doesVideoChannelOfAccountExist(req.body.channelId, user, res)) return cleanUpReqFiles(req)
119 120
@@ -122,7 +123,7 @@ const videosUpdateValidator = getCommonVideoEditAttributes().concat([
122]) 123])
123 124
124async function checkVideoFollowConstraints (req: express.Request, res: express.Response, next: express.NextFunction) { 125async function checkVideoFollowConstraints (req: express.Request, res: express.Response, next: express.NextFunction) {
125 const video = res.locals.video 126 const video = getVideo(res)
126 127
127 // Anybody can watch local videos 128 // Anybody can watch local videos
128 if (video.isOwned() === true) return next() 129 if (video.isOwned() === true) return next()
@@ -146,7 +147,7 @@ async function checkVideoFollowConstraints (req: express.Request, res: express.R
146 }) 147 })
147} 148}
148 149
149const videosCustomGetValidator = (fetchType: VideoFetchType) => { 150const videosCustomGetValidator = (fetchType: 'all' | 'only-video' | 'only-video-with-rights') => {
150 return [ 151 return [
151 param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), 152 param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
152 153
@@ -156,10 +157,11 @@ const videosCustomGetValidator = (fetchType: VideoFetchType) => {
156 if (areValidationErrors(req, res)) return 157 if (areValidationErrors(req, res)) return
157 if (!await doesVideoExist(req.params.id, res, fetchType)) return 158 if (!await doesVideoExist(req.params.id, res, fetchType)) return
158 159
159 const video = res.locals.video 160 const video = getVideo(res)
161 const videoAll = video as MVideoFullLight
160 162
161 // Video private or blacklisted 163 // Video private or blacklisted
162 if (video.privacy === VideoPrivacy.PRIVATE || video.VideoBlacklist) { 164 if (video.privacy === VideoPrivacy.PRIVATE || videoAll.VideoBlacklist) {
163 await authenticatePromiseIfNeeded(req, res) 165 await authenticatePromiseIfNeeded(req, res)
164 166
165 const user = res.locals.oauth ? res.locals.oauth.token.User : null 167 const user = res.locals.oauth ? res.locals.oauth.token.User : null
@@ -167,7 +169,7 @@ const videosCustomGetValidator = (fetchType: VideoFetchType) => {
167 // Only the owner or a user that have blacklist rights can see the video 169 // Only the owner or a user that have blacklist rights can see the video
168 if ( 170 if (
169 !user || 171 !user ||
170 (video.VideoChannel.Account.userId !== user.id && !user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST)) 172 (videoAll.VideoChannel && videoAll.VideoChannel.Account.userId !== user.id && !user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST))
171 ) { 173 ) {
172 return res.status(403) 174 return res.status(403)
173 .json({ error: 'Cannot get this private or blacklisted video.' }) 175 .json({ error: 'Cannot get this private or blacklisted video.' })
@@ -202,7 +204,7 @@ const videosRemoveValidator = [
202 if (!await doesVideoExist(req.params.id, res)) return 204 if (!await doesVideoExist(req.params.id, res)) return
203 205
204 // Check if the user who did the request is able to delete the video 206 // Check if the user who did the request is able to delete the video
205 if (!checkUserCanManageVideo(res.locals.oauth.token.User, res.locals.video, UserRight.REMOVE_ANY_VIDEO, res)) return 207 if (!checkUserCanManageVideo(res.locals.oauth.token.User, res.locals.videoAll, UserRight.REMOVE_ANY_VIDEO, res)) return
206 208
207 return next() 209 return next()
208 } 210 }
@@ -218,7 +220,7 @@ const videosChangeOwnershipValidator = [
218 if (!await doesVideoExist(req.params.videoId, res)) return 220 if (!await doesVideoExist(req.params.videoId, res)) return
219 221
220 // Check if the user who did the request is able to change the ownership of the video 222 // Check if the user who did the request is able to change the ownership of the video
221 if (!checkUserCanManageVideo(res.locals.oauth.token.User, res.locals.video, UserRight.CHANGE_VIDEO_OWNERSHIP, res)) return 223 if (!checkUserCanManageVideo(res.locals.oauth.token.User, res.locals.videoAll, UserRight.CHANGE_VIDEO_OWNERSHIP, res)) return
222 224
223 const nextOwner = await AccountModel.loadLocalByName(req.body.username) 225 const nextOwner = await AccountModel.loadLocalByName(req.body.username)
224 if (!nextOwner) { 226 if (!nextOwner) {
diff --git a/server/middlewares/validators/webfinger.ts b/server/middlewares/validators/webfinger.ts
index d7cfe17f0..d50e6527f 100644
--- a/server/middlewares/validators/webfinger.ts
+++ b/server/middlewares/validators/webfinger.ts
@@ -18,6 +18,7 @@ const webfingerValidator = [
18 const nameWithHost = getHostWithPort(req.query.resource.substr(5)) 18 const nameWithHost = getHostWithPort(req.query.resource.substr(5))
19 const [ name ] = nameWithHost.split('@') 19 const [ name ] = nameWithHost.split('@')
20 20
21 // FIXME: we don't need the full actor
21 const actor = await ActorModel.loadLocalByName(name) 22 const actor = await ActorModel.loadLocalByName(name)
22 if (!actor) { 23 if (!actor) {
23 return res.status(404) 24 return res.status(404)
@@ -25,7 +26,7 @@ const webfingerValidator = [
25 .end() 26 .end()
26 } 27 }
27 28
28 res.locals.actor = actor 29 res.locals.actorFull = actor
29 return next() 30 return next()
30 } 31 }
31] 32]