aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/middlewares/validators
diff options
context:
space:
mode:
Diffstat (limited to 'server/middlewares/validators')
-rw-r--r--server/middlewares/validators/blocklist.ts172
-rw-r--r--server/middlewares/validators/index.ts6
-rw-r--r--server/middlewares/validators/search.ts38
-rw-r--r--server/middlewares/validators/server.ts33
-rw-r--r--server/middlewares/validators/sort.ts8
-rw-r--r--server/middlewares/validators/videos/index.ts8
-rw-r--r--server/middlewares/validators/videos/video-abuses.ts (renamed from server/middlewares/validators/video-abuses.ts)10
-rw-r--r--server/middlewares/validators/videos/video-blacklist.ts (renamed from server/middlewares/validators/video-blacklist.ts)10
-rw-r--r--server/middlewares/validators/videos/video-captions.ts (renamed from server/middlewares/validators/video-captions.ts)16
-rw-r--r--server/middlewares/validators/videos/video-channels.ts (renamed from server/middlewares/validators/video-channels.ts)18
-rw-r--r--server/middlewares/validators/videos/video-comments.ts (renamed from server/middlewares/validators/video-comments.ts)18
-rw-r--r--server/middlewares/validators/videos/video-imports.ts (renamed from server/middlewares/validators/video-imports.ts)16
-rw-r--r--server/middlewares/validators/videos/video-watch.ts28
-rw-r--r--server/middlewares/validators/videos/videos.ts (renamed from server/middlewares/validators/videos.ts)101
14 files changed, 368 insertions, 114 deletions
diff --git a/server/middlewares/validators/blocklist.ts b/server/middlewares/validators/blocklist.ts
new file mode 100644
index 000000000..109276c63
--- /dev/null
+++ b/server/middlewares/validators/blocklist.ts
@@ -0,0 +1,172 @@
1import { body, param } from 'express-validator/check'
2import * as express from 'express'
3import { logger } from '../../helpers/logger'
4import { areValidationErrors } from './utils'
5import { isAccountNameWithHostExist } from '../../helpers/custom-validators/accounts'
6import { UserModel } from '../../models/account/user'
7import { AccountBlocklistModel } from '../../models/account/account-blocklist'
8import { isHostValid } from '../../helpers/custom-validators/servers'
9import { ServerBlocklistModel } from '../../models/server/server-blocklist'
10import { ServerModel } from '../../models/server/server'
11import { CONFIG } from '../../initializers'
12import { getServerActor } from '../../helpers/utils'
13
14const blockAccountValidator = [
15 body('accountName').exists().withMessage('Should have an account name with host'),
16
17 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
18 logger.debug('Checking blockAccountByAccountValidator parameters', { parameters: req.body })
19
20 if (areValidationErrors(req, res)) return
21 if (!await isAccountNameWithHostExist(req.body.accountName, res)) return
22
23 const user = res.locals.oauth.token.User as UserModel
24 const accountToBlock = res.locals.account
25
26 if (user.Account.id === accountToBlock.id) {
27 res.status(409)
28 .send({ error: 'You cannot block yourself.' })
29 .end()
30
31 return
32 }
33
34 return next()
35 }
36]
37
38const unblockAccountByAccountValidator = [
39 param('accountName').exists().withMessage('Should have an account name with host'),
40
41 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
42 logger.debug('Checking unblockAccountByAccountValidator parameters', { parameters: req.params })
43
44 if (areValidationErrors(req, res)) return
45 if (!await isAccountNameWithHostExist(req.params.accountName, res)) return
46
47 const user = res.locals.oauth.token.User as UserModel
48 const targetAccount = res.locals.account
49 if (!await isUnblockAccountExists(user.Account.id, targetAccount.id, res)) return
50
51 return next()
52 }
53]
54
55const unblockAccountByServerValidator = [
56 param('accountName').exists().withMessage('Should have an account name with host'),
57
58 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
59 logger.debug('Checking unblockAccountByServerValidator parameters', { parameters: req.params })
60
61 if (areValidationErrors(req, res)) return
62 if (!await isAccountNameWithHostExist(req.params.accountName, res)) return
63
64 const serverActor = await getServerActor()
65 const targetAccount = res.locals.account
66 if (!await isUnblockAccountExists(serverActor.Account.id, targetAccount.id, res)) return
67
68 return next()
69 }
70]
71
72const blockServerValidator = [
73 body('host').custom(isHostValid).withMessage('Should have a valid host'),
74
75 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
76 logger.debug('Checking serverGetValidator parameters', { parameters: req.body })
77
78 if (areValidationErrors(req, res)) return
79
80 const host: string = req.body.host
81
82 if (host === CONFIG.WEBSERVER.HOST) {
83 return res.status(409)
84 .send({ error: 'You cannot block your own server.' })
85 .end()
86 }
87
88 const server = await ServerModel.loadByHost(host)
89 if (!server) {
90 return res.status(404)
91 .send({ error: 'Server host not found.' })
92 .end()
93 }
94
95 res.locals.server = server
96
97 return next()
98 }
99]
100
101const unblockServerByAccountValidator = [
102 param('host').custom(isHostValid).withMessage('Should have an account name with host'),
103
104 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
105 logger.debug('Checking unblockServerByAccountValidator parameters', { parameters: req.params })
106
107 if (areValidationErrors(req, res)) return
108
109 const user = res.locals.oauth.token.User as UserModel
110 if (!await isUnblockServerExists(user.Account.id, req.params.host, res)) return
111
112 return next()
113 }
114]
115
116const unblockServerByServerValidator = [
117 param('host').custom(isHostValid).withMessage('Should have an account name with host'),
118
119 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
120 logger.debug('Checking unblockServerByServerValidator parameters', { parameters: req.params })
121
122 if (areValidationErrors(req, res)) return
123
124 const serverActor = await getServerActor()
125 if (!await isUnblockServerExists(serverActor.Account.id, req.params.host, res)) return
126
127 return next()
128 }
129]
130
131// ---------------------------------------------------------------------------
132
133export {
134 blockServerValidator,
135 blockAccountValidator,
136 unblockAccountByAccountValidator,
137 unblockServerByAccountValidator,
138 unblockAccountByServerValidator,
139 unblockServerByServerValidator
140}
141
142// ---------------------------------------------------------------------------
143
144async function isUnblockAccountExists (accountId: number, targetAccountId: number, res: express.Response) {
145 const accountBlock = await AccountBlocklistModel.loadByAccountAndTarget(accountId, targetAccountId)
146 if (!accountBlock) {
147 res.status(404)
148 .send({ error: 'Account block entry not found.' })
149 .end()
150
151 return false
152 }
153
154 res.locals.accountBlock = accountBlock
155
156 return true
157}
158
159async function isUnblockServerExists (accountId: number, host: string, res: express.Response) {
160 const serverBlock = await ServerBlocklistModel.loadByAccountAndHost(accountId, host)
161 if (!serverBlock) {
162 res.status(404)
163 .send({ error: 'Server block entry not found.' })
164 .end()
165
166 return false
167 }
168
169 res.locals.serverBlock = serverBlock
170
171 return true
172}
diff --git a/server/middlewares/validators/index.ts b/server/middlewares/validators/index.ts
index 940547a3e..46c7f0f3a 100644
--- a/server/middlewares/validators/index.ts
+++ b/server/middlewares/validators/index.ts
@@ -1,4 +1,5 @@
1export * from './account' 1export * from './account'
2export * from './blocklist'
2export * from './oembed' 3export * from './oembed'
3export * from './activitypub' 4export * from './activitypub'
4export * from './pagination' 5export * from './pagination'
@@ -8,9 +9,6 @@ export * from './sort'
8export * from './users' 9export * from './users'
9export * from './user-subscriptions' 10export * from './user-subscriptions'
10export * from './videos' 11export * from './videos'
11export * from './video-abuses'
12export * from './video-blacklist'
13export * from './video-channels'
14export * from './webfinger' 12export * from './webfinger'
15export * from './search' 13export * from './search'
16export * from './video-imports' 14export * from './server'
diff --git a/server/middlewares/validators/search.ts b/server/middlewares/validators/search.ts
index 8baf643a5..6a95d6095 100644
--- a/server/middlewares/validators/search.ts
+++ b/server/middlewares/validators/search.ts
@@ -2,8 +2,7 @@ import * as express from 'express'
2import { areValidationErrors } from './utils' 2import { areValidationErrors } from './utils'
3import { logger } from '../../helpers/logger' 3import { logger } from '../../helpers/logger'
4import { query } from 'express-validator/check' 4import { query } from 'express-validator/check'
5import { isNumberArray, isStringArray, isNSFWQueryValid } from '../../helpers/custom-validators/search' 5import { isDateValid } from '../../helpers/custom-validators/misc'
6import { isBooleanValid, isDateValid, toArray } from '../../helpers/custom-validators/misc'
7 6
8const videosSearchValidator = [ 7const videosSearchValidator = [
9 query('search').optional().not().isEmpty().withMessage('Should have a valid search'), 8 query('search').optional().not().isEmpty().withMessage('Should have a valid search'),
@@ -35,44 +34,9 @@ const videoChannelsSearchValidator = [
35 } 34 }
36] 35]
37 36
38const commonVideosFiltersValidator = [
39 query('categoryOneOf')
40 .optional()
41 .customSanitizer(toArray)
42 .custom(isNumberArray).withMessage('Should have a valid one of category array'),
43 query('licenceOneOf')
44 .optional()
45 .customSanitizer(toArray)
46 .custom(isNumberArray).withMessage('Should have a valid one of licence array'),
47 query('languageOneOf')
48 .optional()
49 .customSanitizer(toArray)
50 .custom(isStringArray).withMessage('Should have a valid one of language array'),
51 query('tagsOneOf')
52 .optional()
53 .customSanitizer(toArray)
54 .custom(isStringArray).withMessage('Should have a valid one of tags array'),
55 query('tagsAllOf')
56 .optional()
57 .customSanitizer(toArray)
58 .custom(isStringArray).withMessage('Should have a valid all of tags array'),
59 query('nsfw')
60 .optional()
61 .custom(isNSFWQueryValid).withMessage('Should have a valid NSFW attribute'),
62
63 (req: express.Request, res: express.Response, next: express.NextFunction) => {
64 logger.debug('Checking commons video filters query', { parameters: req.query })
65
66 if (areValidationErrors(req, res)) return
67
68 return next()
69 }
70]
71
72// --------------------------------------------------------------------------- 37// ---------------------------------------------------------------------------
73 38
74export { 39export {
75 commonVideosFiltersValidator,
76 videoChannelsSearchValidator, 40 videoChannelsSearchValidator,
77 videosSearchValidator 41 videosSearchValidator
78} 42}
diff --git a/server/middlewares/validators/server.ts b/server/middlewares/validators/server.ts
new file mode 100644
index 000000000..a491dfeb3
--- /dev/null
+++ b/server/middlewares/validators/server.ts
@@ -0,0 +1,33 @@
1import * as express from 'express'
2import { logger } from '../../helpers/logger'
3import { areValidationErrors } from './utils'
4import { isHostValid } from '../../helpers/custom-validators/servers'
5import { ServerModel } from '../../models/server/server'
6import { body } from 'express-validator/check'
7
8const serverGetValidator = [
9 body('host').custom(isHostValid).withMessage('Should have a valid host'),
10
11 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
12 logger.debug('Checking serverGetValidator parameters', { parameters: req.body })
13
14 if (areValidationErrors(req, res)) return
15
16 const server = await ServerModel.loadByHost(req.body.host)
17 if (!server) {
18 return res.status(404)
19 .send({ error: 'Server host not found.' })
20 .end()
21 }
22
23 res.locals.server = server
24
25 return next()
26 }
27]
28
29// ---------------------------------------------------------------------------
30
31export {
32 serverGetValidator
33}
diff --git a/server/middlewares/validators/sort.ts b/server/middlewares/validators/sort.ts
index 08dcc2680..4c0577d8f 100644
--- a/server/middlewares/validators/sort.ts
+++ b/server/middlewares/validators/sort.ts
@@ -16,6 +16,8 @@ const SORTABLE_VIDEO_CHANNELS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.V
16const SORTABLE_FOLLOWERS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.FOLLOWERS) 16const SORTABLE_FOLLOWERS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.FOLLOWERS)
17const SORTABLE_FOLLOWING_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.FOLLOWING) 17const SORTABLE_FOLLOWING_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.FOLLOWING)
18const SORTABLE_USER_SUBSCRIPTIONS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.USER_SUBSCRIPTIONS) 18const SORTABLE_USER_SUBSCRIPTIONS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.USER_SUBSCRIPTIONS)
19const SORTABLE_ACCOUNTS_BLOCKLIST_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.ACCOUNTS_BLOCKLIST)
20const SORTABLE_SERVERS_BLOCKLIST_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.SERVERS_BLOCKLIST)
19 21
20const usersSortValidator = checkSort(SORTABLE_USERS_COLUMNS) 22const usersSortValidator = checkSort(SORTABLE_USERS_COLUMNS)
21const accountsSortValidator = checkSort(SORTABLE_ACCOUNTS_COLUMNS) 23const accountsSortValidator = checkSort(SORTABLE_ACCOUNTS_COLUMNS)
@@ -31,6 +33,8 @@ const videoChannelsSortValidator = checkSort(SORTABLE_VIDEO_CHANNELS_COLUMNS)
31const followersSortValidator = checkSort(SORTABLE_FOLLOWERS_COLUMNS) 33const followersSortValidator = checkSort(SORTABLE_FOLLOWERS_COLUMNS)
32const followingSortValidator = checkSort(SORTABLE_FOLLOWING_COLUMNS) 34const followingSortValidator = checkSort(SORTABLE_FOLLOWING_COLUMNS)
33const userSubscriptionsSortValidator = checkSort(SORTABLE_USER_SUBSCRIPTIONS_COLUMNS) 35const userSubscriptionsSortValidator = checkSort(SORTABLE_USER_SUBSCRIPTIONS_COLUMNS)
36const accountsBlocklistSortValidator = checkSort(SORTABLE_ACCOUNTS_BLOCKLIST_COLUMNS)
37const serversBlocklistSortValidator = checkSort(SORTABLE_SERVERS_BLOCKLIST_COLUMNS)
34 38
35// --------------------------------------------------------------------------- 39// ---------------------------------------------------------------------------
36 40
@@ -48,5 +52,7 @@ export {
48 jobsSortValidator, 52 jobsSortValidator,
49 videoCommentThreadsSortValidator, 53 videoCommentThreadsSortValidator,
50 userSubscriptionsSortValidator, 54 userSubscriptionsSortValidator,
51 videoChannelsSearchSortValidator 55 videoChannelsSearchSortValidator,
56 accountsBlocklistSortValidator,
57 serversBlocklistSortValidator
52} 58}
diff --git a/server/middlewares/validators/videos/index.ts b/server/middlewares/validators/videos/index.ts
new file mode 100644
index 000000000..294783d85
--- /dev/null
+++ b/server/middlewares/validators/videos/index.ts
@@ -0,0 +1,8 @@
1export * from './video-abuses'
2export * from './video-blacklist'
3export * from './video-captions'
4export * from './video-channels'
5export * from './video-comments'
6export * from './video-imports'
7export * from './video-watch'
8export * from './videos'
diff --git a/server/middlewares/validators/video-abuses.ts b/server/middlewares/validators/videos/video-abuses.ts
index f15d55a75..be26ca16a 100644
--- a/server/middlewares/validators/video-abuses.ts
+++ b/server/middlewares/validators/videos/video-abuses.ts
@@ -1,16 +1,16 @@
1import * as express from 'express' 1import * as express from 'express'
2import 'express-validator' 2import 'express-validator'
3import { body, param } from 'express-validator/check' 3import { body, param } from 'express-validator/check'
4import { isIdOrUUIDValid, isIdValid } from '../../helpers/custom-validators/misc' 4import { isIdOrUUIDValid, isIdValid } from '../../../helpers/custom-validators/misc'
5import { isVideoExist } from '../../helpers/custom-validators/videos' 5import { isVideoExist } from '../../../helpers/custom-validators/videos'
6import { logger } from '../../helpers/logger' 6import { logger } from '../../../helpers/logger'
7import { areValidationErrors } from './utils' 7import { areValidationErrors } from '../utils'
8import { 8import {
9 isVideoAbuseExist, 9 isVideoAbuseExist,
10 isVideoAbuseModerationCommentValid, 10 isVideoAbuseModerationCommentValid,
11 isVideoAbuseReasonValid, 11 isVideoAbuseReasonValid,
12 isVideoAbuseStateValid 12 isVideoAbuseStateValid
13} from '../../helpers/custom-validators/video-abuses' 13} from '../../../helpers/custom-validators/video-abuses'
14 14
15const videoAbuseReportValidator = [ 15const videoAbuseReportValidator = [
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'),
diff --git a/server/middlewares/validators/video-blacklist.ts b/server/middlewares/validators/videos/video-blacklist.ts
index 95a2b9f17..13da7acff 100644
--- a/server/middlewares/validators/video-blacklist.ts
+++ b/server/middlewares/validators/videos/video-blacklist.ts
@@ -1,10 +1,10 @@
1import * as express from 'express' 1import * as express from 'express'
2import { body, param } from 'express-validator/check' 2import { body, param } from 'express-validator/check'
3import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc' 3import { isIdOrUUIDValid } from '../../../helpers/custom-validators/misc'
4import { isVideoExist } from '../../helpers/custom-validators/videos' 4import { isVideoExist } from '../../../helpers/custom-validators/videos'
5import { logger } from '../../helpers/logger' 5import { logger } from '../../../helpers/logger'
6import { areValidationErrors } from './utils' 6import { areValidationErrors } from '../utils'
7import { isVideoBlacklistExist, isVideoBlacklistReasonValid } from '../../helpers/custom-validators/video-blacklist' 7import { isVideoBlacklistExist, isVideoBlacklistReasonValid } from '../../../helpers/custom-validators/video-blacklist'
8 8
9const videosBlacklistRemoveValidator = [ 9const videosBlacklistRemoveValidator = [
10 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'), 10 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
diff --git a/server/middlewares/validators/video-captions.ts b/server/middlewares/validators/videos/video-captions.ts
index 51ffd7f3c..63d84fbec 100644
--- a/server/middlewares/validators/video-captions.ts
+++ b/server/middlewares/validators/videos/video-captions.ts
@@ -1,13 +1,13 @@
1import * as express from 'express' 1import * as express from 'express'
2import { areValidationErrors } from './utils' 2import { areValidationErrors } from '../utils'
3import { checkUserCanManageVideo, isVideoExist } from '../../helpers/custom-validators/videos' 3import { checkUserCanManageVideo, isVideoExist } from '../../../helpers/custom-validators/videos'
4import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc' 4import { isIdOrUUIDValid } from '../../../helpers/custom-validators/misc'
5import { body, param } from 'express-validator/check' 5import { body, param } from 'express-validator/check'
6import { CONSTRAINTS_FIELDS } from '../../initializers' 6import { CONSTRAINTS_FIELDS } from '../../../initializers'
7import { UserRight } from '../../../shared' 7import { UserRight } from '../../../../shared'
8import { logger } from '../../helpers/logger' 8import { logger } from '../../../helpers/logger'
9import { isVideoCaptionExist, isVideoCaptionFile, isVideoCaptionLanguageValid } from '../../helpers/custom-validators/video-captions' 9import { isVideoCaptionExist, isVideoCaptionFile, isVideoCaptionLanguageValid } from '../../../helpers/custom-validators/video-captions'
10import { cleanUpReqFiles } from '../../helpers/express-utils' 10import { cleanUpReqFiles } from '../../../helpers/express-utils'
11 11
12const addVideoCaptionValidator = [ 12const addVideoCaptionValidator = [
13 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'), 13 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'),
diff --git a/server/middlewares/validators/video-channels.ts b/server/middlewares/validators/videos/video-channels.ts
index 56a347b39..f039794e0 100644
--- a/server/middlewares/validators/video-channels.ts
+++ b/server/middlewares/validators/videos/video-channels.ts
@@ -1,20 +1,20 @@
1import * as express from 'express' 1import * as express from 'express'
2import { body, param } from 'express-validator/check' 2import { body, param } from 'express-validator/check'
3import { UserRight } from '../../../shared' 3import { UserRight } from '../../../../shared'
4import { isAccountNameWithHostExist } from '../../helpers/custom-validators/accounts' 4import { isAccountNameWithHostExist } from '../../../helpers/custom-validators/accounts'
5import { 5import {
6 isLocalVideoChannelNameExist, 6 isLocalVideoChannelNameExist,
7 isVideoChannelDescriptionValid, 7 isVideoChannelDescriptionValid,
8 isVideoChannelNameValid, 8 isVideoChannelNameValid,
9 isVideoChannelNameWithHostExist, 9 isVideoChannelNameWithHostExist,
10 isVideoChannelSupportValid 10 isVideoChannelSupportValid
11} from '../../helpers/custom-validators/video-channels' 11} from '../../../helpers/custom-validators/video-channels'
12import { logger } from '../../helpers/logger' 12import { logger } from '../../../helpers/logger'
13import { UserModel } from '../../models/account/user' 13import { UserModel } from '../../../models/account/user'
14import { VideoChannelModel } from '../../models/video/video-channel' 14import { VideoChannelModel } from '../../../models/video/video-channel'
15import { areValidationErrors } from './utils' 15import { areValidationErrors } from '../utils'
16import { isActorPreferredUsernameValid } from '../../helpers/custom-validators/activitypub/actor' 16import { isActorPreferredUsernameValid } from '../../../helpers/custom-validators/activitypub/actor'
17import { ActorModel } from '../../models/activitypub/actor' 17import { ActorModel } from '../../../models/activitypub/actor'
18 18
19const listVideoAccountChannelsValidator = [ 19const listVideoAccountChannelsValidator = [
20 param('accountName').exists().withMessage('Should have a valid account name'), 20 param('accountName').exists().withMessage('Should have a valid account name'),
diff --git a/server/middlewares/validators/video-comments.ts b/server/middlewares/validators/videos/video-comments.ts
index 693852499..348d33082 100644
--- a/server/middlewares/validators/video-comments.ts
+++ b/server/middlewares/validators/videos/video-comments.ts
@@ -1,14 +1,14 @@
1import * as express from 'express' 1import * as express from 'express'
2import { body, param } from 'express-validator/check' 2import { body, param } from 'express-validator/check'
3import { UserRight } from '../../../shared' 3import { 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 { isVideoExist } from '../../helpers/custom-validators/videos' 6import { isVideoExist } from '../../../helpers/custom-validators/videos'
7import { logger } from '../../helpers/logger' 7import { logger } from '../../../helpers/logger'
8import { UserModel } from '../../models/account/user' 8import { UserModel } from '../../../models/account/user'
9import { VideoModel } from '../../models/video/video' 9import { VideoModel } from '../../../models/video/video'
10import { VideoCommentModel } from '../../models/video/video-comment' 10import { VideoCommentModel } from '../../../models/video/video-comment'
11import { areValidationErrors } from './utils' 11import { areValidationErrors } from '../utils'
12 12
13const listVideoCommentThreadsValidator = [ 13const listVideoCommentThreadsValidator = [
14 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'), 14 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
diff --git a/server/middlewares/validators/video-imports.ts b/server/middlewares/validators/videos/video-imports.ts
index b2063b8da..48d20f904 100644
--- a/server/middlewares/validators/video-imports.ts
+++ b/server/middlewares/validators/videos/video-imports.ts
@@ -1,14 +1,14 @@
1import * as express from 'express' 1import * as express from 'express'
2import { body } from 'express-validator/check' 2import { body } from 'express-validator/check'
3import { isIdValid } from '../../helpers/custom-validators/misc' 3import { isIdValid } from '../../../helpers/custom-validators/misc'
4import { logger } from '../../helpers/logger' 4import { logger } from '../../../helpers/logger'
5import { areValidationErrors } from './utils' 5import { areValidationErrors } from '../utils'
6import { getCommonVideoAttributes } from './videos' 6import { getCommonVideoAttributes } from './videos'
7import { isVideoImportTargetUrlValid, isVideoImportTorrentFile } from '../../helpers/custom-validators/video-imports' 7import { isVideoImportTargetUrlValid, isVideoImportTorrentFile } from '../../../helpers/custom-validators/video-imports'
8import { cleanUpReqFiles } from '../../helpers/express-utils' 8import { cleanUpReqFiles } from '../../../helpers/express-utils'
9import { isVideoChannelOfAccountExist, isVideoMagnetUriValid, isVideoNameValid } from '../../helpers/custom-validators/videos' 9import { isVideoChannelOfAccountExist, isVideoMagnetUriValid, isVideoNameValid } from '../../../helpers/custom-validators/videos'
10import { CONFIG } from '../../initializers/constants' 10import { CONFIG } from '../../../initializers/constants'
11import { CONSTRAINTS_FIELDS } from '../../initializers' 11import { CONSTRAINTS_FIELDS } from '../../../initializers'
12 12
13const videoImportAddValidator = getCommonVideoAttributes().concat([ 13const videoImportAddValidator = getCommonVideoAttributes().concat([
14 body('channelId') 14 body('channelId')
diff --git a/server/middlewares/validators/videos/video-watch.ts b/server/middlewares/validators/videos/video-watch.ts
new file mode 100644
index 000000000..bca64662f
--- /dev/null
+++ b/server/middlewares/validators/videos/video-watch.ts
@@ -0,0 +1,28 @@
1import { body, param } from 'express-validator/check'
2import * as express from 'express'
3import { isIdOrUUIDValid } from '../../../helpers/custom-validators/misc'
4import { isVideoExist } from '../../../helpers/custom-validators/videos'
5import { areValidationErrors } from '../utils'
6import { logger } from '../../../helpers/logger'
7
8const videoWatchingValidator = [
9 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
10 body('currentTime')
11 .toInt()
12 .isInt().withMessage('Should have correct current time'),
13
14 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
15 logger.debug('Checking videoWatching parameters', { parameters: req.body })
16
17 if (areValidationErrors(req, res)) return
18 if (!await isVideoExist(req.params.videoId, res, 'id')) return
19
20 return next()
21 }
22]
23
24// ---------------------------------------------------------------------------
25
26export {
27 videoWatchingValidator
28}
diff --git a/server/middlewares/validators/videos.ts b/server/middlewares/validators/videos/videos.ts
index 67eabe468..9dc52a134 100644
--- a/server/middlewares/validators/videos.ts
+++ b/server/middlewares/validators/videos/videos.ts
@@ -1,16 +1,17 @@
1import * as express from 'express' 1import * as express from 'express'
2import 'express-validator' 2import 'express-validator'
3import { body, param, ValidationChain } from 'express-validator/check' 3import { body, param, query, ValidationChain } from 'express-validator/check'
4import { UserRight, VideoChangeOwnershipStatus, VideoPrivacy } from '../../../shared' 4import { UserRight, VideoChangeOwnershipStatus, VideoPrivacy } from '../../../../shared'
5import { 5import {
6 isBooleanValid, 6 isBooleanValid,
7 isDateValid, 7 isDateValid,
8 isIdOrUUIDValid, 8 isIdOrUUIDValid,
9 isIdValid, 9 isIdValid,
10 isUUIDValid, 10 isUUIDValid,
11 toArray,
11 toIntOrNull, 12 toIntOrNull,
12 toValueOrNull 13 toValueOrNull
13} from '../../helpers/custom-validators/misc' 14} from '../../../helpers/custom-validators/misc'
14import { 15import {
15 checkUserCanManageVideo, 16 checkUserCanManageVideo,
16 isScheduleVideoUpdatePrivacyValid, 17 isScheduleVideoUpdatePrivacyValid,
@@ -19,6 +20,7 @@ import {
19 isVideoDescriptionValid, 20 isVideoDescriptionValid,
20 isVideoExist, 21 isVideoExist,
21 isVideoFile, 22 isVideoFile,
23 isVideoFilterValid,
22 isVideoImage, 24 isVideoImage,
23 isVideoLanguageValid, 25 isVideoLanguageValid,
24 isVideoLicenceValid, 26 isVideoLicenceValid,
@@ -27,21 +29,22 @@ import {
27 isVideoRatingTypeValid, 29 isVideoRatingTypeValid,
28 isVideoSupportValid, 30 isVideoSupportValid,
29 isVideoTagsValid 31 isVideoTagsValid
30} from '../../helpers/custom-validators/videos' 32} from '../../../helpers/custom-validators/videos'
31import { getDurationFromVideoFile } from '../../helpers/ffmpeg-utils' 33import { getDurationFromVideoFile } from '../../../helpers/ffmpeg-utils'
32import { logger } from '../../helpers/logger' 34import { logger } from '../../../helpers/logger'
33import { CONSTRAINTS_FIELDS } from '../../initializers' 35import { CONSTRAINTS_FIELDS } from '../../../initializers'
34import { VideoShareModel } from '../../models/video/video-share' 36import { VideoShareModel } from '../../../models/video/video-share'
35import { authenticate } from '../oauth' 37import { authenticate } from '../../oauth'
36import { areValidationErrors } from './utils' 38import { areValidationErrors } from '../utils'
37import { cleanUpReqFiles } from '../../helpers/express-utils' 39import { cleanUpReqFiles } from '../../../helpers/express-utils'
38import { VideoModel } from '../../models/video/video' 40import { VideoModel } from '../../../models/video/video'
39import { UserModel } from '../../models/account/user' 41import { UserModel } from '../../../models/account/user'
40import { checkUserCanTerminateOwnershipChange, doesChangeVideoOwnershipExist } from '../../helpers/custom-validators/video-ownership' 42import { checkUserCanTerminateOwnershipChange, doesChangeVideoOwnershipExist } from '../../../helpers/custom-validators/video-ownership'
41import { VideoChangeOwnershipAccept } from '../../../shared/models/videos/video-change-ownership-accept.model' 43import { VideoChangeOwnershipAccept } from '../../../../shared/models/videos/video-change-ownership-accept.model'
42import { VideoChangeOwnershipModel } from '../../models/video/video-change-ownership' 44import { VideoChangeOwnershipModel } from '../../../models/video/video-change-ownership'
43import { AccountModel } from '../../models/account/account' 45import { AccountModel } from '../../../models/account/account'
44import { VideoFetchType } from '../../helpers/video' 46import { VideoFetchType } from '../../../helpers/video'
47import { isNSFWQueryValid, isNumberArray, isStringArray } from '../../../helpers/custom-validators/search'
45 48
46const videosAddValidator = getCommonVideoAttributes().concat([ 49const videosAddValidator = getCommonVideoAttributes().concat([
47 body('videofile') 50 body('videofile')
@@ -69,7 +72,6 @@ const videosAddValidator = getCommonVideoAttributes().concat([
69 if (isAble === false) { 72 if (isAble === false) {
70 res.status(403) 73 res.status(403)
71 .json({ error: 'The user video quota is exceeded with this video.' }) 74 .json({ error: 'The user video quota is exceeded with this video.' })
72 .end()
73 75
74 return cleanUpReqFiles(req) 76 return cleanUpReqFiles(req)
75 } 77 }
@@ -82,7 +84,6 @@ const videosAddValidator = getCommonVideoAttributes().concat([
82 logger.error('Invalid input file in videosAddValidator.', { err }) 84 logger.error('Invalid input file in videosAddValidator.', { err })
83 res.status(400) 85 res.status(400)
84 .json({ error: 'Invalid input file.' }) 86 .json({ error: 'Invalid input file.' })
85 .end()
86 87
87 return cleanUpReqFiles(req) 88 return cleanUpReqFiles(req)
88 } 89 }
@@ -120,7 +121,6 @@ const videosUpdateValidator = getCommonVideoAttributes().concat([
120 cleanUpReqFiles(req) 121 cleanUpReqFiles(req)
121 return res.status(409) 122 return res.status(409)
122 .json({ error: 'Cannot set "private" a video that was not private.' }) 123 .json({ error: 'Cannot set "private" a video that was not private.' })
123 .end()
124 } 124 }
125 125
126 if (req.body.channelId && !await isVideoChannelOfAccountExist(req.body.channelId, user, res)) return cleanUpReqFiles(req) 126 if (req.body.channelId && !await isVideoChannelOfAccountExist(req.body.channelId, user, res)) return cleanUpReqFiles(req)
@@ -150,7 +150,6 @@ const videosCustomGetValidator = (fetchType: VideoFetchType) => {
150 if (video.VideoChannel.Account.userId !== user.id && !user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST)) { 150 if (video.VideoChannel.Account.userId !== user.id && !user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST)) {
151 return res.status(403) 151 return res.status(403)
152 .json({ error: 'Cannot get this private or blacklisted video.' }) 152 .json({ error: 'Cannot get this private or blacklisted video.' })
153 .end()
154 } 153 }
155 154
156 return next() 155 return next()
@@ -239,8 +238,8 @@ const videosChangeOwnershipValidator = [
239 const nextOwner = await AccountModel.loadLocalByName(req.body.username) 238 const nextOwner = await AccountModel.loadLocalByName(req.body.username)
240 if (!nextOwner) { 239 if (!nextOwner) {
241 res.status(400) 240 res.status(400)
242 .type('json') 241 .json({ error: 'Changing video ownership to a remote account is not supported yet' })
243 .end() 242
244 return 243 return
245 } 244 }
246 res.locals.nextOwner = nextOwner 245 res.locals.nextOwner = nextOwner
@@ -271,7 +270,7 @@ const videosTerminateChangeOwnershipValidator = [
271 } else { 270 } else {
272 res.status(403) 271 res.status(403)
273 .json({ error: 'Ownership already accepted or refused' }) 272 .json({ error: 'Ownership already accepted or refused' })
274 .end() 273
275 return 274 return
276 } 275 }
277 } 276 }
@@ -288,7 +287,7 @@ const videosAcceptChangeOwnershipValidator = [
288 if (isAble === false) { 287 if (isAble === false) {
289 res.status(403) 288 res.status(403)
290 .json({ error: 'The user video quota is exceeded with this video.' }) 289 .json({ error: 'The user video quota is exceeded with this video.' })
291 .end() 290
292 return 291 return
293 } 292 }
294 293
@@ -363,6 +362,51 @@ function getCommonVideoAttributes () {
363 ] as (ValidationChain | express.Handler)[] 362 ] as (ValidationChain | express.Handler)[]
364} 363}
365 364
365const commonVideosFiltersValidator = [
366 query('categoryOneOf')
367 .optional()
368 .customSanitizer(toArray)
369 .custom(isNumberArray).withMessage('Should have a valid one of category array'),
370 query('licenceOneOf')
371 .optional()
372 .customSanitizer(toArray)
373 .custom(isNumberArray).withMessage('Should have a valid one of licence array'),
374 query('languageOneOf')
375 .optional()
376 .customSanitizer(toArray)
377 .custom(isStringArray).withMessage('Should have a valid one of language array'),
378 query('tagsOneOf')
379 .optional()
380 .customSanitizer(toArray)
381 .custom(isStringArray).withMessage('Should have a valid one of tags array'),
382 query('tagsAllOf')
383 .optional()
384 .customSanitizer(toArray)
385 .custom(isStringArray).withMessage('Should have a valid all of tags array'),
386 query('nsfw')
387 .optional()
388 .custom(isNSFWQueryValid).withMessage('Should have a valid NSFW attribute'),
389 query('filter')
390 .optional()
391 .custom(isVideoFilterValid).withMessage('Should have a valid filter attribute'),
392
393 (req: express.Request, res: express.Response, next: express.NextFunction) => {
394 logger.debug('Checking commons video filters query', { parameters: req.query })
395
396 if (areValidationErrors(req, res)) return
397
398 const user: UserModel = res.locals.oauth ? res.locals.oauth.token.User : undefined
399 if (req.query.filter === 'all-local' && (!user || user.hasRight(UserRight.SEE_ALL_VIDEOS) === false)) {
400 res.status(401)
401 .json({ error: 'You are not allowed to see all local videos.' })
402
403 return
404 }
405
406 return next()
407 }
408]
409
366// --------------------------------------------------------------------------- 410// ---------------------------------------------------------------------------
367 411
368export { 412export {
@@ -379,7 +423,9 @@ export {
379 videosTerminateChangeOwnershipValidator, 423 videosTerminateChangeOwnershipValidator,
380 videosAcceptChangeOwnershipValidator, 424 videosAcceptChangeOwnershipValidator,
381 425
382 getCommonVideoAttributes 426 getCommonVideoAttributes,
427
428 commonVideosFiltersValidator
383} 429}
384 430
385// --------------------------------------------------------------------------- 431// ---------------------------------------------------------------------------
@@ -389,7 +435,6 @@ function areErrorsInScheduleUpdate (req: express.Request, res: express.Response)
389 if (!req.body.scheduleUpdate.updateAt) { 435 if (!req.body.scheduleUpdate.updateAt) {
390 res.status(400) 436 res.status(400)
391 .json({ error: 'Schedule update at is mandatory.' }) 437 .json({ error: 'Schedule update at is mandatory.' })
392 .end()
393 438
394 return true 439 return true
395 } 440 }