]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/lib/moderation.ts
Process remaining segment hashes on live ending
[github/Chocobozzz/PeerTube.git] / server / lib / moderation.ts
CommitLineData
d95d1559
C
1import { PathLike } from 'fs-extra'
2import { Transaction } from 'sequelize/types'
3import { AbuseAuditView, auditLoggerFactory } from '@server/helpers/audit-logger'
4import { logger } from '@server/helpers/logger'
5import { AbuseModel } from '@server/models/abuse/abuse'
6import { VideoAbuseModel } from '@server/models/abuse/video-abuse'
7import { VideoCommentAbuseModel } from '@server/models/abuse/video-comment-abuse'
8import { VideoFileModel } from '@server/models/video/video-file'
9import { FilteredModelAttributes } from '@server/types'
10import {
11 MAbuseFull,
12 MAccountDefault,
13 MAccountLight,
14 MCommentAbuseAccountVideo,
15 MCommentOwnerVideo,
16 MUser,
17 MVideoAbuseVideoFull,
18 MVideoAccountLightBlacklistAllFiles
19} from '@server/types/models'
20import { ActivityCreate } from '../../shared/models/activitypub'
de6310b2 21import { VideoObject } from '../../shared/models/activitypub/objects'
d95d1559 22import { VideoCommentObject } from '../../shared/models/activitypub/objects/video-comment-object'
3cabf353 23import { LiveVideoCreate, VideoCreate, VideoImportCreate } from '../../shared/models/videos'
d95d1559 24import { VideoCommentCreate } from '../../shared/models/videos/video-comment.model'
b4055e1c 25import { UserModel } from '../models/account/user'
b4055e1c 26import { ActorModel } from '../models/activitypub/actor'
d95d1559
C
27import { VideoModel } from '../models/video/video'
28import { VideoCommentModel } from '../models/video/video-comment'
29import { sendAbuse } from './activitypub/send/send-flag'
30import { Notifier } from './notifier'
b4055e1c
C
31
32export type AcceptResult = {
33 accepted: boolean
34 errorMessage?: string
35}
36
37// Can be filtered by plugins
38function isLocalVideoAccepted (object: {
a1587156
C
39 videoBody: VideoCreate
40 videoFile: Express.Multer.File & { duration?: number }
b4055e1c
C
41 user: UserModel
42}): AcceptResult {
43 return { accepted: true }
44}
45
3cabf353
C
46function isLocalLiveVideoAccepted (object: {
47 liveVideoBody: LiveVideoCreate
48 user: UserModel
49}): AcceptResult {
50 return { accepted: true }
51}
52
b4055e1c 53function isLocalVideoThreadAccepted (_object: {
a1587156
C
54 commentBody: VideoCommentCreate
55 video: VideoModel
b4055e1c
C
56 user: UserModel
57}): AcceptResult {
58 return { accepted: true }
59}
60
61function isLocalVideoCommentReplyAccepted (_object: {
a1587156
C
62 commentBody: VideoCommentCreate
63 parentComment: VideoCommentModel
64 video: VideoModel
b4055e1c
C
65 user: UserModel
66}): AcceptResult {
67 return { accepted: true }
68}
69
70function isRemoteVideoAccepted (_object: {
a1587156 71 activity: ActivityCreate
de6310b2 72 videoAP: VideoObject
b4055e1c
C
73 byActor: ActorModel
74}): AcceptResult {
75 return { accepted: true }
76}
77
78function isRemoteVideoCommentAccepted (_object: {
a1587156
C
79 activity: ActivityCreate
80 commentAP: VideoCommentObject
b4055e1c
C
81 byActor: ActorModel
82}): AcceptResult {
83 return { accepted: true }
84}
85
2158ac90
RK
86function isPreImportVideoAccepted (object: {
87 videoImportBody: VideoImportCreate
88 user: MUser
89}): AcceptResult {
90 return { accepted: true }
91}
92
93function isPostImportVideoAccepted (object: {
94 videoFilePath: PathLike
95 videoFile: VideoFileModel
96 user: MUser
97}): AcceptResult {
98 return { accepted: true }
99}
100
d95d1559
C
101async function createVideoAbuse (options: {
102 baseAbuse: FilteredModelAttributes<AbuseModel>
103 videoInstance: MVideoAccountLightBlacklistAllFiles
104 startAt: number
105 endAt: number
106 transaction: Transaction
107 reporterAccount: MAccountDefault
108}) {
109 const { baseAbuse, videoInstance, startAt, endAt, transaction, reporterAccount } = options
110
111 const associateFun = async (abuseInstance: MAbuseFull) => {
112 const videoAbuseInstance: MVideoAbuseVideoFull = await VideoAbuseModel.create({
113 abuseId: abuseInstance.id,
114 videoId: videoInstance.id,
115 startAt: startAt,
116 endAt: endAt
117 }, { transaction })
118
119 videoAbuseInstance.Video = videoInstance
120 abuseInstance.VideoAbuse = videoAbuseInstance
121
122 return { isOwned: videoInstance.isOwned() }
123 }
124
125 return createAbuse({
126 base: baseAbuse,
127 reporterAccount,
128 flaggedAccount: videoInstance.VideoChannel.Account,
129 transaction,
130 associateFun
131 })
132}
133
134function createVideoCommentAbuse (options: {
135 baseAbuse: FilteredModelAttributes<AbuseModel>
136 commentInstance: MCommentOwnerVideo
137 transaction: Transaction
138 reporterAccount: MAccountDefault
139}) {
140 const { baseAbuse, commentInstance, transaction, reporterAccount } = options
141
142 const associateFun = async (abuseInstance: MAbuseFull) => {
143 const commentAbuseInstance: MCommentAbuseAccountVideo = await VideoCommentAbuseModel.create({
144 abuseId: abuseInstance.id,
145 videoCommentId: commentInstance.id
146 }, { transaction })
147
148 commentAbuseInstance.VideoComment = commentInstance
149 abuseInstance.VideoCommentAbuse = commentAbuseInstance
150
151 return { isOwned: commentInstance.isOwned() }
152 }
153
154 return createAbuse({
155 base: baseAbuse,
156 reporterAccount,
157 flaggedAccount: commentInstance.Account,
158 transaction,
159 associateFun
160 })
161}
162
163function createAccountAbuse (options: {
164 baseAbuse: FilteredModelAttributes<AbuseModel>
165 accountInstance: MAccountDefault
166 transaction: Transaction
167 reporterAccount: MAccountDefault
168}) {
169 const { baseAbuse, accountInstance, transaction, reporterAccount } = options
170
171 const associateFun = async () => {
172 return { isOwned: accountInstance.isOwned() }
173 }
174
175 return createAbuse({
176 base: baseAbuse,
177 reporterAccount,
178 flaggedAccount: accountInstance,
179 transaction,
180 associateFun
181 })
182}
183
b4055e1c 184export {
3cabf353
C
185 isLocalLiveVideoAccepted,
186
b4055e1c
C
187 isLocalVideoAccepted,
188 isLocalVideoThreadAccepted,
189 isRemoteVideoAccepted,
190 isRemoteVideoCommentAccepted,
2158ac90
RK
191 isLocalVideoCommentReplyAccepted,
192 isPreImportVideoAccepted,
d95d1559
C
193 isPostImportVideoAccepted,
194
195 createAbuse,
196 createVideoAbuse,
197 createVideoCommentAbuse,
198 createAccountAbuse
199}
200
201// ---------------------------------------------------------------------------
202
203async function createAbuse (options: {
204 base: FilteredModelAttributes<AbuseModel>
205 reporterAccount: MAccountDefault
206 flaggedAccount: MAccountLight
207 associateFun: (abuseInstance: MAbuseFull) => Promise<{ isOwned: boolean} >
208 transaction: Transaction
209}) {
210 const { base, reporterAccount, flaggedAccount, associateFun, transaction } = options
211 const auditLogger = auditLoggerFactory('abuse')
212
213 const abuseAttributes = Object.assign({}, base, { flaggedAccountId: flaggedAccount.id })
214 const abuseInstance: MAbuseFull = await AbuseModel.create(abuseAttributes, { transaction })
215
216 abuseInstance.ReporterAccount = reporterAccount
217 abuseInstance.FlaggedAccount = flaggedAccount
218
219 const { isOwned } = await associateFun(abuseInstance)
220
221 if (isOwned === false) {
222 await sendAbuse(reporterAccount.Actor, abuseInstance, abuseInstance.FlaggedAccount, transaction)
223 }
224
edbc9325 225 const abuseJSON = abuseInstance.toFormattedAdminJSON()
d95d1559
C
226 auditLogger.create(reporterAccount.Actor.getIdentifier(), new AbuseAuditView(abuseJSON))
227
228 Notifier.Instance.notifyOnNewAbuse({
229 abuse: abuseJSON,
230 abuseInstance,
231 reporter: reporterAccount.Actor.getIdentifier()
232 })
233
234 logger.info('Abuse report %d created.', abuseInstance.id)
235
236 return abuseJSON
b4055e1c 237}