diff options
34 files changed, 484 insertions, 150 deletions
diff --git a/scripts/create-import-video-file-job.ts b/scripts/create-import-video-file-job.ts index 37738ca40..d71e82c14 100644 --- a/scripts/create-import-video-file-job.ts +++ b/scripts/create-import-video-file-job.ts | |||
@@ -4,7 +4,7 @@ registerTSPaths() | |||
4 | import * as program from 'commander' | 4 | import * as program from 'commander' |
5 | import { resolve } from 'path' | 5 | import { resolve } from 'path' |
6 | import { VideoModel } from '../server/models/video/video' | 6 | import { VideoModel } from '../server/models/video/video' |
7 | import { initDatabaseModels } from '../server/initializers' | 7 | import { initDatabaseModels } from '../server/initializers/database' |
8 | import { JobQueue } from '../server/lib/job-queue' | 8 | import { JobQueue } from '../server/lib/job-queue' |
9 | 9 | ||
10 | program | 10 | program |
diff --git a/scripts/create-transcoding-job.ts b/scripts/create-transcoding-job.ts index 1312e8952..7ee0050e3 100755 --- a/scripts/create-transcoding-job.ts +++ b/scripts/create-transcoding-job.ts | |||
@@ -3,7 +3,7 @@ registerTSPaths() | |||
3 | 3 | ||
4 | import * as program from 'commander' | 4 | import * as program from 'commander' |
5 | import { VideoModel } from '../server/models/video/video' | 5 | import { VideoModel } from '../server/models/video/video' |
6 | import { initDatabaseModels } from '../server/initializers' | 6 | import { initDatabaseModels } from '../server/initializers/database' |
7 | import { JobQueue } from '../server/lib/job-queue' | 7 | import { JobQueue } from '../server/lib/job-queue' |
8 | import { computeResolutionsToTranscode } from '@server/helpers/ffmpeg-utils' | 8 | import { computeResolutionsToTranscode } from '@server/helpers/ffmpeg-utils' |
9 | import { VideoTranscodingPayload } from '@shared/models' | 9 | import { VideoTranscodingPayload } from '@shared/models' |
diff --git a/scripts/danger/clean/cleaner.ts b/scripts/danger/clean/cleaner.ts index ed35ef79f..2d5366a91 100644 --- a/scripts/danger/clean/cleaner.ts +++ b/scripts/danger/clean/cleaner.ts | |||
@@ -3,7 +3,7 @@ registerTSPaths() | |||
3 | 3 | ||
4 | import * as Promise from 'bluebird' | 4 | import * as Promise from 'bluebird' |
5 | import * as rimraf from 'rimraf' | 5 | import * as rimraf from 'rimraf' |
6 | import { initDatabaseModels, sequelizeTypescript } from '../../../server/initializers' | 6 | import { initDatabaseModels, sequelizeTypescript } from '../../../server/initializers/database' |
7 | import { CONFIG } from '../../../server/initializers/config' | 7 | import { CONFIG } from '../../../server/initializers/config' |
8 | 8 | ||
9 | initDatabaseModels(true) | 9 | initDatabaseModels(true) |
diff --git a/scripts/migrations/peertube-2.1.ts b/scripts/migrations/peertube-2.1.ts index 892497a88..e17e58166 100644 --- a/scripts/migrations/peertube-2.1.ts +++ b/scripts/migrations/peertube-2.1.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { registerTSPaths } from '../../server/helpers/register-ts-paths' | 1 | import { registerTSPaths } from '../../server/helpers/register-ts-paths' |
2 | registerTSPaths() | 2 | registerTSPaths() |
3 | 3 | ||
4 | import { initDatabaseModels, sequelizeTypescript } from '../../server/initializers' | 4 | import { initDatabaseModels, sequelizeTypescript } from '../../server/initializers/database' |
5 | import * as Sequelize from 'sequelize' | 5 | import * as Sequelize from 'sequelize' |
6 | import { join } from 'path' | 6 | import { join } from 'path' |
7 | import { HLS_STREAMING_PLAYLIST_DIRECTORY, STATIC_PATHS, WEBSERVER } from '@server/initializers/constants' | 7 | import { HLS_STREAMING_PLAYLIST_DIRECTORY, STATIC_PATHS, WEBSERVER } from '@server/initializers/constants' |
diff --git a/scripts/optimize-old-videos.ts b/scripts/optimize-old-videos.ts index a84845068..9595efd9c 100644 --- a/scripts/optimize-old-videos.ts +++ b/scripts/optimize-old-videos.ts | |||
@@ -6,7 +6,7 @@ import { getDurationFromVideoFile, getVideoFileBitrate, getVideoFileFPS, getVide | |||
6 | import { getMaxBitrate } from '../shared/models/videos' | 6 | import { getMaxBitrate } from '../shared/models/videos' |
7 | import { VideoModel } from '../server/models/video/video' | 7 | import { VideoModel } from '../server/models/video/video' |
8 | import { optimizeOriginalVideofile } from '../server/lib/video-transcoding' | 8 | import { optimizeOriginalVideofile } from '../server/lib/video-transcoding' |
9 | import { initDatabaseModels } from '../server/initializers' | 9 | import { initDatabaseModels } from '../server/initializers/database' |
10 | import { basename, dirname } from 'path' | 10 | import { basename, dirname } from 'path' |
11 | import { copy, move, remove } from 'fs-extra' | 11 | import { copy, move, remove } from 'fs-extra' |
12 | import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' | 12 | import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' |
diff --git a/scripts/prune-storage.ts b/scripts/prune-storage.ts index fa3d81744..2b04e906d 100755 --- a/scripts/prune-storage.ts +++ b/scripts/prune-storage.ts | |||
@@ -5,7 +5,7 @@ import * as prompt from 'prompt' | |||
5 | import { join } from 'path' | 5 | import { join } from 'path' |
6 | import { CONFIG } from '../server/initializers/config' | 6 | import { CONFIG } from '../server/initializers/config' |
7 | import { VideoModel } from '../server/models/video/video' | 7 | import { VideoModel } from '../server/models/video/video' |
8 | import { initDatabaseModels } from '../server/initializers' | 8 | import { initDatabaseModels } from '../server/initializers/database' |
9 | import { readdir, remove } from 'fs-extra' | 9 | import { readdir, remove } from 'fs-extra' |
10 | import { VideoRedundancyModel } from '../server/models/redundancy/video-redundancy' | 10 | import { VideoRedundancyModel } from '../server/models/redundancy/video-redundancy' |
11 | import * as Bluebird from 'bluebird' | 11 | import * as Bluebird from 'bluebird' |
diff --git a/scripts/reset-password.ts b/scripts/reset-password.ts index 6126c3cd0..863537500 100755 --- a/scripts/reset-password.ts +++ b/scripts/reset-password.ts | |||
@@ -2,7 +2,7 @@ import { registerTSPaths } from '../server/helpers/register-ts-paths' | |||
2 | registerTSPaths() | 2 | registerTSPaths() |
3 | 3 | ||
4 | import * as program from 'commander' | 4 | import * as program from 'commander' |
5 | import { initDatabaseModels } from '../server/initializers' | 5 | import { initDatabaseModels } from '../server/initializers/database' |
6 | import { UserModel } from '../server/models/account/user' | 6 | import { UserModel } from '../server/models/account/user' |
7 | import { isUserPasswordValid } from '../server/helpers/custom-validators/users' | 7 | import { isUserPasswordValid } from '../server/helpers/custom-validators/users' |
8 | 8 | ||
diff --git a/scripts/update-host.ts b/scripts/update-host.ts index 7b07dea04..2efe326a2 100755 --- a/scripts/update-host.ts +++ b/scripts/update-host.ts | |||
@@ -17,7 +17,7 @@ import { VideoCommentModel } from '../server/models/video/video-comment' | |||
17 | import { AccountModel } from '../server/models/account/account' | 17 | import { AccountModel } from '../server/models/account/account' |
18 | import { VideoChannelModel } from '../server/models/video/video-channel' | 18 | import { VideoChannelModel } from '../server/models/video/video-channel' |
19 | import { VideoStreamingPlaylistModel } from '../server/models/video/video-streaming-playlist' | 19 | import { VideoStreamingPlaylistModel } from '../server/models/video/video-streaming-playlist' |
20 | import { initDatabaseModels } from '../server/initializers' | 20 | import { initDatabaseModels } from '../server/initializers/database' |
21 | import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' | 21 | import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' |
22 | import { getServerActor } from '@server/models/application/application' | 22 | import { getServerActor } from '@server/models/application/application' |
23 | 23 | ||
@@ -84,7 +84,7 @@ migrate() | |||
84 | loadLanguages() | 84 | loadLanguages() |
85 | 85 | ||
86 | // ----------- PeerTube modules ----------- | 86 | // ----------- PeerTube modules ----------- |
87 | import { installApplication } from './server/initializers' | 87 | import { installApplication } from './server/initializers/installer' |
88 | import { Emailer } from './server/lib/emailer' | 88 | import { Emailer } from './server/lib/emailer' |
89 | import { JobQueue } from './server/lib/job-queue' | 89 | import { JobQueue } from './server/lib/job-queue' |
90 | import { VideosPreviewCache, VideosCaptionCache } from './server/lib/files-cache' | 90 | import { VideosPreviewCache, VideosCaptionCache } from './server/lib/files-cache' |
diff --git a/server/controllers/api/users/my-history.ts b/server/controllers/api/users/my-history.ts index 4da1f3496..77a15e5fc 100644 --- a/server/controllers/api/users/my-history.ts +++ b/server/controllers/api/users/my-history.ts | |||
@@ -9,7 +9,7 @@ import { | |||
9 | } from '../../../middlewares' | 9 | } from '../../../middlewares' |
10 | import { getFormattedObjects } from '../../../helpers/utils' | 10 | import { getFormattedObjects } from '../../../helpers/utils' |
11 | import { UserVideoHistoryModel } from '../../../models/account/user-video-history' | 11 | import { UserVideoHistoryModel } from '../../../models/account/user-video-history' |
12 | import { sequelizeTypescript } from '../../../initializers' | 12 | import { sequelizeTypescript } from '../../../initializers/database' |
13 | 13 | ||
14 | const myVideosHistoryRouter = express.Router() | 14 | const myVideosHistoryRouter = express.Router() |
15 | 15 | ||
diff --git a/server/controllers/api/videos/abuse.ts b/server/controllers/api/videos/abuse.ts index 3fe7f7e51..bce50aefb 100644 --- a/server/controllers/api/videos/abuse.ts +++ b/server/controllers/api/videos/abuse.ts | |||
@@ -2,7 +2,7 @@ import * as express from 'express' | |||
2 | import { UserRight, VideoAbuseCreate, VideoAbuseState } from '../../../../shared' | 2 | import { UserRight, VideoAbuseCreate, VideoAbuseState } from '../../../../shared' |
3 | import { logger } from '../../../helpers/logger' | 3 | import { logger } from '../../../helpers/logger' |
4 | import { getFormattedObjects } from '../../../helpers/utils' | 4 | import { getFormattedObjects } from '../../../helpers/utils' |
5 | import { sequelizeTypescript } from '../../../initializers' | 5 | import { sequelizeTypescript } from '../../../initializers/database' |
6 | import { | 6 | import { |
7 | asyncMiddleware, | 7 | asyncMiddleware, |
8 | asyncRetryTransactionMiddleware, | 8 | asyncRetryTransactionMiddleware, |
diff --git a/server/controllers/api/videos/blacklist.ts b/server/controllers/api/videos/blacklist.ts index abd09387c..3b25ceea2 100644 --- a/server/controllers/api/videos/blacklist.ts +++ b/server/controllers/api/videos/blacklist.ts | |||
@@ -1,7 +1,9 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { UserRight, VideoBlacklistCreate, VideoBlacklistType } from '../../../../shared' | 2 | import { blacklistVideo, unblacklistVideo } from '@server/lib/video-blacklist' |
3 | import { UserRight, VideoBlacklistCreate } from '../../../../shared' | ||
3 | import { logger } from '../../../helpers/logger' | 4 | import { logger } from '../../../helpers/logger' |
4 | import { getFormattedObjects } from '../../../helpers/utils' | 5 | import { getFormattedObjects } from '../../../helpers/utils' |
6 | import { sequelizeTypescript } from '../../../initializers/database' | ||
5 | import { | 7 | import { |
6 | asyncMiddleware, | 8 | asyncMiddleware, |
7 | authenticate, | 9 | authenticate, |
@@ -16,11 +18,6 @@ import { | |||
16 | videosBlacklistUpdateValidator | 18 | videosBlacklistUpdateValidator |
17 | } from '../../../middlewares' | 19 | } from '../../../middlewares' |
18 | import { VideoBlacklistModel } from '../../../models/video/video-blacklist' | 20 | import { VideoBlacklistModel } from '../../../models/video/video-blacklist' |
19 | import { sequelizeTypescript } from '../../../initializers' | ||
20 | import { Notifier } from '../../../lib/notifier' | ||
21 | import { sendDeleteVideo } from '../../../lib/activitypub/send' | ||
22 | import { federateVideoIfNeeded } from '../../../lib/activitypub/videos' | ||
23 | import { MVideoBlacklistVideo } from '@server/typings/models' | ||
24 | 21 | ||
25 | const blacklistRouter = express.Router() | 22 | const blacklistRouter = express.Router() |
26 | 23 | ||
@@ -28,7 +25,7 @@ blacklistRouter.post('/:videoId/blacklist', | |||
28 | authenticate, | 25 | authenticate, |
29 | ensureUserHasRight(UserRight.MANAGE_VIDEO_BLACKLIST), | 26 | ensureUserHasRight(UserRight.MANAGE_VIDEO_BLACKLIST), |
30 | asyncMiddleware(videosBlacklistAddValidator), | 27 | asyncMiddleware(videosBlacklistAddValidator), |
31 | asyncMiddleware(addVideoToBlacklist) | 28 | asyncMiddleware(addVideoToBlacklistController) |
32 | ) | 29 | ) |
33 | 30 | ||
34 | blacklistRouter.get('/blacklist', | 31 | blacklistRouter.get('/blacklist', |
@@ -64,29 +61,15 @@ export { | |||
64 | 61 | ||
65 | // --------------------------------------------------------------------------- | 62 | // --------------------------------------------------------------------------- |
66 | 63 | ||
67 | async function addVideoToBlacklist (req: express.Request, res: express.Response) { | 64 | async function addVideoToBlacklistController (req: express.Request, res: express.Response) { |
68 | const videoInstance = res.locals.videoAll | 65 | const videoInstance = res.locals.videoAll |
69 | const body: VideoBlacklistCreate = req.body | 66 | const body: VideoBlacklistCreate = req.body |
70 | 67 | ||
71 | const toCreate = { | 68 | await blacklistVideo(videoInstance, body) |
72 | videoId: videoInstance.id, | ||
73 | unfederated: body.unfederate === true, | ||
74 | reason: body.reason, | ||
75 | type: VideoBlacklistType.MANUAL | ||
76 | } | ||
77 | |||
78 | const blacklist: MVideoBlacklistVideo = await VideoBlacklistModel.create(toCreate) | ||
79 | blacklist.Video = videoInstance | ||
80 | |||
81 | if (body.unfederate === true) { | ||
82 | await sendDeleteVideo(videoInstance, undefined) | ||
83 | } | ||
84 | |||
85 | Notifier.Instance.notifyOnVideoBlacklist(blacklist) | ||
86 | 69 | ||
87 | logger.info('Video %s blacklisted.', videoInstance.uuid) | 70 | logger.info('Video %s blacklisted.', videoInstance.uuid) |
88 | 71 | ||
89 | return res.type('json').status(204).end() | 72 | return res.type('json').sendStatus(204) |
90 | } | 73 | } |
91 | 74 | ||
92 | async function updateVideoBlacklistController (req: express.Request, res: express.Response) { | 75 | async function updateVideoBlacklistController (req: express.Request, res: express.Response) { |
@@ -98,7 +81,7 @@ async function updateVideoBlacklistController (req: express.Request, res: expres | |||
98 | return videoBlacklist.save({ transaction: t }) | 81 | return videoBlacklist.save({ transaction: t }) |
99 | }) | 82 | }) |
100 | 83 | ||
101 | return res.type('json').status(204).end() | 84 | return res.type('json').sendStatus(204) |
102 | } | 85 | } |
103 | 86 | ||
104 | async function listBlacklist (req: express.Request, res: express.Response) { | 87 | async function listBlacklist (req: express.Request, res: express.Response) { |
@@ -117,32 +100,9 @@ async function removeVideoFromBlacklistController (req: express.Request, res: ex | |||
117 | const videoBlacklist = res.locals.videoBlacklist | 100 | const videoBlacklist = res.locals.videoBlacklist |
118 | const video = res.locals.videoAll | 101 | const video = res.locals.videoAll |
119 | 102 | ||
120 | const videoBlacklistType = await sequelizeTypescript.transaction(async t => { | 103 | await unblacklistVideo(videoBlacklist, video) |
121 | const unfederated = videoBlacklist.unfederated | ||
122 | const videoBlacklistType = videoBlacklist.type | ||
123 | |||
124 | await videoBlacklist.destroy({ transaction: t }) | ||
125 | video.VideoBlacklist = undefined | ||
126 | |||
127 | // Re federate the video | ||
128 | if (unfederated === true) { | ||
129 | await federateVideoIfNeeded(video, true, t) | ||
130 | } | ||
131 | |||
132 | return videoBlacklistType | ||
133 | }) | ||
134 | |||
135 | Notifier.Instance.notifyOnVideoUnblacklist(video) | ||
136 | |||
137 | if (videoBlacklistType === VideoBlacklistType.AUTO_BEFORE_PUBLISHED) { | ||
138 | Notifier.Instance.notifyOnVideoPublishedAfterRemovedFromAutoBlacklist(video) | ||
139 | |||
140 | // Delete on object so new video notifications will send | ||
141 | delete video.VideoBlacklist | ||
142 | Notifier.Instance.notifyOnNewVideoIfNeeded(video) | ||
143 | } | ||
144 | 104 | ||
145 | logger.info('Video %s removed from blacklist.', video.uuid) | 105 | logger.info('Video %s removed from blacklist.', video.uuid) |
146 | 106 | ||
147 | return res.type('json').status(204).end() | 107 | return res.type('json').sendStatus(204) |
148 | } | 108 | } |
diff --git a/server/controllers/api/videos/comment.ts b/server/controllers/api/videos/comment.ts index 5f3fed5c0..5070bb3c0 100644 --- a/server/controllers/api/videos/comment.ts +++ b/server/controllers/api/videos/comment.ts | |||
@@ -4,7 +4,7 @@ import { ResultList } from '../../../../shared/models' | |||
4 | import { VideoCommentCreate } from '../../../../shared/models/videos/video-comment.model' | 4 | import { VideoCommentCreate } from '../../../../shared/models/videos/video-comment.model' |
5 | import { logger } from '../../../helpers/logger' | 5 | import { logger } from '../../../helpers/logger' |
6 | import { getFormattedObjects } from '../../../helpers/utils' | 6 | import { getFormattedObjects } from '../../../helpers/utils' |
7 | import { sequelizeTypescript } from '../../../initializers' | 7 | import { sequelizeTypescript } from '../../../initializers/database' |
8 | import { buildFormattedCommentTree, createVideoComment, markCommentAsDeleted } from '../../../lib/video-comment' | 8 | import { buildFormattedCommentTree, createVideoComment, markCommentAsDeleted } from '../../../lib/video-comment' |
9 | import { | 9 | import { |
10 | asyncMiddleware, | 10 | asyncMiddleware, |
diff --git a/server/controllers/api/videos/ownership.ts b/server/controllers/api/videos/ownership.ts index 190036f85..540a49010 100644 --- a/server/controllers/api/videos/ownership.ts +++ b/server/controllers/api/videos/ownership.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { logger } from '../../../helpers/logger' | 2 | import { logger } from '../../../helpers/logger' |
3 | import { sequelizeTypescript } from '../../../initializers' | 3 | import { sequelizeTypescript } from '../../../initializers/database' |
4 | import { | 4 | import { |
5 | asyncMiddleware, | 5 | asyncMiddleware, |
6 | asyncRetryTransactionMiddleware, | 6 | asyncRetryTransactionMiddleware, |
diff --git a/server/initializers/index.ts b/server/initializers/index.ts deleted file mode 100644 index 0fc1a7363..000000000 --- a/server/initializers/index.ts +++ /dev/null | |||
@@ -1,3 +0,0 @@ | |||
1 | export * from './database' | ||
2 | export * from './installer' | ||
3 | export * from './migrator' | ||
diff --git a/server/lib/activitypub/process/process-announce.ts b/server/lib/activitypub/process/process-announce.ts index 7e22125d5..26427aaa1 100644 --- a/server/lib/activitypub/process/process-announce.ts +++ b/server/lib/activitypub/process/process-announce.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import { ActivityAnnounce } from '../../../../shared/models/activitypub' | 1 | import { ActivityAnnounce } from '../../../../shared/models/activitypub' |
2 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | 2 | import { retryTransactionWrapper } from '../../../helpers/database-utils' |
3 | import { sequelizeTypescript } from '../../../initializers' | 3 | import { sequelizeTypescript } from '../../../initializers/database' |
4 | import { VideoShareModel } from '../../../models/video/video-share' | 4 | import { VideoShareModel } from '../../../models/video/video-share' |
5 | import { forwardVideoRelatedActivity } from '../send/utils' | 5 | import { forwardVideoRelatedActivity } from '../send/utils' |
6 | import { getOrCreateVideoAndAccountAndChannel } from '../videos' | 6 | import { getOrCreateVideoAndAccountAndChannel } from '../videos' |
diff --git a/server/lib/activitypub/process/process-create.ts b/server/lib/activitypub/process/process-create.ts index d375e29e3..566bf6992 100644 --- a/server/lib/activitypub/process/process-create.ts +++ b/server/lib/activitypub/process/process-create.ts | |||
@@ -2,7 +2,7 @@ import { ActivityCreate, CacheFileObject, VideoTorrentObject } from '../../../.. | |||
2 | import { VideoCommentObject } from '../../../../shared/models/activitypub/objects/video-comment-object' | 2 | import { VideoCommentObject } from '../../../../shared/models/activitypub/objects/video-comment-object' |
3 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | 3 | import { retryTransactionWrapper } from '../../../helpers/database-utils' |
4 | import { logger } from '../../../helpers/logger' | 4 | import { logger } from '../../../helpers/logger' |
5 | import { sequelizeTypescript } from '../../../initializers' | 5 | import { sequelizeTypescript } from '../../../initializers/database' |
6 | import { resolveThread } from '../video-comments' | 6 | import { resolveThread } from '../video-comments' |
7 | import { getOrCreateVideoAndAccountAndChannel } from '../videos' | 7 | import { getOrCreateVideoAndAccountAndChannel } from '../videos' |
8 | import { forwardVideoRelatedActivity } from '../send/utils' | 8 | import { forwardVideoRelatedActivity } from '../send/utils' |
diff --git a/server/lib/activitypub/process/process-delete.ts b/server/lib/activitypub/process/process-delete.ts index e76132f91..7c8dc83e8 100644 --- a/server/lib/activitypub/process/process-delete.ts +++ b/server/lib/activitypub/process/process-delete.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { ActivityDelete } from '../../../../shared/models/activitypub' | 1 | import { ActivityDelete } from '../../../../shared/models/activitypub' |
2 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | 2 | import { retryTransactionWrapper } from '../../../helpers/database-utils' |
3 | import { logger } from '../../../helpers/logger' | 3 | import { logger } from '../../../helpers/logger' |
4 | import { sequelizeTypescript } from '../../../initializers' | 4 | import { sequelizeTypescript } from '../../../initializers/database' |
5 | import { ActorModel } from '../../../models/activitypub/actor' | 5 | import { ActorModel } from '../../../models/activitypub/actor' |
6 | import { VideoModel } from '../../../models/video/video' | 6 | import { VideoModel } from '../../../models/video/video' |
7 | import { VideoCommentModel } from '../../../models/video/video-comment' | 7 | import { VideoCommentModel } from '../../../models/video/video-comment' |
diff --git a/server/lib/activitypub/process/process-dislike.ts b/server/lib/activitypub/process/process-dislike.ts index debd8a67c..fcdd0b86e 100644 --- a/server/lib/activitypub/process/process-dislike.ts +++ b/server/lib/activitypub/process/process-dislike.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { ActivityCreate, ActivityDislike } from '../../../../shared' | 1 | import { ActivityCreate, ActivityDislike } from '../../../../shared' |
2 | import { DislikeObject } from '../../../../shared/models/activitypub/objects' | 2 | import { DislikeObject } from '../../../../shared/models/activitypub/objects' |
3 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | 3 | import { retryTransactionWrapper } from '../../../helpers/database-utils' |
4 | import { sequelizeTypescript } from '../../../initializers' | 4 | import { sequelizeTypescript } from '../../../initializers/database' |
5 | import { AccountVideoRateModel } from '../../../models/account/account-video-rate' | 5 | import { AccountVideoRateModel } from '../../../models/account/account-video-rate' |
6 | import { getOrCreateVideoAndAccountAndChannel } from '../videos' | 6 | import { getOrCreateVideoAndAccountAndChannel } from '../videos' |
7 | import { forwardVideoRelatedActivity } from '../send/utils' | 7 | import { forwardVideoRelatedActivity } from '../send/utils' |
diff --git a/server/lib/activitypub/process/process-flag.ts b/server/lib/activitypub/process/process-flag.ts index e6e9084de..9a488a473 100644 --- a/server/lib/activitypub/process/process-flag.ts +++ b/server/lib/activitypub/process/process-flag.ts | |||
@@ -2,7 +2,7 @@ import { ActivityCreate, ActivityFlag, VideoAbuseState } from '../../../../share | |||
2 | import { VideoAbuseObject } from '../../../../shared/models/activitypub/objects' | 2 | import { VideoAbuseObject } from '../../../../shared/models/activitypub/objects' |
3 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | 3 | import { retryTransactionWrapper } from '../../../helpers/database-utils' |
4 | import { logger } from '../../../helpers/logger' | 4 | import { logger } from '../../../helpers/logger' |
5 | import { sequelizeTypescript } from '../../../initializers' | 5 | import { sequelizeTypescript } from '../../../initializers/database' |
6 | import { VideoAbuseModel } from '../../../models/video/video-abuse' | 6 | import { VideoAbuseModel } from '../../../models/video/video-abuse' |
7 | import { getOrCreateVideoAndAccountAndChannel } from '../videos' | 7 | import { getOrCreateVideoAndAccountAndChannel } from '../videos' |
8 | import { Notifier } from '../../notifier' | 8 | import { Notifier } from '../../notifier' |
diff --git a/server/lib/activitypub/process/process-follow.ts b/server/lib/activitypub/process/process-follow.ts index 8f7828e41..950d421dd 100644 --- a/server/lib/activitypub/process/process-follow.ts +++ b/server/lib/activitypub/process/process-follow.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { ActivityFollow } from '../../../../shared/models/activitypub' | 1 | import { ActivityFollow } from '../../../../shared/models/activitypub' |
2 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | 2 | import { retryTransactionWrapper } from '../../../helpers/database-utils' |
3 | import { logger } from '../../../helpers/logger' | 3 | import { logger } from '../../../helpers/logger' |
4 | import { sequelizeTypescript } from '../../../initializers' | 4 | import { sequelizeTypescript } from '../../../initializers/database' |
5 | import { ActorModel } from '../../../models/activitypub/actor' | 5 | import { ActorModel } from '../../../models/activitypub/actor' |
6 | import { ActorFollowModel } from '../../../models/activitypub/actor-follow' | 6 | import { ActorFollowModel } from '../../../models/activitypub/actor-follow' |
7 | import { sendAccept, sendReject } from '../send' | 7 | import { sendAccept, sendReject } from '../send' |
diff --git a/server/lib/activitypub/process/process-like.ts b/server/lib/activitypub/process/process-like.ts index 62be0de42..fba3c76a4 100644 --- a/server/lib/activitypub/process/process-like.ts +++ b/server/lib/activitypub/process/process-like.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import { ActivityLike } from '../../../../shared/models/activitypub' | 1 | import { ActivityLike } from '../../../../shared/models/activitypub' |
2 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | 2 | import { retryTransactionWrapper } from '../../../helpers/database-utils' |
3 | import { sequelizeTypescript } from '../../../initializers' | 3 | import { sequelizeTypescript } from '../../../initializers/database' |
4 | import { AccountVideoRateModel } from '../../../models/account/account-video-rate' | 4 | import { AccountVideoRateModel } from '../../../models/account/account-video-rate' |
5 | import { forwardVideoRelatedActivity } from '../send/utils' | 5 | import { forwardVideoRelatedActivity } from '../send/utils' |
6 | import { getOrCreateVideoAndAccountAndChannel } from '../videos' | 6 | import { getOrCreateVideoAndAccountAndChannel } from '../videos' |
diff --git a/server/lib/activitypub/process/process-reject.ts b/server/lib/activitypub/process/process-reject.ts index 00e9afa10..9804436a2 100644 --- a/server/lib/activitypub/process/process-reject.ts +++ b/server/lib/activitypub/process/process-reject.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import { ActivityReject } from '../../../../shared/models/activitypub/activity' | 1 | import { ActivityReject } from '../../../../shared/models/activitypub/activity' |
2 | import { sequelizeTypescript } from '../../../initializers' | 2 | import { sequelizeTypescript } from '../../../initializers/database' |
3 | import { ActorFollowModel } from '../../../models/activitypub/actor-follow' | 3 | import { ActorFollowModel } from '../../../models/activitypub/actor-follow' |
4 | import { APProcessorOptions } from '../../../typings/activitypub-processor.model' | 4 | import { APProcessorOptions } from '../../../typings/activitypub-processor.model' |
5 | import { MActor } from '../../../typings/models' | 5 | import { MActor } from '../../../typings/models' |
diff --git a/server/lib/activitypub/process/process-undo.ts b/server/lib/activitypub/process/process-undo.ts index 10643b2e9..9ef6a8a97 100644 --- a/server/lib/activitypub/process/process-undo.ts +++ b/server/lib/activitypub/process/process-undo.ts | |||
@@ -2,7 +2,7 @@ import { ActivityAnnounce, ActivityFollow, ActivityLike, ActivityUndo, CacheFile | |||
2 | import { DislikeObject } from '../../../../shared/models/activitypub/objects' | 2 | import { DislikeObject } from '../../../../shared/models/activitypub/objects' |
3 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | 3 | import { retryTransactionWrapper } from '../../../helpers/database-utils' |
4 | import { logger } from '../../../helpers/logger' | 4 | import { logger } from '../../../helpers/logger' |
5 | import { sequelizeTypescript } from '../../../initializers' | 5 | import { sequelizeTypescript } from '../../../initializers/database' |
6 | import { AccountVideoRateModel } from '../../../models/account/account-video-rate' | 6 | import { AccountVideoRateModel } from '../../../models/account/account-video-rate' |
7 | import { ActorModel } from '../../../models/activitypub/actor' | 7 | import { ActorModel } from '../../../models/activitypub/actor' |
8 | import { ActorFollowModel } from '../../../models/activitypub/actor-follow' | 8 | import { ActorFollowModel } from '../../../models/activitypub/actor-follow' |
diff --git a/server/lib/activitypub/process/process-update.ts b/server/lib/activitypub/process/process-update.ts index 9579512b7..98ab0f83d 100644 --- a/server/lib/activitypub/process/process-update.ts +++ b/server/lib/activitypub/process/process-update.ts | |||
@@ -2,7 +2,7 @@ import { ActivityUpdate, CacheFileObject, VideoTorrentObject } from '../../../.. | |||
2 | import { ActivityPubActor } from '../../../../shared/models/activitypub/activitypub-actor' | 2 | import { ActivityPubActor } from '../../../../shared/models/activitypub/activitypub-actor' |
3 | import { resetSequelizeInstance, retryTransactionWrapper } from '../../../helpers/database-utils' | 3 | import { resetSequelizeInstance, retryTransactionWrapper } from '../../../helpers/database-utils' |
4 | import { logger } from '../../../helpers/logger' | 4 | import { logger } from '../../../helpers/logger' |
5 | import { sequelizeTypescript } from '../../../initializers' | 5 | import { sequelizeTypescript } from '../../../initializers/database' |
6 | import { AccountModel } from '../../../models/account/account' | 6 | import { AccountModel } from '../../../models/account/account' |
7 | import { ActorModel } from '../../../models/activitypub/actor' | 7 | import { ActorModel } from '../../../models/activitypub/actor' |
8 | import { VideoChannelModel } from '../../../models/video/video-channel' | 8 | import { VideoChannelModel } from '../../../models/video/video-channel' |
diff --git a/server/lib/blocklist.ts b/server/lib/blocklist.ts index 28c69b46e..842eecb5b 100644 --- a/server/lib/blocklist.ts +++ b/server/lib/blocklist.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { sequelizeTypescript } from '../initializers' | 1 | import { sequelizeTypescript } from '@server/initializers/database' |
2 | import { MAccountBlocklist, MServerBlocklist } from '@server/typings/models' | ||
2 | import { AccountBlocklistModel } from '../models/account/account-blocklist' | 3 | import { AccountBlocklistModel } from '../models/account/account-blocklist' |
3 | import { ServerBlocklistModel } from '../models/server/server-blocklist' | 4 | import { ServerBlocklistModel } from '../models/server/server-blocklist' |
4 | import { MAccountBlocklist, MServerBlocklist } from '@server/typings/models' | ||
5 | 5 | ||
6 | function addAccountInBlocklist (byAccountId: number, targetAccountId: number) { | 6 | function addAccountInBlocklist (byAccountId: number, targetAccountId: number) { |
7 | return sequelizeTypescript.transaction(async t => { | 7 | return sequelizeTypescript.transaction(async t => { |
diff --git a/server/lib/job-queue/handlers/video-transcoding.ts b/server/lib/job-queue/handlers/video-transcoding.ts index 04aac515f..46d52e1cf 100644 --- a/server/lib/job-queue/handlers/video-transcoding.ts +++ b/server/lib/job-queue/handlers/video-transcoding.ts | |||
@@ -10,7 +10,7 @@ import { VideoModel } from '../../../models/video/video' | |||
10 | import { JobQueue } from '../job-queue' | 10 | import { JobQueue } from '../job-queue' |
11 | import { federateVideoIfNeeded } from '../../activitypub/videos' | 11 | import { federateVideoIfNeeded } from '../../activitypub/videos' |
12 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | 12 | import { retryTransactionWrapper } from '../../../helpers/database-utils' |
13 | import { sequelizeTypescript } from '../../../initializers' | 13 | import { sequelizeTypescript } from '../../../initializers/database' |
14 | import { computeResolutionsToTranscode } from '../../../helpers/ffmpeg-utils' | 14 | import { computeResolutionsToTranscode } from '../../../helpers/ffmpeg-utils' |
15 | import { generateHlsPlaylist, mergeAudioVideofile, optimizeOriginalVideofile, transcodeNewResolution } from '../../video-transcoding' | 15 | import { generateHlsPlaylist, mergeAudioVideofile, optimizeOriginalVideofile, transcodeNewResolution } from '../../video-transcoding' |
16 | import { Notifier } from '../../notifier' | 16 | import { Notifier } from '../../notifier' |
diff --git a/server/lib/plugins/plugin-helpers.ts b/server/lib/plugins/plugin-helpers.ts index 608207e05..de82b4918 100644 --- a/server/lib/plugins/plugin-helpers.ts +++ b/server/lib/plugins/plugin-helpers.ts | |||
@@ -3,6 +3,15 @@ import { sequelizeTypescript } from '@server/initializers/database' | |||
3 | import { buildLogger } from '@server/helpers/logger' | 3 | import { buildLogger } from '@server/helpers/logger' |
4 | import { VideoModel } from '@server/models/video/video' | 4 | import { VideoModel } from '@server/models/video/video' |
5 | import { WEBSERVER } from '@server/initializers/constants' | 5 | import { WEBSERVER } from '@server/initializers/constants' |
6 | import { ServerModel } from '@server/models/server/server' | ||
7 | import { getServerActor } from '@server/models/application/application' | ||
8 | import { addServerInBlocklist, removeServerFromBlocklist, addAccountInBlocklist, removeAccountFromBlocklist } from '../blocklist' | ||
9 | import { ServerBlocklistModel } from '@server/models/server/server-blocklist' | ||
10 | import { AccountModel } from '@server/models/account/account' | ||
11 | import { VideoBlacklistCreate } from '@shared/models' | ||
12 | import { blacklistVideo, unblacklistVideo } from '../video-blacklist' | ||
13 | import { VideoBlacklistModel } from '@server/models/video/video-blacklist' | ||
14 | import { AccountBlocklistModel } from '@server/models/account/account-blocklist' | ||
6 | 15 | ||
7 | function buildPluginHelpers (npmName: string): PeerTubeHelpers { | 16 | function buildPluginHelpers (npmName: string): PeerTubeHelpers { |
8 | const logger = buildPluginLogger(npmName) | 17 | const logger = buildPluginLogger(npmName) |
@@ -12,11 +21,17 @@ function buildPluginHelpers (npmName: string): PeerTubeHelpers { | |||
12 | 21 | ||
13 | const config = buildConfigHelpers() | 22 | const config = buildConfigHelpers() |
14 | 23 | ||
24 | const server = buildServerHelpers() | ||
25 | |||
26 | const moderation = buildModerationHelpers() | ||
27 | |||
15 | return { | 28 | return { |
16 | logger, | 29 | logger, |
17 | database, | 30 | database, |
18 | videos, | 31 | videos, |
19 | config | 32 | config, |
33 | moderation, | ||
34 | server | ||
20 | } | 35 | } |
21 | } | 36 | } |
22 | 37 | ||
@@ -36,8 +51,18 @@ function buildDatabaseHelpers () { | |||
36 | } | 51 | } |
37 | } | 52 | } |
38 | 53 | ||
54 | function buildServerHelpers () { | ||
55 | return { | ||
56 | getServerActor: () => getServerActor() | ||
57 | } | ||
58 | } | ||
59 | |||
39 | function buildVideosHelpers () { | 60 | function buildVideosHelpers () { |
40 | return { | 61 | return { |
62 | loadByUrl: (url: string) => { | ||
63 | return VideoModel.loadByUrl(url) | ||
64 | }, | ||
65 | |||
41 | removeVideo: (id: number) => { | 66 | removeVideo: (id: number) => { |
42 | return sequelizeTypescript.transaction(async t => { | 67 | return sequelizeTypescript.transaction(async t => { |
43 | const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(id, t) | 68 | const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(id, t) |
@@ -48,6 +73,57 @@ function buildVideosHelpers () { | |||
48 | } | 73 | } |
49 | } | 74 | } |
50 | 75 | ||
76 | function buildModerationHelpers () { | ||
77 | return { | ||
78 | blockServer: async (options: { byAccountId: number, hostToBlock: string }) => { | ||
79 | const serverToBlock = await ServerModel.loadOrCreateByHost(options.hostToBlock) | ||
80 | |||
81 | await addServerInBlocklist(options.byAccountId, serverToBlock.id) | ||
82 | }, | ||
83 | |||
84 | unblockServer: async (options: { byAccountId: number, hostToUnblock: string }) => { | ||
85 | const serverBlock = await ServerBlocklistModel.loadByAccountAndHost(options.byAccountId, options.hostToUnblock) | ||
86 | if (!serverBlock) return | ||
87 | |||
88 | await removeServerFromBlocklist(serverBlock) | ||
89 | }, | ||
90 | |||
91 | blockAccount: async (options: { byAccountId: number, handleToBlock: string }) => { | ||
92 | const accountToBlock = await AccountModel.loadByNameWithHost(options.handleToBlock) | ||
93 | if (!accountToBlock) return | ||
94 | |||
95 | await addAccountInBlocklist(options.byAccountId, accountToBlock.id) | ||
96 | }, | ||
97 | |||
98 | unblockAccount: async (options: { byAccountId: number, handleToUnblock: string }) => { | ||
99 | const targetAccount = await AccountModel.loadByNameWithHost(options.handleToUnblock) | ||
100 | if (!targetAccount) return | ||
101 | |||
102 | const accountBlock = await AccountBlocklistModel.loadByAccountAndTarget(options.byAccountId, targetAccount.id) | ||
103 | if (!accountBlock) return | ||
104 | |||
105 | await removeAccountFromBlocklist(accountBlock) | ||
106 | }, | ||
107 | |||
108 | blacklistVideo: async (options: { videoIdOrUUID: number | string, createOptions: VideoBlacklistCreate }) => { | ||
109 | const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(options.videoIdOrUUID) | ||
110 | if (!video) return | ||
111 | |||
112 | await blacklistVideo(video, options.createOptions) | ||
113 | }, | ||
114 | |||
115 | unblacklistVideo: async (options: { videoIdOrUUID: number | string }) => { | ||
116 | const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(options.videoIdOrUUID) | ||
117 | if (!video) return | ||
118 | |||
119 | const videoBlacklist = await VideoBlacklistModel.loadByVideoId(video.id) | ||
120 | if (!videoBlacklist) return | ||
121 | |||
122 | await unblacklistVideo(videoBlacklist, video) | ||
123 | } | ||
124 | } | ||
125 | } | ||
126 | |||
51 | function buildConfigHelpers () { | 127 | function buildConfigHelpers () { |
52 | return { | 128 | return { |
53 | getWebserverUrl () { | 129 | getWebserverUrl () { |
diff --git a/server/lib/video-blacklist.ts b/server/lib/video-blacklist.ts index 3b90b1b94..bd60c6201 100644 --- a/server/lib/video-blacklist.ts +++ b/server/lib/video-blacklist.ts | |||
@@ -1,12 +1,22 @@ | |||
1 | import { Transaction } from 'sequelize' | 1 | import { Transaction } from 'sequelize' |
2 | import { sequelizeTypescript } from '@server/initializers/database' | ||
3 | import { | ||
4 | MUser, | ||
5 | MVideoAccountLight, | ||
6 | MVideoBlacklist, | ||
7 | MVideoBlacklistVideo, | ||
8 | MVideoFullLight, | ||
9 | MVideoWithBlacklistLight | ||
10 | } from '@server/typings/models' | ||
11 | import { UserRight, VideoBlacklistCreate, VideoBlacklistType } from '../../shared/models' | ||
12 | import { UserAdminFlag } from '../../shared/models/users/user-flag.model' | ||
13 | import { logger } from '../helpers/logger' | ||
2 | import { CONFIG } from '../initializers/config' | 14 | import { CONFIG } from '../initializers/config' |
3 | import { UserRight, VideoBlacklistType } from '../../shared/models' | ||
4 | import { VideoBlacklistModel } from '../models/video/video-blacklist' | 15 | import { VideoBlacklistModel } from '../models/video/video-blacklist' |
5 | import { logger } from '../helpers/logger' | 16 | import { sendDeleteVideo } from './activitypub/send' |
6 | import { UserAdminFlag } from '../../shared/models/users/user-flag.model' | 17 | import { federateVideoIfNeeded } from './activitypub/videos' |
7 | import { Hooks } from './plugins/hooks' | ||
8 | import { Notifier } from './notifier' | 18 | import { Notifier } from './notifier' |
9 | import { MUser, MVideoBlacklistVideo, MVideoWithBlacklistLight } from '@server/typings/models' | 19 | import { Hooks } from './plugins/hooks' |
10 | 20 | ||
11 | async function autoBlacklistVideoIfNeeded (parameters: { | 21 | async function autoBlacklistVideoIfNeeded (parameters: { |
12 | video: MVideoWithBlacklistLight | 22 | video: MVideoWithBlacklistLight |
@@ -49,6 +59,60 @@ async function autoBlacklistVideoIfNeeded (parameters: { | |||
49 | return true | 59 | return true |
50 | } | 60 | } |
51 | 61 | ||
62 | async function blacklistVideo (videoInstance: MVideoAccountLight, options: VideoBlacklistCreate) { | ||
63 | const blacklist: MVideoBlacklistVideo = await VideoBlacklistModel.create({ | ||
64 | videoId: videoInstance.id, | ||
65 | unfederated: options.unfederate === true, | ||
66 | reason: options.reason, | ||
67 | type: VideoBlacklistType.MANUAL | ||
68 | } | ||
69 | ) | ||
70 | blacklist.Video = videoInstance | ||
71 | |||
72 | if (options.unfederate === true) { | ||
73 | await sendDeleteVideo(videoInstance, undefined) | ||
74 | } | ||
75 | |||
76 | Notifier.Instance.notifyOnVideoBlacklist(blacklist) | ||
77 | } | ||
78 | |||
79 | async function unblacklistVideo (videoBlacklist: MVideoBlacklist, video: MVideoFullLight) { | ||
80 | const videoBlacklistType = await sequelizeTypescript.transaction(async t => { | ||
81 | const unfederated = videoBlacklist.unfederated | ||
82 | const videoBlacklistType = videoBlacklist.type | ||
83 | |||
84 | await videoBlacklist.destroy({ transaction: t }) | ||
85 | video.VideoBlacklist = undefined | ||
86 | |||
87 | // Re federate the video | ||
88 | if (unfederated === true) { | ||
89 | await federateVideoIfNeeded(video, true, t) | ||
90 | } | ||
91 | |||
92 | return videoBlacklistType | ||
93 | }) | ||
94 | |||
95 | Notifier.Instance.notifyOnVideoUnblacklist(video) | ||
96 | |||
97 | if (videoBlacklistType === VideoBlacklistType.AUTO_BEFORE_PUBLISHED) { | ||
98 | Notifier.Instance.notifyOnVideoPublishedAfterRemovedFromAutoBlacklist(video) | ||
99 | |||
100 | // Delete on object so new video notifications will send | ||
101 | delete video.VideoBlacklist | ||
102 | Notifier.Instance.notifyOnNewVideoIfNeeded(video) | ||
103 | } | ||
104 | } | ||
105 | |||
106 | // --------------------------------------------------------------------------- | ||
107 | |||
108 | export { | ||
109 | autoBlacklistVideoIfNeeded, | ||
110 | blacklistVideo, | ||
111 | unblacklistVideo | ||
112 | } | ||
113 | |||
114 | // --------------------------------------------------------------------------- | ||
115 | |||
52 | function autoBlacklistNeeded (parameters: { | 116 | function autoBlacklistNeeded (parameters: { |
53 | video: MVideoWithBlacklistLight | 117 | video: MVideoWithBlacklistLight |
54 | isRemote: boolean | 118 | isRemote: boolean |
@@ -66,9 +130,3 @@ function autoBlacklistNeeded (parameters: { | |||
66 | 130 | ||
67 | return true | 131 | return true |
68 | } | 132 | } |
69 | |||
70 | // --------------------------------------------------------------------------- | ||
71 | |||
72 | export { | ||
73 | autoBlacklistVideoIfNeeded | ||
74 | } | ||
diff --git a/server/middlewares/validators/blocklist.ts b/server/middlewares/validators/blocklist.ts index c00a7e4df..27224ff9b 100644 --- a/server/middlewares/validators/blocklist.ts +++ b/server/middlewares/validators/blocklist.ts | |||
@@ -84,10 +84,7 @@ const blockServerValidator = [ | |||
84 | .end() | 84 | .end() |
85 | } | 85 | } |
86 | 86 | ||
87 | let server = await ServerModel.loadByHost(host) | 87 | const server = await ServerModel.loadOrCreateByHost(host) |
88 | if (!server) { | ||
89 | server = await ServerModel.create({ host }) | ||
90 | } | ||
91 | 88 | ||
92 | res.locals.server = server | 89 | res.locals.server = server |
93 | 90 | ||
diff --git a/server/models/server/server.ts b/server/models/server/server.ts index 8b07115f1..5131257ec 100644 --- a/server/models/server/server.ts +++ b/server/models/server/server.ts | |||
@@ -71,6 +71,13 @@ export class ServerModel extends Model<ServerModel> { | |||
71 | return ServerModel.findOne(query) | 71 | return ServerModel.findOne(query) |
72 | } | 72 | } |
73 | 73 | ||
74 | static async loadOrCreateByHost (host: string) { | ||
75 | let server = await ServerModel.loadByHost(host) | ||
76 | if (!server) server = await ServerModel.create({ host }) | ||
77 | |||
78 | return server | ||
79 | } | ||
80 | |||
74 | isBlocked () { | 81 | isBlocked () { |
75 | return this.BlockedByAccounts && this.BlockedByAccounts.length !== 0 | 82 | return this.BlockedByAccounts && this.BlockedByAccounts.length !== 0 |
76 | } | 83 | } |
diff --git a/server/tests/fixtures/peertube-plugin-test-four/main.js b/server/tests/fixtures/peertube-plugin-test-four/main.js index 2e81550c1..067c3fe15 100644 --- a/server/tests/fixtures/peertube-plugin-test-four/main.js +++ b/server/tests/fixtures/peertube-plugin-test-four/main.js | |||
@@ -1,30 +1,70 @@ | |||
1 | async function register ({ | 1 | async function register ({ |
2 | peertubeHelpers, | 2 | peertubeHelpers, |
3 | registerHook | 3 | registerHook, |
4 | getRouter | ||
4 | }) { | 5 | }) { |
5 | const logger = peertubeHelpers.logger | 6 | const logger = peertubeHelpers.logger |
6 | 7 | ||
7 | logger.info('Hello world from plugin four') | 8 | logger.info('Hello world from plugin four') |
8 | 9 | ||
9 | const username = 'root' | 10 | { |
10 | const results = await peertubeHelpers.database.query( | 11 | const username = 'root' |
11 | 'SELECT "email" from "user" WHERE "username" = $username', | 12 | const results = await peertubeHelpers.database.query( |
12 | { | 13 | 'SELECT "email" from "user" WHERE "username" = $username', |
13 | type: 'SELECT', | 14 | { |
14 | bind: { username } | 15 | type: 'SELECT', |
15 | } | 16 | bind: { username } |
16 | ) | 17 | } |
18 | ) | ||
19 | |||
20 | logger.info('root email is ' + results[0]['email']) | ||
21 | } | ||
22 | |||
23 | { | ||
24 | registerHook({ | ||
25 | target: 'action:api.video.viewed', | ||
26 | handler: async ({ video }) => { | ||
27 | const videoFromDB = await peertubeHelpers.videos.loadByUrl(video.url) | ||
28 | logger.info('video from DB uuid is %s.', videoFromDB.uuid) | ||
29 | |||
30 | await peertubeHelpers.videos.removeVideo(video.id) | ||
17 | 31 | ||
18 | logger.info('root email is ' + results[0]['email']) | 32 | logger.info('Video deleted by plugin four.') |
33 | } | ||
34 | }) | ||
35 | } | ||
19 | 36 | ||
20 | registerHook({ | 37 | { |
21 | target: 'action:api.video.viewed', | 38 | const serverActor = await peertubeHelpers.server.getServerActor() |
22 | handler: async ({ video }) => { | 39 | logger.info('server actor name is %s', serverActor.preferredUsername) |
23 | await peertubeHelpers.videos.removeVideo(video.id) | 40 | } |
24 | 41 | ||
25 | logger.info('Video deleted by plugin four.') | 42 | { |
43 | logger.info('server url is %s', peertubeHelpers.config.getWebserverUrl()) | ||
44 | } | ||
45 | |||
46 | { | ||
47 | const actions = { | ||
48 | blockServer, | ||
49 | unblockServer, | ||
50 | blockAccount, | ||
51 | unblockAccount, | ||
52 | blacklist, | ||
53 | unblacklist | ||
26 | } | 54 | } |
27 | }) | 55 | |
56 | const router = getRouter() | ||
57 | router.post('/commander', async (req, res) => { | ||
58 | try { | ||
59 | await actions[req.body.command](peertubeHelpers, req.body) | ||
60 | |||
61 | res.sendStatus(204) | ||
62 | } catch (err) { | ||
63 | logger.error('Error in commander.', { err }) | ||
64 | res.sendStatus(500) | ||
65 | } | ||
66 | }) | ||
67 | } | ||
28 | } | 68 | } |
29 | 69 | ||
30 | async function unregister () { | 70 | async function unregister () { |
@@ -37,3 +77,38 @@ module.exports = { | |||
37 | } | 77 | } |
38 | 78 | ||
39 | // ########################################################################### | 79 | // ########################################################################### |
80 | |||
81 | async function blockServer (peertubeHelpers, body) { | ||
82 | const serverActor = await peertubeHelpers.server.getServerActor() | ||
83 | |||
84 | await peertubeHelpers.moderation.blockServer({ byAccountId: serverActor.Account.id, hostToBlock: body.hostToBlock }) | ||
85 | } | ||
86 | |||
87 | async function unblockServer (peertubeHelpers, body) { | ||
88 | const serverActor = await peertubeHelpers.server.getServerActor() | ||
89 | |||
90 | await peertubeHelpers.moderation.unblockServer({ byAccountId: serverActor.Account.id, hostToUnblock: body.hostToUnblock }) | ||
91 | } | ||
92 | |||
93 | async function blockAccount (peertubeHelpers, body) { | ||
94 | const serverActor = await peertubeHelpers.server.getServerActor() | ||
95 | |||
96 | await peertubeHelpers.moderation.blockAccount({ byAccountId: serverActor.Account.id, handleToBlock: body.handleToBlock }) | ||
97 | } | ||
98 | |||
99 | async function unblockAccount (peertubeHelpers, body) { | ||
100 | const serverActor = await peertubeHelpers.server.getServerActor() | ||
101 | |||
102 | await peertubeHelpers.moderation.unblockAccount({ byAccountId: serverActor.Account.id, handleToUnblock: body.handleToUnblock }) | ||
103 | } | ||
104 | |||
105 | async function blacklist (peertubeHelpers, body) { | ||
106 | await peertubeHelpers.moderation.blacklistVideo({ | ||
107 | videoIdOrUUID: body.videoUUID, | ||
108 | createOptions: body | ||
109 | }) | ||
110 | } | ||
111 | |||
112 | async function unblacklist (peertubeHelpers, body) { | ||
113 | await peertubeHelpers.moderation.unblacklistVideo({ videoIdOrUUID: body.videoUUID }) | ||
114 | } | ||
diff --git a/server/tests/plugins/plugin-helpers.ts b/server/tests/plugins/plugin-helpers.ts index dfe8ebe55..0915603d0 100644 --- a/server/tests/plugins/plugin-helpers.ts +++ b/server/tests/plugins/plugin-helpers.ts | |||
@@ -1,66 +1,210 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | 1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ |
2 | 2 | ||
3 | import 'mocha' | 3 | import 'mocha' |
4 | import { cleanupTests, flushAndRunServer, ServerInfo, waitUntilLog } from '../../../shared/extra-utils/server/servers' | ||
5 | import { | 4 | import { |
6 | checkVideoFilesWereRemoved, | 5 | checkVideoFilesWereRemoved, |
6 | doubleFollow, | ||
7 | getPluginTestPath, | 7 | getPluginTestPath, |
8 | getVideo, | 8 | getVideo, |
9 | installPlugin, | 9 | installPlugin, |
10 | makePostBodyRequest, | ||
10 | setAccessTokensToServers, | 11 | setAccessTokensToServers, |
11 | uploadVideoAndGetId, | 12 | uploadVideoAndGetId, |
12 | viewVideo | 13 | viewVideo, |
14 | getVideosList, | ||
15 | waitJobs | ||
13 | } from '../../../shared/extra-utils' | 16 | } from '../../../shared/extra-utils' |
17 | import { cleanupTests, flushAndRunMultipleServers, ServerInfo, waitUntilLog } from '../../../shared/extra-utils/server/servers' | ||
18 | import { expect } from 'chai' | ||
19 | |||
20 | function postCommand (server: ServerInfo, command: string, bodyArg?: object) { | ||
21 | const body = { command } | ||
22 | if (bodyArg) Object.assign(body, bodyArg) | ||
23 | |||
24 | return makePostBodyRequest({ | ||
25 | url: server.url, | ||
26 | path: '/plugins/test-four/router/commander', | ||
27 | fields: body, | ||
28 | statusCodeExpected: 204 | ||
29 | }) | ||
30 | } | ||
14 | 31 | ||
15 | describe('Test plugin helpers', function () { | 32 | describe('Test plugin helpers', function () { |
16 | let server: ServerInfo | 33 | let servers: ServerInfo[] |
17 | 34 | ||
18 | before(async function () { | 35 | before(async function () { |
19 | this.timeout(30000) | 36 | this.timeout(60000) |
37 | |||
38 | servers = await flushAndRunMultipleServers(2) | ||
39 | await setAccessTokensToServers(servers) | ||
20 | 40 | ||
21 | server = await flushAndRunServer(1) | 41 | await doubleFollow(servers[0], servers[1]) |
22 | await setAccessTokensToServers([ server ]) | ||
23 | 42 | ||
24 | await installPlugin({ | 43 | await installPlugin({ |
25 | url: server.url, | 44 | url: servers[0].url, |
26 | accessToken: server.accessToken, | 45 | accessToken: servers[0].accessToken, |
27 | path: getPluginTestPath('-four') | 46 | path: getPluginTestPath('-four') |
28 | }) | 47 | }) |
29 | }) | 48 | }) |
30 | 49 | ||
31 | it('Should have logged things', async function () { | 50 | describe('Logger', function () { |
32 | await waitUntilLog(server, 'localhost:' + server.port + ' peertube-plugin-test-four', 1, false) | 51 | |
33 | await waitUntilLog(server, 'Hello world from plugin four', 1) | 52 | it('Should have logged things', async function () { |
53 | await waitUntilLog(servers[0], 'localhost:' + servers[0].port + ' peertube-plugin-test-four', 1, false) | ||
54 | await waitUntilLog(servers[0], 'Hello world from plugin four', 1) | ||
55 | }) | ||
34 | }) | 56 | }) |
35 | 57 | ||
36 | it('Should have made a query', async function () { | 58 | describe('Database', function () { |
37 | await waitUntilLog(server, `root email is admin${server.internalServerNumber}@example.com`, 1) | 59 | |
60 | it('Should have made a query', async function () { | ||
61 | await waitUntilLog(servers[0], `root email is admin${servers[0].internalServerNumber}@example.com`) | ||
62 | }) | ||
63 | }) | ||
64 | |||
65 | describe('Config', function () { | ||
66 | |||
67 | it('Should have the correct webserver url', async function () { | ||
68 | await waitUntilLog(servers[0], `server url is http://localhost:${servers[0].port}`) | ||
69 | }) | ||
70 | }) | ||
71 | |||
72 | describe('Server', function () { | ||
73 | |||
74 | it('Should get the server actor', async function () { | ||
75 | await waitUntilLog(servers[0], 'server actor name is peertube') | ||
76 | }) | ||
77 | }) | ||
78 | |||
79 | describe('Moderation', function () { | ||
80 | let videoUUIDServer1: string | ||
81 | |||
82 | before(async function () { | ||
83 | this.timeout(15000) | ||
84 | |||
85 | { | ||
86 | const res = await uploadVideoAndGetId({ server: servers[0], videoName: 'video server 1' }) | ||
87 | videoUUIDServer1 = res.uuid | ||
88 | } | ||
89 | |||
90 | { | ||
91 | await uploadVideoAndGetId({ server: servers[1], videoName: 'video server 2' }) | ||
92 | } | ||
93 | |||
94 | await waitJobs(servers) | ||
95 | |||
96 | const res = await getVideosList(servers[0].url) | ||
97 | const videos = res.body.data | ||
98 | |||
99 | expect(videos).to.have.lengthOf(2) | ||
100 | }) | ||
101 | |||
102 | it('Should mute server 2', async function () { | ||
103 | this.timeout(10000) | ||
104 | await postCommand(servers[0], 'blockServer', { hostToBlock: `localhost:${servers[1].port}` }) | ||
105 | |||
106 | const res = await getVideosList(servers[0].url) | ||
107 | const videos = res.body.data | ||
108 | |||
109 | expect(videos).to.have.lengthOf(1) | ||
110 | expect(videos[0].name).to.equal('video server 1') | ||
111 | }) | ||
112 | |||
113 | it('Should unmute server 2', async function () { | ||
114 | await postCommand(servers[0], 'unblockServer', { hostToUnblock: `localhost:${servers[1].port}` }) | ||
115 | |||
116 | const res = await getVideosList(servers[0].url) | ||
117 | const videos = res.body.data | ||
118 | |||
119 | expect(videos).to.have.lengthOf(2) | ||
120 | }) | ||
121 | |||
122 | it('Should mute account of server 2', async function () { | ||
123 | await postCommand(servers[0], 'blockAccount', { handleToBlock: `root@localhost:${servers[1].port}` }) | ||
124 | |||
125 | const res = await getVideosList(servers[0].url) | ||
126 | const videos = res.body.data | ||
127 | |||
128 | expect(videos).to.have.lengthOf(1) | ||
129 | expect(videos[0].name).to.equal('video server 1') | ||
130 | }) | ||
131 | |||
132 | it('Should unmute account of server 2', async function () { | ||
133 | await postCommand(servers[0], 'unblockAccount', { handleToUnblock: `root@localhost:${servers[1].port}` }) | ||
134 | |||
135 | const res = await getVideosList(servers[0].url) | ||
136 | const videos = res.body.data | ||
137 | |||
138 | expect(videos).to.have.lengthOf(2) | ||
139 | }) | ||
140 | |||
141 | it('Should blacklist video', async function () { | ||
142 | this.timeout(10000) | ||
143 | |||
144 | await postCommand(servers[0], 'blacklist', { videoUUID: videoUUIDServer1, unfederate: true }) | ||
145 | |||
146 | await waitJobs(servers) | ||
147 | |||
148 | for (const server of servers) { | ||
149 | const res = await getVideosList(server.url) | ||
150 | const videos = res.body.data | ||
151 | |||
152 | expect(videos).to.have.lengthOf(1) | ||
153 | expect(videos[0].name).to.equal('video server 2') | ||
154 | } | ||
155 | }) | ||
156 | |||
157 | it('Should unblacklist video', async function () { | ||
158 | this.timeout(10000) | ||
159 | |||
160 | await postCommand(servers[0], 'unblacklist', { videoUUID: videoUUIDServer1 }) | ||
161 | |||
162 | await waitJobs(servers) | ||
163 | |||
164 | for (const server of servers) { | ||
165 | const res = await getVideosList(server.url) | ||
166 | const videos = res.body.data | ||
167 | |||
168 | expect(videos).to.have.lengthOf(2) | ||
169 | } | ||
170 | }) | ||
38 | }) | 171 | }) |
39 | 172 | ||
40 | it('Should remove a video after a view', async function () { | 173 | describe('Videos', function () { |
41 | this.timeout(20000) | 174 | let videoUUID: string |
175 | |||
176 | before(async () => { | ||
177 | const res = await uploadVideoAndGetId({ server: servers[0], videoName: 'video1' }) | ||
178 | videoUUID = res.uuid | ||
179 | }) | ||
42 | 180 | ||
43 | const videoUUID = (await uploadVideoAndGetId({ server: server, videoName: 'video1' })).uuid | 181 | it('Should remove a video after a view', async function () { |
182 | this.timeout(20000) | ||
44 | 183 | ||
45 | // Should not throw -> video exists | 184 | // Should not throw -> video exists |
46 | await getVideo(server.url, videoUUID) | 185 | await getVideo(servers[0].url, videoUUID) |
47 | // Should delete the video | 186 | // Should delete the video |
48 | await viewVideo(server.url, videoUUID) | 187 | await viewVideo(servers[0].url, videoUUID) |
49 | 188 | ||
50 | await waitUntilLog(server, 'Video deleted by plugin four.', 1) | 189 | await waitUntilLog(servers[0], 'Video deleted by plugin four.') |
51 | 190 | ||
52 | try { | 191 | try { |
53 | // Should throw because the video should have been deleted | 192 | // Should throw because the video should have been deleted |
54 | await getVideo(server.url, videoUUID) | 193 | await getVideo(servers[0].url, videoUUID) |
55 | throw new Error('Video exists') | 194 | throw new Error('Video exists') |
56 | } catch (err) { | 195 | } catch (err) { |
57 | if (err.message.includes('exists')) throw err | 196 | if (err.message.includes('exists')) throw err |
58 | } | 197 | } |
59 | 198 | ||
60 | await checkVideoFilesWereRemoved(videoUUID, server.internalServerNumber) | 199 | await checkVideoFilesWereRemoved(videoUUID, servers[0].internalServerNumber) |
200 | }) | ||
201 | |||
202 | it('Should have fetched the video by URL', async function () { | ||
203 | await waitUntilLog(servers[0], `video from DB uuid is ${videoUUID}`) | ||
204 | }) | ||
61 | }) | 205 | }) |
62 | 206 | ||
63 | after(async function () { | 207 | after(async function () { |
64 | await cleanupTests([ server ]) | 208 | await cleanupTests(servers) |
65 | }) | 209 | }) |
66 | }) | 210 | }) |
diff --git a/server/typings/plugins/register-server-option.model.ts b/server/typings/plugins/register-server-option.model.ts index 7f933b43a..8f1d66007 100644 --- a/server/typings/plugins/register-server-option.model.ts +++ b/server/typings/plugins/register-server-option.model.ts | |||
@@ -1,19 +1,23 @@ | |||
1 | import { PluginSettingsManager } from '../../../shared/models/plugins/plugin-settings-manager.model' | 1 | import * as Bluebird from 'bluebird' |
2 | import { PluginStorageManager } from '../../../shared/models/plugins/plugin-storage-manager.model' | ||
3 | import { RegisterServerHookOptions } from '../../../shared/models/plugins/register-server-hook.model' | ||
4 | import { RegisterServerSettingOptions } from '../../../shared/models/plugins/register-server-setting.model' | ||
5 | import { PluginVideoCategoryManager } from '../../../shared/models/plugins/plugin-video-category-manager.model' | ||
6 | import { PluginVideoLanguageManager } from '../../../shared/models/plugins/plugin-video-language-manager.model' | ||
7 | import { PluginVideoLicenceManager } from '../../../shared/models/plugins/plugin-video-licence-manager.model' | ||
8 | import { Logger } from 'winston' | ||
9 | import { Router } from 'express' | 2 | import { Router } from 'express' |
10 | import { PluginVideoPrivacyManager } from '@shared/models/plugins/plugin-video-privacy-manager.model' | 3 | import { Logger } from 'winston' |
4 | import { ActorModel } from '@server/models/activitypub/actor' | ||
5 | import { VideoBlacklistCreate } from '@shared/models' | ||
11 | import { PluginPlaylistPrivacyManager } from '@shared/models/plugins/plugin-playlist-privacy-manager.model' | 6 | import { PluginPlaylistPrivacyManager } from '@shared/models/plugins/plugin-playlist-privacy-manager.model' |
7 | import { PluginVideoPrivacyManager } from '@shared/models/plugins/plugin-video-privacy-manager.model' | ||
12 | import { | 8 | import { |
13 | RegisterServerAuthExternalOptions, | 9 | RegisterServerAuthExternalOptions, |
14 | RegisterServerAuthExternalResult, | 10 | RegisterServerAuthExternalResult, |
15 | RegisterServerAuthPassOptions | 11 | RegisterServerAuthPassOptions |
16 | } from '@shared/models/plugins/register-server-auth.model' | 12 | } from '@shared/models/plugins/register-server-auth.model' |
13 | import { PluginSettingsManager } from '../../../shared/models/plugins/plugin-settings-manager.model' | ||
14 | import { PluginStorageManager } from '../../../shared/models/plugins/plugin-storage-manager.model' | ||
15 | import { PluginVideoCategoryManager } from '../../../shared/models/plugins/plugin-video-category-manager.model' | ||
16 | import { PluginVideoLanguageManager } from '../../../shared/models/plugins/plugin-video-language-manager.model' | ||
17 | import { PluginVideoLicenceManager } from '../../../shared/models/plugins/plugin-video-licence-manager.model' | ||
18 | import { RegisterServerHookOptions } from '../../../shared/models/plugins/register-server-hook.model' | ||
19 | import { RegisterServerSettingOptions } from '../../../shared/models/plugins/register-server-setting.model' | ||
20 | import { MVideoThumbnail } from '../models' | ||
17 | 21 | ||
18 | export type PeerTubeHelpers = { | 22 | export type PeerTubeHelpers = { |
19 | logger: Logger | 23 | logger: Logger |
@@ -23,12 +27,28 @@ export type PeerTubeHelpers = { | |||
23 | } | 27 | } |
24 | 28 | ||
25 | videos: { | 29 | videos: { |
30 | loadByUrl: (url: string) => Bluebird<MVideoThumbnail> | ||
31 | |||
26 | removeVideo: (videoId: number) => Promise<void> | 32 | removeVideo: (videoId: number) => Promise<void> |
27 | } | 33 | } |
28 | 34 | ||
29 | config: { | 35 | config: { |
30 | getWebserverUrl: () => string | 36 | getWebserverUrl: () => string |
31 | } | 37 | } |
38 | |||
39 | moderation: { | ||
40 | blockServer: (options: { byAccountId: number, hostToBlock: string }) => Promise<void> | ||
41 | unblockServer: (options: { byAccountId: number, hostToUnblock: string }) => Promise<void> | ||
42 | blockAccount: (options: { byAccountId: number, handleToBlock: string }) => Promise<void> | ||
43 | unblockAccount: (options: { byAccountId: number, handleToUnblock: string }) => Promise<void> | ||
44 | |||
45 | blacklistVideo: (options: { videoIdOrUUID: number | string, createOptions: VideoBlacklistCreate }) => Promise<void> | ||
46 | unblacklistVideo: (options: { videoIdOrUUID: number | string }) => Promise<void> | ||
47 | } | ||
48 | |||
49 | server: { | ||
50 | getServerActor: () => Promise<ActorModel> | ||
51 | } | ||
32 | } | 52 | } |
33 | 53 | ||
34 | export type RegisterServerOptions = { | 54 | export type RegisterServerOptions = { |