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