]>
Commit | Line | Data |
---|---|---|
1 | import { | |
2 | ActivityCreate, | |
3 | ActivityFlag, | |
4 | VideoAbuseState, | |
5 | videoAbusePredefinedReasonsMap | |
6 | } from '../../../../shared' | |
7 | import { VideoAbuseObject } from '../../../../shared/models/activitypub/objects' | |
8 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | |
9 | import { logger } from '../../../helpers/logger' | |
10 | import { sequelizeTypescript } from '../../../initializers/database' | |
11 | import { VideoAbuseModel } from '../../../models/video/video-abuse' | |
12 | import { getOrCreateVideoAndAccountAndChannel } from '../videos' | |
13 | import { Notifier } from '../../notifier' | |
14 | import { getAPId } from '../../../helpers/activitypub' | |
15 | import { APProcessorOptions } from '../../../types/activitypub-processor.model' | |
16 | import { MActorSignature, MVideoAbuseAccountVideo } from '../../../types/models' | |
17 | import { AccountModel } from '@server/models/account/account' | |
18 | ||
19 | async function processFlagActivity (options: APProcessorOptions<ActivityCreate | ActivityFlag>) { | |
20 | const { activity, byActor } = options | |
21 | return retryTransactionWrapper(processCreateVideoAbuse, activity, byActor) | |
22 | } | |
23 | ||
24 | // --------------------------------------------------------------------------- | |
25 | ||
26 | export { | |
27 | processFlagActivity | |
28 | } | |
29 | ||
30 | // --------------------------------------------------------------------------- | |
31 | ||
32 | async function processCreateVideoAbuse (activity: ActivityCreate | ActivityFlag, byActor: MActorSignature) { | |
33 | const flag = activity.type === 'Flag' ? activity : (activity.object as VideoAbuseObject) | |
34 | ||
35 | const account = byActor.Account | |
36 | if (!account) throw new Error('Cannot create video abuse with the non account actor ' + byActor.url) | |
37 | ||
38 | const objects = Array.isArray(flag.object) ? flag.object : [ flag.object ] | |
39 | ||
40 | for (const object of objects) { | |
41 | try { | |
42 | logger.debug('Reporting remote abuse for video %s.', getAPId(object)) | |
43 | ||
44 | const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: object }) | |
45 | const reporterAccount = await sequelizeTypescript.transaction(async t => AccountModel.load(account.id, t)) | |
46 | const tags = Array.isArray(flag.tag) ? flag.tag : [] | |
47 | const predefinedReasons = tags.map(tag => videoAbusePredefinedReasonsMap[tag.name]) | |
48 | .filter(v => !isNaN(v)) | |
49 | const startAt = flag.startAt | |
50 | const endAt = flag.endAt | |
51 | ||
52 | const videoAbuseInstance = await sequelizeTypescript.transaction(async t => { | |
53 | const videoAbuseData = { | |
54 | reporterAccountId: account.id, | |
55 | reason: flag.content, | |
56 | videoId: video.id, | |
57 | state: VideoAbuseState.PENDING, | |
58 | predefinedReasons, | |
59 | startAt, | |
60 | endAt | |
61 | } | |
62 | ||
63 | const videoAbuseInstance: MVideoAbuseAccountVideo = await VideoAbuseModel.create(videoAbuseData, { transaction: t }) | |
64 | videoAbuseInstance.Video = video | |
65 | videoAbuseInstance.Account = reporterAccount | |
66 | ||
67 | logger.info('Remote abuse for video uuid %s created', flag.object) | |
68 | ||
69 | return videoAbuseInstance | |
70 | }) | |
71 | ||
72 | const videoAbuseJSON = videoAbuseInstance.toFormattedJSON() | |
73 | ||
74 | Notifier.Instance.notifyOnNewVideoAbuse({ | |
75 | videoAbuse: videoAbuseJSON, | |
76 | videoAbuseInstance, | |
77 | reporter: reporterAccount.Actor.getIdentifier() | |
78 | }) | |
79 | } catch (err) { | |
80 | logger.debug('Cannot process report of %s. (Maybe not a video abuse).', getAPId(object), { err }) | |
81 | } | |
82 | } | |
83 | } |