aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/middlewares
diff options
context:
space:
mode:
Diffstat (limited to 'server/middlewares')
-rw-r--r--server/middlewares/auth.ts27
-rw-r--r--server/middlewares/doc.ts2
-rw-r--r--server/middlewares/error.ts6
-rw-r--r--server/middlewares/rate-limiter.ts28
-rw-r--r--server/middlewares/validators/config.ts2
-rw-r--r--server/middlewares/validators/runners/index.ts3
-rw-r--r--server/middlewares/validators/runners/job-files.ts27
-rw-r--r--server/middlewares/validators/runners/jobs.ts156
-rw-r--r--server/middlewares/validators/runners/registration-token.ts37
-rw-r--r--server/middlewares/validators/runners/runners.ts95
-rw-r--r--server/middlewares/validators/sort.ts4
-rw-r--r--server/middlewares/validators/videos/video-live.ts9
-rw-r--r--server/middlewares/validators/videos/video-studio.ts2
-rw-r--r--server/middlewares/validators/videos/videos.ts2
14 files changed, 387 insertions, 13 deletions
diff --git a/server/middlewares/auth.ts b/server/middlewares/auth.ts
index e6025c8ce..0eefa2a8e 100644
--- a/server/middlewares/auth.ts
+++ b/server/middlewares/auth.ts
@@ -1,6 +1,7 @@
1import express from 'express' 1import express from 'express'
2import { Socket } from 'socket.io' 2import { Socket } from 'socket.io'
3import { getAccessToken } from '@server/lib/auth/oauth-model' 3import { getAccessToken } from '@server/lib/auth/oauth-model'
4import { RunnerModel } from '@server/models/runner/runner'
4import { HttpStatusCode } from '../../shared/models/http/http-error-codes' 5import { HttpStatusCode } from '../../shared/models/http/http-error-codes'
5import { logger } from '../helpers/logger' 6import { logger } from '../helpers/logger'
6import { handleOAuthAuthenticate } from '../lib/auth/oauth' 7import { handleOAuthAuthenticate } from '../lib/auth/oauth'
@@ -27,7 +28,7 @@ function authenticate (req: express.Request, res: express.Response, next: expres
27function authenticateSocket (socket: Socket, next: (err?: any) => void) { 28function authenticateSocket (socket: Socket, next: (err?: any) => void) {
28 const accessToken = socket.handshake.query['accessToken'] 29 const accessToken = socket.handshake.query['accessToken']
29 30
30 logger.debug('Checking socket access token %s.', accessToken) 31 logger.debug('Checking access token in runner.')
31 32
32 if (!accessToken) return next(new Error('No access token provided')) 33 if (!accessToken) return next(new Error('No access token provided'))
33 if (typeof accessToken !== 'string') return next(new Error('Access token is invalid')) 34 if (typeof accessToken !== 'string') return next(new Error('Access token is invalid'))
@@ -73,9 +74,31 @@ function optionalAuthenticate (req: express.Request, res: express.Response, next
73 74
74// --------------------------------------------------------------------------- 75// ---------------------------------------------------------------------------
75 76
77function authenticateRunnerSocket (socket: Socket, next: (err?: any) => void) {
78 const runnerToken = socket.handshake.auth['runnerToken']
79
80 logger.debug('Checking runner token in socket.')
81
82 if (!runnerToken) return next(new Error('No runner token provided'))
83 if (typeof runnerToken !== 'string') return next(new Error('Runner token is invalid'))
84
85 RunnerModel.loadByToken(runnerToken)
86 .then(runner => {
87 if (!runner) return next(new Error('Invalid runner token.'))
88
89 socket.handshake.auth.runner = runner
90
91 return next()
92 })
93 .catch(err => logger.error('Cannot get runner token.', { err }))
94}
95
96// ---------------------------------------------------------------------------
97
76export { 98export {
77 authenticate, 99 authenticate,
78 authenticateSocket, 100 authenticateSocket,
79 authenticatePromise, 101 authenticatePromise,
80 optionalAuthenticate 102 optionalAuthenticate,
103 authenticateRunnerSocket
81} 104}
diff --git a/server/middlewares/doc.ts b/server/middlewares/doc.ts
index c43f41977..eef76acaa 100644
--- a/server/middlewares/doc.ts
+++ b/server/middlewares/doc.ts
@@ -5,7 +5,7 @@ function openapiOperationDoc (options: {
5 operationId?: string 5 operationId?: string
6}) { 6}) {
7 return (req: express.Request, res: express.Response, next: express.NextFunction) => { 7 return (req: express.Request, res: express.Response, next: express.NextFunction) => {
8 res.locals.docUrl = options.url || 'https://docs.joinpeertube.org/api/rest-reference.html#operation/' + options.operationId 8 res.locals.docUrl = options.url || 'https://docs.joinpeertube.org/api-rest-reference.html#operation/' + options.operationId
9 9
10 if (next) return next() 10 if (next) return next()
11 } 11 }
diff --git a/server/middlewares/error.ts b/server/middlewares/error.ts
index 540edaeeb..94762e355 100644
--- a/server/middlewares/error.ts
+++ b/server/middlewares/error.ts
@@ -5,7 +5,7 @@ import { HttpStatusCode } from '@shared/models'
5 5
6function apiFailMiddleware (req: express.Request, res: express.Response, next: express.NextFunction) { 6function apiFailMiddleware (req: express.Request, res: express.Response, next: express.NextFunction) {
7 res.fail = options => { 7 res.fail = options => {
8 const { status = HttpStatusCode.BAD_REQUEST_400, message, title, type, data, instance } = options 8 const { status = HttpStatusCode.BAD_REQUEST_400, message, title, type, data, instance, tags } = options
9 9
10 const extension = new ProblemDocumentExtension({ 10 const extension = new ProblemDocumentExtension({
11 ...data, 11 ...data,
@@ -31,11 +31,11 @@ function apiFailMiddleware (req: express.Request, res: express.Response, next: e
31 detail: message, 31 detail: message,
32 32
33 type: type 33 type: type
34 ? `https://docs.joinpeertube.org/api/rest-reference.html#section/Errors/${type}` 34 ? `https://docs.joinpeertube.org/api-rest-reference.html#section/Errors/${type}`
35 : undefined 35 : undefined
36 }, extension) 36 }, extension)
37 37
38 logger.debug('Bad HTTP request.', { json }) 38 logger.debug('Bad HTTP request.', { json, tags })
39 39
40 res.json(json) 40 res.json(json)
41 } 41 }
diff --git a/server/middlewares/rate-limiter.ts b/server/middlewares/rate-limiter.ts
index bc9513969..1eef8b360 100644
--- a/server/middlewares/rate-limiter.ts
+++ b/server/middlewares/rate-limiter.ts
@@ -1,10 +1,12 @@
1import express from 'express'
2import RateLimit, { Options as RateLimitHandlerOptions } from 'express-rate-limit'
3import { RunnerModel } from '@server/models/runner/runner'
1import { UserRole } from '@shared/models' 4import { UserRole } from '@shared/models'
2import RateLimit from 'express-rate-limit'
3import { optionalAuthenticate } from './auth' 5import { optionalAuthenticate } from './auth'
4 6
5const whitelistRoles = new Set([ UserRole.ADMINISTRATOR, UserRole.MODERATOR ]) 7const whitelistRoles = new Set([ UserRole.ADMINISTRATOR, UserRole.MODERATOR ])
6 8
7function buildRateLimiter (options: { 9export function buildRateLimiter (options: {
8 windowMs: number 10 windowMs: number
9 max: number 11 max: number
10 skipFailedRequests?: boolean 12 skipFailedRequests?: boolean
@@ -15,17 +17,33 @@ function buildRateLimiter (options: {
15 skipFailedRequests: options.skipFailedRequests, 17 skipFailedRequests: options.skipFailedRequests,
16 18
17 handler: (req, res, next, options) => { 19 handler: (req, res, next, options) => {
20 // Bypass rate limit for registered runners
21 if (req.body?.runnerToken) {
22 return RunnerModel.loadByToken(req.body.runnerToken)
23 .then(runner => {
24 if (runner) return next()
25
26 return sendRateLimited(res, options)
27 })
28 }
29
30 // Bypass rate limit for admins/moderators
18 return optionalAuthenticate(req, res, () => { 31 return optionalAuthenticate(req, res, () => {
19 if (res.locals.authenticated === true && whitelistRoles.has(res.locals.oauth.token.User.role)) { 32 if (res.locals.authenticated === true && whitelistRoles.has(res.locals.oauth.token.User.role)) {
20 return next() 33 return next()
21 } 34 }
22 35
23 return res.status(options.statusCode).send(options.message) 36 return sendRateLimited(res, options)
24 }) 37 })
25 } 38 }
26 }) 39 })
27} 40}
28 41
29export { 42// ---------------------------------------------------------------------------
30 buildRateLimiter 43// Private
44// ---------------------------------------------------------------------------
45
46function sendRateLimited (res: express.Response, options: RateLimitHandlerOptions) {
47 return res.status(options.statusCode).send(options.message)
48
31} 49}
diff --git a/server/middlewares/validators/config.ts b/server/middlewares/validators/config.ts
index 4a9d1cb54..b3e7e5011 100644
--- a/server/middlewares/validators/config.ts
+++ b/server/middlewares/validators/config.ts
@@ -54,6 +54,7 @@ const customConfigUpdateValidator = [
54 body('transcoding.resolutions.1080p').isBoolean(), 54 body('transcoding.resolutions.1080p').isBoolean(),
55 body('transcoding.resolutions.1440p').isBoolean(), 55 body('transcoding.resolutions.1440p').isBoolean(),
56 body('transcoding.resolutions.2160p').isBoolean(), 56 body('transcoding.resolutions.2160p').isBoolean(),
57 body('transcoding.remoteRunners.enabled').isBoolean(),
57 58
58 body('transcoding.alwaysTranscodeOriginalResolution').isBoolean(), 59 body('transcoding.alwaysTranscodeOriginalResolution').isBoolean(),
59 60
@@ -97,6 +98,7 @@ const customConfigUpdateValidator = [
97 body('live.transcoding.resolutions.1440p').isBoolean(), 98 body('live.transcoding.resolutions.1440p').isBoolean(),
98 body('live.transcoding.resolutions.2160p').isBoolean(), 99 body('live.transcoding.resolutions.2160p').isBoolean(),
99 body('live.transcoding.alwaysTranscodeOriginalResolution').isBoolean(), 100 body('live.transcoding.alwaysTranscodeOriginalResolution').isBoolean(),
101 body('live.transcoding.remoteRunners.enabled').isBoolean(),
100 102
101 body('search.remoteUri.users').isBoolean(), 103 body('search.remoteUri.users').isBoolean(),
102 body('search.remoteUri.anonymous').isBoolean(), 104 body('search.remoteUri.anonymous').isBoolean(),
diff --git a/server/middlewares/validators/runners/index.ts b/server/middlewares/validators/runners/index.ts
new file mode 100644
index 000000000..9a9629a80
--- /dev/null
+++ b/server/middlewares/validators/runners/index.ts
@@ -0,0 +1,3 @@
1export * from './jobs'
2export * from './registration-token'
3export * from './runners'
diff --git a/server/middlewares/validators/runners/job-files.ts b/server/middlewares/validators/runners/job-files.ts
new file mode 100644
index 000000000..56afa39aa
--- /dev/null
+++ b/server/middlewares/validators/runners/job-files.ts
@@ -0,0 +1,27 @@
1import express from 'express'
2import { HttpStatusCode } from '@shared/models'
3import { areValidationErrors, doesVideoExist, isValidVideoIdParam } from '../shared'
4
5const tags = [ 'runner' ]
6
7export const runnerJobGetVideoTranscodingFileValidator = [
8 isValidVideoIdParam('videoId'),
9
10 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
11 if (areValidationErrors(req, res)) return
12
13 if (!await doesVideoExist(req.params.videoId, res, 'all')) return
14
15 const runnerJob = res.locals.runnerJob
16
17 if (runnerJob.privatePayload.videoUUID !== res.locals.videoAll.uuid) {
18 return res.fail({
19 status: HttpStatusCode.FORBIDDEN_403,
20 message: 'Job is not associated to this video',
21 tags: [ ...tags, res.locals.videoAll.uuid ]
22 })
23 }
24
25 return next()
26 }
27]
diff --git a/server/middlewares/validators/runners/jobs.ts b/server/middlewares/validators/runners/jobs.ts
new file mode 100644
index 000000000..8cb87e946
--- /dev/null
+++ b/server/middlewares/validators/runners/jobs.ts
@@ -0,0 +1,156 @@
1import express from 'express'
2import { body, param } from 'express-validator'
3import { isUUIDValid } from '@server/helpers/custom-validators/misc'
4import {
5 isRunnerJobAbortReasonValid,
6 isRunnerJobErrorMessageValid,
7 isRunnerJobProgressValid,
8 isRunnerJobSuccessPayloadValid,
9 isRunnerJobTokenValid,
10 isRunnerJobUpdatePayloadValid
11} from '@server/helpers/custom-validators/runners/jobs'
12import { isRunnerTokenValid } from '@server/helpers/custom-validators/runners/runners'
13import { cleanUpReqFiles } from '@server/helpers/express-utils'
14import { RunnerJobModel } from '@server/models/runner/runner-job'
15import { HttpStatusCode, RunnerJobState, RunnerJobSuccessBody, RunnerJobUpdateBody, ServerErrorCode } from '@shared/models'
16import { areValidationErrors } from '../shared'
17
18const tags = [ 'runner' ]
19
20export const acceptRunnerJobValidator = [
21 (req: express.Request, res: express.Response, next: express.NextFunction) => {
22 if (res.locals.runnerJob.state !== RunnerJobState.PENDING) {
23 return res.fail({
24 status: HttpStatusCode.BAD_REQUEST_400,
25 message: 'This runner job is not in pending state',
26 tags
27 })
28 }
29
30 return next()
31 }
32]
33
34export const abortRunnerJobValidator = [
35 body('reason').custom(isRunnerJobAbortReasonValid),
36
37 (req: express.Request, res: express.Response, next: express.NextFunction) => {
38 if (areValidationErrors(req, res, { tags })) return
39
40 return next()
41 }
42]
43
44export const updateRunnerJobValidator = [
45 body('progress').optional().custom(isRunnerJobProgressValid),
46
47 (req: express.Request, res: express.Response, next: express.NextFunction) => {
48 if (areValidationErrors(req, res, { tags })) return cleanUpReqFiles(req)
49
50 const body = req.body as RunnerJobUpdateBody
51
52 if (isRunnerJobUpdatePayloadValid(body.payload, res.locals.runnerJob.type, req.files) !== true) {
53 cleanUpReqFiles(req)
54
55 return res.fail({
56 status: HttpStatusCode.BAD_REQUEST_400,
57 message: 'Payload is invalid',
58 tags
59 })
60 }
61
62 return next()
63 }
64]
65
66export const errorRunnerJobValidator = [
67 body('message').custom(isRunnerJobErrorMessageValid),
68
69 (req: express.Request, res: express.Response, next: express.NextFunction) => {
70 if (areValidationErrors(req, res, { tags })) return
71
72 return next()
73 }
74]
75
76export const successRunnerJobValidator = [
77 (req: express.Request, res: express.Response, next: express.NextFunction) => {
78 const body = req.body as RunnerJobSuccessBody
79
80 if (isRunnerJobSuccessPayloadValid(body.payload, res.locals.runnerJob.type, req.files) !== true) {
81 cleanUpReqFiles(req)
82
83 return res.fail({
84 status: HttpStatusCode.BAD_REQUEST_400,
85 message: 'Payload is invalid',
86 tags
87 })
88 }
89
90 return next()
91 }
92]
93
94export const runnerJobGetValidator = [
95 param('jobUUID').custom(isUUIDValid),
96
97 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
98 if (areValidationErrors(req, res, { tags })) return
99
100 const runnerJob = await RunnerJobModel.loadWithRunner(req.params.jobUUID)
101
102 if (!runnerJob) {
103 return res.fail({
104 status: HttpStatusCode.NOT_FOUND_404,
105 message: 'Unknown runner job',
106 tags
107 })
108 }
109
110 res.locals.runnerJob = runnerJob
111
112 return next()
113 }
114]
115
116export const jobOfRunnerGetValidator = [
117 param('jobUUID').custom(isUUIDValid),
118
119 body('runnerToken').custom(isRunnerTokenValid),
120 body('jobToken').custom(isRunnerJobTokenValid),
121
122 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
123 if (areValidationErrors(req, res, { tags })) return cleanUpReqFiles(req)
124
125 const runnerJob = await RunnerJobModel.loadByRunnerAndJobTokensWithRunner({
126 uuid: req.params.jobUUID,
127 runnerToken: req.body.runnerToken,
128 jobToken: req.body.jobToken
129 })
130
131 if (!runnerJob) {
132 cleanUpReqFiles(req)
133
134 return res.fail({
135 status: HttpStatusCode.NOT_FOUND_404,
136 message: 'Unknown runner job',
137 tags
138 })
139 }
140
141 if (runnerJob.state !== RunnerJobState.PROCESSING) {
142 cleanUpReqFiles(req)
143
144 return res.fail({
145 status: HttpStatusCode.BAD_REQUEST_400,
146 type: ServerErrorCode.RUNNER_JOB_NOT_IN_PROCESSING_STATE,
147 message: 'Job is not in "processing" state',
148 tags
149 })
150 }
151
152 res.locals.runnerJob = runnerJob
153
154 return next()
155 }
156]
diff --git a/server/middlewares/validators/runners/registration-token.ts b/server/middlewares/validators/runners/registration-token.ts
new file mode 100644
index 000000000..cc31d4a7e
--- /dev/null
+++ b/server/middlewares/validators/runners/registration-token.ts
@@ -0,0 +1,37 @@
1import express from 'express'
2import { param } from 'express-validator'
3import { isIdValid } from '@server/helpers/custom-validators/misc'
4import { RunnerRegistrationTokenModel } from '@server/models/runner/runner-registration-token'
5import { forceNumber } from '@shared/core-utils'
6import { HttpStatusCode } from '@shared/models'
7import { areValidationErrors } from '../shared/utils'
8
9const tags = [ 'runner' ]
10
11const deleteRegistrationTokenValidator = [
12 param('id').custom(isIdValid),
13
14 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
15 if (areValidationErrors(req, res, { tags })) return
16
17 const registrationToken = await RunnerRegistrationTokenModel.load(forceNumber(req.params.id))
18
19 if (!registrationToken) {
20 return res.fail({
21 status: HttpStatusCode.NOT_FOUND_404,
22 message: 'Registration token not found',
23 tags
24 })
25 }
26
27 res.locals.runnerRegistrationToken = registrationToken
28
29 return next()
30 }
31]
32
33// ---------------------------------------------------------------------------
34
35export {
36 deleteRegistrationTokenValidator
37}
diff --git a/server/middlewares/validators/runners/runners.ts b/server/middlewares/validators/runners/runners.ts
new file mode 100644
index 000000000..71a1275d2
--- /dev/null
+++ b/server/middlewares/validators/runners/runners.ts
@@ -0,0 +1,95 @@
1import express from 'express'
2import { body, param } from 'express-validator'
3import { isIdValid } from '@server/helpers/custom-validators/misc'
4import {
5 isRunnerDescriptionValid,
6 isRunnerNameValid,
7 isRunnerRegistrationTokenValid,
8 isRunnerTokenValid
9} from '@server/helpers/custom-validators/runners/runners'
10import { RunnerModel } from '@server/models/runner/runner'
11import { RunnerRegistrationTokenModel } from '@server/models/runner/runner-registration-token'
12import { forceNumber } from '@shared/core-utils'
13import { HttpStatusCode, RegisterRunnerBody, ServerErrorCode } from '@shared/models'
14import { areValidationErrors } from '../shared/utils'
15
16const tags = [ 'runner' ]
17
18const registerRunnerValidator = [
19 body('registrationToken').custom(isRunnerRegistrationTokenValid),
20 body('name').custom(isRunnerNameValid),
21 body('description').optional().custom(isRunnerDescriptionValid),
22
23 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
24 if (areValidationErrors(req, res, { tags })) return
25
26 const body: RegisterRunnerBody = req.body
27
28 const runnerRegistrationToken = await RunnerRegistrationTokenModel.loadByRegistrationToken(body.registrationToken)
29
30 if (!runnerRegistrationToken) {
31 return res.fail({
32 status: HttpStatusCode.NOT_FOUND_404,
33 message: 'Registration token is invalid',
34 tags
35 })
36 }
37
38 res.locals.runnerRegistrationToken = runnerRegistrationToken
39
40 return next()
41 }
42]
43
44const deleteRunnerValidator = [
45 param('runnerId').custom(isIdValid),
46
47 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
48 if (areValidationErrors(req, res, { tags })) return
49
50 const runner = await RunnerModel.load(forceNumber(req.params.runnerId))
51
52 if (!runner) {
53 return res.fail({
54 status: HttpStatusCode.NOT_FOUND_404,
55 message: 'Runner not found',
56 tags
57 })
58 }
59
60 res.locals.runner = runner
61
62 return next()
63 }
64]
65
66const getRunnerFromTokenValidator = [
67 body('runnerToken').custom(isRunnerTokenValid),
68
69 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
70 if (areValidationErrors(req, res, { tags })) return
71
72 const runner = await RunnerModel.loadByToken(req.body.runnerToken)
73
74 if (!runner) {
75 return res.fail({
76 status: HttpStatusCode.NOT_FOUND_404,
77 message: 'Unknown runner token',
78 type: ServerErrorCode.UNKNOWN_RUNNER_TOKEN,
79 tags
80 })
81 }
82
83 res.locals.runner = runner
84
85 return next()
86 }
87]
88
89// ---------------------------------------------------------------------------
90
91export {
92 registerRunnerValidator,
93 deleteRunnerValidator,
94 getRunnerFromTokenValidator
95}
diff --git a/server/middlewares/validators/sort.ts b/server/middlewares/validators/sort.ts
index e6cc46317..959f663ac 100644
--- a/server/middlewares/validators/sort.ts
+++ b/server/middlewares/validators/sort.ts
@@ -34,6 +34,10 @@ export const videoChannelsFollowersSortValidator = checkSortFactory(SORTABLE_COL
34 34
35export const userRegistrationsSortValidator = checkSortFactory(SORTABLE_COLUMNS.USER_REGISTRATIONS) 35export const userRegistrationsSortValidator = checkSortFactory(SORTABLE_COLUMNS.USER_REGISTRATIONS)
36 36
37export const runnersSortValidator = checkSortFactory(SORTABLE_COLUMNS.RUNNERS)
38export const runnerRegistrationTokensSortValidator = checkSortFactory(SORTABLE_COLUMNS.RUNNER_REGISTRATION_TOKENS)
39export const runnerJobsSortValidator = checkSortFactory(SORTABLE_COLUMNS.RUNNER_JOBS)
40
37// --------------------------------------------------------------------------- 41// ---------------------------------------------------------------------------
38 42
39function checkSortFactory (columns: string[], tags: string[] = []) { 43function checkSortFactory (columns: string[], tags: string[] = []) {
diff --git a/server/middlewares/validators/videos/video-live.ts b/server/middlewares/validators/videos/video-live.ts
index e80fe1593..2aff831a8 100644
--- a/server/middlewares/validators/videos/video-live.ts
+++ b/server/middlewares/validators/videos/video-live.ts
@@ -115,6 +115,15 @@ const videoLiveAddValidator = getCommonVideoEditAttributes().concat([
115 }) 115 })
116 } 116 }
117 117
118 if (body.saveReplay && !body.replaySettings?.privacy) {
119 cleanUpReqFiles(req)
120
121 return res.fail({
122 status: HttpStatusCode.BAD_REQUEST_400,
123 message: 'Live replay is enabled but privacy replay setting is missing'
124 })
125 }
126
118 const user = res.locals.oauth.token.User 127 const user = res.locals.oauth.token.User
119 if (!await doesVideoChannelOfAccountExist(body.channelId, user, res)) return cleanUpReqFiles(req) 128 if (!await doesVideoChannelOfAccountExist(body.channelId, user, res)) return cleanUpReqFiles(req)
120 129
diff --git a/server/middlewares/validators/videos/video-studio.ts b/server/middlewares/validators/videos/video-studio.ts
index b3e2d8101..4397e887e 100644
--- a/server/middlewares/validators/videos/video-studio.ts
+++ b/server/middlewares/validators/videos/video-studio.ts
@@ -10,7 +10,7 @@ import {
10import { cleanUpReqFiles } from '@server/helpers/express-utils' 10import { cleanUpReqFiles } from '@server/helpers/express-utils'
11import { CONFIG } from '@server/initializers/config' 11import { CONFIG } from '@server/initializers/config'
12import { approximateIntroOutroAdditionalSize, getTaskFile } from '@server/lib/video-studio' 12import { approximateIntroOutroAdditionalSize, getTaskFile } from '@server/lib/video-studio'
13import { isAudioFile } from '@shared/extra-utils' 13import { isAudioFile } from '@shared/ffmpeg'
14import { HttpStatusCode, UserRight, VideoState, VideoStudioCreateEdition, VideoStudioTask } from '@shared/models' 14import { HttpStatusCode, UserRight, VideoState, VideoStudioCreateEdition, VideoStudioTask } from '@shared/models'
15import { areValidationErrors, checkUserCanManageVideo, checkUserQuota, doesVideoExist } from '../shared' 15import { areValidationErrors, checkUserCanManageVideo, checkUserQuota, doesVideoExist } from '../shared'
16 16
diff --git a/server/middlewares/validators/videos/videos.ts b/server/middlewares/validators/videos/videos.ts
index d3014e8e7..794e1d4f1 100644
--- a/server/middlewares/validators/videos/videos.ts
+++ b/server/middlewares/validators/videos/videos.ts
@@ -7,6 +7,7 @@ import { getServerActor } from '@server/models/application/application'
7import { ExpressPromiseHandler } from '@server/types/express-handler' 7import { ExpressPromiseHandler } from '@server/types/express-handler'
8import { MUserAccountId, MVideoFullLight } from '@server/types/models' 8import { MUserAccountId, MVideoFullLight } from '@server/types/models'
9import { arrayify, getAllPrivacies } from '@shared/core-utils' 9import { arrayify, getAllPrivacies } from '@shared/core-utils'
10import { getVideoStreamDuration } from '@shared/ffmpeg'
10import { HttpStatusCode, ServerErrorCode, UserRight, VideoInclude, VideoState } from '@shared/models' 11import { HttpStatusCode, ServerErrorCode, UserRight, VideoInclude, VideoState } from '@shared/models'
11import { 12import {
12 exists, 13 exists,
@@ -37,7 +38,6 @@ import {
37 isVideoSupportValid 38 isVideoSupportValid
38} from '../../../helpers/custom-validators/videos' 39} from '../../../helpers/custom-validators/videos'
39import { cleanUpReqFiles } from '../../../helpers/express-utils' 40import { cleanUpReqFiles } from '../../../helpers/express-utils'
40import { getVideoStreamDuration } from '../../../helpers/ffmpeg'
41import { logger } from '../../../helpers/logger' 41import { logger } from '../../../helpers/logger'
42import { deleteFileAndCatch } from '../../../helpers/utils' 42import { deleteFileAndCatch } from '../../../helpers/utils'
43import { getVideoWithAttributes } from '../../../helpers/video' 43import { getVideoWithAttributes } from '../../../helpers/video'