Use video abuse filters on client side
This commit is contained in:
parent
d170c5c580
commit
feb34f6b6b
13 changed files with 343 additions and 154 deletions
|
@ -19,8 +19,8 @@
|
||||||
<a [routerLink]="[ '/admin/moderation/video-abuses/list' ]" [queryParams]="{ 'search': 'state:pending' }" class="dropdown-item" i18n>Unsolved reports</a>
|
<a [routerLink]="[ '/admin/moderation/video-abuses/list' ]" [queryParams]="{ 'search': 'state:pending' }" class="dropdown-item" i18n>Unsolved reports</a>
|
||||||
<a [routerLink]="[ '/admin/moderation/video-abuses/list' ]" [queryParams]="{ 'search': 'state:accepted' }" class="dropdown-item" i18n>Accepted reports</a>
|
<a [routerLink]="[ '/admin/moderation/video-abuses/list' ]" [queryParams]="{ 'search': 'state:accepted' }" class="dropdown-item" i18n>Accepted reports</a>
|
||||||
<a [routerLink]="[ '/admin/moderation/video-abuses/list' ]" [queryParams]="{ 'search': 'state:rejected' }" class="dropdown-item" i18n>Refused reports</a>
|
<a [routerLink]="[ '/admin/moderation/video-abuses/list' ]" [queryParams]="{ 'search': 'state:rejected' }" class="dropdown-item" i18n>Refused reports</a>
|
||||||
<a [routerLink]="[ '/admin/moderation/video-abuses/list' ]" [queryParams]="{ 'search': 'is:blacklisted' }" class="dropdown-item" i18n>Reports with blacklisted videos</a>
|
<a [routerLink]="[ '/admin/moderation/video-abuses/list' ]" [queryParams]="{ 'search': 'videoIs:blacklisted' }" class="dropdown-item" i18n>Reports with blacklisted videos</a>
|
||||||
<a [routerLink]="[ '/admin/moderation/video-abuses/list' ]" [queryParams]="{ 'search': 'is:deleted' }" class="dropdown-item" i18n>Reports with deleted videos</a>
|
<a [routerLink]="[ '/admin/moderation/video-abuses/list' ]" [queryParams]="{ 'search': 'videoIs:deleted' }" class="dropdown-item" i18n>Reports with deleted videos</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input
|
<input
|
||||||
|
|
|
@ -1,10 +1,21 @@
|
||||||
import { Injectable } from '@angular/core'
|
|
||||||
import { HttpParams } from '@angular/common/http'
|
|
||||||
import { SortMeta } from 'primeng/api'
|
import { SortMeta } from 'primeng/api'
|
||||||
import { ComponentPagination, ComponentPaginationLight } from './component-pagination.model'
|
import { HttpParams } from '@angular/common/http'
|
||||||
|
import { Injectable } from '@angular/core'
|
||||||
|
import { ComponentPaginationLight } from './component-pagination.model'
|
||||||
import { RestPagination } from './rest-pagination'
|
import { RestPagination } from './rest-pagination'
|
||||||
|
|
||||||
|
interface QueryStringFilterPrefixes {
|
||||||
|
[key: string]: {
|
||||||
|
prefix: string
|
||||||
|
handler?: (v: string) => string | number
|
||||||
|
multiple?: boolean
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ParseQueryStringFilterResult = {
|
||||||
|
[key: string]: string | number | (string | number)[]
|
||||||
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RestService {
|
export class RestService {
|
||||||
|
|
||||||
|
@ -53,4 +64,48 @@ export class RestService {
|
||||||
|
|
||||||
return { start, count }
|
return { start, count }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parseQueryStringFilter (q: string, prefixes: QueryStringFilterPrefixes): ParseQueryStringFilterResult {
|
||||||
|
if (!q) return {}
|
||||||
|
|
||||||
|
// Tokenize the strings using spaces
|
||||||
|
const tokens = q.split(' ').filter(token => !!token)
|
||||||
|
|
||||||
|
// Build prefix array
|
||||||
|
const prefixeStrings = Object.values(prefixes)
|
||||||
|
.map(p => p.prefix)
|
||||||
|
|
||||||
|
// Search is the querystring minus defined filters
|
||||||
|
const searchTokens = tokens.filter(t => {
|
||||||
|
return prefixeStrings.every(prefixString => t.startsWith(prefixString) === false)
|
||||||
|
})
|
||||||
|
|
||||||
|
const additionalFilters: ParseQueryStringFilterResult = {}
|
||||||
|
|
||||||
|
for (const prefixKey of Object.keys(prefixes)) {
|
||||||
|
const prefixObj = prefixes[prefixKey]
|
||||||
|
const prefix = prefixObj.prefix
|
||||||
|
|
||||||
|
const matchedTokens = tokens.filter(t => t.startsWith(prefix))
|
||||||
|
.map(t => t.slice(prefix.length)) // Keep the value filter
|
||||||
|
.map(t => {
|
||||||
|
if (prefixObj.handler) return prefixObj.handler(t)
|
||||||
|
|
||||||
|
return t
|
||||||
|
})
|
||||||
|
.filter(t => !!t)
|
||||||
|
|
||||||
|
if (matchedTokens.length === 0) continue
|
||||||
|
|
||||||
|
additionalFilters[prefixKey] = prefixObj.multiple === true
|
||||||
|
? matchedTokens
|
||||||
|
: matchedTokens[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
search: searchTokens.join(' '),
|
||||||
|
|
||||||
|
...additionalFilters
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { HttpClient, HttpParams } from '@angular/common/http'
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { SortMeta } from 'primeng/api'
|
import { SortMeta } from 'primeng/api'
|
||||||
import { Observable } from 'rxjs'
|
import { Observable } from 'rxjs'
|
||||||
import { ResultList, VideoAbuse, VideoAbuseUpdate } from '../../../../../shared'
|
import { ResultList, VideoAbuse, VideoAbuseUpdate, VideoAbuseState } from '../../../../../shared'
|
||||||
import { environment } from '../../../environments/environment'
|
import { environment } from '../../../environments/environment'
|
||||||
import { RestExtractor, RestPagination, RestService } from '../rest'
|
import { RestExtractor, RestPagination, RestService } from '../rest'
|
||||||
|
|
||||||
|
@ -28,7 +28,34 @@ export class VideoAbuseService {
|
||||||
let params = new HttpParams()
|
let params = new HttpParams()
|
||||||
params = this.restService.addRestGetParams(params, pagination, sort)
|
params = this.restService.addRestGetParams(params, pagination, sort)
|
||||||
|
|
||||||
if (search) params = params.append('search', search)
|
if (search) {
|
||||||
|
const filters = this.restService.parseQueryStringFilter(search, {
|
||||||
|
id: { prefix: '#' },
|
||||||
|
state: {
|
||||||
|
prefix: 'state:',
|
||||||
|
handler: v => {
|
||||||
|
if (v === 'accepted') return VideoAbuseState.ACCEPTED
|
||||||
|
if (v === 'pending') return VideoAbuseState.PENDING
|
||||||
|
if (v === 'rejected') return VideoAbuseState.REJECTED
|
||||||
|
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
},
|
||||||
|
videoIs: {
|
||||||
|
prefix: 'videoIs:',
|
||||||
|
handler: v => {
|
||||||
|
if (v === 'deleted') return v
|
||||||
|
if (v === 'blacklisted') return v
|
||||||
|
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
},
|
||||||
|
searchReporter: { prefix: 'reporter:' },
|
||||||
|
searchReportee: { prefix: 'reportee:' }
|
||||||
|
})
|
||||||
|
|
||||||
|
params = this.restService.addObjectParams(params, filters)
|
||||||
|
}
|
||||||
|
|
||||||
return this.authHttp.get<ResultList<VideoAbuse>>(url, { params })
|
return this.authHttp.get<ResultList<VideoAbuse>>(url, { params })
|
||||||
.pipe(
|
.pipe(
|
||||||
|
|
|
@ -14,7 +14,8 @@ import {
|
||||||
videoAbuseGetValidator,
|
videoAbuseGetValidator,
|
||||||
videoAbuseReportValidator,
|
videoAbuseReportValidator,
|
||||||
videoAbusesSortValidator,
|
videoAbusesSortValidator,
|
||||||
videoAbuseUpdateValidator
|
videoAbuseUpdateValidator,
|
||||||
|
videoAbuseListValidator
|
||||||
} from '../../../middlewares'
|
} from '../../../middlewares'
|
||||||
import { AccountModel } from '../../../models/account/account'
|
import { AccountModel } from '../../../models/account/account'
|
||||||
import { VideoAbuseModel } from '../../../models/video/video-abuse'
|
import { VideoAbuseModel } from '../../../models/video/video-abuse'
|
||||||
|
@ -34,6 +35,7 @@ abuseVideoRouter.get('/abuse',
|
||||||
videoAbusesSortValidator,
|
videoAbusesSortValidator,
|
||||||
setDefaultSort,
|
setDefaultSort,
|
||||||
setDefaultPagination,
|
setDefaultPagination,
|
||||||
|
videoAbuseListValidator,
|
||||||
asyncMiddleware(listVideoAbuses)
|
asyncMiddleware(listVideoAbuses)
|
||||||
)
|
)
|
||||||
abuseVideoRouter.put('/:videoId/abuse/:id',
|
abuseVideoRouter.put('/:videoId/abuse/:id',
|
||||||
|
@ -70,7 +72,14 @@ async function listVideoAbuses (req: express.Request, res: express.Response) {
|
||||||
start: req.query.start,
|
start: req.query.start,
|
||||||
count: req.query.count,
|
count: req.query.count,
|
||||||
sort: req.query.sort,
|
sort: req.query.sort,
|
||||||
|
id: req.query.id,
|
||||||
search: req.query.search,
|
search: req.query.search,
|
||||||
|
state: req.query.state,
|
||||||
|
videoIs: req.query.videoIs,
|
||||||
|
searchReporter: req.query.searchReporter,
|
||||||
|
searchReportee: req.query.searchReportee,
|
||||||
|
searchVideo: req.query.searchVideo,
|
||||||
|
searchVideoChannel: req.query.searchVideoChannel,
|
||||||
serverAccountId: serverActor.Account.id,
|
serverAccountId: serverActor.Account.id,
|
||||||
user
|
user
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import validator from 'validator'
|
import validator from 'validator'
|
||||||
|
|
||||||
import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers/constants'
|
import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers/constants'
|
||||||
import { exists } from './misc'
|
import { exists } from './misc'
|
||||||
|
import { VideoAbuseVideoIs } from '@shared/models/videos/abuse/video-abuse-video-is.type'
|
||||||
|
|
||||||
const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
|
const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
|
||||||
|
|
||||||
|
@ -16,10 +18,18 @@ function isVideoAbuseStateValid (value: string) {
|
||||||
return exists(value) && VIDEO_ABUSE_STATES[value] !== undefined
|
return exists(value) && VIDEO_ABUSE_STATES[value] !== undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isAbuseVideoIsValid (value: VideoAbuseVideoIs) {
|
||||||
|
return exists(value) && (
|
||||||
|
value === 'deleted' ||
|
||||||
|
value === 'blacklisted'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
export {
|
export {
|
||||||
isVideoAbuseStateValid,
|
isVideoAbuseStateValid,
|
||||||
isVideoAbuseReasonValid,
|
isVideoAbuseReasonValid,
|
||||||
|
isAbuseVideoIsValid,
|
||||||
isVideoAbuseModerationCommentValid
|
isVideoAbuseModerationCommentValid
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
import * as express from 'express'
|
import * as express from 'express'
|
||||||
import { body, param } from 'express-validator'
|
import { body, param, query } from 'express-validator'
|
||||||
import { isIdOrUUIDValid, isIdValid } from '../../../helpers/custom-validators/misc'
|
import { exists, isIdOrUUIDValid, isIdValid } from '../../../helpers/custom-validators/misc'
|
||||||
import { logger } from '../../../helpers/logger'
|
|
||||||
import { areValidationErrors } from '../utils'
|
|
||||||
import {
|
import {
|
||||||
|
isAbuseVideoIsValid,
|
||||||
isVideoAbuseModerationCommentValid,
|
isVideoAbuseModerationCommentValid,
|
||||||
isVideoAbuseReasonValid,
|
isVideoAbuseReasonValid,
|
||||||
isVideoAbuseStateValid
|
isVideoAbuseStateValid
|
||||||
} from '../../../helpers/custom-validators/video-abuses'
|
} from '../../../helpers/custom-validators/video-abuses'
|
||||||
|
import { logger } from '../../../helpers/logger'
|
||||||
import { doesVideoAbuseExist, doesVideoExist } from '../../../helpers/middlewares'
|
import { doesVideoAbuseExist, doesVideoExist } from '../../../helpers/middlewares'
|
||||||
|
import { areValidationErrors } from '../utils'
|
||||||
|
|
||||||
const videoAbuseReportValidator = [
|
const videoAbuseReportValidator = [
|
||||||
param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
|
param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
|
||||||
|
@ -58,9 +59,45 @@ const videoAbuseUpdateValidator = [
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const videoAbuseListValidator = [
|
||||||
|
query('id')
|
||||||
|
.optional()
|
||||||
|
.custom(isIdValid).withMessage('Should have a valid id'),
|
||||||
|
query('search')
|
||||||
|
.optional()
|
||||||
|
.custom(exists).withMessage('Should have a valid search'),
|
||||||
|
query('state')
|
||||||
|
.optional()
|
||||||
|
.custom(isVideoAbuseStateValid).withMessage('Should have a valid video abuse state'),
|
||||||
|
query('videoIs')
|
||||||
|
.optional()
|
||||||
|
.custom(isAbuseVideoIsValid).withMessage('Should have a valid "video is" attribute'),
|
||||||
|
query('searchReporter')
|
||||||
|
.optional()
|
||||||
|
.custom(exists).withMessage('Should have a valid reporter search'),
|
||||||
|
query('searchReportee')
|
||||||
|
.optional()
|
||||||
|
.custom(exists).withMessage('Should have a valid reportee search'),
|
||||||
|
query('searchVideo')
|
||||||
|
.optional()
|
||||||
|
.custom(exists).withMessage('Should have a valid video search'),
|
||||||
|
query('searchVideoChannel')
|
||||||
|
.optional()
|
||||||
|
.custom(exists).withMessage('Should have a valid video channel search'),
|
||||||
|
|
||||||
|
(req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||||
|
logger.debug('Checking videoAbuseListValidator parameters', { parameters: req.body })
|
||||||
|
|
||||||
|
if (areValidationErrors(req, res)) return
|
||||||
|
|
||||||
|
return next()
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
videoAbuseListValidator,
|
||||||
videoAbuseReportValidator,
|
videoAbuseReportValidator,
|
||||||
videoAbuseGetValidator,
|
videoAbuseGetValidator,
|
||||||
videoAbuseUpdateValidator
|
videoAbuseUpdateValidator
|
||||||
|
|
|
@ -207,60 +207,13 @@ function buildDirectionAndField (value: string) {
|
||||||
return { direction, field }
|
return { direction, field }
|
||||||
}
|
}
|
||||||
|
|
||||||
function searchAttribute (sourceField, targetField) {
|
function searchAttribute (sourceField?: string, targetField?: string) {
|
||||||
if (sourceField) {
|
if (!sourceField) return {}
|
||||||
return {
|
|
||||||
[targetField]: {
|
|
||||||
[Op.iLike]: `%${sourceField}%`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface QueryStringFilterPrefixes {
|
|
||||||
[key: string]: string | { prefix: string, handler: Function, multiple?: boolean }
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseQueryStringFilter (q: string, prefixes: QueryStringFilterPrefixes): {
|
|
||||||
search: string
|
|
||||||
[key: string]: string | number | string[] | number[]
|
|
||||||
} {
|
|
||||||
const tokens = q // tokenize only if we have a querystring
|
|
||||||
? [].concat.apply([], q.split('"').map((v, i) => i % 2 ? v : v.split(' '))).filter(Boolean) // split by space unless using double quotes
|
|
||||||
: []
|
|
||||||
|
|
||||||
const objectMap = (obj, fn) => Object.fromEntries(
|
|
||||||
Object.entries(obj).map(
|
|
||||||
([ k, v ], i) => [ k, fn(v, k, i) ]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// search is the querystring minus defined filters
|
[targetField]: {
|
||||||
search: tokens.filter(e => !Object.values(prefixes).some(p => {
|
[Op.iLike]: `%${sourceField}%`
|
||||||
if (typeof p === 'string') {
|
}
|
||||||
return e.startsWith(p)
|
|
||||||
} else {
|
|
||||||
return e.startsWith(p.prefix)
|
|
||||||
}
|
|
||||||
})).join(' '),
|
|
||||||
// filters defined in prefixes are added under their own name
|
|
||||||
...objectMap(prefixes, p => {
|
|
||||||
if (typeof p === 'string') {
|
|
||||||
return tokens.filter(e => e.startsWith(p)).map(e => e.slice(p.length)) // we keep the matched item, and remove its prefix
|
|
||||||
} else {
|
|
||||||
const _tokens = tokens.filter(e => e.startsWith(p.prefix)).map(e => e.slice(p.prefix.length)).map(p.handler)
|
|
||||||
// multiple is false by default, meaning we usually just keep the first occurence of a given prefix
|
|
||||||
if (!p.multiple && _tokens.length > 0) {
|
|
||||||
return _tokens[0]
|
|
||||||
} else if (!p.multiple) {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
return _tokens
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,8 +239,7 @@ export {
|
||||||
getFollowsSort,
|
getFollowsSort,
|
||||||
buildDirectionAndField,
|
buildDirectionAndField,
|
||||||
createSafeIn,
|
createSafeIn,
|
||||||
searchAttribute,
|
searchAttribute
|
||||||
parseQueryStringFilter
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
|
@ -1,6 +1,21 @@
|
||||||
|
import * as Bluebird from 'bluebird'
|
||||||
|
import { literal, Op } from 'sequelize'
|
||||||
import {
|
import {
|
||||||
AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Is, Model, Table, UpdatedAt, Scopes
|
AllowNull,
|
||||||
|
BelongsTo,
|
||||||
|
Column,
|
||||||
|
CreatedAt,
|
||||||
|
DataType,
|
||||||
|
Default,
|
||||||
|
ForeignKey,
|
||||||
|
Is,
|
||||||
|
Model,
|
||||||
|
Scopes,
|
||||||
|
Table,
|
||||||
|
UpdatedAt
|
||||||
} from 'sequelize-typescript'
|
} from 'sequelize-typescript'
|
||||||
|
import { VideoAbuseVideoIs } from '@shared/models/videos/abuse/video-abuse-video-is.type'
|
||||||
|
import { VideoAbuseState, VideoDetails } from '../../../shared'
|
||||||
import { VideoAbuseObject } from '../../../shared/models/activitypub/objects'
|
import { VideoAbuseObject } from '../../../shared/models/activitypub/objects'
|
||||||
import { VideoAbuse } from '../../../shared/models/videos'
|
import { VideoAbuse } from '../../../shared/models/videos'
|
||||||
import {
|
import {
|
||||||
|
@ -8,15 +23,12 @@ import {
|
||||||
isVideoAbuseReasonValid,
|
isVideoAbuseReasonValid,
|
||||||
isVideoAbuseStateValid
|
isVideoAbuseStateValid
|
||||||
} from '../../helpers/custom-validators/video-abuses'
|
} from '../../helpers/custom-validators/video-abuses'
|
||||||
import { AccountModel } from '../account/account'
|
|
||||||
import { buildBlockedAccountSQL, getSort, throwIfNotValid, searchAttribute, parseQueryStringFilter } from '../utils'
|
|
||||||
import { VideoModel } from './video'
|
|
||||||
import { VideoAbuseState, VideoDetails } from '../../../shared'
|
|
||||||
import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers/constants'
|
import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers/constants'
|
||||||
import { MUserAccountId, MVideoAbuse, MVideoAbuseFormattable, MVideoAbuseVideo } from '../../typings/models'
|
import { MUserAccountId, MVideoAbuse, MVideoAbuseFormattable, MVideoAbuseVideo } from '../../typings/models'
|
||||||
import * as Bluebird from 'bluebird'
|
import { AccountModel } from '../account/account'
|
||||||
import { literal, Op } from 'sequelize'
|
import { buildBlockedAccountSQL, getSort, searchAttribute, throwIfNotValid } from '../utils'
|
||||||
import { ThumbnailModel } from './thumbnail'
|
import { ThumbnailModel } from './thumbnail'
|
||||||
|
import { VideoModel } from './video'
|
||||||
import { VideoBlacklistModel } from './video-blacklist'
|
import { VideoBlacklistModel } from './video-blacklist'
|
||||||
import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from './video-channel'
|
import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from './video-channel'
|
||||||
|
|
||||||
|
@ -35,21 +47,22 @@ export enum ScopeNames {
|
||||||
|
|
||||||
// filters
|
// filters
|
||||||
id?: number
|
id?: number
|
||||||
|
|
||||||
state?: VideoAbuseState
|
state?: VideoAbuseState
|
||||||
is?: 'deleted' | 'blacklisted'
|
videoIs?: VideoAbuseVideoIs
|
||||||
|
|
||||||
// accountIds
|
// accountIds
|
||||||
serverAccountId: number
|
serverAccountId: number
|
||||||
userAccountId: number
|
userAccountId: number
|
||||||
}) => {
|
}) => {
|
||||||
let where = {
|
const where = {
|
||||||
reporterAccountId: {
|
reporterAccountId: {
|
||||||
[Op.notIn]: literal('(' + buildBlockedAccountSQL(options.serverAccountId, options.userAccountId) + ')')
|
[Op.notIn]: literal('(' + buildBlockedAccountSQL(options.serverAccountId, options.userAccountId) + ')')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.search) {
|
if (options.search) {
|
||||||
where = Object.assign(where, {
|
Object.assign(where, {
|
||||||
[Op.or]: [
|
[Op.or]: [
|
||||||
{
|
{
|
||||||
[Op.and]: [
|
[Op.and]: [
|
||||||
|
@ -80,26 +93,18 @@ export enum ScopeNames {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.id) {
|
if (options.id) Object.assign(where, { id: options.id })
|
||||||
where = Object.assign(where, {
|
if (options.state) Object.assign(where, { state: options.state })
|
||||||
id: options.id
|
|
||||||
|
if (options.videoIs === 'deleted') {
|
||||||
|
Object.assign(where, {
|
||||||
|
deletedVideo: {
|
||||||
|
[Op.not]: null
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.state) {
|
const onlyBlacklisted = options.videoIs === 'blacklisted'
|
||||||
where = Object.assign(where, {
|
|
||||||
state: options.state
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
let onlyBlacklisted = false
|
|
||||||
if (options.is === 'deleted') {
|
|
||||||
where = Object.assign(where, {
|
|
||||||
deletedVideo: { [Op.not]: null }
|
|
||||||
})
|
|
||||||
} else if (options.is === 'blacklisted') {
|
|
||||||
onlyBlacklisted = true
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
attributes: {
|
attributes: {
|
||||||
|
@ -189,7 +194,7 @@ export enum ScopeNames {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
model: VideoModel,
|
model: VideoModel,
|
||||||
required: onlyBlacklisted,
|
required: !!(onlyBlacklisted || options.searchVideo || options.searchReportee || options.searchVideoChannel),
|
||||||
where: searchAttribute(options.searchVideo, 'name'),
|
where: searchAttribute(options.searchVideo, 'name'),
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
|
@ -301,11 +306,36 @@ export class VideoAbuseModel extends Model<VideoAbuseModel> {
|
||||||
start: number
|
start: number
|
||||||
count: number
|
count: number
|
||||||
sort: string
|
sort: string
|
||||||
search?: string
|
|
||||||
serverAccountId: number
|
serverAccountId: number
|
||||||
user?: MUserAccountId
|
user?: MUserAccountId
|
||||||
|
|
||||||
|
id?: number
|
||||||
|
state?: VideoAbuseState
|
||||||
|
videoIs?: VideoAbuseVideoIs
|
||||||
|
|
||||||
|
search?: string
|
||||||
|
searchReporter?: string
|
||||||
|
searchReportee?: string
|
||||||
|
searchVideo?: string
|
||||||
|
searchVideoChannel?: string
|
||||||
}) {
|
}) {
|
||||||
const { start, count, sort, search, user, serverAccountId } = parameters
|
const {
|
||||||
|
start,
|
||||||
|
count,
|
||||||
|
sort,
|
||||||
|
search,
|
||||||
|
user,
|
||||||
|
serverAccountId,
|
||||||
|
state,
|
||||||
|
videoIs,
|
||||||
|
searchReportee,
|
||||||
|
searchVideo,
|
||||||
|
searchVideoChannel,
|
||||||
|
searchReporter,
|
||||||
|
id
|
||||||
|
} = parameters
|
||||||
|
|
||||||
const userAccountId = user ? user.Account.id : undefined
|
const userAccountId = user ? user.Account.id : undefined
|
||||||
|
|
||||||
const query = {
|
const query = {
|
||||||
|
@ -317,37 +347,14 @@ export class VideoAbuseModel extends Model<VideoAbuseModel> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const filters = {
|
const filters = {
|
||||||
...parseQueryStringFilter(search, {
|
id,
|
||||||
id: {
|
search,
|
||||||
prefix: '#',
|
state,
|
||||||
handler: v => v
|
videoIs,
|
||||||
},
|
searchReportee,
|
||||||
state: {
|
searchVideo,
|
||||||
prefix: 'state:',
|
searchVideoChannel,
|
||||||
handler: v => {
|
searchReporter,
|
||||||
if (v === 'accepted') return VideoAbuseState.ACCEPTED
|
|
||||||
if (v === 'pending') return VideoAbuseState.PENDING
|
|
||||||
if (v === 'rejected') return VideoAbuseState.REJECTED
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
},
|
|
||||||
is: {
|
|
||||||
prefix: 'is:',
|
|
||||||
handler: v => {
|
|
||||||
if (v === 'deleted') return v
|
|
||||||
if (v === 'blacklisted') return v
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
},
|
|
||||||
searchReporter: {
|
|
||||||
prefix: 'reporter:',
|
|
||||||
handler: v => v
|
|
||||||
},
|
|
||||||
searchReportee: {
|
|
||||||
prefix: 'reportee:',
|
|
||||||
handler: v => v
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
serverAccountId,
|
serverAccountId,
|
||||||
userAccountId
|
userAccountId
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,22 @@ describe('Test video abuses API validators', function () {
|
||||||
statusCodeExpected: 403
|
statusCodeExpected: 403
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Should fail with a bad id filter', async function () {
|
||||||
|
await makeGetRequest({ url: server.url, path, token: server.accessToken, query: { id: 'toto' } })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should fail with a bad state filter', async function () {
|
||||||
|
await makeGetRequest({ url: server.url, path, token: server.accessToken, query: { state: 'toto' } })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should fail with a bad videoIs filter', async function () {
|
||||||
|
await makeGetRequest({ url: server.url, path, token: server.accessToken, query: { videoIs: 'toto' } })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should succeed with the correct params', async function () {
|
||||||
|
await makeGetRequest({ url: server.url, path, token: server.accessToken, query: { id: 13 }, statusCodeExpected: 200 })
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('When reporting a video abuse', function () {
|
describe('When reporting a video abuse', function () {
|
||||||
|
|
|
@ -901,7 +901,7 @@ describe('Test users', function () {
|
||||||
const reason = 'my super bad reason'
|
const reason = 'my super bad reason'
|
||||||
await reportVideoAbuse(server.url, user17AccessToken, videoId, reason)
|
await reportVideoAbuse(server.url, user17AccessToken, videoId, reason)
|
||||||
|
|
||||||
const res1 = await getVideoAbusesList(server.url, server.accessToken)
|
const res1 = await getVideoAbusesList({ url: server.url, token: server.accessToken })
|
||||||
const abuseId = res1.body.data[0].id
|
const abuseId = res1.body.data[0].id
|
||||||
|
|
||||||
const res2 = await getUserInformation(server.url, server.accessToken, user17Id, true)
|
const res2 = await getUserInformation(server.url, server.accessToken, user17Id, true)
|
||||||
|
|
|
@ -71,7 +71,7 @@ describe('Test video abuses', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should not have video abuses', async function () {
|
it('Should not have video abuses', async function () {
|
||||||
const res = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
|
const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken })
|
||||||
|
|
||||||
expect(res.body.total).to.equal(0)
|
expect(res.body.total).to.equal(0)
|
||||||
expect(res.body.data).to.be.an('array')
|
expect(res.body.data).to.be.an('array')
|
||||||
|
@ -89,7 +89,7 @@ describe('Test video abuses', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should have 1 video abuses on server 1 and 0 on server 2', async function () {
|
it('Should have 1 video abuses on server 1 and 0 on server 2', async function () {
|
||||||
const res1 = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
|
const res1 = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken })
|
||||||
|
|
||||||
expect(res1.body.total).to.equal(1)
|
expect(res1.body.total).to.equal(1)
|
||||||
expect(res1.body.data).to.be.an('array')
|
expect(res1.body.data).to.be.an('array')
|
||||||
|
@ -106,7 +106,7 @@ describe('Test video abuses', function () {
|
||||||
expect(abuse.countReportsForReporter).to.equal(1)
|
expect(abuse.countReportsForReporter).to.equal(1)
|
||||||
expect(abuse.countReportsForReportee).to.equal(1)
|
expect(abuse.countReportsForReportee).to.equal(1)
|
||||||
|
|
||||||
const res2 = await getVideoAbusesList(servers[1].url, servers[1].accessToken)
|
const res2 = await getVideoAbusesList({ url: servers[1].url, token: servers[1].accessToken })
|
||||||
expect(res2.body.total).to.equal(0)
|
expect(res2.body.total).to.equal(0)
|
||||||
expect(res2.body.data).to.be.an('array')
|
expect(res2.body.data).to.be.an('array')
|
||||||
expect(res2.body.data.length).to.equal(0)
|
expect(res2.body.data.length).to.equal(0)
|
||||||
|
@ -123,7 +123,7 @@ describe('Test video abuses', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should have 2 video abuses on server 1 and 1 on server 2', async function () {
|
it('Should have 2 video abuses on server 1 and 1 on server 2', async function () {
|
||||||
const res1 = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
|
const res1 = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken })
|
||||||
expect(res1.body.total).to.equal(2)
|
expect(res1.body.total).to.equal(2)
|
||||||
expect(res1.body.data).to.be.an('array')
|
expect(res1.body.data).to.be.an('array')
|
||||||
expect(res1.body.data.length).to.equal(2)
|
expect(res1.body.data.length).to.equal(2)
|
||||||
|
@ -148,7 +148,7 @@ describe('Test video abuses', function () {
|
||||||
expect(abuse2.state.label).to.equal('Pending')
|
expect(abuse2.state.label).to.equal('Pending')
|
||||||
expect(abuse2.moderationComment).to.be.null
|
expect(abuse2.moderationComment).to.be.null
|
||||||
|
|
||||||
const res2 = await getVideoAbusesList(servers[1].url, servers[1].accessToken)
|
const res2 = await getVideoAbusesList({ url: servers[1].url, token: servers[1].accessToken })
|
||||||
expect(res2.body.total).to.equal(1)
|
expect(res2.body.total).to.equal(1)
|
||||||
expect(res2.body.data).to.be.an('array')
|
expect(res2.body.data).to.be.an('array')
|
||||||
expect(res2.body.data.length).to.equal(1)
|
expect(res2.body.data.length).to.equal(1)
|
||||||
|
@ -166,7 +166,7 @@ describe('Test video abuses', function () {
|
||||||
const body = { state: VideoAbuseState.REJECTED }
|
const body = { state: VideoAbuseState.REJECTED }
|
||||||
await updateVideoAbuse(servers[1].url, servers[1].accessToken, abuseServer2.video.uuid, abuseServer2.id, body)
|
await updateVideoAbuse(servers[1].url, servers[1].accessToken, abuseServer2.video.uuid, abuseServer2.id, body)
|
||||||
|
|
||||||
const res = await getVideoAbusesList(servers[1].url, servers[1].accessToken)
|
const res = await getVideoAbusesList({ url: servers[1].url, token: servers[1].accessToken })
|
||||||
expect(res.body.data[0].state.id).to.equal(VideoAbuseState.REJECTED)
|
expect(res.body.data[0].state.id).to.equal(VideoAbuseState.REJECTED)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ describe('Test video abuses', function () {
|
||||||
const body = { state: VideoAbuseState.ACCEPTED, moderationComment: 'It is valid' }
|
const body = { state: VideoAbuseState.ACCEPTED, moderationComment: 'It is valid' }
|
||||||
await updateVideoAbuse(servers[1].url, servers[1].accessToken, abuseServer2.video.uuid, abuseServer2.id, body)
|
await updateVideoAbuse(servers[1].url, servers[1].accessToken, abuseServer2.video.uuid, abuseServer2.id, body)
|
||||||
|
|
||||||
const res = await getVideoAbusesList(servers[1].url, servers[1].accessToken)
|
const res = await getVideoAbusesList({ url: servers[1].url, token: servers[1].accessToken })
|
||||||
expect(res.body.data[0].state.id).to.equal(VideoAbuseState.ACCEPTED)
|
expect(res.body.data[0].state.id).to.equal(VideoAbuseState.ACCEPTED)
|
||||||
expect(res.body.data[0].moderationComment).to.equal('It is valid')
|
expect(res.body.data[0].moderationComment).to.equal('It is valid')
|
||||||
})
|
})
|
||||||
|
@ -186,7 +186,7 @@ describe('Test video abuses', function () {
|
||||||
await reportVideoAbuse(servers[1].url, servers[1].accessToken, servers[0].video.uuid, 'will mute this')
|
await reportVideoAbuse(servers[1].url, servers[1].accessToken, servers[0].video.uuid, 'will mute this')
|
||||||
await waitJobs(servers)
|
await waitJobs(servers)
|
||||||
|
|
||||||
const res = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
|
const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken })
|
||||||
expect(res.body.total).to.equal(3)
|
expect(res.body.total).to.equal(3)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@ describe('Test video abuses', function () {
|
||||||
{
|
{
|
||||||
await addAccountToServerBlocklist(servers[0].url, servers[0].accessToken, accountToBlock)
|
await addAccountToServerBlocklist(servers[0].url, servers[0].accessToken, accountToBlock)
|
||||||
|
|
||||||
const res = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
|
const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken })
|
||||||
expect(res.body.total).to.equal(2)
|
expect(res.body.total).to.equal(2)
|
||||||
|
|
||||||
const abuse = res.body.data.find(a => a.reason === 'will mute this')
|
const abuse = res.body.data.find(a => a.reason === 'will mute this')
|
||||||
|
@ -205,7 +205,7 @@ describe('Test video abuses', function () {
|
||||||
{
|
{
|
||||||
await removeAccountFromServerBlocklist(servers[0].url, servers[0].accessToken, accountToBlock)
|
await removeAccountFromServerBlocklist(servers[0].url, servers[0].accessToken, accountToBlock)
|
||||||
|
|
||||||
const res = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
|
const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken })
|
||||||
expect(res.body.total).to.equal(3)
|
expect(res.body.total).to.equal(3)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -216,7 +216,7 @@ describe('Test video abuses', function () {
|
||||||
{
|
{
|
||||||
await addServerToServerBlocklist(servers[0].url, servers[0].accessToken, servers[1].host)
|
await addServerToServerBlocklist(servers[0].url, servers[0].accessToken, servers[1].host)
|
||||||
|
|
||||||
const res = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
|
const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken })
|
||||||
expect(res.body.total).to.equal(2)
|
expect(res.body.total).to.equal(2)
|
||||||
|
|
||||||
const abuse = res.body.data.find(a => a.reason === 'will mute this')
|
const abuse = res.body.data.find(a => a.reason === 'will mute this')
|
||||||
|
@ -226,7 +226,7 @@ describe('Test video abuses', function () {
|
||||||
{
|
{
|
||||||
await removeServerFromServerBlocklist(servers[0].url, servers[0].accessToken, serverToBlock)
|
await removeServerFromServerBlocklist(servers[0].url, servers[0].accessToken, serverToBlock)
|
||||||
|
|
||||||
const res = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
|
const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken })
|
||||||
expect(res.body.total).to.equal(3)
|
expect(res.body.total).to.equal(3)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -238,7 +238,7 @@ describe('Test video abuses', function () {
|
||||||
|
|
||||||
await waitJobs(servers)
|
await waitJobs(servers)
|
||||||
|
|
||||||
const res = await getVideoAbusesList(servers[1].url, servers[1].accessToken)
|
const res = await getVideoAbusesList({ url: servers[1].url, token: servers[1].accessToken })
|
||||||
expect(res.body.total).to.equal(2, "wrong number of videos returned")
|
expect(res.body.total).to.equal(2, "wrong number of videos returned")
|
||||||
expect(res.body.data.length).to.equal(2, "wrong number of videos returned")
|
expect(res.body.data.length).to.equal(2, "wrong number of videos returned")
|
||||||
expect(res.body.data[0].id).to.equal(abuseServer2.id, "wrong origin server id for first video")
|
expect(res.body.data[0].id).to.equal(abuseServer2.id, "wrong origin server id for first video")
|
||||||
|
@ -274,7 +274,7 @@ describe('Test video abuses', function () {
|
||||||
const reason4 = 'my super bad reason 4'
|
const reason4 = 'my super bad reason 4'
|
||||||
await reportVideoAbuse(servers[0].url, userAccessToken, servers[0].video.id, reason4)
|
await reportVideoAbuse(servers[0].url, userAccessToken, servers[0].video.id, reason4)
|
||||||
|
|
||||||
const res2 = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
|
const res2 = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken })
|
||||||
|
|
||||||
{
|
{
|
||||||
for (const abuse of res2.body.data as VideoAbuse[]) {
|
for (const abuse of res2.body.data as VideoAbuse[]) {
|
||||||
|
@ -299,18 +299,56 @@ describe('Test video abuses', function () {
|
||||||
await waitJobs(servers)
|
await waitJobs(servers)
|
||||||
|
|
||||||
{
|
{
|
||||||
const res = await getVideoAbusesList(servers[1].url, servers[1].accessToken)
|
const res = await getVideoAbusesList({ url: servers[1].url, token: servers[1].accessToken })
|
||||||
expect(res.body.total).to.equal(1)
|
expect(res.body.total).to.equal(1)
|
||||||
expect(res.body.data.length).to.equal(1)
|
expect(res.body.data.length).to.equal(1)
|
||||||
expect(res.body.data[0].id).to.not.equal(abuseServer2.id)
|
expect(res.body.data[0].id).to.not.equal(abuseServer2.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const res = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
|
const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken })
|
||||||
expect(res.body.total).to.equal(5)
|
expect(res.body.total).to.equal(5)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Should list and filter video abuses', async function () {
|
||||||
|
async function list (query: Omit<Parameters<typeof getVideoAbusesList>[0], 'url' | 'token'>) {
|
||||||
|
const options = {
|
||||||
|
url: servers[0].url,
|
||||||
|
token: servers[0].accessToken
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(options, query)
|
||||||
|
|
||||||
|
const res = await getVideoAbusesList(options)
|
||||||
|
|
||||||
|
return res.body.data as VideoAbuse[]
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(await list({ id: 56 })).to.have.lengthOf(0)
|
||||||
|
expect(await list({ id: 1 })).to.have.lengthOf(1)
|
||||||
|
|
||||||
|
expect(await list({ search: 'my super name for server 1' })).to.have.lengthOf(3)
|
||||||
|
expect(await list({ search: 'aaaaaaaaaaaaaaaaaaaaaaaaaa' })).to.have.lengthOf(0)
|
||||||
|
|
||||||
|
expect(await list({ searchVideo: 'my second super name for server 1' })).to.have.lengthOf(1)
|
||||||
|
|
||||||
|
expect(await list({ searchVideoChannel: 'root' })).to.have.lengthOf(3)
|
||||||
|
expect(await list({ searchVideoChannel: 'aaaa' })).to.have.lengthOf(0)
|
||||||
|
|
||||||
|
expect(await list({ searchReporter: 'user2' })).to.have.lengthOf(1)
|
||||||
|
expect(await list({ searchReporter: 'root' })).to.have.lengthOf(4)
|
||||||
|
|
||||||
|
expect(await list({ searchReportee: 'root' })).to.have.lengthOf(3)
|
||||||
|
expect(await list({ searchReportee: 'aaaa' })).to.have.lengthOf(0)
|
||||||
|
|
||||||
|
expect(await list({ videoIs: 'deleted' })).to.have.lengthOf(1)
|
||||||
|
expect(await list({ videoIs: 'blacklisted' })).to.have.lengthOf(0)
|
||||||
|
|
||||||
|
expect(await list({ state: VideoAbuseState.ACCEPTED })).to.have.lengthOf(0)
|
||||||
|
expect(await list({ state: VideoAbuseState.PENDING })).to.have.lengthOf(5)
|
||||||
|
})
|
||||||
|
|
||||||
after(async function () {
|
after(async function () {
|
||||||
await cleanupTests(servers)
|
await cleanupTests(servers)
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import * as request from 'supertest'
|
import * as request from 'supertest'
|
||||||
import { VideoAbuseUpdate } from '../../models/videos/abuse/video-abuse-update.model'
|
import { VideoAbuseUpdate } from '../../models/videos/abuse/video-abuse-update.model'
|
||||||
import { makeDeleteRequest, makePutBodyRequest } from '../requests/requests'
|
import { makeDeleteRequest, makePutBodyRequest, makeGetRequest } from '../requests/requests'
|
||||||
|
import { VideoAbuseState } from '@shared/models'
|
||||||
|
import { VideoAbuseVideoIs } from '@shared/models/videos/abuse/video-abuse-video-is.type'
|
||||||
|
|
||||||
function reportVideoAbuse (url: string, token: string, videoId: number | string, reason: string, specialStatus = 200) {
|
function reportVideoAbuse (url: string, token: string, videoId: number | string, reason: string, specialStatus = 200) {
|
||||||
const path = '/api/v1/videos/' + videoId + '/abuse'
|
const path = '/api/v1/videos/' + videoId + '/abuse'
|
||||||
|
@ -13,16 +15,51 @@ function reportVideoAbuse (url: string, token: string, videoId: number | string,
|
||||||
.expect(specialStatus)
|
.expect(specialStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVideoAbusesList (url: string, token: string) {
|
function getVideoAbusesList (options: {
|
||||||
|
url: string
|
||||||
|
token: string
|
||||||
|
id?: number
|
||||||
|
search?: string
|
||||||
|
state?: VideoAbuseState
|
||||||
|
videoIs?: VideoAbuseVideoIs
|
||||||
|
searchReporter?: string
|
||||||
|
searchReportee?: string
|
||||||
|
searchVideo?: string
|
||||||
|
searchVideoChannel?: string
|
||||||
|
}) {
|
||||||
|
const {
|
||||||
|
url,
|
||||||
|
token,
|
||||||
|
id,
|
||||||
|
search,
|
||||||
|
state,
|
||||||
|
videoIs,
|
||||||
|
searchReporter,
|
||||||
|
searchReportee,
|
||||||
|
searchVideo,
|
||||||
|
searchVideoChannel
|
||||||
|
} = options
|
||||||
const path = '/api/v1/videos/abuse'
|
const path = '/api/v1/videos/abuse'
|
||||||
|
|
||||||
return request(url)
|
const query = {
|
||||||
.get(path)
|
sort: 'createdAt',
|
||||||
.query({ sort: 'createdAt' })
|
id,
|
||||||
.set('Accept', 'application/json')
|
search,
|
||||||
.set('Authorization', 'Bearer ' + token)
|
state,
|
||||||
.expect(200)
|
videoIs,
|
||||||
.expect('Content-Type', /json/)
|
searchReporter,
|
||||||
|
searchReportee,
|
||||||
|
searchVideo,
|
||||||
|
searchVideoChannel
|
||||||
|
}
|
||||||
|
|
||||||
|
return makeGetRequest({
|
||||||
|
url,
|
||||||
|
path,
|
||||||
|
token,
|
||||||
|
query,
|
||||||
|
statusCodeExpected: 200
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateVideoAbuse (
|
function updateVideoAbuse (
|
||||||
|
|
1
shared/models/videos/abuse/video-abuse-video-is.type.ts
Normal file
1
shared/models/videos/abuse/video-abuse-video-is.type.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export type VideoAbuseVideoIs = 'deleted' | 'blacklisted'
|
Loading…
Reference in a new issue