diff options
author | Chocobozzz <me@florianbigard.com> | 2019-08-30 16:50:12 +0200 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2019-09-04 16:24:58 +0200 |
commit | 8424c4026afd7304880a4ce8138a04ffb3d8c938 (patch) | |
tree | 5b42625a59307b03333aa7d293b40b4c90da8f73 /server/lib | |
parent | f69ec5f340638ef577e8f5b9b1fb844778656a1f (diff) | |
download | PeerTube-8424c4026afd7304880a4ce8138a04ffb3d8c938.tar.gz PeerTube-8424c4026afd7304880a4ce8138a04ffb3d8c938.tar.zst PeerTube-8424c4026afd7304880a4ce8138a04ffb3d8c938.zip |
Add auto follow back support for instances
Diffstat (limited to 'server/lib')
-rw-r--r-- | server/lib/activitypub/follow.ts | 36 | ||||
-rw-r--r-- | server/lib/activitypub/process/process-accept.ts | 2 | ||||
-rw-r--r-- | server/lib/activitypub/process/process-follow.ts | 20 | ||||
-rw-r--r-- | server/lib/activitypub/send/send-follow.ts | 1 | ||||
-rw-r--r-- | server/lib/emailer.ts | 33 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/activitypub-follow.ts | 24 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/video-import.ts | 5 | ||||
-rw-r--r-- | server/lib/notifier.ts | 184 | ||||
-rw-r--r-- | server/lib/user.ts | 3 | ||||
-rw-r--r-- | server/lib/video-blacklist.ts | 8 |
10 files changed, 210 insertions, 106 deletions
diff --git a/server/lib/activitypub/follow.ts b/server/lib/activitypub/follow.ts new file mode 100644 index 000000000..c57e43c91 --- /dev/null +++ b/server/lib/activitypub/follow.ts | |||
@@ -0,0 +1,36 @@ | |||
1 | import { MActorFollowActors } from '../../typings/models' | ||
2 | import { CONFIG } from '../../initializers/config' | ||
3 | import { SERVER_ACTOR_NAME } from '../../initializers/constants' | ||
4 | import { JobQueue } from '../job-queue' | ||
5 | import { logger } from '../../helpers/logger' | ||
6 | import { getServerActor } from '../../helpers/utils' | ||
7 | import { ServerModel } from '@server/models/server/server' | ||
8 | |||
9 | async function autoFollowBackIfNeeded (actorFollow: MActorFollowActors) { | ||
10 | if (!CONFIG.FOLLOWINGS.INSTANCE.AUTO_FOLLOW_BACK.ENABLED) return | ||
11 | |||
12 | const follower = actorFollow.ActorFollower | ||
13 | |||
14 | if (follower.type === 'Application' && follower.preferredUsername === SERVER_ACTOR_NAME) { | ||
15 | logger.info('Auto follow back %s.', follower.url) | ||
16 | |||
17 | const me = await getServerActor() | ||
18 | |||
19 | const server = await ServerModel.load(follower.serverId) | ||
20 | const host = server.host | ||
21 | |||
22 | const payload = { | ||
23 | host, | ||
24 | name: SERVER_ACTOR_NAME, | ||
25 | followerActorId: me.id, | ||
26 | isAutoFollow: true | ||
27 | } | ||
28 | |||
29 | JobQueue.Instance.createJob({ type: 'activitypub-follow', payload }) | ||
30 | .catch(err => logger.error('Cannot create auto follow back job for %s.', host, err)) | ||
31 | } | ||
32 | } | ||
33 | |||
34 | export { | ||
35 | autoFollowBackIfNeeded | ||
36 | } | ||
diff --git a/server/lib/activitypub/process/process-accept.ts b/server/lib/activitypub/process/process-accept.ts index 86f7c764d..dcfbb2c84 100644 --- a/server/lib/activitypub/process/process-accept.ts +++ b/server/lib/activitypub/process/process-accept.ts | |||
@@ -24,7 +24,7 @@ async function processAccept (actor: MActorDefault, targetActor: MActorSignature | |||
24 | if (!follow) throw new Error('Cannot find associated follow.') | 24 | if (!follow) throw new Error('Cannot find associated follow.') |
25 | 25 | ||
26 | if (follow.state !== 'accepted') { | 26 | if (follow.state !== 'accepted') { |
27 | follow.set('state', 'accepted') | 27 | follow.state = 'accepted' |
28 | await follow.save() | 28 | await follow.save() |
29 | 29 | ||
30 | await addFetchOutboxJob(targetActor) | 30 | await addFetchOutboxJob(targetActor) |
diff --git a/server/lib/activitypub/process/process-follow.ts b/server/lib/activitypub/process/process-follow.ts index bc5660395..85f22d654 100644 --- a/server/lib/activitypub/process/process-follow.ts +++ b/server/lib/activitypub/process/process-follow.ts | |||
@@ -10,7 +10,8 @@ import { getAPId } from '../../../helpers/activitypub' | |||
10 | import { getServerActor } from '../../../helpers/utils' | 10 | import { getServerActor } from '../../../helpers/utils' |
11 | import { CONFIG } from '../../../initializers/config' | 11 | import { CONFIG } from '../../../initializers/config' |
12 | import { APProcessorOptions } from '../../../typings/activitypub-processor.model' | 12 | import { APProcessorOptions } from '../../../typings/activitypub-processor.model' |
13 | import { MAccount, MActorFollowActors, MActorFollowFull, MActorSignature } from '../../../typings/models' | 13 | import { MActorFollowActors, MActorSignature } from '../../../typings/models' |
14 | import { autoFollowBackIfNeeded } from '../follow' | ||
14 | 15 | ||
15 | async function processFollowActivity (options: APProcessorOptions<ActivityFollow>) { | 16 | async function processFollowActivity (options: APProcessorOptions<ActivityFollow>) { |
16 | const { activity, byActor } = options | 17 | const { activity, byActor } = options |
@@ -28,7 +29,7 @@ export { | |||
28 | // --------------------------------------------------------------------------- | 29 | // --------------------------------------------------------------------------- |
29 | 30 | ||
30 | async function processFollow (byActor: MActorSignature, targetActorURL: string) { | 31 | async function processFollow (byActor: MActorSignature, targetActorURL: string) { |
31 | const { actorFollow, created, isFollowingInstance } = await sequelizeTypescript.transaction(async t => { | 32 | const { actorFollow, created, isFollowingInstance, targetActor } = await sequelizeTypescript.transaction(async t => { |
32 | const targetActor = await ActorModel.loadByUrlAndPopulateAccountAndChannel(targetActorURL, t) | 33 | const targetActor = await ActorModel.loadByUrlAndPopulateAccountAndChannel(targetActorURL, t) |
33 | 34 | ||
34 | if (!targetActor) throw new Error('Unknown actor') | 35 | if (!targetActor) throw new Error('Unknown actor') |
@@ -67,21 +68,24 @@ async function processFollow (byActor: MActorSignature, targetActorURL: string) | |||
67 | actorFollow.ActorFollowing = targetActor | 68 | actorFollow.ActorFollowing = targetActor |
68 | 69 | ||
69 | // Target sends to actor he accepted the follow request | 70 | // Target sends to actor he accepted the follow request |
70 | if (actorFollow.state === 'accepted') await sendAccept(actorFollow) | 71 | if (actorFollow.state === 'accepted') { |
72 | await sendAccept(actorFollow) | ||
73 | await autoFollowBackIfNeeded(actorFollow) | ||
74 | } | ||
71 | 75 | ||
72 | return { actorFollow, created, isFollowingInstance } | 76 | return { actorFollow, created, isFollowingInstance, targetActor } |
73 | }) | 77 | }) |
74 | 78 | ||
75 | // Rejected | 79 | // Rejected |
76 | if (!actorFollow) return | 80 | if (!actorFollow) return |
77 | 81 | ||
78 | if (created) { | 82 | if (created) { |
83 | const follower = await ActorModel.loadFull(byActor.id) | ||
84 | const actorFollowFull = Object.assign(actorFollow, { ActorFollowing: targetActor, ActorFollower: follower }) | ||
85 | |||
79 | if (isFollowingInstance) { | 86 | if (isFollowingInstance) { |
80 | Notifier.Instance.notifyOfNewInstanceFollow(actorFollow) | 87 | Notifier.Instance.notifyOfNewInstanceFollow(actorFollowFull) |
81 | } else { | 88 | } else { |
82 | const actorFollowFull = actorFollow as MActorFollowFull | ||
83 | actorFollowFull.ActorFollower.Account = await actorFollow.ActorFollower.$get('Account') as MAccount | ||
84 | |||
85 | Notifier.Instance.notifyOfNewUserFollow(actorFollowFull) | 89 | Notifier.Instance.notifyOfNewUserFollow(actorFollowFull) |
86 | } | 90 | } |
87 | } | 91 | } |
diff --git a/server/lib/activitypub/send/send-follow.ts b/server/lib/activitypub/send/send-follow.ts index 6b17b25da..ce400d8ff 100644 --- a/server/lib/activitypub/send/send-follow.ts +++ b/server/lib/activitypub/send/send-follow.ts | |||
@@ -1,5 +1,4 @@ | |||
1 | import { ActivityFollow } from '../../../../shared/models/activitypub' | 1 | import { ActivityFollow } from '../../../../shared/models/activitypub' |
2 | import { ActorFollowModel } from '../../../models/activitypub/actor-follow' | ||
3 | import { getActorFollowActivityPubUrl } from '../url' | 2 | import { getActorFollowActivityPubUrl } from '../url' |
4 | import { unicastTo } from './utils' | 3 | import { unicastTo } from './utils' |
5 | import { logger } from '../../../helpers/logger' | 4 | import { logger } from '../../../helpers/logger' |
diff --git a/server/lib/emailer.ts b/server/lib/emailer.ts index 76349ef8f..bd3d4f252 100644 --- a/server/lib/emailer.ts +++ b/server/lib/emailer.ts | |||
@@ -6,8 +6,15 @@ import { JobQueue } from './job-queue' | |||
6 | import { EmailPayload } from './job-queue/handlers/email' | 6 | import { EmailPayload } from './job-queue/handlers/email' |
7 | import { readFileSync } from 'fs-extra' | 7 | import { readFileSync } from 'fs-extra' |
8 | import { WEBSERVER } from '../initializers/constants' | 8 | import { WEBSERVER } from '../initializers/constants' |
9 | import { MCommentOwnerVideo, MVideo, MVideoAbuseVideo, MVideoAccountLight, MVideoBlacklistVideo } from '../typings/models/video' | 9 | import { |
10 | import { MActorFollowActors, MActorFollowFollowingFullFollowerAccount, MUser } from '../typings/models' | 10 | MCommentOwnerVideo, |
11 | MVideo, | ||
12 | MVideoAbuseVideo, | ||
13 | MVideoAccountLight, | ||
14 | MVideoBlacklistLightVideo, | ||
15 | MVideoBlacklistVideo | ||
16 | } from '../typings/models/video' | ||
17 | import { MActorFollowActors, MActorFollowFull, MUser } from '../typings/models' | ||
11 | import { MVideoImport, MVideoImportVideo } from '@server/typings/models/video/video-import' | 18 | import { MVideoImport, MVideoImportVideo } from '@server/typings/models/video/video-import' |
12 | 19 | ||
13 | type SendEmailOptions = { | 20 | type SendEmailOptions = { |
@@ -107,7 +114,7 @@ class Emailer { | |||
107 | return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) | 114 | return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) |
108 | } | 115 | } |
109 | 116 | ||
110 | addNewFollowNotification (to: string[], actorFollow: MActorFollowFollowingFullFollowerAccount, followType: 'account' | 'channel') { | 117 | addNewFollowNotification (to: string[], actorFollow: MActorFollowFull, followType: 'account' | 'channel') { |
111 | const followerName = actorFollow.ActorFollower.Account.getDisplayName() | 118 | const followerName = actorFollow.ActorFollower.Account.getDisplayName() |
112 | const followingName = (actorFollow.ActorFollowing.VideoChannel || actorFollow.ActorFollowing.Account).getDisplayName() | 119 | const followingName = (actorFollow.ActorFollowing.VideoChannel || actorFollow.ActorFollowing.Account).getDisplayName() |
113 | 120 | ||
@@ -144,6 +151,22 @@ class Emailer { | |||
144 | return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) | 151 | return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) |
145 | } | 152 | } |
146 | 153 | ||
154 | addAutoInstanceFollowingNotification (to: string[], actorFollow: MActorFollowActors) { | ||
155 | const text = `Hi dear admin,\n\n` + | ||
156 | `Your instance automatically followed a new instance: ${actorFollow.ActorFollowing.url}` + | ||
157 | `\n\n` + | ||
158 | `Cheers,\n` + | ||
159 | `${CONFIG.EMAIL.BODY.SIGNATURE}` | ||
160 | |||
161 | const emailPayload: EmailPayload = { | ||
162 | to, | ||
163 | subject: CONFIG.EMAIL.SUBJECT.PREFIX + 'Auto instance following', | ||
164 | text | ||
165 | } | ||
166 | |||
167 | return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) | ||
168 | } | ||
169 | |||
147 | myVideoPublishedNotification (to: string[], video: MVideo) { | 170 | myVideoPublishedNotification (to: string[], video: MVideo) { |
148 | const videoUrl = WEBSERVER.URL + video.getWatchStaticPath() | 171 | const videoUrl = WEBSERVER.URL + video.getWatchStaticPath() |
149 | 172 | ||
@@ -265,9 +288,9 @@ class Emailer { | |||
265 | return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) | 288 | return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) |
266 | } | 289 | } |
267 | 290 | ||
268 | addVideoAutoBlacklistModeratorsNotification (to: string[], video: MVideo) { | 291 | addVideoAutoBlacklistModeratorsNotification (to: string[], videoBlacklist: MVideoBlacklistLightVideo) { |
269 | const VIDEO_AUTO_BLACKLIST_URL = WEBSERVER.URL + '/admin/moderation/video-auto-blacklist/list' | 292 | const VIDEO_AUTO_BLACKLIST_URL = WEBSERVER.URL + '/admin/moderation/video-auto-blacklist/list' |
270 | const videoUrl = WEBSERVER.URL + video.getWatchStaticPath() | 293 | const videoUrl = WEBSERVER.URL + videoBlacklist.Video.getWatchStaticPath() |
271 | 294 | ||
272 | const text = `Hi,\n\n` + | 295 | const text = `Hi,\n\n` + |
273 | `A recently added video was auto-blacklisted and requires moderator review before publishing.` + | 296 | `A recently added video was auto-blacklisted and requires moderator review before publishing.` + |
diff --git a/server/lib/job-queue/handlers/activitypub-follow.ts b/server/lib/job-queue/handlers/activitypub-follow.ts index 5cb55cad6..af7c8a838 100644 --- a/server/lib/job-queue/handlers/activitypub-follow.ts +++ b/server/lib/job-queue/handlers/activitypub-follow.ts | |||
@@ -10,12 +10,13 @@ import { ActorFollowModel } from '../../../models/activitypub/actor-follow' | |||
10 | import { ActorModel } from '../../../models/activitypub/actor' | 10 | import { ActorModel } from '../../../models/activitypub/actor' |
11 | import { Notifier } from '../../notifier' | 11 | import { Notifier } from '../../notifier' |
12 | import { sequelizeTypescript } from '../../../initializers/database' | 12 | import { sequelizeTypescript } from '../../../initializers/database' |
13 | import { MAccount, MActor, MActorFollowActors, MActorFollowFull, MActorFull } from '../../../typings/models' | 13 | import { MActor, MActorFollowActors, MActorFull } from '../../../typings/models' |
14 | 14 | ||
15 | export type ActivitypubFollowPayload = { | 15 | export type ActivitypubFollowPayload = { |
16 | followerActorId: number | 16 | followerActorId: number |
17 | name: string | 17 | name: string |
18 | host: string | 18 | host: string |
19 | isAutoFollow?: boolean | ||
19 | } | 20 | } |
20 | 21 | ||
21 | async function processActivityPubFollow (job: Bull.Job) { | 22 | async function processActivityPubFollow (job: Bull.Job) { |
@@ -35,7 +36,7 @@ async function processActivityPubFollow (job: Bull.Job) { | |||
35 | 36 | ||
36 | const fromActor = await ActorModel.load(payload.followerActorId) | 37 | const fromActor = await ActorModel.load(payload.followerActorId) |
37 | 38 | ||
38 | return retryTransactionWrapper(follow, fromActor, targetActor) | 39 | return retryTransactionWrapper(follow, fromActor, targetActor, payload.isAutoFollow) |
39 | } | 40 | } |
40 | // --------------------------------------------------------------------------- | 41 | // --------------------------------------------------------------------------- |
41 | 42 | ||
@@ -45,7 +46,7 @@ export { | |||
45 | 46 | ||
46 | // --------------------------------------------------------------------------- | 47 | // --------------------------------------------------------------------------- |
47 | 48 | ||
48 | async function follow (fromActor: MActor, targetActor: MActorFull) { | 49 | async function follow (fromActor: MActor, targetActor: MActorFull, isAutoFollow = false) { |
49 | if (fromActor.id === targetActor.id) { | 50 | if (fromActor.id === targetActor.id) { |
50 | throw new Error('Follower is the same than target actor.') | 51 | throw new Error('Follower is the same than target actor.') |
51 | } | 52 | } |
@@ -75,14 +76,15 @@ async function follow (fromActor: MActor, targetActor: MActorFull) { | |||
75 | return actorFollow | 76 | return actorFollow |
76 | }) | 77 | }) |
77 | 78 | ||
78 | if (actorFollow.state === 'accepted') { | 79 | const followerFull = await ActorModel.loadFull(fromActor.id) |
79 | const followerFull = Object.assign(fromActor, { Account: await actorFollow.ActorFollower.$get('Account') as MAccount }) | ||
80 | 80 | ||
81 | const actorFollowFull = Object.assign(actorFollow, { | 81 | const actorFollowFull = Object.assign(actorFollow, { |
82 | ActorFollowing: targetActor, | 82 | ActorFollowing: targetActor, |
83 | ActorFollower: followerFull | 83 | ActorFollower: followerFull |
84 | }) | 84 | }) |
85 | 85 | ||
86 | Notifier.Instance.notifyOfNewUserFollow(actorFollowFull) | 86 | if (actorFollow.state === 'accepted') Notifier.Instance.notifyOfNewUserFollow(actorFollowFull) |
87 | } | 87 | if (isAutoFollow === true) Notifier.Instance.notifyOfAutoInstanceFollowing(actorFollowFull) |
88 | |||
89 | return actorFollow | ||
88 | } | 90 | } |
diff --git a/server/lib/job-queue/handlers/video-import.ts b/server/lib/job-queue/handlers/video-import.ts index ff8c93328..93a3e9d90 100644 --- a/server/lib/job-queue/handlers/video-import.ts +++ b/server/lib/job-queue/handlers/video-import.ts | |||
@@ -21,6 +21,7 @@ import { createVideoMiniatureFromUrl, generateVideoMiniature } from '../../thumb | |||
21 | import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type' | 21 | import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type' |
22 | import { MThumbnail } from '../../../typings/models/video/thumbnail' | 22 | import { MThumbnail } from '../../../typings/models/video/thumbnail' |
23 | import { MVideoImportDefault, MVideoImportDefaultFiles, MVideoImportVideo } from '@server/typings/models/video/video-import' | 23 | import { MVideoImportDefault, MVideoImportDefaultFiles, MVideoImportVideo } from '@server/typings/models/video/video-import' |
24 | import { MVideoBlacklistVideo, MVideoBlacklist } from '@server/typings/models' | ||
24 | 25 | ||
25 | type VideoImportYoutubeDLPayload = { | 26 | type VideoImportYoutubeDLPayload = { |
26 | type: 'youtube-dl' | 27 | type: 'youtube-dl' |
@@ -204,7 +205,9 @@ async function processFile (downloader: () => Promise<string>, videoImport: MVid | |||
204 | Notifier.Instance.notifyOnFinishedVideoImport(videoImportUpdated, true) | 205 | Notifier.Instance.notifyOnFinishedVideoImport(videoImportUpdated, true) |
205 | 206 | ||
206 | if (video.isBlacklisted()) { | 207 | if (video.isBlacklisted()) { |
207 | Notifier.Instance.notifyOnVideoAutoBlacklist(video) | 208 | const videoBlacklist = Object.assign(video.VideoBlacklist, { Video: video }) |
209 | |||
210 | Notifier.Instance.notifyOnVideoAutoBlacklist(videoBlacklist) | ||
208 | } else { | 211 | } else { |
209 | Notifier.Instance.notifyOnNewVideoIfNeeded(video) | 212 | Notifier.Instance.notifyOnNewVideoIfNeeded(video) |
210 | } | 213 | } |
diff --git a/server/lib/notifier.ts b/server/lib/notifier.ts index 23f76a21a..b7cc2607d 100644 --- a/server/lib/notifier.ts +++ b/server/lib/notifier.ts | |||
@@ -1,30 +1,30 @@ | |||
1 | import { UserNotificationSettingValue, UserNotificationType, UserRight } from '../../shared/models/users' | 1 | import { UserNotificationSettingValue, UserNotificationType, UserRight } from '../../shared/models/users' |
2 | import { logger } from '../helpers/logger' | 2 | import { logger } from '../helpers/logger' |
3 | import { VideoModel } from '../models/video/video' | ||
4 | import { Emailer } from './emailer' | 3 | import { Emailer } from './emailer' |
5 | import { UserNotificationModel } from '../models/account/user-notification' | 4 | import { UserNotificationModel } from '../models/account/user-notification' |
6 | import { VideoCommentModel } from '../models/video/video-comment' | ||
7 | import { UserModel } from '../models/account/user' | 5 | import { UserModel } from '../models/account/user' |
8 | import { PeerTubeSocket } from './peertube-socket' | 6 | import { PeerTubeSocket } from './peertube-socket' |
9 | import { CONFIG } from '../initializers/config' | 7 | import { CONFIG } from '../initializers/config' |
10 | import { VideoPrivacy, VideoState } from '../../shared/models/videos' | 8 | import { VideoPrivacy, VideoState } from '../../shared/models/videos' |
11 | import { VideoBlacklistModel } from '../models/video/video-blacklist' | ||
12 | import * as Bluebird from 'bluebird' | 9 | import * as Bluebird from 'bluebird' |
13 | import { VideoImportModel } from '../models/video/video-import' | ||
14 | import { AccountBlocklistModel } from '../models/account/account-blocklist' | 10 | import { AccountBlocklistModel } from '../models/account/account-blocklist' |
15 | import { | 11 | import { |
16 | MCommentOwnerVideo, | 12 | MCommentOwnerVideo, |
17 | MVideo, | ||
18 | MVideoAbuseVideo, | 13 | MVideoAbuseVideo, |
19 | MVideoAccountLight, | 14 | MVideoAccountLight, |
15 | MVideoBlacklistLightVideo, | ||
20 | MVideoBlacklistVideo, | 16 | MVideoBlacklistVideo, |
21 | MVideoFullLight | 17 | MVideoFullLight |
22 | } from '../typings/models/video' | 18 | } from '../typings/models/video' |
23 | import { MUser, MUserAccount, MUserWithNotificationSetting, UserNotificationModelForApi } from '@server/typings/models/user' | 19 | import { |
24 | import { MActorFollowActors, MActorFollowFull, MActorFollowFollowingFullFollowerAccount } from '../typings/models' | 20 | MUser, |
25 | import { ActorFollowModel } from '../models/activitypub/actor-follow' | 21 | MUserDefault, |
22 | MUserNotifSettingAccount, | ||
23 | MUserWithNotificationSetting, | ||
24 | UserNotificationModelForApi | ||
25 | } from '@server/typings/models/user' | ||
26 | import { MActorFollowFull } from '../typings/models' | ||
26 | import { MVideoImportVideo } from '@server/typings/models/video/video-import' | 27 | import { MVideoImportVideo } from '@server/typings/models/video/video-import' |
27 | import { AccountModel } from '@server/models/account/account' | ||
28 | 28 | ||
29 | class Notifier { | 29 | class Notifier { |
30 | 30 | ||
@@ -77,9 +77,9 @@ class Notifier { | |||
77 | .catch(err => logger.error('Cannot notify of new video abuse of video %s.', videoAbuse.Video.url, { err })) | 77 | .catch(err => logger.error('Cannot notify of new video abuse of video %s.', videoAbuse.Video.url, { err })) |
78 | } | 78 | } |
79 | 79 | ||
80 | notifyOnVideoAutoBlacklist (video: MVideo): void { | 80 | notifyOnVideoAutoBlacklist (videoBlacklist: MVideoBlacklistLightVideo): void { |
81 | this.notifyModeratorsOfVideoAutoBlacklist(video) | 81 | this.notifyModeratorsOfVideoAutoBlacklist(videoBlacklist) |
82 | .catch(err => logger.error('Cannot notify of auto-blacklist of video %s.', video.url, { err })) | 82 | .catch(err => logger.error('Cannot notify of auto-blacklist of video %s.', videoBlacklist.Video.url, { err })) |
83 | } | 83 | } |
84 | 84 | ||
85 | notifyOnVideoBlacklist (videoBlacklist: MVideoBlacklistVideo): void { | 85 | notifyOnVideoBlacklist (videoBlacklist: MVideoBlacklistVideo): void { |
@@ -87,7 +87,7 @@ class Notifier { | |||
87 | .catch(err => logger.error('Cannot notify video owner of new video blacklist of %s.', videoBlacklist.Video.url, { err })) | 87 | .catch(err => logger.error('Cannot notify video owner of new video blacklist of %s.', videoBlacklist.Video.url, { err })) |
88 | } | 88 | } |
89 | 89 | ||
90 | notifyOnVideoUnblacklist (video: MVideo): void { | 90 | notifyOnVideoUnblacklist (video: MVideoFullLight): void { |
91 | this.notifyVideoOwnerOfUnblacklist(video) | 91 | this.notifyVideoOwnerOfUnblacklist(video) |
92 | .catch(err => logger.error('Cannot notify video owner of unblacklist of %s.', video.url, { err })) | 92 | .catch(err => logger.error('Cannot notify video owner of unblacklist of %s.', video.url, { err })) |
93 | } | 93 | } |
@@ -97,12 +97,12 @@ class Notifier { | |||
97 | .catch(err => logger.error('Cannot notify owner that its video import %s is finished.', videoImport.getTargetIdentifier(), { err })) | 97 | .catch(err => logger.error('Cannot notify owner that its video import %s is finished.', videoImport.getTargetIdentifier(), { err })) |
98 | } | 98 | } |
99 | 99 | ||
100 | notifyOnNewUserRegistration (user: MUserAccount): void { | 100 | notifyOnNewUserRegistration (user: MUserDefault): void { |
101 | this.notifyModeratorsOfNewUserRegistration(user) | 101 | this.notifyModeratorsOfNewUserRegistration(user) |
102 | .catch(err => logger.error('Cannot notify moderators of new user registration (%s).', user.username, { err })) | 102 | .catch(err => logger.error('Cannot notify moderators of new user registration (%s).', user.username, { err })) |
103 | } | 103 | } |
104 | 104 | ||
105 | notifyOfNewUserFollow (actorFollow: MActorFollowFollowingFullFollowerAccount): void { | 105 | notifyOfNewUserFollow (actorFollow: MActorFollowFull): void { |
106 | this.notifyUserOfNewActorFollow(actorFollow) | 106 | this.notifyUserOfNewActorFollow(actorFollow) |
107 | .catch(err => { | 107 | .catch(err => { |
108 | logger.error( | 108 | logger.error( |
@@ -114,30 +114,37 @@ class Notifier { | |||
114 | }) | 114 | }) |
115 | } | 115 | } |
116 | 116 | ||
117 | notifyOfNewInstanceFollow (actorFollow: MActorFollowActors): void { | 117 | notifyOfNewInstanceFollow (actorFollow: MActorFollowFull): void { |
118 | this.notifyAdminsOfNewInstanceFollow(actorFollow) | 118 | this.notifyAdminsOfNewInstanceFollow(actorFollow) |
119 | .catch(err => { | 119 | .catch(err => { |
120 | logger.error('Cannot notify administrators of new follower %s.', actorFollow.ActorFollower.url, { err }) | 120 | logger.error('Cannot notify administrators of new follower %s.', actorFollow.ActorFollower.url, { err }) |
121 | }) | 121 | }) |
122 | } | 122 | } |
123 | 123 | ||
124 | notifyOfAutoInstanceFollowing (actorFollow: MActorFollowFull): void { | ||
125 | this.notifyAdminsOfAutoInstanceFollowing(actorFollow) | ||
126 | .catch(err => { | ||
127 | logger.error('Cannot notify administrators of auto instance following %s.', actorFollow.ActorFollowing.url, { err }) | ||
128 | }) | ||
129 | } | ||
130 | |||
124 | private async notifySubscribersOfNewVideo (video: MVideoAccountLight) { | 131 | private async notifySubscribersOfNewVideo (video: MVideoAccountLight) { |
125 | // List all followers that are users | 132 | // List all followers that are users |
126 | const users = await UserModel.listUserSubscribersOf(video.VideoChannel.actorId) | 133 | const users = await UserModel.listUserSubscribersOf(video.VideoChannel.actorId) |
127 | 134 | ||
128 | logger.info('Notifying %d users of new video %s.', users.length, video.url) | 135 | logger.info('Notifying %d users of new video %s.', users.length, video.url) |
129 | 136 | ||
130 | function settingGetter (user: UserModel) { | 137 | function settingGetter (user: MUserWithNotificationSetting) { |
131 | return user.NotificationSetting.newVideoFromSubscription | 138 | return user.NotificationSetting.newVideoFromSubscription |
132 | } | 139 | } |
133 | 140 | ||
134 | async function notificationCreator (user: UserModel) { | 141 | async function notificationCreator (user: MUserWithNotificationSetting) { |
135 | const notification = await UserNotificationModel.create({ | 142 | const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ |
136 | type: UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION, | 143 | type: UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION, |
137 | userId: user.id, | 144 | userId: user.id, |
138 | videoId: video.id | 145 | videoId: video.id |
139 | }) | 146 | }) |
140 | notification.Video = video as VideoModel | 147 | notification.Video = video |
141 | 148 | ||
142 | return notification | 149 | return notification |
143 | } | 150 | } |
@@ -162,17 +169,17 @@ class Notifier { | |||
162 | 169 | ||
163 | logger.info('Notifying user %s of new comment %s.', user.username, comment.url) | 170 | logger.info('Notifying user %s of new comment %s.', user.username, comment.url) |
164 | 171 | ||
165 | function settingGetter (user: UserModel) { | 172 | function settingGetter (user: MUserWithNotificationSetting) { |
166 | return user.NotificationSetting.newCommentOnMyVideo | 173 | return user.NotificationSetting.newCommentOnMyVideo |
167 | } | 174 | } |
168 | 175 | ||
169 | async function notificationCreator (user: UserModel) { | 176 | async function notificationCreator (user: MUserWithNotificationSetting) { |
170 | const notification = await UserNotificationModel.create({ | 177 | const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ |
171 | type: UserNotificationType.NEW_COMMENT_ON_MY_VIDEO, | 178 | type: UserNotificationType.NEW_COMMENT_ON_MY_VIDEO, |
172 | userId: user.id, | 179 | userId: user.id, |
173 | commentId: comment.id | 180 | commentId: comment.id |
174 | }) | 181 | }) |
175 | notification.Comment = comment as VideoCommentModel | 182 | notification.Comment = comment |
176 | 183 | ||
177 | return notification | 184 | return notification |
178 | } | 185 | } |
@@ -207,19 +214,19 @@ class Notifier { | |||
207 | 214 | ||
208 | logger.info('Notifying %d users of new comment %s.', users.length, comment.url) | 215 | logger.info('Notifying %d users of new comment %s.', users.length, comment.url) |
209 | 216 | ||
210 | function settingGetter (user: UserModel) { | 217 | function settingGetter (user: MUserNotifSettingAccount) { |
211 | if (accountMutedHash[user.Account.id] === true) return UserNotificationSettingValue.NONE | 218 | if (accountMutedHash[user.Account.id] === true) return UserNotificationSettingValue.NONE |
212 | 219 | ||
213 | return user.NotificationSetting.commentMention | 220 | return user.NotificationSetting.commentMention |
214 | } | 221 | } |
215 | 222 | ||
216 | async function notificationCreator (user: UserModel) { | 223 | async function notificationCreator (user: MUserNotifSettingAccount) { |
217 | const notification = await UserNotificationModel.create({ | 224 | const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ |
218 | type: UserNotificationType.COMMENT_MENTION, | 225 | type: UserNotificationType.COMMENT_MENTION, |
219 | userId: user.id, | 226 | userId: user.id, |
220 | commentId: comment.id | 227 | commentId: comment.id |
221 | }) | 228 | }) |
222 | notification.Comment = comment as VideoCommentModel | 229 | notification.Comment = comment |
223 | 230 | ||
224 | return notification | 231 | return notification |
225 | } | 232 | } |
@@ -231,7 +238,7 @@ class Notifier { | |||
231 | return this.notify({ users, settingGetter, notificationCreator, emailSender }) | 238 | return this.notify({ users, settingGetter, notificationCreator, emailSender }) |
232 | } | 239 | } |
233 | 240 | ||
234 | private async notifyUserOfNewActorFollow (actorFollow: MActorFollowFollowingFullFollowerAccount) { | 241 | private async notifyUserOfNewActorFollow (actorFollow: MActorFollowFull) { |
235 | if (actorFollow.ActorFollowing.isOwned() === false) return | 242 | if (actorFollow.ActorFollowing.isOwned() === false) return |
236 | 243 | ||
237 | // Account follows one of our account? | 244 | // Account follows one of our account? |
@@ -253,17 +260,17 @@ class Notifier { | |||
253 | 260 | ||
254 | logger.info('Notifying user %s of new follower: %s.', user.username, followerAccount.getDisplayName()) | 261 | logger.info('Notifying user %s of new follower: %s.', user.username, followerAccount.getDisplayName()) |
255 | 262 | ||
256 | function settingGetter (user: UserModel) { | 263 | function settingGetter (user: MUserWithNotificationSetting) { |
257 | return user.NotificationSetting.newFollow | 264 | return user.NotificationSetting.newFollow |
258 | } | 265 | } |
259 | 266 | ||
260 | async function notificationCreator (user: UserModel) { | 267 | async function notificationCreator (user: MUserWithNotificationSetting) { |
261 | const notification = await UserNotificationModel.create({ | 268 | const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ |
262 | type: UserNotificationType.NEW_FOLLOW, | 269 | type: UserNotificationType.NEW_FOLLOW, |
263 | userId: user.id, | 270 | userId: user.id, |
264 | actorFollowId: actorFollow.id | 271 | actorFollowId: actorFollow.id |
265 | }) | 272 | }) |
266 | notification.ActorFollow = actorFollow as ActorFollowModel | 273 | notification.ActorFollow = actorFollow |
267 | 274 | ||
268 | return notification | 275 | return notification |
269 | } | 276 | } |
@@ -275,22 +282,22 @@ class Notifier { | |||
275 | return this.notify({ users: [ user ], settingGetter, notificationCreator, emailSender }) | 282 | return this.notify({ users: [ user ], settingGetter, notificationCreator, emailSender }) |
276 | } | 283 | } |
277 | 284 | ||
278 | private async notifyAdminsOfNewInstanceFollow (actorFollow: MActorFollowActors) { | 285 | private async notifyAdminsOfNewInstanceFollow (actorFollow: MActorFollowFull) { |
279 | const admins = await UserModel.listWithRight(UserRight.MANAGE_SERVER_FOLLOW) | 286 | const admins = await UserModel.listWithRight(UserRight.MANAGE_SERVER_FOLLOW) |
280 | 287 | ||
281 | logger.info('Notifying %d administrators of new instance follower: %s.', admins.length, actorFollow.ActorFollower.url) | 288 | logger.info('Notifying %d administrators of new instance follower: %s.', admins.length, actorFollow.ActorFollower.url) |
282 | 289 | ||
283 | function settingGetter (user: UserModel) { | 290 | function settingGetter (user: MUserWithNotificationSetting) { |
284 | return user.NotificationSetting.newInstanceFollower | 291 | return user.NotificationSetting.newInstanceFollower |
285 | } | 292 | } |
286 | 293 | ||
287 | async function notificationCreator (user: UserModel) { | 294 | async function notificationCreator (user: MUserWithNotificationSetting) { |
288 | const notification = await UserNotificationModel.create({ | 295 | const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ |
289 | type: UserNotificationType.NEW_INSTANCE_FOLLOWER, | 296 | type: UserNotificationType.NEW_INSTANCE_FOLLOWER, |
290 | userId: user.id, | 297 | userId: user.id, |
291 | actorFollowId: actorFollow.id | 298 | actorFollowId: actorFollow.id |
292 | }) | 299 | }) |
293 | notification.ActorFollow = actorFollow as ActorFollowModel | 300 | notification.ActorFollow = actorFollow |
294 | 301 | ||
295 | return notification | 302 | return notification |
296 | } | 303 | } |
@@ -302,18 +309,45 @@ class Notifier { | |||
302 | return this.notify({ users: admins, settingGetter, notificationCreator, emailSender }) | 309 | return this.notify({ users: admins, settingGetter, notificationCreator, emailSender }) |
303 | } | 310 | } |
304 | 311 | ||
312 | private async notifyAdminsOfAutoInstanceFollowing (actorFollow: MActorFollowFull) { | ||
313 | const admins = await UserModel.listWithRight(UserRight.MANAGE_SERVER_FOLLOW) | ||
314 | |||
315 | logger.info('Notifying %d administrators of auto instance following: %s.', admins.length, actorFollow.ActorFollowing.url) | ||
316 | |||
317 | function settingGetter (user: MUserWithNotificationSetting) { | ||
318 | return user.NotificationSetting.autoInstanceFollowing | ||
319 | } | ||
320 | |||
321 | async function notificationCreator (user: MUserWithNotificationSetting) { | ||
322 | const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ | ||
323 | type: UserNotificationType.AUTO_INSTANCE_FOLLOWING, | ||
324 | userId: user.id, | ||
325 | actorFollowId: actorFollow.id | ||
326 | }) | ||
327 | notification.ActorFollow = actorFollow | ||
328 | |||
329 | return notification | ||
330 | } | ||
331 | |||
332 | function emailSender (emails: string[]) { | ||
333 | return Emailer.Instance.addAutoInstanceFollowingNotification(emails, actorFollow) | ||
334 | } | ||
335 | |||
336 | return this.notify({ users: admins, settingGetter, notificationCreator, emailSender }) | ||
337 | } | ||
338 | |||
305 | private async notifyModeratorsOfNewVideoAbuse (videoAbuse: MVideoAbuseVideo) { | 339 | private async notifyModeratorsOfNewVideoAbuse (videoAbuse: MVideoAbuseVideo) { |
306 | const moderators = await UserModel.listWithRight(UserRight.MANAGE_VIDEO_ABUSES) | 340 | const moderators = await UserModel.listWithRight(UserRight.MANAGE_VIDEO_ABUSES) |
307 | if (moderators.length === 0) return | 341 | if (moderators.length === 0) return |
308 | 342 | ||
309 | logger.info('Notifying %s user/moderators of new video abuse %s.', moderators.length, videoAbuse.Video.url) | 343 | logger.info('Notifying %s user/moderators of new video abuse %s.', moderators.length, videoAbuse.Video.url) |
310 | 344 | ||
311 | function settingGetter (user: UserModel) { | 345 | function settingGetter (user: MUserWithNotificationSetting) { |
312 | return user.NotificationSetting.videoAbuseAsModerator | 346 | return user.NotificationSetting.videoAbuseAsModerator |
313 | } | 347 | } |
314 | 348 | ||
315 | async function notificationCreator (user: UserModel) { | 349 | async function notificationCreator (user: MUserWithNotificationSetting) { |
316 | const notification: UserNotificationModelForApi = await UserNotificationModel.create({ | 350 | const notification: UserNotificationModelForApi = await UserNotificationModel.create<UserNotificationModelForApi>({ |
317 | type: UserNotificationType.NEW_VIDEO_ABUSE_FOR_MODERATORS, | 351 | type: UserNotificationType.NEW_VIDEO_ABUSE_FOR_MODERATORS, |
318 | userId: user.id, | 352 | userId: user.id, |
319 | videoAbuseId: videoAbuse.id | 353 | videoAbuseId: videoAbuse.id |
@@ -330,29 +364,29 @@ class Notifier { | |||
330 | return this.notify({ users: moderators, settingGetter, notificationCreator, emailSender }) | 364 | return this.notify({ users: moderators, settingGetter, notificationCreator, emailSender }) |
331 | } | 365 | } |
332 | 366 | ||
333 | private async notifyModeratorsOfVideoAutoBlacklist (video: MVideo) { | 367 | private async notifyModeratorsOfVideoAutoBlacklist (videoBlacklist: MVideoBlacklistLightVideo) { |
334 | const moderators = await UserModel.listWithRight(UserRight.MANAGE_VIDEO_BLACKLIST) | 368 | const moderators = await UserModel.listWithRight(UserRight.MANAGE_VIDEO_BLACKLIST) |
335 | if (moderators.length === 0) return | 369 | if (moderators.length === 0) return |
336 | 370 | ||
337 | logger.info('Notifying %s moderators of video auto-blacklist %s.', moderators.length, video.url) | 371 | logger.info('Notifying %s moderators of video auto-blacklist %s.', moderators.length, videoBlacklist.Video.url) |
338 | 372 | ||
339 | function settingGetter (user: UserModel) { | 373 | function settingGetter (user: MUserWithNotificationSetting) { |
340 | return user.NotificationSetting.videoAutoBlacklistAsModerator | 374 | return user.NotificationSetting.videoAutoBlacklistAsModerator |
341 | } | 375 | } |
342 | async function notificationCreator (user: UserModel) { | ||
343 | 376 | ||
344 | const notification = await UserNotificationModel.create({ | 377 | async function notificationCreator (user: MUserWithNotificationSetting) { |
378 | const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ | ||
345 | type: UserNotificationType.VIDEO_AUTO_BLACKLIST_FOR_MODERATORS, | 379 | type: UserNotificationType.VIDEO_AUTO_BLACKLIST_FOR_MODERATORS, |
346 | userId: user.id, | 380 | userId: user.id, |
347 | videoId: video.id | 381 | videoBlacklistId: videoBlacklist.id |
348 | }) | 382 | }) |
349 | notification.Video = video as VideoModel | 383 | notification.VideoBlacklist = videoBlacklist |
350 | 384 | ||
351 | return notification | 385 | return notification |
352 | } | 386 | } |
353 | 387 | ||
354 | function emailSender (emails: string[]) { | 388 | function emailSender (emails: string[]) { |
355 | return Emailer.Instance.addVideoAutoBlacklistModeratorsNotification(emails, video) | 389 | return Emailer.Instance.addVideoAutoBlacklistModeratorsNotification(emails, videoBlacklist) |
356 | } | 390 | } |
357 | 391 | ||
358 | return this.notify({ users: moderators, settingGetter, notificationCreator, emailSender }) | 392 | return this.notify({ users: moderators, settingGetter, notificationCreator, emailSender }) |
@@ -364,17 +398,17 @@ class Notifier { | |||
364 | 398 | ||
365 | logger.info('Notifying user %s that its video %s has been blacklisted.', user.username, videoBlacklist.Video.url) | 399 | logger.info('Notifying user %s that its video %s has been blacklisted.', user.username, videoBlacklist.Video.url) |
366 | 400 | ||
367 | function settingGetter (user: UserModel) { | 401 | function settingGetter (user: MUserWithNotificationSetting) { |
368 | return user.NotificationSetting.blacklistOnMyVideo | 402 | return user.NotificationSetting.blacklistOnMyVideo |
369 | } | 403 | } |
370 | 404 | ||
371 | async function notificationCreator (user: UserModel) { | 405 | async function notificationCreator (user: MUserWithNotificationSetting) { |
372 | const notification = await UserNotificationModel.create({ | 406 | const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ |
373 | type: UserNotificationType.BLACKLIST_ON_MY_VIDEO, | 407 | type: UserNotificationType.BLACKLIST_ON_MY_VIDEO, |
374 | userId: user.id, | 408 | userId: user.id, |
375 | videoBlacklistId: videoBlacklist.id | 409 | videoBlacklistId: videoBlacklist.id |
376 | }) | 410 | }) |
377 | notification.VideoBlacklist = videoBlacklist as VideoBlacklistModel | 411 | notification.VideoBlacklist = videoBlacklist |
378 | 412 | ||
379 | return notification | 413 | return notification |
380 | } | 414 | } |
@@ -386,23 +420,23 @@ class Notifier { | |||
386 | return this.notify({ users: [ user ], settingGetter, notificationCreator, emailSender }) | 420 | return this.notify({ users: [ user ], settingGetter, notificationCreator, emailSender }) |
387 | } | 421 | } |
388 | 422 | ||
389 | private async notifyVideoOwnerOfUnblacklist (video: MVideo) { | 423 | private async notifyVideoOwnerOfUnblacklist (video: MVideoFullLight) { |
390 | const user = await UserModel.loadByVideoId(video.id) | 424 | const user = await UserModel.loadByVideoId(video.id) |
391 | if (!user) return | 425 | if (!user) return |
392 | 426 | ||
393 | logger.info('Notifying user %s that its video %s has been unblacklisted.', user.username, video.url) | 427 | logger.info('Notifying user %s that its video %s has been unblacklisted.', user.username, video.url) |
394 | 428 | ||
395 | function settingGetter (user: UserModel) { | 429 | function settingGetter (user: MUserWithNotificationSetting) { |
396 | return user.NotificationSetting.blacklistOnMyVideo | 430 | return user.NotificationSetting.blacklistOnMyVideo |
397 | } | 431 | } |
398 | 432 | ||
399 | async function notificationCreator (user: UserModel) { | 433 | async function notificationCreator (user: MUserWithNotificationSetting) { |
400 | const notification = await UserNotificationModel.create({ | 434 | const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ |
401 | type: UserNotificationType.UNBLACKLIST_ON_MY_VIDEO, | 435 | type: UserNotificationType.UNBLACKLIST_ON_MY_VIDEO, |
402 | userId: user.id, | 436 | userId: user.id, |
403 | videoId: video.id | 437 | videoId: video.id |
404 | }) | 438 | }) |
405 | notification.Video = video as VideoModel | 439 | notification.Video = video |
406 | 440 | ||
407 | return notification | 441 | return notification |
408 | } | 442 | } |
@@ -420,17 +454,17 @@ class Notifier { | |||
420 | 454 | ||
421 | logger.info('Notifying user %s of the publication of its video %s.', user.username, video.url) | 455 | logger.info('Notifying user %s of the publication of its video %s.', user.username, video.url) |
422 | 456 | ||
423 | function settingGetter (user: UserModel) { | 457 | function settingGetter (user: MUserWithNotificationSetting) { |
424 | return user.NotificationSetting.myVideoPublished | 458 | return user.NotificationSetting.myVideoPublished |
425 | } | 459 | } |
426 | 460 | ||
427 | async function notificationCreator (user: UserModel) { | 461 | async function notificationCreator (user: MUserWithNotificationSetting) { |
428 | const notification = await UserNotificationModel.create({ | 462 | const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ |
429 | type: UserNotificationType.MY_VIDEO_PUBLISHED, | 463 | type: UserNotificationType.MY_VIDEO_PUBLISHED, |
430 | userId: user.id, | 464 | userId: user.id, |
431 | videoId: video.id | 465 | videoId: video.id |
432 | }) | 466 | }) |
433 | notification.Video = video as VideoModel | 467 | notification.Video = video |
434 | 468 | ||
435 | return notification | 469 | return notification |
436 | } | 470 | } |
@@ -448,17 +482,17 @@ class Notifier { | |||
448 | 482 | ||
449 | logger.info('Notifying user %s its video import %s is finished.', user.username, videoImport.getTargetIdentifier()) | 483 | logger.info('Notifying user %s its video import %s is finished.', user.username, videoImport.getTargetIdentifier()) |
450 | 484 | ||
451 | function settingGetter (user: UserModel) { | 485 | function settingGetter (user: MUserWithNotificationSetting) { |
452 | return user.NotificationSetting.myVideoImportFinished | 486 | return user.NotificationSetting.myVideoImportFinished |
453 | } | 487 | } |
454 | 488 | ||
455 | async function notificationCreator (user: UserModel) { | 489 | async function notificationCreator (user: MUserWithNotificationSetting) { |
456 | const notification = await UserNotificationModel.create({ | 490 | const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ |
457 | type: success ? UserNotificationType.MY_VIDEO_IMPORT_SUCCESS : UserNotificationType.MY_VIDEO_IMPORT_ERROR, | 491 | type: success ? UserNotificationType.MY_VIDEO_IMPORT_SUCCESS : UserNotificationType.MY_VIDEO_IMPORT_ERROR, |
458 | userId: user.id, | 492 | userId: user.id, |
459 | videoImportId: videoImport.id | 493 | videoImportId: videoImport.id |
460 | }) | 494 | }) |
461 | notification.VideoImport = videoImport as VideoImportModel | 495 | notification.VideoImport = videoImport |
462 | 496 | ||
463 | return notification | 497 | return notification |
464 | } | 498 | } |
@@ -472,7 +506,7 @@ class Notifier { | |||
472 | return this.notify({ users: [ user ], settingGetter, notificationCreator, emailSender }) | 506 | return this.notify({ users: [ user ], settingGetter, notificationCreator, emailSender }) |
473 | } | 507 | } |
474 | 508 | ||
475 | private async notifyModeratorsOfNewUserRegistration (registeredUser: MUserAccount) { | 509 | private async notifyModeratorsOfNewUserRegistration (registeredUser: MUserDefault) { |
476 | const moderators = await UserModel.listWithRight(UserRight.MANAGE_USERS) | 510 | const moderators = await UserModel.listWithRight(UserRight.MANAGE_USERS) |
477 | if (moderators.length === 0) return | 511 | if (moderators.length === 0) return |
478 | 512 | ||
@@ -481,17 +515,17 @@ class Notifier { | |||
481 | moderators.length, registeredUser.username | 515 | moderators.length, registeredUser.username |
482 | ) | 516 | ) |
483 | 517 | ||
484 | function settingGetter (user: UserModel) { | 518 | function settingGetter (user: MUserWithNotificationSetting) { |
485 | return user.NotificationSetting.newUserRegistration | 519 | return user.NotificationSetting.newUserRegistration |
486 | } | 520 | } |
487 | 521 | ||
488 | async function notificationCreator (user: UserModel) { | 522 | async function notificationCreator (user: MUserWithNotificationSetting) { |
489 | const notification = await UserNotificationModel.create({ | 523 | const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ |
490 | type: UserNotificationType.NEW_USER_REGISTRATION, | 524 | type: UserNotificationType.NEW_USER_REGISTRATION, |
491 | userId: user.id, | 525 | userId: user.id, |
492 | accountId: registeredUser.Account.id | 526 | accountId: registeredUser.Account.id |
493 | }) | 527 | }) |
494 | notification.Account = registeredUser.Account as AccountModel | 528 | notification.Account = registeredUser.Account |
495 | 529 | ||
496 | return notification | 530 | return notification |
497 | } | 531 | } |
@@ -503,11 +537,11 @@ class Notifier { | |||
503 | return this.notify({ users: moderators, settingGetter, notificationCreator, emailSender }) | 537 | return this.notify({ users: moderators, settingGetter, notificationCreator, emailSender }) |
504 | } | 538 | } |
505 | 539 | ||
506 | private async notify (options: { | 540 | private async notify <T extends MUserWithNotificationSetting> (options: { |
507 | users: MUserWithNotificationSetting[], | 541 | users: T[], |
508 | notificationCreator: (user: MUserWithNotificationSetting) => Promise<UserNotificationModelForApi>, | 542 | notificationCreator: (user: T) => Promise<UserNotificationModelForApi>, |
509 | emailSender: (emails: string[]) => Promise<any> | Bluebird<any>, | 543 | emailSender: (emails: string[]) => Promise<any> | Bluebird<any>, |
510 | settingGetter: (user: MUserWithNotificationSetting) => UserNotificationSettingValue | 544 | settingGetter: (user: T) => UserNotificationSettingValue |
511 | }) { | 545 | }) { |
512 | const emails: string[] = [] | 546 | const emails: string[] = [] |
513 | 547 | ||
diff --git a/server/lib/user.ts b/server/lib/user.ts index d84aff464..c45438d95 100644 --- a/server/lib/user.ts +++ b/server/lib/user.ts | |||
@@ -138,7 +138,8 @@ function createDefaultUserNotificationSettings (user: MUserId, t: Transaction | | |||
138 | newUserRegistration: UserNotificationSettingValue.WEB, | 138 | newUserRegistration: UserNotificationSettingValue.WEB, |
139 | commentMention: UserNotificationSettingValue.WEB, | 139 | commentMention: UserNotificationSettingValue.WEB, |
140 | newFollow: UserNotificationSettingValue.WEB, | 140 | newFollow: UserNotificationSettingValue.WEB, |
141 | newInstanceFollower: UserNotificationSettingValue.WEB | 141 | newInstanceFollower: UserNotificationSettingValue.WEB, |
142 | autoInstanceFollowing: UserNotificationSettingValue.WEB | ||
142 | } | 143 | } |
143 | 144 | ||
144 | return UserNotificationSettingModel.create(values, { transaction: t }) | 145 | return UserNotificationSettingModel.create(values, { transaction: t }) |
diff --git a/server/lib/video-blacklist.ts b/server/lib/video-blacklist.ts index a0fc26e84..1dd45b76d 100644 --- a/server/lib/video-blacklist.ts +++ b/server/lib/video-blacklist.ts | |||
@@ -6,7 +6,7 @@ import { logger } from '../helpers/logger' | |||
6 | import { UserAdminFlag } from '../../shared/models/users/user-flag.model' | 6 | import { UserAdminFlag } from '../../shared/models/users/user-flag.model' |
7 | import { Hooks } from './plugins/hooks' | 7 | import { Hooks } from './plugins/hooks' |
8 | import { Notifier } from './notifier' | 8 | import { Notifier } from './notifier' |
9 | import { MUser, MVideoBlacklist, MVideoWithBlacklistLight } from '@server/typings/models' | 9 | import { MUser, MVideoBlacklistVideo, MVideoWithBlacklistLight } from '@server/typings/models' |
10 | 10 | ||
11 | async function autoBlacklistVideoIfNeeded (parameters: { | 11 | async function autoBlacklistVideoIfNeeded (parameters: { |
12 | video: MVideoWithBlacklistLight, | 12 | video: MVideoWithBlacklistLight, |
@@ -31,7 +31,7 @@ async function autoBlacklistVideoIfNeeded (parameters: { | |||
31 | reason: 'Auto-blacklisted. Moderator review required.', | 31 | reason: 'Auto-blacklisted. Moderator review required.', |
32 | type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED | 32 | type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED |
33 | } | 33 | } |
34 | const [ videoBlacklist ] = await VideoBlacklistModel.findOrCreate<MVideoBlacklist>({ | 34 | const [ videoBlacklist ] = await VideoBlacklistModel.findOrCreate<MVideoBlacklistVideo>({ |
35 | where: { | 35 | where: { |
36 | videoId: video.id | 36 | videoId: video.id |
37 | }, | 37 | }, |
@@ -40,7 +40,9 @@ async function autoBlacklistVideoIfNeeded (parameters: { | |||
40 | }) | 40 | }) |
41 | video.VideoBlacklist = videoBlacklist | 41 | video.VideoBlacklist = videoBlacklist |
42 | 42 | ||
43 | if (notify) Notifier.Instance.notifyOnVideoAutoBlacklist(video) | 43 | videoBlacklist.Video = video |
44 | |||
45 | if (notify) Notifier.Instance.notifyOnVideoAutoBlacklist(videoBlacklist) | ||
44 | 46 | ||
45 | logger.info('Video %s auto-blacklisted.', video.uuid) | 47 | logger.info('Video %s auto-blacklisted.', video.uuid) |
46 | 48 | ||