Init commit

This commit is contained in:
ShreejitPanchal
2026-05-19 19:56:02 +08:00
commit 6601501eff
4047 changed files with 2185372 additions and 0 deletions

View File

@@ -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
}
}

View File

@@ -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
}
}

View 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'

View File

@@ -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)
}
}
}

View File

@@ -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')
}
}

View File

@@ -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')
}
}