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