video-abuse.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import {
  2. AfterCreate,
  3. AllowNull,
  4. BelongsTo,
  5. Column,
  6. CreatedAt,
  7. DataType,
  8. Default,
  9. ForeignKey,
  10. Is,
  11. Model,
  12. Table,
  13. UpdatedAt
  14. } from 'sequelize-typescript'
  15. import { VideoAbuseObject } from '../../../shared/models/activitypub/objects'
  16. import { VideoAbuse } from '../../../shared/models/videos'
  17. import {
  18. isVideoAbuseModerationCommentValid,
  19. isVideoAbuseReasonValid,
  20. isVideoAbuseStateValid
  21. } from '../../helpers/custom-validators/video-abuses'
  22. import { Emailer } from '../../lib/emailer'
  23. import { AccountModel } from '../account/account'
  24. import { getSort, throwIfNotValid } from '../utils'
  25. import { VideoModel } from './video'
  26. import { VideoAbuseState } from '../../../shared'
  27. import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers'
  28. @Table({
  29. tableName: 'videoAbuse',
  30. indexes: [
  31. {
  32. fields: [ 'videoId' ]
  33. },
  34. {
  35. fields: [ 'reporterAccountId' ]
  36. }
  37. ]
  38. })
  39. export class VideoAbuseModel extends Model<VideoAbuseModel> {
  40. @AllowNull(false)
  41. @Is('VideoAbuseReason', value => throwIfNotValid(value, isVideoAbuseReasonValid, 'reason'))
  42. @Column
  43. reason: string
  44. @AllowNull(false)
  45. @Default(null)
  46. @Is('VideoAbuseState', value => throwIfNotValid(value, isVideoAbuseStateValid, 'state'))
  47. @Column
  48. state: VideoAbuseState
  49. @AllowNull(true)
  50. @Default(null)
  51. @Is('VideoAbuseModerationComment', value => throwIfNotValid(value, isVideoAbuseModerationCommentValid, 'moderationComment'))
  52. @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_ABUSES.MODERATION_COMMENT.max))
  53. moderationComment: string
  54. @CreatedAt
  55. createdAt: Date
  56. @UpdatedAt
  57. updatedAt: Date
  58. @ForeignKey(() => AccountModel)
  59. @Column
  60. reporterAccountId: number
  61. @BelongsTo(() => AccountModel, {
  62. foreignKey: {
  63. allowNull: false
  64. },
  65. onDelete: 'cascade'
  66. })
  67. Account: AccountModel
  68. @ForeignKey(() => VideoModel)
  69. @Column
  70. videoId: number
  71. @BelongsTo(() => VideoModel, {
  72. foreignKey: {
  73. allowNull: false
  74. },
  75. onDelete: 'cascade'
  76. })
  77. Video: VideoModel
  78. @AfterCreate
  79. static sendEmailNotification (instance: VideoAbuseModel) {
  80. return Emailer.Instance.addVideoAbuseReportJob(instance.videoId)
  81. }
  82. static loadByIdAndVideoId (id: number, videoId: number) {
  83. const query = {
  84. where: {
  85. id,
  86. videoId
  87. }
  88. }
  89. return VideoAbuseModel.findOne(query)
  90. }
  91. static listForApi (start: number, count: number, sort: string) {
  92. const query = {
  93. offset: start,
  94. limit: count,
  95. order: getSort(sort),
  96. include: [
  97. {
  98. model: AccountModel,
  99. required: true
  100. },
  101. {
  102. model: VideoModel,
  103. required: true
  104. }
  105. ]
  106. }
  107. return VideoAbuseModel.findAndCountAll(query)
  108. .then(({ rows, count }) => {
  109. return { total: count, data: rows }
  110. })
  111. }
  112. toFormattedJSON (): VideoAbuse {
  113. return {
  114. id: this.id,
  115. reason: this.reason,
  116. reporterAccount: this.Account.toFormattedJSON(),
  117. state: {
  118. id: this.state,
  119. label: VideoAbuseModel.getStateLabel(this.state)
  120. },
  121. moderationComment: this.moderationComment,
  122. video: {
  123. id: this.Video.id,
  124. uuid: this.Video.uuid,
  125. name: this.Video.name
  126. },
  127. createdAt: this.createdAt
  128. }
  129. }
  130. toActivityPubObject (): VideoAbuseObject {
  131. return {
  132. type: 'Flag' as 'Flag',
  133. content: this.reason,
  134. object: this.Video.url
  135. }
  136. }
  137. private static getStateLabel (id: number) {
  138. return VIDEO_ABUSE_STATES[id] || 'Unknown'
  139. }
  140. }