aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/controllers
diff options
context:
space:
mode:
Diffstat (limited to 'server/controllers')
-rw-r--r--server/controllers/api/abuse.ts15
-rw-r--r--server/controllers/api/blocklist.ts108
-rw-r--r--server/controllers/api/config.ts12
-rw-r--r--server/controllers/api/index.ts2
-rw-r--r--server/controllers/api/plugins.ts7
-rw-r--r--server/controllers/api/server/stats.ts4
-rw-r--r--server/controllers/api/users/my-subscriptions.ts21
-rw-r--r--server/controllers/api/videos/import.ts17
-rw-r--r--server/controllers/api/videos/live.ts4
-rw-r--r--server/controllers/api/videos/update.ts32
-rw-r--r--server/controllers/api/videos/upload.ts12
11 files changed, 196 insertions, 38 deletions
diff --git a/server/controllers/api/abuse.ts b/server/controllers/api/abuse.ts
index 72c418e74..a6d0b0512 100644
--- a/server/controllers/api/abuse.ts
+++ b/server/controllers/api/abuse.ts
@@ -167,7 +167,11 @@ async function reportAbuse (req: express.Request, res: express.Response) {
167 const body: AbuseCreate = req.body 167 const body: AbuseCreate = req.body
168 168
169 const { id } = await sequelizeTypescript.transaction(async t => { 169 const { id } = await sequelizeTypescript.transaction(async t => {
170 const reporterAccount = await AccountModel.load(res.locals.oauth.token.User.Account.id, t) 170 const user = res.locals.oauth.token.User
171 // Don't send abuse notification if reporter is an admin/moderator
172 const skipNotification = user.hasRight(UserRight.MANAGE_ABUSES)
173
174 const reporterAccount = await AccountModel.load(user.Account.id, t)
171 const predefinedReasons = body.predefinedReasons?.map(r => abusePredefinedReasonsMap[r]) 175 const predefinedReasons = body.predefinedReasons?.map(r => abusePredefinedReasonsMap[r])
172 176
173 const baseAbuse = { 177 const baseAbuse = {
@@ -184,7 +188,8 @@ async function reportAbuse (req: express.Request, res: express.Response) {
184 reporterAccount, 188 reporterAccount,
185 transaction: t, 189 transaction: t,
186 startAt: body.video.startAt, 190 startAt: body.video.startAt,
187 endAt: body.video.endAt 191 endAt: body.video.endAt,
192 skipNotification
188 }) 193 })
189 } 194 }
190 195
@@ -193,7 +198,8 @@ async function reportAbuse (req: express.Request, res: express.Response) {
193 baseAbuse, 198 baseAbuse,
194 commentInstance, 199 commentInstance,
195 reporterAccount, 200 reporterAccount,
196 transaction: t 201 transaction: t,
202 skipNotification
197 }) 203 })
198 } 204 }
199 205
@@ -202,7 +208,8 @@ async function reportAbuse (req: express.Request, res: express.Response) {
202 baseAbuse, 208 baseAbuse,
203 accountInstance, 209 accountInstance,
204 reporterAccount, 210 reporterAccount,
205 transaction: t 211 transaction: t,
212 skipNotification
206 }) 213 })
207 }) 214 })
208 215
diff --git a/server/controllers/api/blocklist.ts b/server/controllers/api/blocklist.ts
new file mode 100644
index 000000000..1e936ad10
--- /dev/null
+++ b/server/controllers/api/blocklist.ts
@@ -0,0 +1,108 @@
1import express from 'express'
2import { handleToNameAndHost } from '@server/helpers/actors'
3import { AccountBlocklistModel } from '@server/models/account/account-blocklist'
4import { getServerActor } from '@server/models/application/application'
5import { ServerBlocklistModel } from '@server/models/server/server-blocklist'
6import { MActorAccountId, MUserAccountId } from '@server/types/models'
7import { BlockStatus } from '@shared/models'
8import { asyncMiddleware, blocklistStatusValidator, optionalAuthenticate } from '../../middlewares'
9import { logger } from '@server/helpers/logger'
10
11const blocklistRouter = express.Router()
12
13blocklistRouter.get('/status',
14 optionalAuthenticate,
15 blocklistStatusValidator,
16 asyncMiddleware(getBlocklistStatus)
17)
18
19// ---------------------------------------------------------------------------
20
21export {
22 blocklistRouter
23}
24
25// ---------------------------------------------------------------------------
26
27async function getBlocklistStatus (req: express.Request, res: express.Response) {
28 const hosts = req.query.hosts as string[]
29 const accounts = req.query.accounts as string[]
30 const user = res.locals.oauth?.token.User
31
32 const serverActor = await getServerActor()
33
34 const byAccountIds = [ serverActor.Account.id ]
35 if (user) byAccountIds.push(user.Account.id)
36
37 const status: BlockStatus = {
38 accounts: {},
39 hosts: {}
40 }
41
42 const baseOptions = {
43 byAccountIds,
44 user,
45 serverActor,
46 status
47 }
48
49 await Promise.all([
50 populateServerBlocklistStatus({ ...baseOptions, hosts }),
51 populateAccountBlocklistStatus({ ...baseOptions, accounts })
52 ])
53
54 return res.json(status)
55}
56
57async function populateServerBlocklistStatus (options: {
58 byAccountIds: number[]
59 user?: MUserAccountId
60 serverActor: MActorAccountId
61 hosts: string[]
62 status: BlockStatus
63}) {
64 const { byAccountIds, user, serverActor, hosts, status } = options
65
66 if (!hosts || hosts.length === 0) return
67
68 const serverBlocklistStatus = await ServerBlocklistModel.getBlockStatus(byAccountIds, hosts)
69
70 logger.debug('Got server blocklist status.', { serverBlocklistStatus, byAccountIds, hosts })
71
72 for (const host of hosts) {
73 const block = serverBlocklistStatus.find(b => b.host === host)
74
75 status.hosts[host] = getStatus(block, serverActor, user)
76 }
77}
78
79async function populateAccountBlocklistStatus (options: {
80 byAccountIds: number[]
81 user?: MUserAccountId
82 serverActor: MActorAccountId
83 accounts: string[]
84 status: BlockStatus
85}) {
86 const { byAccountIds, user, serverActor, accounts, status } = options
87
88 if (!accounts || accounts.length === 0) return
89
90 const accountBlocklistStatus = await AccountBlocklistModel.getBlockStatus(byAccountIds, accounts)
91
92 logger.debug('Got account blocklist status.', { accountBlocklistStatus, byAccountIds, accounts })
93
94 for (const account of accounts) {
95 const sanitizedHandle = handleToNameAndHost(account)
96
97 const block = accountBlocklistStatus.find(b => b.name === sanitizedHandle.name && b.host === sanitizedHandle.host)
98
99 status.accounts[sanitizedHandle.handle] = getStatus(block, serverActor, user)
100 }
101}
102
103function getStatus (block: { accountId: number }, serverActor: MActorAccountId, user?: MUserAccountId) {
104 return {
105 blockedByServer: !!(block && block.accountId === serverActor.Account.id),
106 blockedByUser: !!(block && user && block.accountId === user.Account.id)
107 }
108}
diff --git a/server/controllers/api/config.ts b/server/controllers/api/config.ts
index 805ad99c7..b253db397 100644
--- a/server/controllers/api/config.ts
+++ b/server/controllers/api/config.ts
@@ -169,6 +169,18 @@ function customConfig (): CustomConfig {
169 whitelisted: CONFIG.SERVICES.TWITTER.WHITELISTED 169 whitelisted: CONFIG.SERVICES.TWITTER.WHITELISTED
170 } 170 }
171 }, 171 },
172 client: {
173 videos: {
174 miniature: {
175 preferAuthorDisplayName: CONFIG.CLIENT.VIDEOS.MINIATURE.PREFER_AUTHOR_DISPLAY_NAME
176 }
177 },
178 menu: {
179 login: {
180 redirectOnSingleExternalAuth: CONFIG.CLIENT.MENU.LOGIN.REDIRECT_ON_SINGLE_EXTERNAL_AUTH
181 }
182 }
183 },
172 cache: { 184 cache: {
173 previews: { 185 previews: {
174 size: CONFIG.CACHE.PREVIEWS.SIZE 186 size: CONFIG.CACHE.PREVIEWS.SIZE
diff --git a/server/controllers/api/index.ts b/server/controllers/api/index.ts
index 9949b378a..5f49336b1 100644
--- a/server/controllers/api/index.ts
+++ b/server/controllers/api/index.ts
@@ -6,6 +6,7 @@ import { badRequest } from '../../helpers/express-utils'
6import { CONFIG } from '../../initializers/config' 6import { CONFIG } from '../../initializers/config'
7import { abuseRouter } from './abuse' 7import { abuseRouter } from './abuse'
8import { accountsRouter } from './accounts' 8import { accountsRouter } from './accounts'
9import { blocklistRouter } from './blocklist'
9import { bulkRouter } from './bulk' 10import { bulkRouter } from './bulk'
10import { configRouter } from './config' 11import { configRouter } from './config'
11import { customPageRouter } from './custom-page' 12import { customPageRouter } from './custom-page'
@@ -49,6 +50,7 @@ apiRouter.use('/search', searchRouter)
49apiRouter.use('/overviews', overviewsRouter) 50apiRouter.use('/overviews', overviewsRouter)
50apiRouter.use('/plugins', pluginRouter) 51apiRouter.use('/plugins', pluginRouter)
51apiRouter.use('/custom-pages', customPageRouter) 52apiRouter.use('/custom-pages', customPageRouter)
53apiRouter.use('/blocklist', blocklistRouter)
52apiRouter.use('/ping', pong) 54apiRouter.use('/ping', pong)
53apiRouter.use('/*', badRequest) 55apiRouter.use('/*', badRequest)
54 56
diff --git a/server/controllers/api/plugins.ts b/server/controllers/api/plugins.ts
index 2de7fe41f..de9e055dc 100644
--- a/server/controllers/api/plugins.ts
+++ b/server/controllers/api/plugins.ts
@@ -144,8 +144,13 @@ async function installPlugin (req: express.Request, res: express.Response) {
144 144
145 const fromDisk = !!body.path 145 const fromDisk = !!body.path
146 const toInstall = body.npmName || body.path 146 const toInstall = body.npmName || body.path
147
148 const pluginVersion = body.pluginVersion && body.npmName
149 ? body.pluginVersion
150 : undefined
151
147 try { 152 try {
148 const plugin = await PluginManager.Instance.install(toInstall, undefined, fromDisk) 153 const plugin = await PluginManager.Instance.install(toInstall, pluginVersion, fromDisk)
149 154
150 return res.json(plugin.toFormattedJSON()) 155 return res.json(plugin.toFormattedJSON())
151 } catch (err) { 156 } catch (err) {
diff --git a/server/controllers/api/server/stats.ts b/server/controllers/api/server/stats.ts
index d661144ca..2ab398f4d 100644
--- a/server/controllers/api/server/stats.ts
+++ b/server/controllers/api/server/stats.ts
@@ -3,6 +3,7 @@ import { StatsManager } from '@server/lib/stat-manager'
3import { ROUTE_CACHE_LIFETIME } from '../../../initializers/constants' 3import { ROUTE_CACHE_LIFETIME } from '../../../initializers/constants'
4import { asyncMiddleware } from '../../../middlewares' 4import { asyncMiddleware } from '../../../middlewares'
5import { cacheRoute } from '../../../middlewares/cache/cache' 5import { cacheRoute } from '../../../middlewares/cache/cache'
6import { Hooks } from '@server/lib/plugins/hooks'
6 7
7const statsRouter = express.Router() 8const statsRouter = express.Router()
8 9
@@ -12,7 +13,8 @@ statsRouter.get('/stats',
12) 13)
13 14
14async function getStats (_req: express.Request, res: express.Response) { 15async function getStats (_req: express.Request, res: express.Response) {
15 const data = await StatsManager.Instance.getStats() 16 let data = await StatsManager.Instance.getStats()
17 data = await Hooks.wrapObject(data, 'filter:api.server.stats.get.result')
16 18
17 return res.json(data) 19 return res.json(data)
18} 20}
diff --git a/server/controllers/api/users/my-subscriptions.ts b/server/controllers/api/users/my-subscriptions.ts
index 6799ca8c5..fb1f68635 100644
--- a/server/controllers/api/users/my-subscriptions.ts
+++ b/server/controllers/api/users/my-subscriptions.ts
@@ -1,5 +1,6 @@
1import 'multer' 1import 'multer'
2import express from 'express' 2import express from 'express'
3import { handlesToNameAndHost } from '@server/helpers/actors'
3import { pickCommonVideoQuery } from '@server/helpers/query' 4import { pickCommonVideoQuery } from '@server/helpers/query'
4import { sendUndoFollow } from '@server/lib/activitypub/send' 5import { sendUndoFollow } from '@server/lib/activitypub/send'
5import { guessAdditionalAttributesFromQuery } from '@server/models/video/formatter/video-format-utils' 6import { guessAdditionalAttributesFromQuery } from '@server/models/video/formatter/video-format-utils'
@@ -7,7 +8,6 @@ import { VideoChannelModel } from '@server/models/video/video-channel'
7import { HttpStatusCode } from '../../../../shared/models/http/http-error-codes' 8import { HttpStatusCode } from '../../../../shared/models/http/http-error-codes'
8import { buildNSFWFilter, getCountVideos } from '../../../helpers/express-utils' 9import { buildNSFWFilter, getCountVideos } from '../../../helpers/express-utils'
9import { getFormattedObjects } from '../../../helpers/utils' 10import { getFormattedObjects } from '../../../helpers/utils'
10import { WEBSERVER } from '../../../initializers/constants'
11import { sequelizeTypescript } from '../../../initializers/database' 11import { sequelizeTypescript } from '../../../initializers/database'
12import { JobQueue } from '../../../lib/job-queue' 12import { JobQueue } from '../../../lib/job-queue'
13import { 13import {
@@ -89,28 +89,23 @@ async function areSubscriptionsExist (req: express.Request, res: express.Respons
89 const uris = req.query.uris as string[] 89 const uris = req.query.uris as string[]
90 const user = res.locals.oauth.token.User 90 const user = res.locals.oauth.token.User
91 91
92 const handles = uris.map(u => { 92 const sanitizedHandles = handlesToNameAndHost(uris)
93 let [ name, host ] = u.split('@')
94 if (host === WEBSERVER.HOST) host = null
95 93
96 return { name, host, uri: u } 94 const results = await ActorFollowModel.listSubscriptionsOf(user.Account.Actor.id, sanitizedHandles)
97 })
98
99 const results = await ActorFollowModel.listSubscriptionsOf(user.Account.Actor.id, handles)
100 95
101 const existObject: { [id: string ]: boolean } = {} 96 const existObject: { [id: string ]: boolean } = {}
102 for (const handle of handles) { 97 for (const sanitizedHandle of sanitizedHandles) {
103 const obj = results.find(r => { 98 const obj = results.find(r => {
104 const server = r.ActorFollowing.Server 99 const server = r.ActorFollowing.Server
105 100
106 return r.ActorFollowing.preferredUsername === handle.name && 101 return r.ActorFollowing.preferredUsername === sanitizedHandle.name &&
107 ( 102 (
108 (!server && !handle.host) || 103 (!server && !sanitizedHandle.host) ||
109 (server.host === handle.host) 104 (server.host === sanitizedHandle.host)
110 ) 105 )
111 }) 106 })
112 107
113 existObject[handle.uri] = obj !== undefined 108 existObject[sanitizedHandle.handle] = obj !== undefined
114 } 109 }
115 110
116 return res.json(existObject) 111 return res.json(existObject)
diff --git a/server/controllers/api/videos/import.ts b/server/controllers/api/videos/import.ts
index eddb9b32d..52864bdfd 100644
--- a/server/controllers/api/videos/import.ts
+++ b/server/controllers/api/videos/import.ts
@@ -38,6 +38,7 @@ import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoIm
38import { VideoModel } from '../../../models/video/video' 38import { VideoModel } from '../../../models/video/video'
39import { VideoCaptionModel } from '../../../models/video/video-caption' 39import { VideoCaptionModel } from '../../../models/video/video-caption'
40import { VideoImportModel } from '../../../models/video/video-import' 40import { VideoImportModel } from '../../../models/video/video-import'
41import { Hooks } from '@server/lib/plugins/hooks'
41 42
42const auditLogger = auditLoggerFactory('video-imports') 43const auditLogger = auditLoggerFactory('video-imports')
43const videoImportsRouter = express.Router() 44const videoImportsRouter = express.Router()
@@ -94,7 +95,7 @@ async function addTorrentImport (req: express.Request, res: express.Response, to
94 videoName = result.name 95 videoName = result.name
95 } 96 }
96 97
97 const video = buildVideo(res.locals.videoChannel.id, body, { name: videoName }) 98 const video = await buildVideo(res.locals.videoChannel.id, body, { name: videoName })
98 99
99 const thumbnailModel = await processThumbnail(req, video) 100 const thumbnailModel = await processThumbnail(req, video)
100 const previewModel = await processPreview(req, video) 101 const previewModel = await processPreview(req, video)
@@ -151,7 +152,7 @@ async function addYoutubeDLImport (req: express.Request, res: express.Response)
151 }) 152 })
152 } 153 }
153 154
154 const video = buildVideo(res.locals.videoChannel.id, body, youtubeDLInfo) 155 const video = await buildVideo(res.locals.videoChannel.id, body, youtubeDLInfo)
155 156
156 // Process video thumbnail from request.files 157 // Process video thumbnail from request.files
157 let thumbnailModel = await processThumbnail(req, video) 158 let thumbnailModel = await processThumbnail(req, video)
@@ -210,8 +211,8 @@ async function addYoutubeDLImport (req: express.Request, res: express.Response)
210 return res.json(videoImport.toFormattedJSON()).end() 211 return res.json(videoImport.toFormattedJSON()).end()
211} 212}
212 213
213function buildVideo (channelId: number, body: VideoImportCreate, importData: YoutubeDLInfo): MVideoThumbnail { 214async function buildVideo (channelId: number, body: VideoImportCreate, importData: YoutubeDLInfo): Promise<MVideoThumbnail> {
214 const videoData = { 215 let videoData = {
215 name: body.name || importData.name || 'Unknown name', 216 name: body.name || importData.name || 'Unknown name',
216 remote: false, 217 remote: false,
217 category: body.category || importData.category, 218 category: body.category || importData.category,
@@ -231,6 +232,14 @@ function buildVideo (channelId: number, body: VideoImportCreate, importData: You
231 ? new Date(body.originallyPublishedAt) 232 ? new Date(body.originallyPublishedAt)
232 : importData.originallyPublishedAt 233 : importData.originallyPublishedAt
233 } 234 }
235
236 videoData = await Hooks.wrapObject(
237 videoData,
238 body.targetUrl
239 ? 'filter:api.video.import-url.video-attribute.result'
240 : 'filter:api.video.import-torrent.video-attribute.result'
241 )
242
234 const video = new VideoModel(videoData) 243 const video = new VideoModel(videoData)
235 video.url = getLocalVideoActivityPubUrl(video) 244 video.url = getLocalVideoActivityPubUrl(video)
236 245
diff --git a/server/controllers/api/videos/live.ts b/server/controllers/api/videos/live.ts
index e29615ff5..3e1480cf2 100644
--- a/server/controllers/api/videos/live.ts
+++ b/server/controllers/api/videos/live.ts
@@ -83,7 +83,9 @@ async function addLiveVideo (req: express.Request, res: express.Response) {
83 const videoInfo: LiveVideoCreate = req.body 83 const videoInfo: LiveVideoCreate = req.body
84 84
85 // Prepare data so we don't block the transaction 85 // Prepare data so we don't block the transaction
86 const videoData = buildLocalVideoFromReq(videoInfo, res.locals.videoChannel.id) 86 let videoData = buildLocalVideoFromReq(videoInfo, res.locals.videoChannel.id)
87 videoData = await Hooks.wrapObject(videoData, 'filter:api.video.live.video-attribute.result')
88
87 videoData.isLive = true 89 videoData.isLive = true
88 videoData.state = VideoState.WAITING_FOR_LIVE 90 videoData.state = VideoState.WAITING_FOR_LIVE
89 videoData.duration = 0 91 videoData.duration = 0
diff --git a/server/controllers/api/videos/update.ts b/server/controllers/api/videos/update.ts
index 3fcff3e86..589556f47 100644
--- a/server/controllers/api/videos/update.ts
+++ b/server/controllers/api/videos/update.ts
@@ -1,5 +1,6 @@
1import express from 'express' 1import express from 'express'
2import { Transaction } from 'sequelize/types' 2import { Transaction } from 'sequelize/types'
3import { updateTorrentMetadata } from '@server/helpers/webtorrent'
3import { changeVideoChannelShare } from '@server/lib/activitypub/share' 4import { changeVideoChannelShare } from '@server/lib/activitypub/share'
4import { buildVideoThumbnailsFromReq, setVideoTags } from '@server/lib/video' 5import { buildVideoThumbnailsFromReq, setVideoTags } from '@server/lib/video'
5import { openapiOperationDoc } from '@server/middlewares/doc' 6import { openapiOperationDoc } from '@server/middlewares/doc'
@@ -68,7 +69,7 @@ async function updateVideo (req: express.Request, res: express.Response) {
68 }) 69 })
69 70
70 try { 71 try {
71 const videoInstanceUpdated = await sequelizeTypescript.transaction(async t => { 72 const { videoInstanceUpdated, isNewVideo } = await sequelizeTypescript.transaction(async t => {
72 // Refresh video since thumbnails to prevent concurrent updates 73 // Refresh video since thumbnails to prevent concurrent updates
73 const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(videoFromReq.id, t) 74 const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(videoFromReq.id, t)
74 75
@@ -137,8 +138,6 @@ async function updateVideo (req: express.Request, res: express.Response) {
137 transaction: t 138 transaction: t
138 }) 139 })
139 140
140 await federateVideoIfNeeded(videoInstanceUpdated, isNewVideo, t)
141
142 auditLogger.update( 141 auditLogger.update(
143 getAuditIdFromRes(res), 142 getAuditIdFromRes(res),
144 new VideoAuditView(videoInstanceUpdated.toFormattedDetailsJSON()), 143 new VideoAuditView(videoInstanceUpdated.toFormattedDetailsJSON()),
@@ -146,12 +145,14 @@ async function updateVideo (req: express.Request, res: express.Response) {
146 ) 145 )
147 logger.info('Video with name %s and uuid %s updated.', video.name, video.uuid, lTags(video.uuid)) 146 logger.info('Video with name %s and uuid %s updated.', video.name, video.uuid, lTags(video.uuid))
148 147
149 return videoInstanceUpdated 148 return { videoInstanceUpdated, isNewVideo }
150 }) 149 })
151 150
152 if (wasConfidentialVideo) { 151 if (videoInfoToUpdate.name) await updateTorrentsMetadata(videoInstanceUpdated)
153 Notifier.Instance.notifyOnNewVideoIfNeeded(videoInstanceUpdated) 152
154 } 153 await sequelizeTypescript.transaction(t => federateVideoIfNeeded(videoInstanceUpdated, isNewVideo, t))
154
155 if (wasConfidentialVideo) Notifier.Instance.notifyOnNewVideoIfNeeded(videoInstanceUpdated)
155 156
156 Hooks.runAction('action:api.video.updated', { video: videoInstanceUpdated, body: req.body, req, res }) 157 Hooks.runAction('action:api.video.updated', { video: videoInstanceUpdated, body: req.body, req, res })
157 } catch (err) { 158 } catch (err) {
@@ -199,3 +200,20 @@ function updateSchedule (videoInstance: MVideoFullLight, videoInfoToUpdate: Vide
199 return ScheduleVideoUpdateModel.deleteByVideoId(videoInstance.id, transaction) 200 return ScheduleVideoUpdateModel.deleteByVideoId(videoInstance.id, transaction)
200 } 201 }
201} 202}
203
204async function updateTorrentsMetadata (video: MVideoFullLight) {
205 for (const file of (video.VideoFiles || [])) {
206 await updateTorrentMetadata(video, file)
207
208 await file.save()
209 }
210
211 const hls = video.getHLSPlaylist()
212 if (!hls) return
213
214 for (const file of (hls.VideoFiles || [])) {
215 await updateTorrentMetadata(hls, file)
216
217 await file.save()
218 }
219}
diff --git a/server/controllers/api/videos/upload.ts b/server/controllers/api/videos/upload.ts
index 6773b500f..1be87f746 100644
--- a/server/controllers/api/videos/upload.ts
+++ b/server/controllers/api/videos/upload.ts
@@ -8,6 +8,7 @@ import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent'
8import { getLocalVideoActivityPubUrl } from '@server/lib/activitypub/url' 8import { getLocalVideoActivityPubUrl } from '@server/lib/activitypub/url'
9import { generateWebTorrentVideoFilename } from '@server/lib/paths' 9import { generateWebTorrentVideoFilename } from '@server/lib/paths'
10import { Redis } from '@server/lib/redis' 10import { Redis } from '@server/lib/redis'
11import { uploadx } from '@server/lib/uploadx'
11import { 12import {
12 addMoveToObjectStorageJob, 13 addMoveToObjectStorageJob,
13 addOptimizeOrMergeAudioJob, 14 addOptimizeOrMergeAudioJob,
@@ -19,7 +20,6 @@ import { VideoPathManager } from '@server/lib/video-path-manager'
19import { buildNextVideoState } from '@server/lib/video-state' 20import { buildNextVideoState } from '@server/lib/video-state'
20import { openapiOperationDoc } from '@server/middlewares/doc' 21import { openapiOperationDoc } from '@server/middlewares/doc'
21import { MVideo, MVideoFile, MVideoFullLight } from '@server/types/models' 22import { MVideo, MVideoFile, MVideoFullLight } from '@server/types/models'
22import { Uploadx } from '@uploadx/core'
23import { VideoCreate, VideoState } from '../../../../shared' 23import { VideoCreate, VideoState } from '../../../../shared'
24import { HttpStatusCode } from '../../../../shared/models' 24import { HttpStatusCode } from '../../../../shared/models'
25import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger' 25import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger'
@@ -41,8 +41,8 @@ import {
41 authenticate, 41 authenticate,
42 videosAddLegacyValidator, 42 videosAddLegacyValidator,
43 videosAddResumableInitValidator, 43 videosAddResumableInitValidator,
44 videosResumableUploadIdValidator, 44 videosAddResumableValidator,
45 videosAddResumableValidator 45 videosResumableUploadIdValidator
46} from '../../../middlewares' 46} from '../../../middlewares'
47import { ScheduleVideoUpdateModel } from '../../../models/video/schedule-video-update' 47import { ScheduleVideoUpdateModel } from '../../../models/video/schedule-video-update'
48import { VideoModel } from '../../../models/video/video' 48import { VideoModel } from '../../../models/video/video'
@@ -52,9 +52,6 @@ const lTags = loggerTagsFactory('api', 'video')
52const auditLogger = auditLoggerFactory('videos') 52const auditLogger = auditLoggerFactory('videos')
53const uploadRouter = express.Router() 53const uploadRouter = express.Router()
54 54
55const uploadx = new Uploadx({ directory: getResumableUploadPath() })
56uploadx.getUserId = (_, res: express.Response) => res.locals.oauth?.token.user.id
57
58const reqVideoFileAdd = createReqFiles( 55const reqVideoFileAdd = createReqFiles(
59 [ 'videofile', 'thumbnailfile', 'previewfile' ], 56 [ 'videofile', 'thumbnailfile', 'previewfile' ],
60 Object.assign({}, MIMETYPES.VIDEO.MIMETYPE_EXT, MIMETYPES.IMAGE.MIMETYPE_EXT), 57 Object.assign({}, MIMETYPES.VIDEO.MIMETYPE_EXT, MIMETYPES.IMAGE.MIMETYPE_EXT),
@@ -156,7 +153,8 @@ async function addVideo (options: {
156 const videoChannel = res.locals.videoChannel 153 const videoChannel = res.locals.videoChannel
157 const user = res.locals.oauth.token.User 154 const user = res.locals.oauth.token.User
158 155
159 const videoData = buildLocalVideoFromReq(videoInfo, videoChannel.id) 156 let videoData = buildLocalVideoFromReq(videoInfo, videoChannel.id)
157 videoData = await Hooks.wrapObject(videoData, 'filter:api.video.upload.video-attribute.result')
160 158
161 videoData.state = buildNextVideoState() 159 videoData.state = buildNextVideoState()
162 videoData.duration = videoPhysicalFile.duration // duration was added by a previous middleware 160 videoData.duration = videoPhysicalFile.duration // duration was added by a previous middleware