aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/abuse/abuse.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/models/abuse/abuse.ts')
-rw-r--r--server/models/abuse/abuse.ts182
1 files changed, 132 insertions, 50 deletions
diff --git a/server/models/abuse/abuse.ts b/server/models/abuse/abuse.ts
index bd96cf79c..7002502d5 100644
--- a/server/models/abuse/abuse.ts
+++ b/server/models/abuse/abuse.ts
@@ -18,7 +18,6 @@ import {
18} from 'sequelize-typescript' 18} from 'sequelize-typescript'
19import { isAbuseModerationCommentValid, isAbuseReasonValid, isAbuseStateValid } from '@server/helpers/custom-validators/abuses' 19import { isAbuseModerationCommentValid, isAbuseReasonValid, isAbuseStateValid } from '@server/helpers/custom-validators/abuses'
20import { 20import {
21 Abuse,
22 AbuseFilter, 21 AbuseFilter,
23 AbuseObject, 22 AbuseObject,
24 AbusePredefinedReasons, 23 AbusePredefinedReasons,
@@ -26,11 +25,14 @@ import {
26 AbusePredefinedReasonsString, 25 AbusePredefinedReasonsString,
27 AbuseState, 26 AbuseState,
28 AbuseVideoIs, 27 AbuseVideoIs,
29 VideoAbuse, 28 AdminVideoAbuse,
30 VideoCommentAbuse 29 AdminAbuse,
30 AdminVideoCommentAbuse,
31 UserAbuse,
32 UserVideoAbuse
31} from '@shared/models' 33} from '@shared/models'
32import { ABUSE_STATES, CONSTRAINTS_FIELDS } from '../../initializers/constants' 34import { ABUSE_STATES, CONSTRAINTS_FIELDS } from '../../initializers/constants'
33import { MAbuse, MAbuseAP, MAbuseFormattable, MUserAccountId } from '../../types/models' 35import { MAbuse, MAbuseAdminFormattable, MAbuseAP, MUserAccountId, MAbuseUserFormattable } from '../../types/models'
34import { AccountModel, ScopeNames as AccountScopeNames, SummaryOptions as AccountSummaryOptions } from '../account/account' 36import { AccountModel, ScopeNames as AccountScopeNames, SummaryOptions as AccountSummaryOptions } from '../account/account'
35import { getSort, throwIfNotValid } from '../utils' 37import { getSort, throwIfNotValid } from '../utils'
36import { ThumbnailModel } from '../video/thumbnail' 38import { ThumbnailModel } from '../video/thumbnail'
@@ -52,6 +54,16 @@ export enum ScopeNames {
52 attributes: { 54 attributes: {
53 include: [ 55 include: [
54 [ 56 [
57 literal(
58 '(' +
59 'SELECT count(*) ' +
60 'FROM "abuseMessage" ' +
61 'WHERE "abuseId" = "AbuseModel"."id"' +
62 ')'
63 ),
64 'countMessages'
65 ],
66 [
55 // we don't care about this count for deleted videos, so there are not included 67 // we don't care about this count for deleted videos, so there are not included
56 literal( 68 literal(
57 '(' + 69 '(' +
@@ -285,7 +297,7 @@ export class AbuseModel extends Model<AbuseModel> {
285 return AbuseModel.findOne(query) 297 return AbuseModel.findOne(query)
286 } 298 }
287 299
288 static async listForApi (parameters: { 300 static async listForAdminApi (parameters: {
289 start: number 301 start: number
290 count: number 302 count: number
291 sort: string 303 sort: string
@@ -353,71 +365,98 @@ export class AbuseModel extends Model<AbuseModel> {
353 return { total, data } 365 return { total, data }
354 } 366 }
355 367
356 toFormattedJSON (this: MAbuseFormattable): Abuse { 368 static async listForUserApi (parameters: {
357 const predefinedReasons = AbuseModel.getPredefinedReasonsStrings(this.predefinedReasons) 369 user: MUserAccountId
358 370
359 const countReportsForVideo = this.get('countReportsForVideo') as number 371 start: number
360 const nthReportForVideo = this.get('nthReportForVideo') as number 372 count: number
373 sort: string
361 374
362 const countReportsForReporter = this.get('countReportsForReporter') as number 375 id?: number
363 const countReportsForReportee = this.get('countReportsForReportee') as number 376 search?: string
377 state?: AbuseState
378 }) {
379 const {
380 start,
381 count,
382 sort,
383 search,
384 user,
385 state,
386 id
387 } = parameters
364 388
365 let video: VideoAbuse = null 389 const queryOptions: BuildAbusesQueryOptions = {
366 let comment: VideoCommentAbuse = null 390 start,
391 count,
392 sort,
393 id,
394 search,
395 state,
396 reporterAccountId: user.Account.id
397 }
398
399 const [ total, data ] = await Promise.all([
400 AbuseModel.internalCountForApi(queryOptions),
401 AbuseModel.internalListForApi(queryOptions)
402 ])
403
404 return { total, data }
405 }
367 406
368 if (this.VideoAbuse) { 407 buildBaseVideoCommentAbuse (this: MAbuseUserFormattable) {
369 const abuseModel = this.VideoAbuse 408 if (!this.VideoCommentAbuse) return null
370 const entity = abuseModel.Video || abuseModel.deletedVideo
371 409
372 video = { 410 const abuseModel = this.VideoCommentAbuse
373 id: entity.id, 411 const entity = abuseModel.VideoComment
374 uuid: entity.uuid,
375 name: entity.name,
376 nsfw: entity.nsfw,
377 412
378 startAt: abuseModel.startAt, 413 return {
379 endAt: abuseModel.endAt, 414 id: entity.id,
415 threadId: entity.getThreadId(),
380 416
381 deleted: !abuseModel.Video, 417 text: entity.text ?? '',
382 blacklisted: abuseModel.Video?.isBlacklisted() || false,
383 thumbnailPath: abuseModel.Video?.getMiniatureStaticPath(),
384 418
385 channel: abuseModel.Video?.VideoChannel.toFormattedJSON() || abuseModel.deletedVideo?.channel, 419 deleted: entity.isDeleted(),
386 420
387 countReports: countReportsForVideo, 421 video: {
388 nthReport: nthReportForVideo 422 id: entity.Video.id,
423 name: entity.Video.name,
424 uuid: entity.Video.uuid
389 } 425 }
390 } 426 }
427 }
391 428
392 if (this.VideoCommentAbuse) { 429 buildBaseVideoAbuse (this: MAbuseUserFormattable): UserVideoAbuse {
393 const abuseModel = this.VideoCommentAbuse 430 if (!this.VideoAbuse) return null
394 const entity = abuseModel.VideoComment
395 431
396 comment = { 432 const abuseModel = this.VideoAbuse
397 id: entity.id, 433 const entity = abuseModel.Video || abuseModel.deletedVideo
398 threadId: entity.getThreadId(),
399 434
400 text: entity.text ?? '', 435 return {
436 id: entity.id,
437 uuid: entity.uuid,
438 name: entity.name,
439 nsfw: entity.nsfw,
401 440
402 deleted: entity.isDeleted(), 441 startAt: abuseModel.startAt,
442 endAt: abuseModel.endAt,
403 443
404 video: { 444 deleted: !abuseModel.Video,
405 id: entity.Video.id, 445 blacklisted: abuseModel.Video?.isBlacklisted() || false,
406 name: entity.Video.name, 446 thumbnailPath: abuseModel.Video?.getMiniatureStaticPath(),
407 uuid: entity.Video.uuid 447
408 } 448 channel: abuseModel.Video?.VideoChannel.toFormattedJSON() || abuseModel.deletedVideo?.channel,
409 }
410 } 449 }
450 }
451
452 buildBaseAbuse (this: MAbuseUserFormattable, countMessages: number): UserAbuse {
453 const predefinedReasons = AbuseModel.getPredefinedReasonsStrings(this.predefinedReasons)
411 454
412 return { 455 return {
413 id: this.id, 456 id: this.id,
414 reason: this.reason, 457 reason: this.reason,
415 predefinedReasons, 458 predefinedReasons,
416 459
417 reporterAccount: this.ReporterAccount
418 ? this.ReporterAccount.toFormattedJSON()
419 : null,
420
421 flaggedAccount: this.FlaggedAccount 460 flaggedAccount: this.FlaggedAccount
422 ? this.FlaggedAccount.toFormattedJSON() 461 ? this.FlaggedAccount.toFormattedJSON()
423 : null, 462 : null,
@@ -429,11 +468,41 @@ export class AbuseModel extends Model<AbuseModel> {
429 468
430 moderationComment: this.moderationComment, 469 moderationComment: this.moderationComment,
431 470
471 countMessages,
472
473 createdAt: this.createdAt,
474 updatedAt: this.updatedAt
475 }
476 }
477
478 toFormattedAdminJSON (this: MAbuseAdminFormattable): AdminAbuse {
479 const countReportsForVideo = this.get('countReportsForVideo') as number
480 const nthReportForVideo = this.get('nthReportForVideo') as number
481
482 const countReportsForReporter = this.get('countReportsForReporter') as number
483 const countReportsForReportee = this.get('countReportsForReportee') as number
484
485 const countMessages = this.get('countMessages') as number
486
487 const baseVideo = this.buildBaseVideoAbuse()
488 const video: AdminVideoAbuse = baseVideo
489 ? Object.assign(baseVideo, {
490 countReports: countReportsForVideo,
491 nthReport: nthReportForVideo
492 })
493 : null
494
495 const comment: AdminVideoCommentAbuse = this.buildBaseVideoCommentAbuse()
496
497 const abuse = this.buildBaseAbuse(countMessages || 0)
498
499 return Object.assign(abuse, {
432 video, 500 video,
433 comment, 501 comment,
434 502
435 createdAt: this.createdAt, 503 reporterAccount: this.ReporterAccount
436 updatedAt: this.updatedAt, 504 ? this.ReporterAccount.toFormattedJSON()
505 : null,
437 506
438 countReportsForReporter: (countReportsForReporter || 0), 507 countReportsForReporter: (countReportsForReporter || 0),
439 countReportsForReportee: (countReportsForReportee || 0), 508 countReportsForReportee: (countReportsForReportee || 0),
@@ -443,7 +512,20 @@ export class AbuseModel extends Model<AbuseModel> {
443 endAt: null, 512 endAt: null,
444 count: countReportsForVideo || 0, 513 count: countReportsForVideo || 0,
445 nth: nthReportForVideo || 0 514 nth: nthReportForVideo || 0
446 } 515 })
516 }
517
518 toFormattedUserJSON (this: MAbuseUserFormattable): UserAbuse {
519 const countMessages = this.get('countMessages') as number
520
521 const video = this.buildBaseVideoAbuse()
522 const comment: AdminVideoCommentAbuse = this.buildBaseVideoCommentAbuse()
523 const abuse = this.buildBaseAbuse(countMessages || 0)
524
525 return Object.assign(abuse, {
526 video,
527 comment
528 })
447 } 529 }
448 530
449 toActivityPubObject (this: MAbuseAP): AbuseObject { 531 toActivityPubObject (this: MAbuseAP): AbuseObject {