Init commit
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
import { To, UserNotificationType } from '@peertube/peertube-models'
|
||||
import { t } from '@server/helpers/i18n.js'
|
||||
import { getAdminAbuseUrl, getUserAbuseUrl } from '@server/lib/client-urls.js'
|
||||
import { AccountModel } from '@server/models/account/account.js'
|
||||
import { UserNotificationModel } from '@server/models/user/user-notification.js'
|
||||
import {
|
||||
MAbuseFull,
|
||||
MAbuseMessage,
|
||||
MAccountDefault,
|
||||
MUserWithNotificationSetting,
|
||||
UserNotificationModelForApi
|
||||
} from '@server/types/models/index.js'
|
||||
import { AbstractNotification } from '../common/abstract-notification.js'
|
||||
|
||||
type NewAbuseMessagePayload = {
|
||||
abuse: MAbuseFull
|
||||
message: MAbuseMessage
|
||||
}
|
||||
|
||||
export abstract class AbstractNewAbuseMessage extends AbstractNotification<NewAbuseMessagePayload> {
|
||||
protected messageAccount: MAccountDefault
|
||||
|
||||
async loadMessageAccount () {
|
||||
this.messageAccount = await AccountModel.load(this.message.accountId)
|
||||
}
|
||||
|
||||
getSetting (user: MUserWithNotificationSetting) {
|
||||
return user.NotificationSetting.abuseNewMessage
|
||||
}
|
||||
|
||||
createNotification (user: MUserWithNotificationSetting) {
|
||||
const notification = UserNotificationModel.build<UserNotificationModelForApi>({
|
||||
type: UserNotificationType.ABUSE_NEW_MESSAGE,
|
||||
userId: user.id,
|
||||
abuseId: this.abuse.id
|
||||
})
|
||||
notification.Abuse = this.abuse
|
||||
|
||||
return notification
|
||||
}
|
||||
|
||||
protected createEmailFor (to: To, target: 'moderator' | 'reporter') {
|
||||
const text = t('New message on report #{id}', to.language, { id: this.abuse.id })
|
||||
const abuseUrl = target === 'moderator'
|
||||
? getAdminAbuseUrl(this.abuse)
|
||||
: getUserAbuseUrl(this.abuse)
|
||||
|
||||
const action = {
|
||||
text: t('View report #{id}', to.language, { id: this.abuse.id }),
|
||||
url: abuseUrl
|
||||
}
|
||||
|
||||
return {
|
||||
template: 'abuse-new-message',
|
||||
to,
|
||||
subject: text,
|
||||
locals: {
|
||||
abuseId: this.abuse.id,
|
||||
abuseUrl,
|
||||
messageAccountName: this.messageAccount.getDisplayName(),
|
||||
messageText: this.message.message,
|
||||
action
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected get abuse () {
|
||||
return this.payload.abuse
|
||||
}
|
||||
|
||||
protected get message () {
|
||||
return this.payload.message
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import { AbuseState, UserNotificationType } from '@peertube/peertube-models'
|
||||
import { t } from '@server/helpers/i18n.js'
|
||||
import { logger } from '@server/helpers/logger.js'
|
||||
import { getAbuseIdentifier } from '@server/lib/activitypub/url.js'
|
||||
import { getUserAbuseUrl } from '@server/lib/client-urls.js'
|
||||
import { UserNotificationModel } from '@server/models/user/user-notification.js'
|
||||
import { UserModel } from '@server/models/user/user.js'
|
||||
import { MAbuseFull, MUserDefault, MUserWithNotificationSetting, UserNotificationModelForApi } from '@server/types/models/index.js'
|
||||
import { AbstractNotification } from '../common/abstract-notification.js'
|
||||
|
||||
export class AbuseStateChangeForReporter extends AbstractNotification<MAbuseFull> {
|
||||
private user: MUserDefault
|
||||
|
||||
async prepare () {
|
||||
const reporter = this.abuse.ReporterAccount
|
||||
if (reporter.isLocal() !== true) return
|
||||
|
||||
this.user = await UserModel.loadByAccountActorId(this.abuse.ReporterAccount.Actor.id)
|
||||
}
|
||||
|
||||
log () {
|
||||
logger.info('Notifying reporter of abuse % of state change.', getAbuseIdentifier(this.abuse))
|
||||
}
|
||||
|
||||
getSetting (user: MUserWithNotificationSetting) {
|
||||
return user.NotificationSetting.abuseStateChange
|
||||
}
|
||||
|
||||
getTargetUsers () {
|
||||
if (!this.user) return []
|
||||
|
||||
return [ this.user ]
|
||||
}
|
||||
|
||||
createNotification (user: MUserWithNotificationSetting) {
|
||||
const notification = UserNotificationModel.build<UserNotificationModelForApi>({
|
||||
type: UserNotificationType.ABUSE_STATE_CHANGE,
|
||||
userId: user.id,
|
||||
abuseId: this.abuse.id
|
||||
})
|
||||
notification.Abuse = this.abuse
|
||||
|
||||
return notification
|
||||
}
|
||||
|
||||
createEmail (user: MUserWithNotificationSetting) {
|
||||
const language = user.getLanguage()
|
||||
const to = { email: user.email, language }
|
||||
|
||||
const text = this.abuse.state === AbuseState.ACCEPTED
|
||||
? t('Report #{id} has been accepted', language, { id: this.abuse.id })
|
||||
: t('Report #{id} has been rejected', language, { id: this.abuse.id })
|
||||
|
||||
const abuseUrl = getUserAbuseUrl(this.abuse)
|
||||
|
||||
const action = {
|
||||
text: t('View report #{id}', language, { id: this.abuse.id }),
|
||||
url: abuseUrl
|
||||
}
|
||||
|
||||
return {
|
||||
template: 'abuse-state-change',
|
||||
to,
|
||||
subject: text,
|
||||
locals: {
|
||||
action,
|
||||
abuseId: this.abuse.id,
|
||||
abuseUrl,
|
||||
isAccepted: this.abuse.state === AbuseState.ACCEPTED
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private get abuse () {
|
||||
return this.payload
|
||||
}
|
||||
}
|
||||
4
server/core/lib/notifier/shared/abuse/index.ts
Normal file
4
server/core/lib/notifier/shared/abuse/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export * from './abuse-state-change-for-reporter.js'
|
||||
export * from './new-abuse-for-moderators.js'
|
||||
export * from './new-abuse-message-for-reporter.js'
|
||||
export * from './new-abuse-message-for-moderators.js'
|
||||
@@ -0,0 +1,123 @@
|
||||
import { To, UserAbuse, UserNotificationType, UserRight } from '@peertube/peertube-models'
|
||||
import { t } from '@server/helpers/i18n.js'
|
||||
import { logger } from '@server/helpers/logger.js'
|
||||
import { WEBSERVER } from '@server/initializers/constants.js'
|
||||
import { getAbuseIdentifier } from '@server/lib/activitypub/url.js'
|
||||
import { getAdminAbuseUrl } from '@server/lib/client-urls.js'
|
||||
import { UserNotificationModel } from '@server/models/user/user-notification.js'
|
||||
import { UserModel } from '@server/models/user/user.js'
|
||||
import { MAbuseFull, MUserDefault, MUserWithNotificationSetting, UserNotificationModelForApi } from '@server/types/models/index.js'
|
||||
import { AbstractNotification } from '../common/abstract-notification.js'
|
||||
|
||||
export type NewAbusePayload = { abuse: Pick<UserAbuse, 'reason' | 'video'>, abuseInstance: MAbuseFull, reporter: string }
|
||||
|
||||
export class NewAbuseForModerators extends AbstractNotification<NewAbusePayload> {
|
||||
private moderators: MUserDefault[]
|
||||
|
||||
async prepare () {
|
||||
this.moderators = await UserModel.listWithRight(UserRight.MANAGE_ABUSES)
|
||||
}
|
||||
|
||||
log () {
|
||||
logger.info('Notifying %s user/moderators of new abuse %s.', this.moderators.length, getAbuseIdentifier(this.payload.abuseInstance))
|
||||
}
|
||||
|
||||
getSetting (user: MUserWithNotificationSetting) {
|
||||
return user.NotificationSetting.abuseAsModerator
|
||||
}
|
||||
|
||||
getTargetUsers () {
|
||||
return this.moderators
|
||||
}
|
||||
|
||||
createNotification (user: MUserWithNotificationSetting) {
|
||||
const notification = UserNotificationModel.build<UserNotificationModelForApi>({
|
||||
type: UserNotificationType.NEW_ABUSE_FOR_MODERATORS,
|
||||
userId: user.id,
|
||||
abuseId: this.payload.abuseInstance.id
|
||||
})
|
||||
notification.Abuse = this.payload.abuseInstance
|
||||
|
||||
return notification
|
||||
}
|
||||
|
||||
createEmail (user: MUserWithNotificationSetting) {
|
||||
const to = { email: user.email, language: user.getLanguage() }
|
||||
|
||||
const abuseInstance = this.payload.abuseInstance
|
||||
|
||||
if (abuseInstance.VideoAbuse) return this.createVideoAbuseEmail(to)
|
||||
if (abuseInstance.VideoCommentAbuse) return this.createCommentAbuseEmail(to)
|
||||
|
||||
return this.createAccountAbuseEmail(to)
|
||||
}
|
||||
|
||||
private createVideoAbuseEmail (to: To) {
|
||||
const video = this.payload.abuseInstance.VideoAbuse.Video
|
||||
const channel = video.VideoChannel
|
||||
|
||||
return {
|
||||
template: 'video-abuse-new',
|
||||
to,
|
||||
subject: t('New video abuse report from {reporter}', to.language, { reporter: this.payload.reporter }),
|
||||
locals: {
|
||||
videoUrl: WEBSERVER.URL + video.getWatchStaticPath(),
|
||||
isLocal: video.remote === false,
|
||||
videoCreatedAt: new Date(video.createdAt).toLocaleString(),
|
||||
videoPublishedAt: new Date(video.publishedAt).toLocaleString(),
|
||||
videoName: video.name,
|
||||
reason: this.payload.abuse.reason,
|
||||
channelDisplayName: channel.getDisplayName(),
|
||||
channelUrl: channel.getClientUrl(),
|
||||
reporter: this.payload.reporter,
|
||||
action: this.buildEmailAction(to)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private createCommentAbuseEmail (to: To) {
|
||||
const comment = this.payload.abuseInstance.VideoCommentAbuse.VideoComment
|
||||
|
||||
return {
|
||||
template: 'video-comment-abuse-new',
|
||||
to,
|
||||
subject: t('New comment abuse report from {reporter}', to.language, { reporter: this.payload.reporter }),
|
||||
locals: {
|
||||
commentUrl: WEBSERVER.URL + comment.getCommentStaticPath(),
|
||||
videoName: comment.Video.name,
|
||||
isLocal: comment.isLocal(),
|
||||
commentCreatedAt: new Date(comment.createdAt).toLocaleString(),
|
||||
reason: this.payload.abuse.reason,
|
||||
flaggedAccount: this.payload.abuseInstance.FlaggedAccount.getDisplayName(),
|
||||
reporter: this.payload.reporter,
|
||||
action: this.buildEmailAction(to)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private createAccountAbuseEmail (to: To) {
|
||||
const account = this.payload.abuseInstance.FlaggedAccount
|
||||
const accountUrl = account.getClientUrl()
|
||||
|
||||
return {
|
||||
template: 'account-abuse-new',
|
||||
to,
|
||||
subject: t('New account abuse report from {reporter}', to.language, { reporter: this.payload.reporter }),
|
||||
locals: {
|
||||
accountUrl,
|
||||
accountDisplayName: account.getDisplayName(),
|
||||
isLocal: account.isLocal(),
|
||||
reason: this.payload.abuse.reason,
|
||||
reporter: this.payload.reporter,
|
||||
action: this.buildEmailAction(to)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private buildEmailAction (to: To) {
|
||||
return {
|
||||
text: t('View report #' + this.payload.abuseInstance.id, to.language),
|
||||
url: getAdminAbuseUrl(this.payload.abuseInstance)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { UserRight } from '@peertube/peertube-models'
|
||||
import { logger } from '@server/helpers/logger.js'
|
||||
import { getAbuseIdentifier } from '@server/lib/activitypub/url.js'
|
||||
import { UserModel } from '@server/models/user/user.js'
|
||||
import { MUserDefault, MUserWithNotificationSetting } from '@server/types/models/index.js'
|
||||
import { AbstractNewAbuseMessage } from './abstract-new-abuse-message.js'
|
||||
|
||||
export class NewAbuseMessageForModerators extends AbstractNewAbuseMessage {
|
||||
private moderators: MUserDefault[]
|
||||
|
||||
async prepare () {
|
||||
this.moderators = await UserModel.listWithRight(UserRight.MANAGE_ABUSES)
|
||||
|
||||
// Don't notify my own message
|
||||
this.moderators = this.moderators.filter(m => m.Account.id !== this.message.accountId)
|
||||
if (this.moderators.length === 0) return
|
||||
|
||||
await this.loadMessageAccount()
|
||||
}
|
||||
|
||||
log () {
|
||||
logger.info('Notifying moderators of new abuse message on %s.', getAbuseIdentifier(this.abuse))
|
||||
}
|
||||
|
||||
getTargetUsers () {
|
||||
return this.moderators
|
||||
}
|
||||
|
||||
createEmail (user: MUserWithNotificationSetting) {
|
||||
const to = { email: user.email, language: user.getLanguage() }
|
||||
|
||||
return this.createEmailFor(to, 'moderator')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { logger } from '@server/helpers/logger.js'
|
||||
import { getAbuseIdentifier } from '@server/lib/activitypub/url.js'
|
||||
import { UserModel } from '@server/models/user/user.js'
|
||||
import { MUserDefault, MUserWithNotificationSetting } from '@server/types/models/index.js'
|
||||
import { AbstractNewAbuseMessage } from './abstract-new-abuse-message.js'
|
||||
|
||||
export class NewAbuseMessageForReporter extends AbstractNewAbuseMessage {
|
||||
private reporter: MUserDefault
|
||||
|
||||
async prepare () {
|
||||
// Only notify our users
|
||||
if (this.abuse.ReporterAccount.isLocal() !== true) return
|
||||
|
||||
await this.loadMessageAccount()
|
||||
|
||||
const reporter = await UserModel.loadByAccountActorId(this.abuse.ReporterAccount.Actor.id)
|
||||
// Don't notify my own message
|
||||
if (reporter.Account.id === this.message.accountId) return
|
||||
|
||||
this.reporter = reporter
|
||||
}
|
||||
|
||||
log () {
|
||||
logger.info('Notifying reporter of new abuse message on %s.', getAbuseIdentifier(this.abuse))
|
||||
}
|
||||
|
||||
getTargetUsers () {
|
||||
if (!this.reporter) return []
|
||||
|
||||
return [ this.reporter ]
|
||||
}
|
||||
|
||||
createEmail (user: MUserWithNotificationSetting) {
|
||||
const to = { email: user.email, language: user.getLanguage() }
|
||||
|
||||
return this.createEmailFor(to, 'reporter')
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user