Improve blacklist management
This commit is contained in:
parent
26b7305a23
commit
191764f30b
|
@ -42,7 +42,7 @@
|
|||
<td>{{ videoAbuse.createdAt }}</td>
|
||||
|
||||
<td>
|
||||
<a [href]="videoAbuse.video.url" i18n-title title="Go to the video" target="_blank" rel="noopener noreferrer">
|
||||
<a [href]="getVideoUrl(videoAbuse)" i18n-title title="Go to the video" target="_blank" rel="noopener noreferrer">
|
||||
{{ videoAbuse.video.name }}
|
||||
</a>
|
||||
</td>
|
||||
|
|
|
@ -8,6 +8,7 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
|
|||
import { DropdownAction } from '@app/shared/buttons/action-dropdown.component'
|
||||
import { ConfirmService } from '@app/core'
|
||||
import { ModerationCommentModalComponent } from './moderation-comment-modal.component'
|
||||
import { Video } from '@app/shared/video/video.model'
|
||||
|
||||
@Component({
|
||||
selector: 'my-video-abuse-list',
|
||||
|
@ -79,6 +80,10 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
|
|||
return videoAbuse.state.id === VideoAbuseState.REJECTED
|
||||
}
|
||||
|
||||
getVideoUrl (videoAbuse: VideoAbuse) {
|
||||
return Video.buildClientUrl(videoAbuse.video.uuid)
|
||||
}
|
||||
|
||||
async removeVideoAbuse (videoAbuse: VideoAbuse) {
|
||||
const res = await this.confirmService.confirm(this.i18n('Do you really want to delete this abuse?'), this.i18n('Delete'))
|
||||
if (res === false) return
|
||||
|
|
|
@ -10,8 +10,7 @@
|
|||
<tr>
|
||||
<th style="width: 40px"></th>
|
||||
<th i18n pSortableColumn="name">Video name <p-sortIcon field="name"></p-sortIcon></th>
|
||||
<th i18n>NSFW</th>
|
||||
<th i18n>UUID</th>
|
||||
<th i18n>Sensitive</th>
|
||||
<th i18n pSortableColumn="createdAt">Date <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||
<th style="width: 50px;"></th>
|
||||
</tr>
|
||||
|
@ -25,9 +24,13 @@
|
|||
</span>
|
||||
</td>
|
||||
|
||||
<td>{{ videoBlacklist.video.name }}</td>
|
||||
<td>
|
||||
<a [href]="getVideoUrl(videoBlacklist)" i18n-title title="Go to the video" target="_blank" rel="noopener noreferrer">
|
||||
{{ videoBlacklist.video.name }}
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<td>{{ videoBlacklist.video.nsfw }}</td>
|
||||
<td>{{ videoBlacklist.video.uuid }}</td>
|
||||
<td>{{ videoBlacklist.createdAt }}</td>
|
||||
|
||||
<td class="action-cell">
|
||||
|
|
|
@ -3,9 +3,10 @@ import { SortMeta } from 'primeng/components/common/sortmeta'
|
|||
import { NotificationsService } from 'angular2-notifications'
|
||||
import { ConfirmService } from '../../../core'
|
||||
import { RestPagination, RestTable, VideoBlacklistService } from '../../../shared'
|
||||
import { BlacklistedVideo } from '../../../../../../shared'
|
||||
import { VideoBlacklist } from '../../../../../../shared'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
import { DropdownAction } from '@app/shared/buttons/action-dropdown.component'
|
||||
import { Video } from '@app/shared/video/video.model'
|
||||
|
||||
@Component({
|
||||
selector: 'my-video-blacklist-list',
|
||||
|
@ -13,13 +14,13 @@ import { DropdownAction } from '@app/shared/buttons/action-dropdown.component'
|
|||
styleUrls: [ './video-blacklist-list.component.scss' ]
|
||||
})
|
||||
export class VideoBlacklistListComponent extends RestTable implements OnInit {
|
||||
blacklist: BlacklistedVideo[] = []
|
||||
blacklist: VideoBlacklist[] = []
|
||||
totalRecords = 0
|
||||
rowsPerPage = 10
|
||||
sort: SortMeta = { field: 'createdAt', order: 1 }
|
||||
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
||||
|
||||
videoBlacklistActions: DropdownAction<BlacklistedVideo>[] = []
|
||||
videoBlacklistActions: DropdownAction<VideoBlacklist>[] = []
|
||||
|
||||
constructor (
|
||||
private notificationsService: NotificationsService,
|
||||
|
@ -41,7 +42,11 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
|
|||
this.loadSort()
|
||||
}
|
||||
|
||||
async removeVideoFromBlacklist (entry: BlacklistedVideo) {
|
||||
getVideoUrl (videoBlacklist: VideoBlacklist) {
|
||||
return Video.buildClientUrl(videoBlacklist.video.uuid)
|
||||
}
|
||||
|
||||
async removeVideoFromBlacklist (entry: VideoBlacklist) {
|
||||
const confirmMessage = this.i18n(
|
||||
'Do you really want to remove this video from the blacklist? It will be available again in the videos list.'
|
||||
)
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
<a class="video-info-name" [routerLink]="['/videos/watch', video.uuid]" [attr.title]="video.name">{{ video.name }}</a>
|
||||
<span i18n class="video-info-date-views">{{ video.createdAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span>
|
||||
<div class="video-info-private">{{ video.privacy.label }}{{ getStateLabel(video) }}</div>
|
||||
<div *ngIf="video.blacklisted" class="video-info-blacklisted">
|
||||
<span class="blacklisted-label" i18n>Blacklisted</span>
|
||||
<span class="blacklisted-reason" *ngIf="video.blacklistedReason">{{ video.blacklistedReason }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Display only once -->
|
||||
|
|
|
@ -76,12 +76,25 @@
|
|||
font-weight: $font-semibold;
|
||||
}
|
||||
|
||||
.video-info-date-views, .video-info-private {
|
||||
.video-info-date-views,
|
||||
.video-info-private,
|
||||
.video-info-blacklisted {
|
||||
font-size: 13px;
|
||||
|
||||
&.video-info-private {
|
||||
&.video-info-private,
|
||||
&.video-info-blacklisted .blacklisted-label {
|
||||
font-weight: $font-semibold;
|
||||
}
|
||||
|
||||
&.video-info-blacklisted {
|
||||
color: red;
|
||||
|
||||
.blacklisted-reason {
|
||||
&::before {
|
||||
content: ' - ';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ div {
|
|||
height: 100%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-top: 150px;
|
||||
padding-top: 150px;
|
||||
|
||||
font-size: 32px;
|
||||
}
|
|
@ -3,7 +3,7 @@ import { HttpClient, HttpParams } from '@angular/common/http'
|
|||
import { Injectable } from '@angular/core'
|
||||
import { SortMeta } from 'primeng/components/common/sortmeta'
|
||||
import { Observable } from 'rxjs'
|
||||
import { BlacklistedVideo, ResultList } from '../../../../../shared'
|
||||
import { VideoBlacklist, ResultList } from '../../../../../shared'
|
||||
import { environment } from '../../../environments/environment'
|
||||
import { RestExtractor, RestPagination, RestService } from '../rest'
|
||||
|
||||
|
@ -17,11 +17,11 @@ export class VideoBlacklistService {
|
|||
private restExtractor: RestExtractor
|
||||
) {}
|
||||
|
||||
listBlacklist (pagination: RestPagination, sort: SortMeta): Observable<ResultList<BlacklistedVideo>> {
|
||||
listBlacklist (pagination: RestPagination, sort: SortMeta): Observable<ResultList<VideoBlacklist>> {
|
||||
let params = new HttpParams()
|
||||
params = this.restService.addRestGetParams(params, pagination, sort)
|
||||
|
||||
return this.authHttp.get<ResultList<BlacklistedVideo>>(VideoBlacklistService.BASE_VIDEOS_URL + 'blacklist', { params })
|
||||
return this.authHttp.get<ResultList<VideoBlacklist>>(VideoBlacklistService.BASE_VIDEOS_URL + 'blacklist', { params })
|
||||
.pipe(
|
||||
map(res => this.restExtractor.convertResultListDateToHuman(res)),
|
||||
catchError(res => this.restExtractor.handleError(res))
|
||||
|
|
|
@ -44,7 +44,11 @@ export class VideoDetails extends Video implements VideoDetailsServerModel {
|
|||
}
|
||||
|
||||
isBlackistableBy (user: AuthUser) {
|
||||
return user && user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) === true
|
||||
return this.blacklisted !== true && user && user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) === true
|
||||
}
|
||||
|
||||
isUnblacklistableBy (user: AuthUser) {
|
||||
return this.blacklisted === true && user && user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) === true
|
||||
}
|
||||
|
||||
isUpdatableBy (user: AuthUser) {
|
||||
|
|
|
@ -41,6 +41,8 @@ export class Video implements VideoServerModel {
|
|||
waitTranscoding?: boolean
|
||||
state?: VideoConstant<VideoState>
|
||||
scheduledUpdate?: VideoScheduleUpdate
|
||||
blacklisted?: boolean
|
||||
blacklistedReason?: string
|
||||
|
||||
account: {
|
||||
id: number
|
||||
|
@ -62,6 +64,10 @@ export class Video implements VideoServerModel {
|
|||
avatar: Avatar
|
||||
}
|
||||
|
||||
static buildClientUrl (videoUUID: string) {
|
||||
return '/videos/watch/' + videoUUID
|
||||
}
|
||||
|
||||
private static createDurationString (duration: number) {
|
||||
const hours = Math.floor(duration / 3600)
|
||||
const minutes = Math.floor((duration % 3600) / 60)
|
||||
|
@ -116,6 +122,9 @@ export class Video implements VideoServerModel {
|
|||
|
||||
this.scheduledUpdate = hash.scheduledUpdate
|
||||
if (this.state) this.state.label = peertubeTranslate(this.state.label, translations)
|
||||
|
||||
this.blacklisted = hash.blacklisted
|
||||
this.blacklistedReason = hash.blacklistedReason
|
||||
}
|
||||
|
||||
isVideoNSFWForUser (user: User, serverConfig: ServerConfig) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div class="row">
|
||||
<div class="root-row row">
|
||||
<!-- We need the video container for videojs so we just hide it -->
|
||||
<div id="video-element-wrapper">
|
||||
<div *ngIf="remoteServerDown" class="remote-server-down">
|
||||
|
@ -17,7 +17,12 @@
|
|||
</div>
|
||||
|
||||
<div i18n class="alert alert-info" *ngIf="hasVideoScheduledPublication()">
|
||||
This video will be published on {{ video.scheduledUpdate.updateAt | date: 'full' }}
|
||||
This video will be published on {{ video.scheduledUpdate.updateAt | date: 'full' }}.
|
||||
</div>
|
||||
|
||||
<div class="alert alert-danger" *ngIf="video?.blacklisted">
|
||||
<div class="blacklisted-label" i18n>This video is blacklisted.</div>
|
||||
{{ video.blacklistedReason }}
|
||||
</div>
|
||||
|
||||
<!-- Video information -->
|
||||
|
@ -98,6 +103,10 @@
|
|||
<span class="icon icon-blacklist"></span> <ng-container i18n>Blacklist</ng-container>
|
||||
</a>
|
||||
|
||||
<a *ngIf="isVideoUnblacklistable()" class="dropdown-item" i18n-title title="Unblacklist this video" href="#" (click)="unblacklistVideo($event)">
|
||||
<span class="icon icon-unblacklist"></span> <ng-container i18n>Unblacklist</ng-container>
|
||||
</a>
|
||||
|
||||
<a *ngIf="isVideoRemovable()" class="dropdown-item" i18n-title title="Delete this video" href="#" (click)="removeVideo($event)">
|
||||
<span class="icon icon-delete"></span> <ng-container i18n>Delete</ng-container>
|
||||
</a>
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
@import '_variables';
|
||||
@import '_mixins';
|
||||
|
||||
.root-row {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.blacklisted-label {
|
||||
font-weight: $font-semibold;
|
||||
}
|
||||
|
||||
#video-element-wrapper {
|
||||
background-color: #000;
|
||||
display: flex;
|
||||
|
@ -259,6 +267,10 @@
|
|||
background-image: url('../../../assets/images/video/blacklist.svg');
|
||||
}
|
||||
|
||||
&.icon-unblacklist {
|
||||
background-image: url('../../../assets/images/global/undo.svg');
|
||||
}
|
||||
|
||||
&.icon-delete {
|
||||
background-image: url('../../../assets/images/global/delete-black.svg');
|
||||
}
|
||||
|
|
|
@ -121,7 +121,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
|||
this.videoCaptionService.listCaptions(uuid)
|
||||
)
|
||||
.pipe(
|
||||
catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ 400, 404 ]))
|
||||
// If 401, the video is private or blacklisted so redirect to 404
|
||||
catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ 400, 401, 404 ]))
|
||||
)
|
||||
.subscribe(([ video, captionsResult ]) => {
|
||||
const startTime = this.route.snapshot.queryParams.start
|
||||
|
@ -217,6 +218,31 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
|||
this.videoBlacklistModal.show()
|
||||
}
|
||||
|
||||
async unblacklistVideo (event: Event) {
|
||||
event.preventDefault()
|
||||
|
||||
const confirmMessage = this.i18n(
|
||||
'Do you really want to remove this video from the blacklist? It will be available again in the videos list.'
|
||||
)
|
||||
|
||||
const res = await this.confirmService.confirm(confirmMessage, this.i18n('Unblacklist'))
|
||||
if (res === false) return
|
||||
|
||||
this.videoBlacklistService.removeVideoFromBlacklist(this.video.id).subscribe(
|
||||
() => {
|
||||
this.notificationsService.success(
|
||||
this.i18n('Success'),
|
||||
this.i18n('Video {{name}} removed from the blacklist.', { name: this.video.name })
|
||||
)
|
||||
|
||||
this.video.blacklisted = false
|
||||
this.video.blacklistedReason = null
|
||||
},
|
||||
|
||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
)
|
||||
}
|
||||
|
||||
isUserLoggedIn () {
|
||||
return this.authService.isLoggedIn()
|
||||
}
|
||||
|
@ -229,6 +255,10 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
|||
return this.video.isBlackistableBy(this.user)
|
||||
}
|
||||
|
||||
isVideoUnblacklistable () {
|
||||
return this.video.isUnblacklistableBy(this.user)
|
||||
}
|
||||
|
||||
getVideoPoster () {
|
||||
if (!this.video) return ''
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Artboard-4" transform="translate(-180.000000, -115.000000)" fill="#000">
|
||||
<g id="4" transform="translate(180.000000, 115.000000)">
|
||||
<path d="M10,19 C10.5522847,19 11,19.4477153 11,20 C11,20.5522847 10.5522847,21 10,21 C9.99404288,21 9.98809793,20.9999479 9.98216558,20.9998442 C5.01980239,20.990358 1,16.9646166 1,12 C1,7.02943725 5.02943725,3 10,3 C14.9705627,3 19,7.02943725 19,12 L17,12 C17,8.13400675 13.8659932,5 10,5 C6.13400675,5 3,8.13400675 3,12 C3,15.8659932 6.13400675,19 10,19 Z M14,12 L22,12 L18,16 L14,12 Z" id="Combined-Shape" transform="translate(11.500000, 12.000000) scale(-1, 1) translate(-11.500000, -12.000000) "></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1014 B |
|
@ -1,5 +1,5 @@
|
|||
import * as express from 'express'
|
||||
import { BlacklistedVideo, UserRight, VideoBlacklistCreate } from '../../../../shared'
|
||||
import { VideoBlacklist, UserRight, VideoBlacklistCreate } from '../../../../shared'
|
||||
import { logger } from '../../../helpers/logger'
|
||||
import { getFormattedObjects } from '../../../helpers/utils'
|
||||
import {
|
||||
|
@ -87,7 +87,7 @@ async function updateVideoBlacklistController (req: express.Request, res: expres
|
|||
async function listBlacklist (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
const resultList = await VideoBlacklistModel.listForApi(req.query.start, req.query.count, req.query.sort)
|
||||
|
||||
return res.json(getFormattedObjects<BlacklistedVideo, VideoBlacklistModel>(resultList.data, resultList.total))
|
||||
return res.json(getFormattedObjects<VideoBlacklist, VideoBlacklistModel>(resultList.data, resultList.total))
|
||||
}
|
||||
|
||||
async function removeVideoFromBlacklistController (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
|
|
|
@ -35,6 +35,8 @@ import { VideoShareModel } from '../../models/video/video-share'
|
|||
import { authenticate } from '../oauth'
|
||||
import { areValidationErrors } from './utils'
|
||||
import { cleanUpReqFiles } from '../../helpers/utils'
|
||||
import { VideoModel } from '../../models/video/video'
|
||||
import { UserModel } from '../../models/account/user'
|
||||
|
||||
const videosAddValidator = getCommonVideoAttributes().concat([
|
||||
body('videofile')
|
||||
|
@ -131,7 +133,25 @@ const videosGetValidator = [
|
|||
if (areValidationErrors(req, res)) return
|
||||
if (!await isVideoExist(req.params.id, res)) return
|
||||
|
||||
const video = res.locals.video
|
||||
const video: VideoModel = res.locals.video
|
||||
|
||||
// Video private or blacklisted
|
||||
if (video.privacy === VideoPrivacy.PRIVATE || video.VideoBlacklist) {
|
||||
authenticate(req, res, () => {
|
||||
const user: UserModel = res.locals.oauth.token.User
|
||||
|
||||
// Only the owner or a user that have blacklist rights can see the video
|
||||
if (video.VideoChannel.Account.userId !== user.id && !user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST)) {
|
||||
return res.status(403)
|
||||
.json({ error: 'Cannot get this private or blacklisted video.' })
|
||||
.end()
|
||||
}
|
||||
|
||||
return next()
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Video is public, anyone can access it
|
||||
if (video.privacy === VideoPrivacy.PUBLIC) return next()
|
||||
|
@ -143,17 +163,6 @@ const videosGetValidator = [
|
|||
// Don't leak this unlisted video
|
||||
return res.status(404).end()
|
||||
}
|
||||
|
||||
// Video is private, check the user
|
||||
authenticate(req, res, () => {
|
||||
if (video.VideoChannel.Account.userId !== res.locals.oauth.token.User.id) {
|
||||
return res.status(403)
|
||||
.json({ error: 'Cannot get this private video of another user' })
|
||||
.end()
|
||||
}
|
||||
|
||||
return next()
|
||||
})
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
@ -137,7 +137,6 @@ export class VideoAbuseModel extends Model<VideoAbuseModel> {
|
|||
video: {
|
||||
id: this.Video.id,
|
||||
uuid: this.Video.uuid,
|
||||
url: this.Video.url,
|
||||
name: this.Video.name
|
||||
},
|
||||
createdAt: this.createdAt
|
||||
|
|
|
@ -16,7 +16,7 @@ import { getSortOnModel, throwIfNotValid } from '../utils'
|
|||
import { VideoModel } from './video'
|
||||
import { isVideoBlacklistReasonValid } from '../../helpers/custom-validators/video-blacklist'
|
||||
import { Emailer } from '../../lib/emailer'
|
||||
import { BlacklistedVideo } from '../../../shared/models/videos'
|
||||
import { VideoBlacklist } from '../../../shared/models/videos'
|
||||
import { CONSTRAINTS_FIELDS } from '../../initializers'
|
||||
|
||||
@Table({
|
||||
|
@ -68,7 +68,12 @@ export class VideoBlacklistModel extends Model<VideoBlacklistModel> {
|
|||
offset: start,
|
||||
limit: count,
|
||||
order: getSortOnModel(sort.sortModel, sort.sortValue),
|
||||
include: [ { model: VideoModel } ]
|
||||
include: [
|
||||
{
|
||||
model: VideoModel,
|
||||
required: true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
return VideoBlacklistModel.findAndCountAll(query)
|
||||
|
@ -90,7 +95,7 @@ export class VideoBlacklistModel extends Model<VideoBlacklistModel> {
|
|||
return VideoBlacklistModel.findOne(query)
|
||||
}
|
||||
|
||||
toFormattedJSON (): BlacklistedVideo {
|
||||
toFormattedJSON (): VideoBlacklist {
|
||||
const video = this.Video
|
||||
|
||||
return {
|
||||
|
|
|
@ -127,7 +127,8 @@ export enum ScopeNames {
|
|||
WITH_ACCOUNT_DETAILS = 'WITH_ACCOUNT_DETAILS',
|
||||
WITH_TAGS = 'WITH_TAGS',
|
||||
WITH_FILES = 'WITH_FILES',
|
||||
WITH_SCHEDULED_UPDATE = 'WITH_SCHEDULED_UPDATE'
|
||||
WITH_SCHEDULED_UPDATE = 'WITH_SCHEDULED_UPDATE',
|
||||
WITH_BLACKLISTED = 'WITH_BLACKLISTED'
|
||||
}
|
||||
|
||||
type AvailableForListOptions = {
|
||||
|
@ -374,6 +375,15 @@ type AvailableForListOptions = {
|
|||
[ScopeNames.WITH_TAGS]: {
|
||||
include: [ () => TagModel ]
|
||||
},
|
||||
[ScopeNames.WITH_BLACKLISTED]: {
|
||||
include: [
|
||||
{
|
||||
attributes: [ 'id', 'reason' ],
|
||||
model: () => VideoBlacklistModel,
|
||||
required: false
|
||||
}
|
||||
]
|
||||
},
|
||||
[ScopeNames.WITH_FILES]: {
|
||||
include: [
|
||||
{
|
||||
|
@ -1004,7 +1014,13 @@ export class VideoModel extends Model<VideoModel> {
|
|||
}
|
||||
|
||||
return VideoModel
|
||||
.scope([ ScopeNames.WITH_TAGS, ScopeNames.WITH_FILES, ScopeNames.WITH_ACCOUNT_DETAILS, ScopeNames.WITH_SCHEDULED_UPDATE ])
|
||||
.scope([
|
||||
ScopeNames.WITH_TAGS,
|
||||
ScopeNames.WITH_BLACKLISTED,
|
||||
ScopeNames.WITH_FILES,
|
||||
ScopeNames.WITH_ACCOUNT_DETAILS,
|
||||
ScopeNames.WITH_SCHEDULED_UPDATE
|
||||
])
|
||||
.findById(id, options)
|
||||
}
|
||||
|
||||
|
@ -1030,7 +1046,13 @@ export class VideoModel extends Model<VideoModel> {
|
|||
}
|
||||
|
||||
return VideoModel
|
||||
.scope([ ScopeNames.WITH_TAGS, ScopeNames.WITH_FILES, ScopeNames.WITH_ACCOUNT_DETAILS, ScopeNames.WITH_SCHEDULED_UPDATE ])
|
||||
.scope([
|
||||
ScopeNames.WITH_TAGS,
|
||||
ScopeNames.WITH_BLACKLISTED,
|
||||
ScopeNames.WITH_FILES,
|
||||
ScopeNames.WITH_ACCOUNT_DETAILS,
|
||||
ScopeNames.WITH_SCHEDULED_UPDATE
|
||||
])
|
||||
.findOne(options)
|
||||
}
|
||||
|
||||
|
@ -1276,7 +1298,8 @@ export class VideoModel extends Model<VideoModel> {
|
|||
toFormattedDetailsJSON (): VideoDetails {
|
||||
const formattedJson = this.toFormattedJSON({
|
||||
additionalAttributes: {
|
||||
scheduledUpdate: true
|
||||
scheduledUpdate: true,
|
||||
blacklistInfo: true
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -19,7 +19,8 @@ function updateVideoBlacklist (url: string, token: string, videoId: number, reas
|
|||
.send({ reason })
|
||||
.set('Accept', 'application/json')
|
||||
.set('Authorization', 'Bearer ' + token)
|
||||
.expect(specialStatus)}
|
||||
.expect(specialStatus)
|
||||
}
|
||||
|
||||
function removeVideoFromBlacklist (url: string, token: string, videoId: number | string, specialStatus = 204) {
|
||||
const path = '/api/v1/videos/' + videoId + '/blacklist'
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
export enum UserRight {
|
||||
ALL,
|
||||
|
||||
MANAGE_USERS,
|
||||
MANAGE_SERVER_FOLLOW,
|
||||
MANAGE_VIDEO_ABUSES,
|
||||
MANAGE_VIDEO_BLACKLIST,
|
||||
MANAGE_JOBS,
|
||||
MANAGE_CONFIGURATION,
|
||||
|
||||
MANAGE_VIDEO_BLACKLIST,
|
||||
|
||||
REMOVE_ANY_VIDEO,
|
||||
REMOVE_ANY_VIDEO_CHANNEL,
|
||||
REMOVE_ANY_VIDEO_COMMENT,
|
||||
|
|
|
@ -14,7 +14,6 @@ export interface VideoAbuse {
|
|||
id: number
|
||||
name: string
|
||||
uuid: string
|
||||
url: string
|
||||
}
|
||||
|
||||
createdAt: Date
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export interface BlacklistedVideo {
|
||||
export interface VideoBlacklist {
|
||||
id: number
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
|
|
Loading…
Reference in New Issue