diff options
Diffstat (limited to 'server/lib')
-rw-r--r-- | server/lib/activitypub/process/process-flag.ts | 9 | ||||
-rw-r--r-- | server/lib/blocklist.ts | 4 | ||||
-rw-r--r-- | server/lib/client-html.ts | 4 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/move-to-object-storage.ts | 4 | ||||
-rw-r--r-- | server/lib/moderation.ts | 29 | ||||
-rw-r--r-- | server/lib/notifier/shared/comment/comment-mention.ts | 4 | ||||
-rw-r--r-- | server/lib/plugins/plugin-manager.ts | 4 | ||||
-rw-r--r-- | server/lib/schedulers/remove-dangling-resumable-uploads-scheduler.ts | 35 | ||||
-rw-r--r-- | server/lib/server-config-manager.ts | 5 | ||||
-rw-r--r-- | server/lib/uploadx.ts | 10 |
10 files changed, 55 insertions, 53 deletions
diff --git a/server/lib/activitypub/process/process-flag.ts b/server/lib/activitypub/process/process-flag.ts index 7ed409d0e..fd3e46e2b 100644 --- a/server/lib/activitypub/process/process-flag.ts +++ b/server/lib/activitypub/process/process-flag.ts | |||
@@ -75,7 +75,8 @@ async function processCreateAbuse (activity: ActivityCreate | ActivityFlag, byAc | |||
75 | endAt, | 75 | endAt, |
76 | reporterAccount, | 76 | reporterAccount, |
77 | transaction: t, | 77 | transaction: t, |
78 | videoInstance: video | 78 | videoInstance: video, |
79 | skipNotification: false | ||
79 | }) | 80 | }) |
80 | } | 81 | } |
81 | 82 | ||
@@ -84,7 +85,8 @@ async function processCreateAbuse (activity: ActivityCreate | ActivityFlag, byAc | |||
84 | baseAbuse, | 85 | baseAbuse, |
85 | reporterAccount, | 86 | reporterAccount, |
86 | transaction: t, | 87 | transaction: t, |
87 | commentInstance: videoComment | 88 | commentInstance: videoComment, |
89 | skipNotification: false | ||
88 | }) | 90 | }) |
89 | } | 91 | } |
90 | 92 | ||
@@ -92,7 +94,8 @@ async function processCreateAbuse (activity: ActivityCreate | ActivityFlag, byAc | |||
92 | baseAbuse, | 94 | baseAbuse, |
93 | reporterAccount, | 95 | reporterAccount, |
94 | transaction: t, | 96 | transaction: t, |
95 | accountInstance: flaggedAccount | 97 | accountInstance: flaggedAccount, |
98 | skipNotification: false | ||
96 | }) | 99 | }) |
97 | }) | 100 | }) |
98 | } catch (err) { | 101 | } catch (err) { |
diff --git a/server/lib/blocklist.ts b/server/lib/blocklist.ts index d6b684015..98273a6ea 100644 --- a/server/lib/blocklist.ts +++ b/server/lib/blocklist.ts | |||
@@ -40,12 +40,12 @@ async function isBlockedByServerOrAccount (targetAccount: MAccountServer, userAc | |||
40 | 40 | ||
41 | if (userAccount) sourceAccounts.push(userAccount.id) | 41 | if (userAccount) sourceAccounts.push(userAccount.id) |
42 | 42 | ||
43 | const accountMutedHash = await AccountBlocklistModel.isAccountMutedByMulti(sourceAccounts, targetAccount.id) | 43 | const accountMutedHash = await AccountBlocklistModel.isAccountMutedByAccounts(sourceAccounts, targetAccount.id) |
44 | if (accountMutedHash[serverAccountId] || (userAccount && accountMutedHash[userAccount.id])) { | 44 | if (accountMutedHash[serverAccountId] || (userAccount && accountMutedHash[userAccount.id])) { |
45 | return true | 45 | return true |
46 | } | 46 | } |
47 | 47 | ||
48 | const instanceMutedHash = await ServerBlocklistModel.isServerMutedByMulti(sourceAccounts, targetAccount.Actor.serverId) | 48 | const instanceMutedHash = await ServerBlocklistModel.isServerMutedByAccounts(sourceAccounts, targetAccount.Actor.serverId) |
49 | if (instanceMutedHash[serverAccountId] || (userAccount && instanceMutedHash[userAccount.id])) { | 49 | if (instanceMutedHash[serverAccountId] || (userAccount && instanceMutedHash[userAccount.id])) { |
50 | return true | 50 | return true |
51 | } | 51 | } |
diff --git a/server/lib/client-html.ts b/server/lib/client-html.ts index 360b4667f..adc3d712e 100644 --- a/server/lib/client-html.ts +++ b/server/lib/client-html.ts | |||
@@ -350,10 +350,6 @@ class ClientHtml { | |||
350 | return join(__dirname, '../../../client/dist/standalone/videos/embed.html') | 350 | return join(__dirname, '../../../client/dist/standalone/videos/embed.html') |
351 | } | 351 | } |
352 | 352 | ||
353 | private static addHtmlLang (htmlStringPage: string, paramLang: string) { | ||
354 | return htmlStringPage.replace('<html>', `<html lang="${paramLang}">`) | ||
355 | } | ||
356 | |||
357 | private static addManifestContentHash (htmlStringPage: string) { | 353 | private static addManifestContentHash (htmlStringPage: string) { |
358 | return htmlStringPage.replace('[manifestContentHash]', FILES_CONTENT_HASH.MANIFEST) | 354 | return htmlStringPage.replace('[manifestContentHash]', FILES_CONTENT_HASH.MANIFEST) |
359 | } | 355 | } |
diff --git a/server/lib/job-queue/handlers/move-to-object-storage.ts b/server/lib/job-queue/handlers/move-to-object-storage.ts index 54a7c566b..b5eea0184 100644 --- a/server/lib/job-queue/handlers/move-to-object-storage.ts +++ b/server/lib/job-queue/handlers/move-to-object-storage.ts | |||
@@ -2,7 +2,7 @@ import { Job } from 'bull' | |||
2 | import { remove } from 'fs-extra' | 2 | import { remove } from 'fs-extra' |
3 | import { join } from 'path' | 3 | import { join } from 'path' |
4 | import { logger } from '@server/helpers/logger' | 4 | import { logger } from '@server/helpers/logger' |
5 | import { updateTorrentUrls } from '@server/helpers/webtorrent' | 5 | import { updateTorrentMetadata } from '@server/helpers/webtorrent' |
6 | import { CONFIG } from '@server/initializers/config' | 6 | import { CONFIG } from '@server/initializers/config' |
7 | import { P2P_MEDIA_LOADER_PEER_VERSION } from '@server/initializers/constants' | 7 | import { P2P_MEDIA_LOADER_PEER_VERSION } from '@server/initializers/constants' |
8 | import { storeHLSFile, storeWebTorrentFile } from '@server/lib/object-storage' | 8 | import { storeHLSFile, storeWebTorrentFile } from '@server/lib/object-storage' |
@@ -113,7 +113,7 @@ async function onFileMoved (options: { | |||
113 | file.fileUrl = fileUrl | 113 | file.fileUrl = fileUrl |
114 | file.storage = VideoStorage.OBJECT_STORAGE | 114 | file.storage = VideoStorage.OBJECT_STORAGE |
115 | 115 | ||
116 | await updateTorrentUrls(videoOrPlaylist, file) | 116 | await updateTorrentMetadata(videoOrPlaylist, file) |
117 | await file.save() | 117 | await file.save() |
118 | 118 | ||
119 | logger.debug('Removing %s because it\'s now on object storage', oldPath) | 119 | logger.debug('Removing %s because it\'s now on object storage', oldPath) |
diff --git a/server/lib/moderation.ts b/server/lib/moderation.ts index 456b615b2..c2565f867 100644 --- a/server/lib/moderation.ts +++ b/server/lib/moderation.ts | |||
@@ -107,8 +107,9 @@ async function createVideoAbuse (options: { | |||
107 | endAt: number | 107 | endAt: number |
108 | transaction: Transaction | 108 | transaction: Transaction |
109 | reporterAccount: MAccountDefault | 109 | reporterAccount: MAccountDefault |
110 | skipNotification: boolean | ||
110 | }) { | 111 | }) { |
111 | const { baseAbuse, videoInstance, startAt, endAt, transaction, reporterAccount } = options | 112 | const { baseAbuse, videoInstance, startAt, endAt, transaction, reporterAccount, skipNotification } = options |
112 | 113 | ||
113 | const associateFun = async (abuseInstance: MAbuseFull) => { | 114 | const associateFun = async (abuseInstance: MAbuseFull) => { |
114 | const videoAbuseInstance: MVideoAbuseVideoFull = await VideoAbuseModel.create({ | 115 | const videoAbuseInstance: MVideoAbuseVideoFull = await VideoAbuseModel.create({ |
@@ -129,6 +130,7 @@ async function createVideoAbuse (options: { | |||
129 | reporterAccount, | 130 | reporterAccount, |
130 | flaggedAccount: videoInstance.VideoChannel.Account, | 131 | flaggedAccount: videoInstance.VideoChannel.Account, |
131 | transaction, | 132 | transaction, |
133 | skipNotification, | ||
132 | associateFun | 134 | associateFun |
133 | }) | 135 | }) |
134 | } | 136 | } |
@@ -138,8 +140,9 @@ function createVideoCommentAbuse (options: { | |||
138 | commentInstance: MCommentOwnerVideo | 140 | commentInstance: MCommentOwnerVideo |
139 | transaction: Transaction | 141 | transaction: Transaction |
140 | reporterAccount: MAccountDefault | 142 | reporterAccount: MAccountDefault |
143 | skipNotification: boolean | ||
141 | }) { | 144 | }) { |
142 | const { baseAbuse, commentInstance, transaction, reporterAccount } = options | 145 | const { baseAbuse, commentInstance, transaction, reporterAccount, skipNotification } = options |
143 | 146 | ||
144 | const associateFun = async (abuseInstance: MAbuseFull) => { | 147 | const associateFun = async (abuseInstance: MAbuseFull) => { |
145 | const commentAbuseInstance: MCommentAbuseAccountVideo = await VideoCommentAbuseModel.create({ | 148 | const commentAbuseInstance: MCommentAbuseAccountVideo = await VideoCommentAbuseModel.create({ |
@@ -158,6 +161,7 @@ function createVideoCommentAbuse (options: { | |||
158 | reporterAccount, | 161 | reporterAccount, |
159 | flaggedAccount: commentInstance.Account, | 162 | flaggedAccount: commentInstance.Account, |
160 | transaction, | 163 | transaction, |
164 | skipNotification, | ||
161 | associateFun | 165 | associateFun |
162 | }) | 166 | }) |
163 | } | 167 | } |
@@ -167,8 +171,9 @@ function createAccountAbuse (options: { | |||
167 | accountInstance: MAccountDefault | 171 | accountInstance: MAccountDefault |
168 | transaction: Transaction | 172 | transaction: Transaction |
169 | reporterAccount: MAccountDefault | 173 | reporterAccount: MAccountDefault |
174 | skipNotification: boolean | ||
170 | }) { | 175 | }) { |
171 | const { baseAbuse, accountInstance, transaction, reporterAccount } = options | 176 | const { baseAbuse, accountInstance, transaction, reporterAccount, skipNotification } = options |
172 | 177 | ||
173 | const associateFun = () => { | 178 | const associateFun = () => { |
174 | return Promise.resolve({ isOwned: accountInstance.isOwned() }) | 179 | return Promise.resolve({ isOwned: accountInstance.isOwned() }) |
@@ -179,6 +184,7 @@ function createAccountAbuse (options: { | |||
179 | reporterAccount, | 184 | reporterAccount, |
180 | flaggedAccount: accountInstance, | 185 | flaggedAccount: accountInstance, |
181 | transaction, | 186 | transaction, |
187 | skipNotification, | ||
182 | associateFun | 188 | associateFun |
183 | }) | 189 | }) |
184 | } | 190 | } |
@@ -207,9 +213,10 @@ async function createAbuse (options: { | |||
207 | reporterAccount: MAccountDefault | 213 | reporterAccount: MAccountDefault |
208 | flaggedAccount: MAccountLight | 214 | flaggedAccount: MAccountLight |
209 | associateFun: (abuseInstance: MAbuseFull) => Promise<{ isOwned: boolean} > | 215 | associateFun: (abuseInstance: MAbuseFull) => Promise<{ isOwned: boolean} > |
216 | skipNotification: boolean | ||
210 | transaction: Transaction | 217 | transaction: Transaction |
211 | }) { | 218 | }) { |
212 | const { base, reporterAccount, flaggedAccount, associateFun, transaction } = options | 219 | const { base, reporterAccount, flaggedAccount, associateFun, transaction, skipNotification } = options |
213 | const auditLogger = auditLoggerFactory('abuse') | 220 | const auditLogger = auditLoggerFactory('abuse') |
214 | 221 | ||
215 | const abuseAttributes = Object.assign({}, base, { flaggedAccountId: flaggedAccount.id }) | 222 | const abuseAttributes = Object.assign({}, base, { flaggedAccountId: flaggedAccount.id }) |
@@ -227,13 +234,15 @@ async function createAbuse (options: { | |||
227 | const abuseJSON = abuseInstance.toFormattedAdminJSON() | 234 | const abuseJSON = abuseInstance.toFormattedAdminJSON() |
228 | auditLogger.create(reporterAccount.Actor.getIdentifier(), new AbuseAuditView(abuseJSON)) | 235 | auditLogger.create(reporterAccount.Actor.getIdentifier(), new AbuseAuditView(abuseJSON)) |
229 | 236 | ||
230 | afterCommitIfTransaction(transaction, () => { | 237 | if (!skipNotification) { |
231 | Notifier.Instance.notifyOnNewAbuse({ | 238 | afterCommitIfTransaction(transaction, () => { |
232 | abuse: abuseJSON, | 239 | Notifier.Instance.notifyOnNewAbuse({ |
233 | abuseInstance, | 240 | abuse: abuseJSON, |
234 | reporter: reporterAccount.Actor.getIdentifier() | 241 | abuseInstance, |
242 | reporter: reporterAccount.Actor.getIdentifier() | ||
243 | }) | ||
235 | }) | 244 | }) |
236 | }) | 245 | } |
237 | 246 | ||
238 | logger.info('Abuse report %d created.', abuseInstance.id) | 247 | logger.info('Abuse report %d created.', abuseInstance.id) |
239 | 248 | ||
diff --git a/server/lib/notifier/shared/comment/comment-mention.ts b/server/lib/notifier/shared/comment/comment-mention.ts index 4f84d8dea..765cbaad9 100644 --- a/server/lib/notifier/shared/comment/comment-mention.ts +++ b/server/lib/notifier/shared/comment/comment-mention.ts | |||
@@ -47,8 +47,8 @@ export class CommentMention extends AbstractNotification <MCommentOwnerVideo, MU | |||
47 | 47 | ||
48 | const sourceAccounts = this.users.map(u => u.Account.id).concat([ this.serverAccountId ]) | 48 | const sourceAccounts = this.users.map(u => u.Account.id).concat([ this.serverAccountId ]) |
49 | 49 | ||
50 | this.accountMutedHash = await AccountBlocklistModel.isAccountMutedByMulti(sourceAccounts, this.payload.accountId) | 50 | this.accountMutedHash = await AccountBlocklistModel.isAccountMutedByAccounts(sourceAccounts, this.payload.accountId) |
51 | this.instanceMutedHash = await ServerBlocklistModel.isServerMutedByMulti(sourceAccounts, this.payload.Account.Actor.serverId) | 51 | this.instanceMutedHash = await ServerBlocklistModel.isServerMutedByAccounts(sourceAccounts, this.payload.Account.Actor.serverId) |
52 | } | 52 | } |
53 | 53 | ||
54 | log () { | 54 | log () { |
diff --git a/server/lib/plugins/plugin-manager.ts b/server/lib/plugins/plugin-manager.ts index d4d2a7edc..6c2f4764e 100644 --- a/server/lib/plugins/plugin-manager.ts +++ b/server/lib/plugins/plugin-manager.ts | |||
@@ -1,8 +1,8 @@ | |||
1 | import decache from 'decache' | ||
2 | import express from 'express' | 1 | import express from 'express' |
3 | import { createReadStream, createWriteStream } from 'fs' | 2 | import { createReadStream, createWriteStream } from 'fs' |
4 | import { ensureDir, outputFile, readJSON } from 'fs-extra' | 3 | import { ensureDir, outputFile, readJSON } from 'fs-extra' |
5 | import { basename, join } from 'path' | 4 | import { basename, join } from 'path' |
5 | import { decachePlugin } from '@server/helpers/decache' | ||
6 | import { MOAuthTokenUser, MUser } from '@server/types/models' | 6 | import { MOAuthTokenUser, MUser } from '@server/types/models' |
7 | import { getCompleteLocale } from '@shared/core-utils' | 7 | import { getCompleteLocale } from '@shared/core-utils' |
8 | import { ClientScript, PluginPackageJson, PluginTranslation, PluginTranslationPaths, RegisterServerHookOptions } from '@shared/models' | 8 | import { ClientScript, PluginPackageJson, PluginTranslation, PluginTranslationPaths, RegisterServerHookOptions } from '@shared/models' |
@@ -420,7 +420,7 @@ export class PluginManager implements ServerHook { | |||
420 | 420 | ||
421 | // Delete cache if needed | 421 | // Delete cache if needed |
422 | const modulePath = join(pluginPath, packageJSON.library) | 422 | const modulePath = join(pluginPath, packageJSON.library) |
423 | decache(modulePath) | 423 | decachePlugin(pluginPath, modulePath) |
424 | const library: PluginLibrary = require(modulePath) | 424 | const library: PluginLibrary = require(modulePath) |
425 | 425 | ||
426 | if (!isLibraryCodeValid(library)) { | 426 | if (!isLibraryCodeValid(library)) { |
diff --git a/server/lib/schedulers/remove-dangling-resumable-uploads-scheduler.ts b/server/lib/schedulers/remove-dangling-resumable-uploads-scheduler.ts index d6e561cad..61e93eafa 100644 --- a/server/lib/schedulers/remove-dangling-resumable-uploads-scheduler.ts +++ b/server/lib/schedulers/remove-dangling-resumable-uploads-scheduler.ts | |||
@@ -1,9 +1,7 @@ | |||
1 | import { map } from 'bluebird' | 1 | |
2 | import { readdir, remove, stat } from 'fs-extra' | ||
3 | import { logger, loggerTagsFactory } from '@server/helpers/logger' | 2 | import { logger, loggerTagsFactory } from '@server/helpers/logger' |
4 | import { getResumableUploadPath } from '@server/helpers/upload' | ||
5 | import { SCHEDULER_INTERVALS_MS } from '@server/initializers/constants' | 3 | import { SCHEDULER_INTERVALS_MS } from '@server/initializers/constants' |
6 | import { METAFILE_EXTNAME } from '@uploadx/core' | 4 | import { uploadx } from '../uploadx' |
7 | import { AbstractScheduler } from './abstract-scheduler' | 5 | import { AbstractScheduler } from './abstract-scheduler' |
8 | 6 | ||
9 | const lTags = loggerTagsFactory('scheduler', 'resumable-upload', 'cleaner') | 7 | const lTags = loggerTagsFactory('scheduler', 'resumable-upload', 'cleaner') |
@@ -22,36 +20,17 @@ export class RemoveDanglingResumableUploadsScheduler extends AbstractScheduler { | |||
22 | } | 20 | } |
23 | 21 | ||
24 | protected async internalExecute () { | 22 | protected async internalExecute () { |
25 | const path = getResumableUploadPath() | 23 | logger.debug('Removing dangling resumable uploads', lTags()) |
26 | const files = await readdir(path) | ||
27 | |||
28 | const metafiles = files.filter(f => f.endsWith(METAFILE_EXTNAME)) | ||
29 | 24 | ||
30 | if (metafiles.length === 0) return | 25 | const now = new Date().getTime() |
31 | |||
32 | logger.debug('Reading resumable video upload folder %s with %d files', path, metafiles.length, lTags()) | ||
33 | 26 | ||
34 | try { | 27 | try { |
35 | await map(metafiles, metafile => { | 28 | // Remove files that were not updated since the last execution |
36 | return this.deleteIfOlderThan(metafile, this.lastExecutionTimeMs) | 29 | await uploadx.storage.purge(now - this.lastExecutionTimeMs) |
37 | }, { concurrency: 5 }) | ||
38 | } catch (error) { | 30 | } catch (error) { |
39 | logger.error('Failed to handle file during resumable video upload folder cleanup', { error, ...lTags() }) | 31 | logger.error('Failed to handle file during resumable video upload folder cleanup', { error, ...lTags() }) |
40 | } finally { | 32 | } finally { |
41 | this.lastExecutionTimeMs = new Date().getTime() | 33 | this.lastExecutionTimeMs = now |
42 | } | ||
43 | } | ||
44 | |||
45 | private async deleteIfOlderThan (metafile: string, olderThan: number) { | ||
46 | const metafilePath = getResumableUploadPath(metafile) | ||
47 | const statResult = await stat(metafilePath) | ||
48 | |||
49 | // Delete uploads that started since a long time | ||
50 | if (statResult.ctimeMs < olderThan) { | ||
51 | await remove(metafilePath) | ||
52 | |||
53 | const datafile = metafilePath.replace(new RegExp(`${METAFILE_EXTNAME}$`), '') | ||
54 | await remove(datafile) | ||
55 | } | 34 | } |
56 | } | 35 | } |
57 | 36 | ||
diff --git a/server/lib/server-config-manager.ts b/server/lib/server-config-manager.ts index bdf6492f9..6aa459f82 100644 --- a/server/lib/server-config-manager.ts +++ b/server/lib/server-config-manager.ts | |||
@@ -47,6 +47,11 @@ class ServerConfigManager { | |||
47 | miniature: { | 47 | miniature: { |
48 | preferAuthorDisplayName: CONFIG.CLIENT.VIDEOS.MINIATURE.PREFER_AUTHOR_DISPLAY_NAME | 48 | preferAuthorDisplayName: CONFIG.CLIENT.VIDEOS.MINIATURE.PREFER_AUTHOR_DISPLAY_NAME |
49 | } | 49 | } |
50 | }, | ||
51 | menu: { | ||
52 | login: { | ||
53 | redirectOnSingleExternalAuth: CONFIG.CLIENT.MENU.LOGIN.REDIRECT_ON_SINGLE_EXTERNAL_AUTH | ||
54 | } | ||
50 | } | 55 | } |
51 | }, | 56 | }, |
52 | 57 | ||
diff --git a/server/lib/uploadx.ts b/server/lib/uploadx.ts new file mode 100644 index 000000000..11b1044db --- /dev/null +++ b/server/lib/uploadx.ts | |||
@@ -0,0 +1,10 @@ | |||
1 | import express from 'express' | ||
2 | import { getResumableUploadPath } from '@server/helpers/upload' | ||
3 | import { Uploadx } from '@uploadx/core' | ||
4 | |||
5 | const uploadx = new Uploadx({ directory: getResumableUploadPath() }) | ||
6 | uploadx.getUserId = (_, res: express.Response) => res.locals.oauth?.token.user.id | ||
7 | |||
8 | export { | ||
9 | uploadx | ||
10 | } | ||