diff options
author | Chocobozzz <me@florianbigard.com> | 2019-04-08 17:26:01 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2019-04-08 17:30:48 +0200 |
commit | 883993c81ecc2388d4a4b37b29b81b6de73d264f (patch) | |
tree | f0f76995b6762b10a0c1a7ccc2b5d952f68014ea /server | |
parent | 0dc647775881eb1378b213a530996cd096de24ea (diff) | |
download | PeerTube-883993c81ecc2388d4a4b37b29b81b6de73d264f.tar.gz PeerTube-883993c81ecc2388d4a4b37b29b81b6de73d264f.tar.zst PeerTube-883993c81ecc2388d4a4b37b29b81b6de73d264f.zip |
Add notification on new instance follower (server side)
Diffstat (limited to 'server')
-rw-r--r-- | server/controllers/api/users/my-notifications.ts | 3 | ||||
-rw-r--r-- | server/initializers/migrations/0360-notification-instance-follower.ts | 40 | ||||
-rw-r--r-- | server/lib/activitypub/actor.ts | 2 | ||||
-rw-r--r-- | server/lib/activitypub/process/process-follow.ts | 19 | ||||
-rw-r--r-- | server/lib/emailer.ts | 18 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/activitypub-follow.ts | 2 | ||||
-rw-r--r-- | server/lib/notifier.ts | 38 | ||||
-rw-r--r-- | server/lib/user.ts | 3 | ||||
-rw-r--r-- | server/middlewares/validators/user-notifications.ts | 14 | ||||
-rw-r--r-- | server/models/account/user-notification-setting.ts | 12 | ||||
-rw-r--r-- | server/models/account/user-notification.ts | 1 | ||||
-rw-r--r-- | server/tests/api/check-params/user-notifications.ts | 3 | ||||
-rw-r--r-- | server/tests/api/index-1.ts | 1 | ||||
-rw-r--r-- | server/tests/api/notifications/index.ts | 1 | ||||
-rw-r--r-- | server/tests/api/notifications/user-notifications.ts (renamed from server/tests/api/users/user-notifications.ts) | 35 | ||||
-rw-r--r-- | server/tests/api/users/index.ts | 1 |
16 files changed, 174 insertions, 19 deletions
diff --git a/server/controllers/api/users/my-notifications.ts b/server/controllers/api/users/my-notifications.ts index 4edad2a74..f146284e4 100644 --- a/server/controllers/api/users/my-notifications.ts +++ b/server/controllers/api/users/my-notifications.ts | |||
@@ -75,7 +75,8 @@ async function updateNotificationSettings (req: express.Request, res: express.Re | |||
75 | myVideoImportFinished: body.myVideoImportFinished, | 75 | myVideoImportFinished: body.myVideoImportFinished, |
76 | newFollow: body.newFollow, | 76 | newFollow: body.newFollow, |
77 | newUserRegistration: body.newUserRegistration, | 77 | newUserRegistration: body.newUserRegistration, |
78 | commentMention: body.commentMention | 78 | commentMention: body.commentMention, |
79 | newInstanceFollower: body.newInstanceFollower | ||
79 | } | 80 | } |
80 | 81 | ||
81 | await UserNotificationSettingModel.update(values, query) | 82 | await UserNotificationSettingModel.update(values, query) |
diff --git a/server/initializers/migrations/0360-notification-instance-follower.ts b/server/initializers/migrations/0360-notification-instance-follower.ts new file mode 100644 index 000000000..05caf8e1d --- /dev/null +++ b/server/initializers/migrations/0360-notification-instance-follower.ts | |||
@@ -0,0 +1,40 @@ | |||
1 | import * as Sequelize from 'sequelize' | ||
2 | |||
3 | async function up (utils: { | ||
4 | transaction: Sequelize.Transaction, | ||
5 | queryInterface: Sequelize.QueryInterface, | ||
6 | sequelize: Sequelize.Sequelize, | ||
7 | db: any | ||
8 | }): Promise<void> { | ||
9 | { | ||
10 | const data = { | ||
11 | type: Sequelize.INTEGER, | ||
12 | defaultValue: null, | ||
13 | allowNull: true | ||
14 | } | ||
15 | await utils.queryInterface.addColumn('userNotificationSetting', 'newInstanceFollower', data) | ||
16 | } | ||
17 | |||
18 | { | ||
19 | const query = 'UPDATE "userNotificationSetting" SET "newInstanceFollower" = 1' | ||
20 | await utils.sequelize.query(query) | ||
21 | } | ||
22 | |||
23 | { | ||
24 | const data = { | ||
25 | type: Sequelize.INTEGER, | ||
26 | defaultValue: null, | ||
27 | allowNull: false | ||
28 | } | ||
29 | await utils.queryInterface.changeColumn('userNotificationSetting', 'newInstanceFollower', data) | ||
30 | } | ||
31 | } | ||
32 | |||
33 | function down (options) { | ||
34 | throw new Error('Not implemented.') | ||
35 | } | ||
36 | |||
37 | export { | ||
38 | up, | ||
39 | down | ||
40 | } | ||
diff --git a/server/lib/activitypub/actor.ts b/server/lib/activitypub/actor.ts index 63e810642..c0ad07a52 100644 --- a/server/lib/activitypub/actor.ts +++ b/server/lib/activitypub/actor.ts | |||
@@ -342,6 +342,8 @@ function saveActorAndServerAndModelIfNotExist ( | |||
342 | actorCreated.VideoChannel.Account = ownerActor.Account | 342 | actorCreated.VideoChannel.Account = ownerActor.Account |
343 | } | 343 | } |
344 | 344 | ||
345 | actorCreated.Server = server | ||
346 | |||
345 | return actorCreated | 347 | return actorCreated |
346 | } | 348 | } |
347 | } | 349 | } |
diff --git a/server/lib/activitypub/process/process-follow.ts b/server/lib/activitypub/process/process-follow.ts index 140bbe9f1..276a57e60 100644 --- a/server/lib/activitypub/process/process-follow.ts +++ b/server/lib/activitypub/process/process-follow.ts | |||
@@ -24,14 +24,16 @@ export { | |||
24 | // --------------------------------------------------------------------------- | 24 | // --------------------------------------------------------------------------- |
25 | 25 | ||
26 | async function processFollow (actor: ActorModel, targetActorURL: string) { | 26 | async function processFollow (actor: ActorModel, targetActorURL: string) { |
27 | const { actorFollow, created } = await sequelizeTypescript.transaction(async t => { | 27 | const { actorFollow, created, isFollowingInstance } = await sequelizeTypescript.transaction(async t => { |
28 | const targetActor = await ActorModel.loadByUrlAndPopulateAccountAndChannel(targetActorURL, t) | 28 | const targetActor = await ActorModel.loadByUrlAndPopulateAccountAndChannel(targetActorURL, t) |
29 | 29 | ||
30 | if (!targetActor) throw new Error('Unknown actor') | 30 | if (!targetActor) throw new Error('Unknown actor') |
31 | if (targetActor.isOwned() === false) throw new Error('This is not a local actor.') | 31 | if (targetActor.isOwned() === false) throw new Error('This is not a local actor.') |
32 | 32 | ||
33 | const serverActor = await getServerActor() | 33 | const serverActor = await getServerActor() |
34 | if (targetActor.id === serverActor.id && CONFIG.FOLLOWERS.INSTANCE.ENABLED === false) { | 34 | const isFollowingInstance = targetActor.id === serverActor.id |
35 | |||
36 | if (isFollowingInstance && CONFIG.FOLLOWERS.INSTANCE.ENABLED === false) { | ||
35 | logger.info('Rejecting %s because instance followers are disabled.', targetActor.url) | 37 | logger.info('Rejecting %s because instance followers are disabled.', targetActor.url) |
36 | 38 | ||
37 | return sendReject(actor, targetActor) | 39 | return sendReject(actor, targetActor) |
@@ -50,9 +52,6 @@ async function processFollow (actor: ActorModel, targetActorURL: string) { | |||
50 | transaction: t | 52 | transaction: t |
51 | }) | 53 | }) |
52 | 54 | ||
53 | actorFollow.ActorFollower = actor | ||
54 | actorFollow.ActorFollowing = targetActor | ||
55 | |||
56 | if (actorFollow.state !== 'accepted' && CONFIG.FOLLOWERS.INSTANCE.MANUAL_APPROVAL === false) { | 55 | if (actorFollow.state !== 'accepted' && CONFIG.FOLLOWERS.INSTANCE.MANUAL_APPROVAL === false) { |
57 | actorFollow.state = 'accepted' | 56 | actorFollow.state = 'accepted' |
58 | await actorFollow.save({ transaction: t }) | 57 | await actorFollow.save({ transaction: t }) |
@@ -64,10 +63,16 @@ async function processFollow (actor: ActorModel, targetActorURL: string) { | |||
64 | // Target sends to actor he accepted the follow request | 63 | // Target sends to actor he accepted the follow request |
65 | if (actorFollow.state === 'accepted') await sendAccept(actorFollow) | 64 | if (actorFollow.state === 'accepted') await sendAccept(actorFollow) |
66 | 65 | ||
67 | return { actorFollow, created } | 66 | return { actorFollow, created, isFollowingInstance } |
68 | }) | 67 | }) |
69 | 68 | ||
70 | if (created) Notifier.Instance.notifyOfNewFollow(actorFollow) | 69 | // Rejected |
70 | if (!actorFollow) return | ||
71 | |||
72 | if (created) { | ||
73 | if (isFollowingInstance) Notifier.Instance.notifyOfNewInstanceFollow(actorFollow) | ||
74 | else Notifier.Instance.notifyOfNewUserFollow(actorFollow) | ||
75 | } | ||
71 | 76 | ||
72 | logger.info('Actor %s is followed by actor %s.', targetActorURL, actor.url) | 77 | logger.info('Actor %s is followed by actor %s.', targetActorURL, actor.url) |
73 | } | 78 | } |
diff --git a/server/lib/emailer.ts b/server/lib/emailer.ts index eec97c27e..aa9083362 100644 --- a/server/lib/emailer.ts +++ b/server/lib/emailer.ts | |||
@@ -129,6 +129,24 @@ class Emailer { | |||
129 | return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) | 129 | return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) |
130 | } | 130 | } |
131 | 131 | ||
132 | addNewInstanceFollowerNotification (to: string[], actorFollow: ActorFollowModel) { | ||
133 | const awaitingApproval = actorFollow.state === 'pending' ? ' awaiting manual approval.' : '' | ||
134 | |||
135 | const text = `Hi dear admin,\n\n` + | ||
136 | `Your instance has a new follower: ${actorFollow.ActorFollower.url}${awaitingApproval}` + | ||
137 | `\n\n` + | ||
138 | `Cheers,\n` + | ||
139 | `PeerTube.` | ||
140 | |||
141 | const emailPayload: EmailPayload = { | ||
142 | to, | ||
143 | subject: 'New instance follower', | ||
144 | text | ||
145 | } | ||
146 | |||
147 | return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) | ||
148 | } | ||
149 | |||
132 | myVideoPublishedNotification (to: string[], video: VideoModel) { | 150 | myVideoPublishedNotification (to: string[], video: VideoModel) { |
133 | const videoUrl = CONFIG.WEBSERVER.URL + video.getWatchStaticPath() | 151 | const videoUrl = CONFIG.WEBSERVER.URL + video.getWatchStaticPath() |
134 | 152 | ||
diff --git a/server/lib/job-queue/handlers/activitypub-follow.ts b/server/lib/job-queue/handlers/activitypub-follow.ts index b4d381062..e7e5ff950 100644 --- a/server/lib/job-queue/handlers/activitypub-follow.ts +++ b/server/lib/job-queue/handlers/activitypub-follow.ts | |||
@@ -73,5 +73,5 @@ async function follow (fromActor: ActorModel, targetActor: ActorModel) { | |||
73 | return actorFollow | 73 | return actorFollow |
74 | }) | 74 | }) |
75 | 75 | ||
76 | if (actorFollow.state === 'accepted') Notifier.Instance.notifyOfNewFollow(actorFollow) | 76 | if (actorFollow.state === 'accepted') Notifier.Instance.notifyOfNewUserFollow(actorFollow) |
77 | } | 77 | } |
diff --git a/server/lib/notifier.ts b/server/lib/notifier.ts index 9fe93ec0d..91b71cc64 100644 --- a/server/lib/notifier.ts +++ b/server/lib/notifier.ts | |||
@@ -92,18 +92,25 @@ class Notifier { | |||
92 | .catch(err => logger.error('Cannot notify moderators of new user registration (%s).', user.username, { err })) | 92 | .catch(err => logger.error('Cannot notify moderators of new user registration (%s).', user.username, { err })) |
93 | } | 93 | } |
94 | 94 | ||
95 | notifyOfNewFollow (actorFollow: ActorFollowModel): void { | 95 | notifyOfNewUserFollow (actorFollow: ActorFollowModel): void { |
96 | this.notifyUserOfNewActorFollow(actorFollow) | 96 | this.notifyUserOfNewActorFollow(actorFollow) |
97 | .catch(err => { | 97 | .catch(err => { |
98 | logger.error( | 98 | logger.error( |
99 | 'Cannot notify owner of channel %s of a new follow by %s.', | 99 | 'Cannot notify owner of channel %s of a new follow by %s.', |
100 | actorFollow.ActorFollowing.VideoChannel.getDisplayName(), | 100 | actorFollow.ActorFollowing.VideoChannel.getDisplayName(), |
101 | actorFollow.ActorFollower.Account.getDisplayName(), | 101 | actorFollow.ActorFollower.Account.getDisplayName(), |
102 | err | 102 | { err } |
103 | ) | 103 | ) |
104 | }) | 104 | }) |
105 | } | 105 | } |
106 | 106 | ||
107 | notifyOfNewInstanceFollow (actorFollow: ActorFollowModel): void { | ||
108 | this.notifyAdminsOfNewInstanceFollow(actorFollow) | ||
109 | .catch(err => { | ||
110 | logger.error('Cannot notify administrators of new follower %s.', actorFollow.ActorFollower.url, { err }) | ||
111 | }) | ||
112 | } | ||
113 | |||
107 | private async notifySubscribersOfNewVideo (video: VideoModel) { | 114 | private async notifySubscribersOfNewVideo (video: VideoModel) { |
108 | // List all followers that are users | 115 | // List all followers that are users |
109 | const users = await UserModel.listUserSubscribersOf(video.VideoChannel.actorId) | 116 | const users = await UserModel.listUserSubscribersOf(video.VideoChannel.actorId) |
@@ -261,6 +268,33 @@ class Notifier { | |||
261 | return this.notify({ users: [ user ], settingGetter, notificationCreator, emailSender }) | 268 | return this.notify({ users: [ user ], settingGetter, notificationCreator, emailSender }) |
262 | } | 269 | } |
263 | 270 | ||
271 | private async notifyAdminsOfNewInstanceFollow (actorFollow: ActorFollowModel) { | ||
272 | const admins = await UserModel.listWithRight(UserRight.MANAGE_SERVER_FOLLOW) | ||
273 | |||
274 | logger.info('Notifying %d administrators of new instance follower: %s.', admins.length, actorFollow.ActorFollower.url) | ||
275 | |||
276 | function settingGetter (user: UserModel) { | ||
277 | return user.NotificationSetting.newInstanceFollower | ||
278 | } | ||
279 | |||
280 | async function notificationCreator (user: UserModel) { | ||
281 | const notification = await UserNotificationModel.create({ | ||
282 | type: UserNotificationType.NEW_INSTANCE_FOLLOWER, | ||
283 | userId: user.id, | ||
284 | actorFollowId: actorFollow.id | ||
285 | }) | ||
286 | notification.ActorFollow = actorFollow | ||
287 | |||
288 | return notification | ||
289 | } | ||
290 | |||
291 | function emailSender (emails: string[]) { | ||
292 | return Emailer.Instance.addNewInstanceFollowerNotification(emails, actorFollow) | ||
293 | } | ||
294 | |||
295 | return this.notify({ users: admins, settingGetter, notificationCreator, emailSender }) | ||
296 | } | ||
297 | |||
264 | private async notifyModeratorsOfNewVideoAbuse (videoAbuse: VideoAbuseModel) { | 298 | private async notifyModeratorsOfNewVideoAbuse (videoAbuse: VideoAbuseModel) { |
265 | const moderators = await UserModel.listWithRight(UserRight.MANAGE_VIDEO_ABUSES) | 299 | const moderators = await UserModel.listWithRight(UserRight.MANAGE_VIDEO_ABUSES) |
266 | if (moderators.length === 0) return | 300 | if (moderators.length === 0) return |
diff --git a/server/lib/user.ts b/server/lib/user.ts index 5588b0f76..6fbe3ed03 100644 --- a/server/lib/user.ts +++ b/server/lib/user.ts | |||
@@ -110,7 +110,8 @@ function createDefaultUserNotificationSettings (user: UserModel, t: Sequelize.Tr | |||
110 | blacklistOnMyVideo: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, | 110 | blacklistOnMyVideo: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, |
111 | newUserRegistration: UserNotificationSettingValue.WEB, | 111 | newUserRegistration: UserNotificationSettingValue.WEB, |
112 | commentMention: UserNotificationSettingValue.WEB, | 112 | commentMention: UserNotificationSettingValue.WEB, |
113 | newFollow: UserNotificationSettingValue.WEB | 113 | newFollow: UserNotificationSettingValue.WEB, |
114 | newInstanceFollower: UserNotificationSettingValue.WEB | ||
114 | } | 115 | } |
115 | 116 | ||
116 | return UserNotificationSettingModel.create(values, { transaction: t }) | 117 | return UserNotificationSettingModel.create(values, { transaction: t }) |
diff --git a/server/middlewares/validators/user-notifications.ts b/server/middlewares/validators/user-notifications.ts index 46486e081..3ded8d8cf 100644 --- a/server/middlewares/validators/user-notifications.ts +++ b/server/middlewares/validators/user-notifications.ts | |||
@@ -28,8 +28,22 @@ const updateNotificationSettingsValidator = [ | |||
28 | .custom(isUserNotificationSettingValid).withMessage('Should have a valid new comment on my video notification setting'), | 28 | .custom(isUserNotificationSettingValid).withMessage('Should have a valid new comment on my video notification setting'), |
29 | body('videoAbuseAsModerator') | 29 | body('videoAbuseAsModerator') |
30 | .custom(isUserNotificationSettingValid).withMessage('Should have a valid new video abuse as moderator notification setting'), | 30 | .custom(isUserNotificationSettingValid).withMessage('Should have a valid new video abuse as moderator notification setting'), |
31 | body('videoAutoBlacklistAsModerator') | ||
32 | .custom(isUserNotificationSettingValid).withMessage('Should have a valid video auto blacklist notification setting'), | ||
31 | body('blacklistOnMyVideo') | 33 | body('blacklistOnMyVideo') |
32 | .custom(isUserNotificationSettingValid).withMessage('Should have a valid new blacklist on my video notification setting'), | 34 | .custom(isUserNotificationSettingValid).withMessage('Should have a valid new blacklist on my video notification setting'), |
35 | body('myVideoImportFinished') | ||
36 | .custom(isUserNotificationSettingValid).withMessage('Should have a valid video import finished video notification setting'), | ||
37 | body('myVideoPublished') | ||
38 | .custom(isUserNotificationSettingValid).withMessage('Should have a valid video published notification setting'), | ||
39 | body('commentMention') | ||
40 | .custom(isUserNotificationSettingValid).withMessage('Should have a valid comment mention notification setting'), | ||
41 | body('newFollow') | ||
42 | .custom(isUserNotificationSettingValid).withMessage('Should have a valid new follow notification setting'), | ||
43 | body('newUserRegistration') | ||
44 | .custom(isUserNotificationSettingValid).withMessage('Should have a valid new user registration notification setting'), | ||
45 | body('newInstanceFollower') | ||
46 | .custom(isUserNotificationSettingValid).withMessage('Should have a valid new instance follower notification setting'), | ||
33 | 47 | ||
34 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 48 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
35 | logger.debug('Checking updateNotificationSettingsValidator parameters', { parameters: req.body }) | 49 | logger.debug('Checking updateNotificationSettingsValidator parameters', { parameters: req.body }) |
diff --git a/server/models/account/user-notification-setting.ts b/server/models/account/user-notification-setting.ts index ba7f739b9..c2fbc6d23 100644 --- a/server/models/account/user-notification-setting.ts +++ b/server/models/account/user-notification-setting.ts | |||
@@ -104,6 +104,15 @@ export class UserNotificationSettingModel extends Model<UserNotificationSettingM | |||
104 | @AllowNull(false) | 104 | @AllowNull(false) |
105 | @Default(null) | 105 | @Default(null) |
106 | @Is( | 106 | @Is( |
107 | 'UserNotificationSettingNewInstanceFollower', | ||
108 | value => throwIfNotValid(value, isUserNotificationSettingValid, 'newInstanceFollower') | ||
109 | ) | ||
110 | @Column | ||
111 | newInstanceFollower: UserNotificationSettingValue | ||
112 | |||
113 | @AllowNull(false) | ||
114 | @Default(null) | ||
115 | @Is( | ||
107 | 'UserNotificationSettingNewFollow', | 116 | 'UserNotificationSettingNewFollow', |
108 | value => throwIfNotValid(value, isUserNotificationSettingValid, 'newFollow') | 117 | value => throwIfNotValid(value, isUserNotificationSettingValid, 'newFollow') |
109 | ) | 118 | ) |
@@ -154,7 +163,8 @@ export class UserNotificationSettingModel extends Model<UserNotificationSettingM | |||
154 | myVideoImportFinished: this.myVideoImportFinished, | 163 | myVideoImportFinished: this.myVideoImportFinished, |
155 | newUserRegistration: this.newUserRegistration, | 164 | newUserRegistration: this.newUserRegistration, |
156 | commentMention: this.commentMention, | 165 | commentMention: this.commentMention, |
157 | newFollow: this.newFollow | 166 | newFollow: this.newFollow, |
167 | newInstanceFollower: this.newInstanceFollower | ||
158 | } | 168 | } |
159 | } | 169 | } |
160 | } | 170 | } |
diff --git a/server/models/account/user-notification.ts b/server/models/account/user-notification.ts index 6cdbb827b..ccf8277ab 100644 --- a/server/models/account/user-notification.ts +++ b/server/models/account/user-notification.ts | |||
@@ -418,6 +418,7 @@ export class UserNotificationModel extends Model<UserNotificationModel> { | |||
418 | 418 | ||
419 | const actorFollow = this.ActorFollow ? { | 419 | const actorFollow = this.ActorFollow ? { |
420 | id: this.ActorFollow.id, | 420 | id: this.ActorFollow.id, |
421 | state: this.ActorFollow.state, | ||
421 | follower: { | 422 | follower: { |
422 | id: this.ActorFollow.ActorFollower.Account.id, | 423 | id: this.ActorFollow.ActorFollower.Account.id, |
423 | displayName: this.ActorFollow.ActorFollower.Account.getDisplayName(), | 424 | displayName: this.ActorFollow.ActorFollower.Account.getDisplayName(), |
diff --git a/server/tests/api/check-params/user-notifications.ts b/server/tests/api/check-params/user-notifications.ts index 36eaceac7..4b75f6920 100644 --- a/server/tests/api/check-params/user-notifications.ts +++ b/server/tests/api/check-params/user-notifications.ts | |||
@@ -174,7 +174,8 @@ describe('Test user notifications API validators', function () { | |||
174 | myVideoPublished: UserNotificationSettingValue.WEB, | 174 | myVideoPublished: UserNotificationSettingValue.WEB, |
175 | commentMention: UserNotificationSettingValue.WEB, | 175 | commentMention: UserNotificationSettingValue.WEB, |
176 | newFollow: UserNotificationSettingValue.WEB, | 176 | newFollow: UserNotificationSettingValue.WEB, |
177 | newUserRegistration: UserNotificationSettingValue.WEB | 177 | newUserRegistration: UserNotificationSettingValue.WEB, |
178 | newInstanceFollower: UserNotificationSettingValue.WEB | ||
178 | } | 179 | } |
179 | 180 | ||
180 | it('Should fail with missing fields', async function () { | 181 | it('Should fail with missing fields', async function () { |
diff --git a/server/tests/api/index-1.ts b/server/tests/api/index-1.ts index 80d752f42..75cdd9025 100644 --- a/server/tests/api/index-1.ts +++ b/server/tests/api/index-1.ts | |||
@@ -1,2 +1,3 @@ | |||
1 | import './check-params' | 1 | import './check-params' |
2 | import './notifications' | ||
2 | import './search' | 3 | import './search' |
diff --git a/server/tests/api/notifications/index.ts b/server/tests/api/notifications/index.ts new file mode 100644 index 000000000..95ac8fc51 --- /dev/null +++ b/server/tests/api/notifications/index.ts | |||
@@ -0,0 +1 @@ | |||
export * from './user-notifications' | |||
diff --git a/server/tests/api/users/user-notifications.ts b/server/tests/api/notifications/user-notifications.ts index ac47978e2..7bff52796 100644 --- a/server/tests/api/users/user-notifications.ts +++ b/server/tests/api/notifications/user-notifications.ts | |||
@@ -19,7 +19,7 @@ import { | |||
19 | userLogin, | 19 | userLogin, |
20 | wait, | 20 | wait, |
21 | getCustomConfig, | 21 | getCustomConfig, |
22 | updateCustomConfig, getVideoThreadComments, getVideoCommentThreads | 22 | updateCustomConfig, getVideoThreadComments, getVideoCommentThreads, follow |
23 | } from '../../../../shared/utils' | 23 | } from '../../../../shared/utils' |
24 | import { killallServers, ServerInfo, uploadVideo } from '../../../../shared/utils/index' | 24 | import { killallServers, ServerInfo, uploadVideo } from '../../../../shared/utils/index' |
25 | import { setAccessTokensToServers } from '../../../../shared/utils/users/login' | 25 | import { setAccessTokensToServers } from '../../../../shared/utils/users/login' |
@@ -41,7 +41,7 @@ import { | |||
41 | getUserNotifications, | 41 | getUserNotifications, |
42 | markAsReadNotifications, | 42 | markAsReadNotifications, |
43 | updateMyNotificationSettings, | 43 | updateMyNotificationSettings, |
44 | markAsReadAllNotifications | 44 | markAsReadAllNotifications, checkNewInstanceFollower |
45 | } from '../../../../shared/utils/users/user-notifications' | 45 | } from '../../../../shared/utils/users/user-notifications' |
46 | import { | 46 | import { |
47 | User, | 47 | User, |
@@ -103,7 +103,8 @@ describe('Test users notifications', function () { | |||
103 | myVideoPublished: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, | 103 | myVideoPublished: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, |
104 | commentMention: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, | 104 | commentMention: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, |
105 | newFollow: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, | 105 | newFollow: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, |
106 | newUserRegistration: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL | 106 | newUserRegistration: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, |
107 | newInstanceFollower: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL | ||
107 | } | 108 | } |
108 | 109 | ||
109 | before(async function () { | 110 | before(async function () { |
@@ -118,7 +119,7 @@ describe('Test users notifications', function () { | |||
118 | hostname: 'localhost' | 119 | hostname: 'localhost' |
119 | } | 120 | } |
120 | } | 121 | } |
121 | servers = await flushAndRunMultipleServers(2, overrideConfig) | 122 | servers = await flushAndRunMultipleServers(3, overrideConfig) |
122 | 123 | ||
123 | // Get the access tokens | 124 | // Get the access tokens |
124 | await setAccessTokensToServers(servers) | 125 | await setAccessTokensToServers(servers) |
@@ -861,6 +862,32 @@ describe('Test users notifications', function () { | |||
861 | }) | 862 | }) |
862 | }) | 863 | }) |
863 | 864 | ||
865 | describe('New instance follower', function () { | ||
866 | let baseParams: CheckerBaseParams | ||
867 | |||
868 | before(async () => { | ||
869 | baseParams = { | ||
870 | server: servers[0], | ||
871 | emails, | ||
872 | socketNotifications: adminNotifications, | ||
873 | token: servers[0].accessToken | ||
874 | } | ||
875 | }) | ||
876 | |||
877 | it('Should send a notification only to admin when there is a new instance follower', async function () { | ||
878 | this.timeout(10000) | ||
879 | |||
880 | await follow(servers[2].url, [ servers[0].url ], servers[2].accessToken) | ||
881 | |||
882 | await waitJobs(servers) | ||
883 | |||
884 | await checkNewInstanceFollower(baseParams, 'localhost:9003', 'presence') | ||
885 | |||
886 | const userOverride = { socketNotifications: userNotifications, token: userAccessToken, check: { web: true, mail: false } } | ||
887 | await checkNewInstanceFollower(immutableAssign(baseParams, userOverride), 'localhost:9003', 'absence') | ||
888 | }) | ||
889 | }) | ||
890 | |||
864 | describe('New actor follow', function () { | 891 | describe('New actor follow', function () { |
865 | let baseParams: CheckerBaseParams | 892 | let baseParams: CheckerBaseParams |
866 | let myChannelName = 'super channel name' | 893 | let myChannelName = 'super channel name' |
diff --git a/server/tests/api/users/index.ts b/server/tests/api/users/index.ts index 52ba6984e..fcd022429 100644 --- a/server/tests/api/users/index.ts +++ b/server/tests/api/users/index.ts | |||
@@ -1,5 +1,4 @@ | |||
1 | import './users-verification' | 1 | import './users-verification' |
2 | import './user-notifications' | ||
3 | import './blocklist' | 2 | import './blocklist' |
4 | import './user-subscriptions' | 3 | import './user-subscriptions' |
5 | import './users' | 4 | import './users' |