process-flag.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import { createAccountAbuse, createVideoAbuse, createVideoCommentAbuse } from '@server/lib/moderation.js'
  2. import { AccountModel } from '@server/models/account/account.js'
  3. import { VideoCommentModel } from '@server/models/video/video-comment.js'
  4. import { VideoModel } from '@server/models/video/video.js'
  5. import { abusePredefinedReasonsMap } from '@peertube/peertube-core-utils'
  6. import { AbuseState, ActivityFlag } from '@peertube/peertube-models'
  7. import { retryTransactionWrapper } from '../../../helpers/database-utils.js'
  8. import { logger } from '../../../helpers/logger.js'
  9. import { sequelizeTypescript } from '../../../initializers/database.js'
  10. import { getAPId } from '../../../lib/activitypub/activity.js'
  11. import { APProcessorOptions } from '../../../types/activitypub-processor.model.js'
  12. import { MAccountDefault, MActorSignature, MCommentOwnerVideo } from '../../../types/models/index.js'
  13. async function processFlagActivity (options: APProcessorOptions<ActivityFlag>) {
  14. const { activity, byActor } = options
  15. return retryTransactionWrapper(processCreateAbuse, activity, byActor)
  16. }
  17. // ---------------------------------------------------------------------------
  18. export {
  19. processFlagActivity
  20. }
  21. // ---------------------------------------------------------------------------
  22. async function processCreateAbuse (flag: ActivityFlag, byActor: MActorSignature) {
  23. const account = byActor.Account
  24. if (!account) throw new Error('Cannot create abuse with the non account actor ' + byActor.url)
  25. const reporterAccount = await AccountModel.load(account.id)
  26. const objects = Array.isArray(flag.object) ? flag.object : [ flag.object ]
  27. const tags = Array.isArray(flag.tag) ? flag.tag : []
  28. const predefinedReasons = tags.map(tag => abusePredefinedReasonsMap[tag.name])
  29. .filter(v => !isNaN(v))
  30. const startAt = flag.startAt
  31. const endAt = flag.endAt
  32. for (const object of objects) {
  33. try {
  34. const uri = getAPId(object)
  35. logger.debug('Reporting remote abuse for object %s.', uri)
  36. await sequelizeTypescript.transaction(async t => {
  37. const video = await VideoModel.loadByUrlAndPopulateAccountAndFiles(uri, t)
  38. let videoComment: MCommentOwnerVideo
  39. let flaggedAccount: MAccountDefault
  40. if (!video) videoComment = await VideoCommentModel.loadByUrlAndPopulateAccountAndVideo(uri, t)
  41. if (!videoComment) flaggedAccount = await AccountModel.loadByUrl(uri, t)
  42. if (!video && !videoComment && !flaggedAccount) {
  43. logger.warn('Cannot flag unknown entity %s.', object)
  44. return
  45. }
  46. const baseAbuse = {
  47. reporterAccountId: reporterAccount.id,
  48. reason: flag.content,
  49. state: AbuseState.PENDING,
  50. predefinedReasons
  51. }
  52. if (video) {
  53. return createVideoAbuse({
  54. baseAbuse,
  55. startAt,
  56. endAt,
  57. reporterAccount,
  58. transaction: t,
  59. videoInstance: video,
  60. skipNotification: false
  61. })
  62. }
  63. if (videoComment) {
  64. return createVideoCommentAbuse({
  65. baseAbuse,
  66. reporterAccount,
  67. transaction: t,
  68. commentInstance: videoComment,
  69. skipNotification: false
  70. })
  71. }
  72. return await createAccountAbuse({
  73. baseAbuse,
  74. reporterAccount,
  75. transaction: t,
  76. accountInstance: flaggedAccount,
  77. skipNotification: false
  78. })
  79. })
  80. } catch (err) {
  81. logger.debug('Cannot process report of %s', getAPId(object), { err })
  82. }
  83. }
  84. }