diff options
Diffstat (limited to 'server/models/abuse/abuse.ts')
-rw-r--r-- | server/models/abuse/abuse.ts | 91 |
1 files changed, 75 insertions, 16 deletions
diff --git a/server/models/abuse/abuse.ts b/server/models/abuse/abuse.ts index 4f99f9c9b..087c77bd3 100644 --- a/server/models/abuse/abuse.ts +++ b/server/models/abuse/abuse.ts | |||
@@ -19,16 +19,17 @@ import { | |||
19 | import { isAbuseModerationCommentValid, isAbuseReasonValid, isAbuseStateValid } from '@server/helpers/custom-validators/abuses' | 19 | import { isAbuseModerationCommentValid, isAbuseReasonValid, isAbuseStateValid } from '@server/helpers/custom-validators/abuses' |
20 | import { | 20 | import { |
21 | Abuse, | 21 | Abuse, |
22 | AbuseFilter, | ||
22 | AbuseObject, | 23 | AbuseObject, |
23 | AbusePredefinedReasons, | 24 | AbusePredefinedReasons, |
24 | abusePredefinedReasonsMap, | 25 | abusePredefinedReasonsMap, |
25 | AbusePredefinedReasonsString, | 26 | AbusePredefinedReasonsString, |
26 | AbuseState, | 27 | AbuseState, |
27 | AbuseVideoIs, | 28 | AbuseVideoIs, |
28 | VideoAbuse | 29 | VideoAbuse, |
30 | VideoCommentAbuse | ||
29 | } from '@shared/models' | 31 | } from '@shared/models' |
30 | import { AbuseFilter } from '@shared/models/moderation/abuse/abuse-filter' | 32 | import { ABUSE_STATES, CONSTRAINTS_FIELDS } from '../../initializers/constants' |
31 | import { CONSTRAINTS_FIELDS, ABUSE_STATES } from '../../initializers/constants' | ||
32 | import { MAbuse, MAbuseAP, MAbuseFormattable, MUserAccountId } from '../../types/models' | 33 | import { MAbuse, MAbuseAP, MAbuseFormattable, MUserAccountId } from '../../types/models' |
33 | import { AccountModel, ScopeNames as AccountScopeNames } from '../account/account' | 34 | import { AccountModel, ScopeNames as AccountScopeNames } from '../account/account' |
34 | import { buildBlockedAccountSQL, getSort, searchAttribute, throwIfNotValid } from '../utils' | 35 | import { buildBlockedAccountSQL, getSort, searchAttribute, throwIfNotValid } from '../utils' |
@@ -38,6 +39,7 @@ import { VideoBlacklistModel } from '../video/video-blacklist' | |||
38 | import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from '../video/video-channel' | 39 | import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from '../video/video-channel' |
39 | import { VideoAbuseModel } from './video-abuse' | 40 | import { VideoAbuseModel } from './video-abuse' |
40 | import { VideoCommentAbuseModel } from './video-comment-abuse' | 41 | import { VideoCommentAbuseModel } from './video-comment-abuse' |
42 | import { VideoCommentModel } from '../video/video-comment' | ||
41 | 43 | ||
42 | export enum ScopeNames { | 44 | export enum ScopeNames { |
43 | FOR_API = 'FOR_API' | 45 | FOR_API = 'FOR_API' |
@@ -66,19 +68,18 @@ export enum ScopeNames { | |||
66 | serverAccountId: number | 68 | serverAccountId: number |
67 | userAccountId: number | 69 | userAccountId: number |
68 | }) => { | 70 | }) => { |
69 | const onlyBlacklisted = options.videoIs === 'blacklisted' | 71 | const whereAnd: WhereOptions[] = [] |
70 | const videoRequired = !!(onlyBlacklisted || options.searchVideo || options.searchVideoChannel) | ||
71 | 72 | ||
72 | const where = { | 73 | whereAnd.push({ |
73 | reporterAccountId: { | 74 | reporterAccountId: { |
74 | [Op.notIn]: literal('(' + buildBlockedAccountSQL([ options.serverAccountId, options.userAccountId ]) + ')') | 75 | [Op.notIn]: literal('(' + buildBlockedAccountSQL([ options.serverAccountId, options.userAccountId ]) + ')') |
75 | } | 76 | } |
76 | } | 77 | }) |
77 | 78 | ||
78 | if (options.search) { | 79 | if (options.search) { |
79 | const escapedSearch = AbuseModel.sequelize.escape('%' + options.search + '%') | 80 | const escapedSearch = AbuseModel.sequelize.escape('%' + options.search + '%') |
80 | 81 | ||
81 | Object.assign(where, { | 82 | whereAnd.push({ |
82 | [Op.or]: [ | 83 | [Op.or]: [ |
83 | { | 84 | { |
84 | [Op.and]: [ | 85 | [Op.and]: [ |
@@ -110,11 +111,11 @@ export enum ScopeNames { | |||
110 | }) | 111 | }) |
111 | } | 112 | } |
112 | 113 | ||
113 | if (options.id) Object.assign(where, { id: options.id }) | 114 | if (options.id) whereAnd.push({ id: options.id }) |
114 | if (options.state) Object.assign(where, { state: options.state }) | 115 | if (options.state) whereAnd.push({ state: options.state }) |
115 | 116 | ||
116 | if (options.videoIs === 'deleted') { | 117 | if (options.videoIs === 'deleted') { |
117 | Object.assign(where, { | 118 | whereAnd.push({ |
118 | '$VideoAbuse.deletedVideo$': { | 119 | '$VideoAbuse.deletedVideo$': { |
119 | [Op.not]: null | 120 | [Op.not]: null |
120 | } | 121 | } |
@@ -122,13 +123,23 @@ export enum ScopeNames { | |||
122 | } | 123 | } |
123 | 124 | ||
124 | if (options.predefinedReasonId) { | 125 | if (options.predefinedReasonId) { |
125 | Object.assign(where, { | 126 | whereAnd.push({ |
126 | predefinedReasons: { | 127 | predefinedReasons: { |
127 | [Op.contains]: [ options.predefinedReasonId ] | 128 | [Op.contains]: [ options.predefinedReasonId ] |
128 | } | 129 | } |
129 | }) | 130 | }) |
130 | } | 131 | } |
131 | 132 | ||
133 | if (options.filter === 'account') { | ||
134 | whereAnd.push({ | ||
135 | videoId: null, | ||
136 | commentId: null | ||
137 | }) | ||
138 | } | ||
139 | |||
140 | const onlyBlacklisted = options.videoIs === 'blacklisted' | ||
141 | const videoRequired = !!(onlyBlacklisted || options.searchVideo || options.searchVideoChannel) | ||
142 | |||
132 | return { | 143 | return { |
133 | attributes: { | 144 | attributes: { |
134 | include: [ | 145 | include: [ |
@@ -223,6 +234,23 @@ export enum ScopeNames { | |||
223 | where: searchAttribute(options.searchReportee, 'name') | 234 | where: searchAttribute(options.searchReportee, 'name') |
224 | }, | 235 | }, |
225 | { | 236 | { |
237 | model: VideoCommentAbuseModel.unscoped(), | ||
238 | required: options.filter === 'comment', | ||
239 | include: [ | ||
240 | { | ||
241 | model: VideoCommentModel.unscoped(), | ||
242 | required: false, | ||
243 | include: [ | ||
244 | { | ||
245 | model: VideoModel.unscoped(), | ||
246 | attributes: [ 'name', 'id', 'uuid' ], | ||
247 | required: true | ||
248 | } | ||
249 | ] | ||
250 | } | ||
251 | ] | ||
252 | }, | ||
253 | { | ||
226 | model: VideoAbuseModel, | 254 | model: VideoAbuseModel, |
227 | required: options.filter === 'video' || !!options.videoIs || videoRequired, | 255 | required: options.filter === 'video' || !!options.videoIs || videoRequired, |
228 | include: [ | 256 | include: [ |
@@ -241,8 +269,7 @@ export enum ScopeNames { | |||
241 | include: [ | 269 | include: [ |
242 | { | 270 | { |
243 | model: AccountModel.scope(AccountScopeNames.SUMMARY), | 271 | model: AccountModel.scope(AccountScopeNames.SUMMARY), |
244 | required: true, | 272 | required: true |
245 | where: searchAttribute(options.searchReportee, 'name') | ||
246 | } | 273 | } |
247 | ] | 274 | ] |
248 | }, | 275 | }, |
@@ -256,7 +283,9 @@ export enum ScopeNames { | |||
256 | ] | 283 | ] |
257 | } | 284 | } |
258 | ], | 285 | ], |
259 | where | 286 | where: { |
287 | [Op.and]: whereAnd | ||
288 | } | ||
260 | } | 289 | } |
261 | } | 290 | } |
262 | })) | 291 | })) |
@@ -348,6 +377,7 @@ export class AbuseModel extends Model<AbuseModel> { | |||
348 | }) | 377 | }) |
349 | VideoAbuse: VideoAbuseModel | 378 | VideoAbuse: VideoAbuseModel |
350 | 379 | ||
380 | // FIXME: deprecated in 2.3. Remove these validators | ||
351 | static loadByIdAndVideoId (id: number, videoId?: number, uuid?: string): Bluebird<MAbuse> { | 381 | static loadByIdAndVideoId (id: number, videoId?: number, uuid?: string): Bluebird<MAbuse> { |
352 | const videoWhere: WhereOptions = {} | 382 | const videoWhere: WhereOptions = {} |
353 | 383 | ||
@@ -369,6 +399,16 @@ export class AbuseModel extends Model<AbuseModel> { | |||
369 | return AbuseModel.findOne(query) | 399 | return AbuseModel.findOne(query) |
370 | } | 400 | } |
371 | 401 | ||
402 | static loadById (id: number): Bluebird<MAbuse> { | ||
403 | const query = { | ||
404 | where: { | ||
405 | id | ||
406 | } | ||
407 | } | ||
408 | |||
409 | return AbuseModel.findOne(query) | ||
410 | } | ||
411 | |||
372 | static listForApi (parameters: { | 412 | static listForApi (parameters: { |
373 | start: number | 413 | start: number |
374 | count: number | 414 | count: number |
@@ -454,6 +494,7 @@ export class AbuseModel extends Model<AbuseModel> { | |||
454 | const countReportsForReporteeDeletedVideo = this.get('countReportsForReportee__deletedVideo') as number | 494 | const countReportsForReporteeDeletedVideo = this.get('countReportsForReportee__deletedVideo') as number |
455 | 495 | ||
456 | let video: VideoAbuse | 496 | let video: VideoAbuse |
497 | let comment: VideoCommentAbuse | ||
457 | 498 | ||
458 | if (this.VideoAbuse) { | 499 | if (this.VideoAbuse) { |
459 | const abuseModel = this.VideoAbuse | 500 | const abuseModel = this.VideoAbuse |
@@ -475,6 +516,24 @@ export class AbuseModel extends Model<AbuseModel> { | |||
475 | } | 516 | } |
476 | } | 517 | } |
477 | 518 | ||
519 | if (this.VideoCommentAbuse) { | ||
520 | const abuseModel = this.VideoCommentAbuse | ||
521 | const entity = abuseModel.VideoComment || abuseModel.deletedComment | ||
522 | |||
523 | comment = { | ||
524 | id: entity.id, | ||
525 | text: entity.text, | ||
526 | |||
527 | deleted: !abuseModel.VideoComment, | ||
528 | |||
529 | video: { | ||
530 | id: entity.Video.id, | ||
531 | name: entity.Video.name, | ||
532 | uuid: entity.Video.uuid | ||
533 | } | ||
534 | } | ||
535 | } | ||
536 | |||
478 | return { | 537 | return { |
479 | id: this.id, | 538 | id: this.id, |
480 | reason: this.reason, | 539 | reason: this.reason, |
@@ -490,7 +549,7 @@ export class AbuseModel extends Model<AbuseModel> { | |||
490 | moderationComment: this.moderationComment, | 549 | moderationComment: this.moderationComment, |
491 | 550 | ||
492 | video, | 551 | video, |
493 | comment: null, | 552 | comment, |
494 | 553 | ||
495 | createdAt: this.createdAt, | 554 | createdAt: this.createdAt, |
496 | updatedAt: this.updatedAt, | 555 | updatedAt: this.updatedAt, |