From d26836cd95e981d636006652927773c7943e77ce Mon Sep 17 00:00:00 2001 From: Chocobozzz <me@florianbigard.com> Date: Fri, 30 Jul 2021 16:51:27 +0200 Subject: Refactor notifier --- .../shared/follow/auto-follow-for-instance.ts | 51 ++++++++++++++ .../notifier/shared/follow/follow-for-instance.ts | 68 ++++++++++++++++++ .../lib/notifier/shared/follow/follow-for-user.ts | 82 ++++++++++++++++++++++ server/lib/notifier/shared/follow/index.ts | 3 + 4 files changed, 204 insertions(+) create mode 100644 server/lib/notifier/shared/follow/auto-follow-for-instance.ts create mode 100644 server/lib/notifier/shared/follow/follow-for-instance.ts create mode 100644 server/lib/notifier/shared/follow/follow-for-user.ts create mode 100644 server/lib/notifier/shared/follow/index.ts (limited to 'server/lib/notifier/shared/follow') diff --git a/server/lib/notifier/shared/follow/auto-follow-for-instance.ts b/server/lib/notifier/shared/follow/auto-follow-for-instance.ts new file mode 100644 index 000000000..16cc62984 --- /dev/null +++ b/server/lib/notifier/shared/follow/auto-follow-for-instance.ts @@ -0,0 +1,51 @@ +import { logger } from '@server/helpers/logger' +import { UserModel } from '@server/models/user/user' +import { UserNotificationModel } from '@server/models/user/user-notification' +import { MActorFollowFull, MUserDefault, MUserWithNotificationSetting, UserNotificationModelForApi } from '@server/types/models' +import { UserNotificationType, UserRight } from '@shared/models' +import { AbstractNotification } from '../common/abstract-notification' + +export class AutoFollowForInstance extends AbstractNotification <MActorFollowFull> { + private admins: MUserDefault[] + + async prepare () { + this.admins = await UserModel.listWithRight(UserRight.MANAGE_SERVER_FOLLOW) + } + + log () { + logger.info('Notifying %d administrators of auto instance following: %s.', this.admins.length, this.actorFollow.ActorFollowing.url) + } + + getSetting (user: MUserWithNotificationSetting) { + return user.NotificationSetting.autoInstanceFollowing + } + + getTargetUsers () { + return this.admins + } + + async createNotification (user: MUserWithNotificationSetting) { + const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ + type: UserNotificationType.AUTO_INSTANCE_FOLLOWING, + userId: user.id, + actorFollowId: this.actorFollow.id + }) + notification.ActorFollow = this.actorFollow + + return notification + } + + async createEmail (to: string) { + const instanceUrl = this.actorFollow.ActorFollowing.url + + return { + to, + subject: 'Auto instance following', + text: `Your instance automatically followed a new instance: <a href="${instanceUrl}">${instanceUrl}</a>.` + } + } + + private get actorFollow () { + return this.payload + } +} diff --git a/server/lib/notifier/shared/follow/follow-for-instance.ts b/server/lib/notifier/shared/follow/follow-for-instance.ts new file mode 100644 index 000000000..9ab269cf1 --- /dev/null +++ b/server/lib/notifier/shared/follow/follow-for-instance.ts @@ -0,0 +1,68 @@ +import { logger } from '@server/helpers/logger' +import { WEBSERVER } from '@server/initializers/constants' +import { isBlockedByServerOrAccount } from '@server/lib/blocklist' +import { UserModel } from '@server/models/user/user' +import { UserNotificationModel } from '@server/models/user/user-notification' +import { MActorFollowFull, MUserDefault, MUserWithNotificationSetting, UserNotificationModelForApi } from '@server/types/models' +import { UserNotificationType, UserRight } from '@shared/models' +import { AbstractNotification } from '../common/abstract-notification' + +export class FollowForInstance extends AbstractNotification <MActorFollowFull> { + private admins: MUserDefault[] + + async prepare () { + this.admins = await UserModel.listWithRight(UserRight.MANAGE_SERVER_FOLLOW) + } + + isDisabled () { + const follower = Object.assign(this.actorFollow.ActorFollower.Account, { Actor: this.actorFollow.ActorFollower }) + + return isBlockedByServerOrAccount(follower) + } + + log () { + logger.info('Notifying %d administrators of new instance follower: %s.', this.admins.length, this.actorFollow.ActorFollower.url) + } + + getSetting (user: MUserWithNotificationSetting) { + return user.NotificationSetting.newInstanceFollower + } + + getTargetUsers () { + return this.admins + } + + async createNotification (user: MUserWithNotificationSetting) { + const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ + type: UserNotificationType.NEW_INSTANCE_FOLLOWER, + userId: user.id, + actorFollowId: this.actorFollow.id + }) + notification.ActorFollow = this.actorFollow + + return notification + } + + async createEmail (to: string) { + const awaitingApproval = this.actorFollow.state === 'pending' + ? ' awaiting manual approval.' + : '' + + return { + to, + subject: 'New instance follower', + text: `Your instance has a new follower: ${this.actorFollow.ActorFollower.url}${awaitingApproval}.`, + locals: { + title: 'New instance follower', + action: { + text: 'Review followers', + url: WEBSERVER.URL + '/admin/follows/followers-list' + } + } + } + } + + private get actorFollow () { + return this.payload + } +} diff --git a/server/lib/notifier/shared/follow/follow-for-user.ts b/server/lib/notifier/shared/follow/follow-for-user.ts new file mode 100644 index 000000000..2d0f675a8 --- /dev/null +++ b/server/lib/notifier/shared/follow/follow-for-user.ts @@ -0,0 +1,82 @@ +import { logger } from '@server/helpers/logger' +import { isBlockedByServerOrAccount } from '@server/lib/blocklist' +import { UserModel } from '@server/models/user/user' +import { UserNotificationModel } from '@server/models/user/user-notification' +import { MActorFollowFull, MUserDefault, MUserWithNotificationSetting, UserNotificationModelForApi } from '@server/types/models' +import { UserNotificationType } from '@shared/models' +import { AbstractNotification } from '../common/abstract-notification' + +export class FollowForUser extends AbstractNotification <MActorFollowFull> { + private followType: 'account' | 'channel' + private user: MUserDefault + + async prepare () { + // Account follows one of our account? + this.followType = 'channel' + this.user = await UserModel.loadByChannelActorId(this.actorFollow.ActorFollowing.id) + + // Account follows one of our channel? + if (!this.user) { + this.user = await UserModel.loadByAccountActorId(this.actorFollow.ActorFollowing.id) + this.followType = 'account' + } + } + + async isDisabled () { + if (this.payload.ActorFollowing.isOwned() === false) return true + + const followerAccount = this.actorFollow.ActorFollower.Account + const followerAccountWithActor = Object.assign(followerAccount, { Actor: this.actorFollow.ActorFollower }) + + return isBlockedByServerOrAccount(followerAccountWithActor, this.user.Account) + } + + log () { + logger.info('Notifying user %s of new follower: %s.', this.user.username, this.actorFollow.ActorFollower.Account.getDisplayName()) + } + + getSetting (user: MUserWithNotificationSetting) { + return user.NotificationSetting.newFollow + } + + getTargetUsers () { + if (!this.user) return [] + + return [ this.user ] + } + + async createNotification (user: MUserWithNotificationSetting) { + const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ + type: UserNotificationType.NEW_FOLLOW, + userId: user.id, + actorFollowId: this.actorFollow.id + }) + notification.ActorFollow = this.actorFollow + + return notification + } + + async createEmail (to: string) { + const following = this.actorFollow.ActorFollowing + const follower = this.actorFollow.ActorFollower + + const followingName = (following.VideoChannel || following.Account).getDisplayName() + + return { + template: 'follower-on-channel', + to, + subject: `New follower on your channel ${followingName}`, + locals: { + followerName: follower.Account.getDisplayName(), + followerUrl: follower.url, + followingName, + followingUrl: following.url, + followType: this.followType + } + } + } + + private get actorFollow () { + return this.payload + } +} diff --git a/server/lib/notifier/shared/follow/index.ts b/server/lib/notifier/shared/follow/index.ts new file mode 100644 index 000000000..27f5289d9 --- /dev/null +++ b/server/lib/notifier/shared/follow/index.ts @@ -0,0 +1,3 @@ +export * from './auto-follow-for-instance' +export * from './follow-for-instance' +export * from './follow-for-user' -- cgit v1.2.3