diff options
Diffstat (limited to 'server/lib/activitypub/process/process-flag.ts')
-rw-r--r-- | server/lib/activitypub/process/process-flag.ts | 117 |
1 files changed, 68 insertions, 49 deletions
diff --git a/server/lib/activitypub/process/process-flag.ts b/server/lib/activitypub/process/process-flag.ts index 1d7132a3a..6350cee12 100644 --- a/server/lib/activitypub/process/process-flag.ts +++ b/server/lib/activitypub/process/process-flag.ts | |||
@@ -1,24 +1,19 @@ | |||
1 | import { | 1 | import { createAccountAbuse, createVideoAbuse, createVideoCommentAbuse } from '@server/lib/moderation' |
2 | ActivityCreate, | 2 | import { AccountModel } from '@server/models/account/account' |
3 | ActivityFlag, | 3 | import { VideoModel } from '@server/models/video/video' |
4 | VideoAbuseState, | 4 | import { VideoCommentModel } from '@server/models/video/video-comment' |
5 | videoAbusePredefinedReasonsMap | 5 | import { AbuseObject, abusePredefinedReasonsMap, AbuseState, ActivityCreate, ActivityFlag } from '../../../../shared' |
6 | } from '../../../../shared' | 6 | import { getAPId } from '../../../helpers/activitypub' |
7 | import { VideoAbuseObject } from '../../../../shared/models/activitypub/objects' | ||
8 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | 7 | import { retryTransactionWrapper } from '../../../helpers/database-utils' |
9 | import { logger } from '../../../helpers/logger' | 8 | import { logger } from '../../../helpers/logger' |
10 | import { sequelizeTypescript } from '../../../initializers/database' | 9 | 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' | 10 | import { APProcessorOptions } from '../../../types/activitypub-processor.model' |
16 | import { MActorSignature, MVideoAbuseAccountVideo } from '../../../types/models' | 11 | import { MAccountDefault, MActorSignature, MCommentOwnerVideo } from '../../../types/models' |
17 | import { AccountModel } from '@server/models/account/account' | ||
18 | 12 | ||
19 | async function processFlagActivity (options: APProcessorOptions<ActivityCreate | ActivityFlag>) { | 13 | async function processFlagActivity (options: APProcessorOptions<ActivityCreate | ActivityFlag>) { |
20 | const { activity, byActor } = options | 14 | const { activity, byActor } = options |
21 | return retryTransactionWrapper(processCreateVideoAbuse, activity, byActor) | 15 | |
16 | return retryTransactionWrapper(processCreateAbuse, activity, byActor) | ||
22 | } | 17 | } |
23 | 18 | ||
24 | // --------------------------------------------------------------------------- | 19 | // --------------------------------------------------------------------------- |
@@ -29,55 +24,79 @@ export { | |||
29 | 24 | ||
30 | // --------------------------------------------------------------------------- | 25 | // --------------------------------------------------------------------------- |
31 | 26 | ||
32 | async function processCreateVideoAbuse (activity: ActivityCreate | ActivityFlag, byActor: MActorSignature) { | 27 | async function processCreateAbuse (activity: ActivityCreate | ActivityFlag, byActor: MActorSignature) { |
33 | const flag = activity.type === 'Flag' ? activity : (activity.object as VideoAbuseObject) | 28 | const flag = activity.type === 'Flag' ? activity : (activity.object as AbuseObject) |
34 | 29 | ||
35 | const account = byActor.Account | 30 | const account = byActor.Account |
36 | if (!account) throw new Error('Cannot create video abuse with the non account actor ' + byActor.url) | 31 | if (!account) throw new Error('Cannot create abuse with the non account actor ' + byActor.url) |
32 | |||
33 | const reporterAccount = await AccountModel.load(account.id) | ||
37 | 34 | ||
38 | const objects = Array.isArray(flag.object) ? flag.object : [ flag.object ] | 35 | const objects = Array.isArray(flag.object) ? flag.object : [ flag.object ] |
39 | 36 | ||
37 | const tags = Array.isArray(flag.tag) ? flag.tag : [] | ||
38 | const predefinedReasons = tags.map(tag => abusePredefinedReasonsMap[tag.name]) | ||
39 | .filter(v => !isNaN(v)) | ||
40 | |||
41 | const startAt = flag.startAt | ||
42 | const endAt = flag.endAt | ||
43 | |||
40 | for (const object of objects) { | 44 | for (const object of objects) { |
41 | try { | 45 | try { |
42 | logger.debug('Reporting remote abuse for video %s.', getAPId(object)) | 46 | const uri = 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 | 47 | ||
63 | const videoAbuseInstance: MVideoAbuseAccountVideo = await VideoAbuseModel.create(videoAbuseData, { transaction: t }) | 48 | logger.debug('Reporting remote abuse for object %s.', uri) |
64 | videoAbuseInstance.Video = video | ||
65 | videoAbuseInstance.Account = reporterAccount | ||
66 | 49 | ||
67 | logger.info('Remote abuse for video uuid %s created', flag.object) | 50 | await sequelizeTypescript.transaction(async t => { |
68 | 51 | ||
69 | return videoAbuseInstance | 52 | const video = await VideoModel.loadByUrlAndPopulateAccount(uri) |
70 | }) | 53 | let videoComment: MCommentOwnerVideo |
54 | let flaggedAccount: MAccountDefault | ||
55 | |||
56 | if (!video) videoComment = await VideoCommentModel.loadByUrlAndPopulateAccountAndVideo(uri) | ||
57 | if (!videoComment) flaggedAccount = await AccountModel.loadByUrl(uri) | ||
58 | |||
59 | if (!video && !videoComment && !flaggedAccount) { | ||
60 | logger.warn('Cannot flag unknown entity %s.', object) | ||
61 | return | ||
62 | } | ||
63 | |||
64 | const baseAbuse = { | ||
65 | reporterAccountId: reporterAccount.id, | ||
66 | reason: flag.content, | ||
67 | state: AbuseState.PENDING, | ||
68 | predefinedReasons | ||
69 | } | ||
71 | 70 | ||
72 | const videoAbuseJSON = videoAbuseInstance.toFormattedJSON() | 71 | if (video) { |
72 | return createVideoAbuse({ | ||
73 | baseAbuse, | ||
74 | startAt, | ||
75 | endAt, | ||
76 | reporterAccount, | ||
77 | transaction: t, | ||
78 | videoInstance: video | ||
79 | }) | ||
80 | } | ||
81 | |||
82 | if (videoComment) { | ||
83 | return createVideoCommentAbuse({ | ||
84 | baseAbuse, | ||
85 | reporterAccount, | ||
86 | transaction: t, | ||
87 | commentInstance: videoComment | ||
88 | }) | ||
89 | } | ||
73 | 90 | ||
74 | Notifier.Instance.notifyOnNewVideoAbuse({ | 91 | return await createAccountAbuse({ |
75 | videoAbuse: videoAbuseJSON, | 92 | baseAbuse, |
76 | videoAbuseInstance, | 93 | reporterAccount, |
77 | reporter: reporterAccount.Actor.getIdentifier() | 94 | transaction: t, |
95 | accountInstance: flaggedAccount | ||
96 | }) | ||
78 | }) | 97 | }) |
79 | } catch (err) { | 98 | } catch (err) { |
80 | logger.debug('Cannot process report of %s. (Maybe not a video abuse).', getAPId(object), { err }) | 99 | logger.debug('Cannot process report of %s', getAPId(object), { err }) |
81 | } | 100 | } |
82 | } | 101 | } |
83 | } | 102 | } |