Refactor follow/mute as modals in admin, add actions in abuse list
This commit is contained in:
parent
1055eb3a7b
commit
bb152476c8
29 changed files with 341 additions and 184 deletions
|
@ -5,7 +5,7 @@ import { TableModule } from 'primeng/table'
|
||||||
import { SharedModule } from '../shared'
|
import { SharedModule } from '../shared'
|
||||||
import { AdminRoutingModule } from './admin-routing.module'
|
import { AdminRoutingModule } from './admin-routing.module'
|
||||||
import { AdminComponent } from './admin.component'
|
import { AdminComponent } from './admin.component'
|
||||||
import { FollowersListComponent, FollowingAddComponent, FollowsComponent, VideoRedundanciesListComponent } from './follows'
|
import { FollowersListComponent, FollowsComponent, VideoRedundanciesListComponent } from './follows'
|
||||||
import { FollowingListComponent } from './follows/following-list/following-list.component'
|
import { FollowingListComponent } from './follows/following-list/following-list.component'
|
||||||
import { UserCreateComponent, UserListComponent, UserPasswordComponent, UsersComponent, UserUpdateComponent } from './users'
|
import { UserCreateComponent, UserListComponent, UserPasswordComponent, UsersComponent, UserUpdateComponent } from './users'
|
||||||
import {
|
import {
|
||||||
|
@ -28,6 +28,7 @@ import { SelectButtonModule } from 'primeng/selectbutton'
|
||||||
import { PluginApiService } from '@app/+admin/plugins/shared/plugin-api.service'
|
import { PluginApiService } from '@app/+admin/plugins/shared/plugin-api.service'
|
||||||
import { VideoRedundancyInformationComponent } from '@app/+admin/follows/video-redundancies-list/video-redundancy-information.component'
|
import { VideoRedundancyInformationComponent } from '@app/+admin/follows/video-redundancies-list/video-redundancy-information.component'
|
||||||
import { ChartModule } from 'primeng/chart'
|
import { ChartModule } from 'primeng/chart'
|
||||||
|
import { BatchDomainsModalComponent } from './config/shared/batch-domains-modal.component'
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
|
@ -44,7 +45,6 @@ import { ChartModule } from 'primeng/chart'
|
||||||
AdminComponent,
|
AdminComponent,
|
||||||
|
|
||||||
FollowsComponent,
|
FollowsComponent,
|
||||||
FollowingAddComponent,
|
|
||||||
FollowersListComponent,
|
FollowersListComponent,
|
||||||
FollowingListComponent,
|
FollowingListComponent,
|
||||||
RedundancyCheckboxComponent,
|
RedundancyCheckboxComponent,
|
||||||
|
@ -76,7 +76,9 @@ import { ChartModule } from 'primeng/chart'
|
||||||
DebugComponent,
|
DebugComponent,
|
||||||
|
|
||||||
ConfigComponent,
|
ConfigComponent,
|
||||||
EditCustomConfigComponent
|
EditCustomConfigComponent,
|
||||||
|
|
||||||
|
BatchDomainsModalComponent
|
||||||
],
|
],
|
||||||
|
|
||||||
exports: [
|
exports: [
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
<ng-template #modal>
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 i18n class="modal-title">{{ action }}</h4>
|
||||||
|
|
||||||
|
<my-global-icon iconName="cross" aria-label="Close" role="button" (click)="hide()"></my-global-icon>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-body">
|
||||||
|
<form novalidate [formGroup]="form" (ngSubmit)="submit()">
|
||||||
|
<div class="form-group">
|
||||||
|
<label i18n for="hosts">1 host (without "http://") per line</label>
|
||||||
|
|
||||||
|
<textarea
|
||||||
|
[placeholder]="placeholder" formControlName="domains" type="text" id="hosts" name="hosts"
|
||||||
|
class="form-control" [ngClass]="{ 'input-error': formErrors['domains'] }" ngbAutofocus
|
||||||
|
></textarea>
|
||||||
|
|
||||||
|
<div *ngIf="formErrors.domains" class="form-error">
|
||||||
|
{{ formErrors.domains }}
|
||||||
|
|
||||||
|
<div *ngIf="form.controls['domains'].errors.validDomains">
|
||||||
|
{{ form.controls['domains'].errors.validDomains.value }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ng-content select="warning"></ng-content>
|
||||||
|
|
||||||
|
<div class="form-group inputs">
|
||||||
|
<input
|
||||||
|
type="button" role="button" i18n-value value="Cancel" class="action-button action-button-cancel"
|
||||||
|
(click)="hide()" (key.enter)="hide()"
|
||||||
|
>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="submit" [value]="action" class="action-button-submit"
|
||||||
|
[disabled]="!form.valid"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</ng-template>
|
|
@ -0,0 +1,3 @@
|
||||||
|
textarea {
|
||||||
|
height: 200px;
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
import { Component, OnInit, ViewChild, Input, Output, EventEmitter } from '@angular/core'
|
||||||
|
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||||
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
|
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref'
|
||||||
|
import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
|
||||||
|
import { FormReactive } from '@app/shared/forms'
|
||||||
|
import { BatchDomainsValidatorsService } from './batch-domains-validators.service'
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'my-batch-domains-modal',
|
||||||
|
templateUrl: './batch-domains-modal.component.html',
|
||||||
|
styleUrls: [ './batch-domains-modal.component.scss' ]
|
||||||
|
})
|
||||||
|
export class BatchDomainsModalComponent extends FormReactive implements OnInit {
|
||||||
|
@ViewChild('modal', { static: true }) modal: NgbModal
|
||||||
|
@Input() placeholder = 'example.com'
|
||||||
|
@Input() action: string
|
||||||
|
@Output() domains = new EventEmitter<string[]>()
|
||||||
|
|
||||||
|
private openedModal: NgbModalRef
|
||||||
|
|
||||||
|
constructor (
|
||||||
|
protected formValidatorService: FormValidatorService,
|
||||||
|
private modalService: NgbModal,
|
||||||
|
private batchDomainsValidatorsService: BatchDomainsValidatorsService,
|
||||||
|
private i18n: I18n
|
||||||
|
) {
|
||||||
|
super()
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit () {
|
||||||
|
if (!this.action) this.action = this.i18n('Process domains')
|
||||||
|
|
||||||
|
this.buildForm({
|
||||||
|
domains: this.batchDomainsValidatorsService.DOMAINS
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
openModal () {
|
||||||
|
this.openedModal = this.modalService.open(this.modal, { centered: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
hide () {
|
||||||
|
this.openedModal.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
submit () {
|
||||||
|
this.domains.emit(
|
||||||
|
this.batchDomainsValidatorsService.getNotEmptyHosts(this.form.controls['domains'].value)
|
||||||
|
)
|
||||||
|
this.form.reset()
|
||||||
|
this.hide()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||||
|
import { Validators, ValidatorFn } from '@angular/forms'
|
||||||
|
import { Injectable } from '@angular/core'
|
||||||
|
import { BuildFormValidator, validateHost } from '@app/shared'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class BatchDomainsValidatorsService {
|
||||||
|
readonly DOMAINS: BuildFormValidator
|
||||||
|
|
||||||
|
constructor (private i18n: I18n) {
|
||||||
|
this.DOMAINS = {
|
||||||
|
VALIDATORS: [ Validators.required, this.validDomains, this.isHostsUnique ],
|
||||||
|
MESSAGES: {
|
||||||
|
'required': this.i18n('Domain is required.'),
|
||||||
|
'validDomains': this.i18n('Domains entered are invalid.'),
|
||||||
|
'uniqueDomains': this.i18n('Domains entered contain duplicates.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getNotEmptyHosts (hosts: string) {
|
||||||
|
return hosts
|
||||||
|
.split('\n')
|
||||||
|
.filter((host: string) => host && host.length !== 0) // Eject empty hosts
|
||||||
|
}
|
||||||
|
|
||||||
|
private validDomains: ValidatorFn = (control) => {
|
||||||
|
if (!control.value) return null
|
||||||
|
|
||||||
|
const newHostsErrors = []
|
||||||
|
const hosts = this.getNotEmptyHosts(control.value)
|
||||||
|
|
||||||
|
for (const host of hosts) {
|
||||||
|
if (validateHost(host) === false) {
|
||||||
|
newHostsErrors.push(this.i18n('{{host}} is not valid', { host }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is not valid. */
|
||||||
|
if (newHostsErrors.length !== 0) {
|
||||||
|
return {
|
||||||
|
'validDomains': {
|
||||||
|
reason: 'invalid',
|
||||||
|
value: newHostsErrors.join('. ') + '.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is valid. */
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private isHostsUnique: ValidatorFn = (control) => {
|
||||||
|
if (!control.value) return null
|
||||||
|
|
||||||
|
const hosts = this.getNotEmptyHosts(control.value)
|
||||||
|
|
||||||
|
if (hosts.every((host: string) => hosts.indexOf(host) === hosts.lastIndexOf(host))) {
|
||||||
|
return null
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
'uniqueDomains': {
|
||||||
|
reason: 'invalid'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,7 +15,7 @@ export class FollowersListComponent extends RestTable implements OnInit {
|
||||||
followers: ActorFollow[] = []
|
followers: ActorFollow[] = []
|
||||||
totalRecords = 0
|
totalRecords = 0
|
||||||
rowsPerPage = 10
|
rowsPerPage = 10
|
||||||
sort: SortMeta = { field: 'createdAt', order: 1 }
|
sort: SortMeta = { field: 'createdAt', order: -1 }
|
||||||
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
|
|
||||||
|
|
||||||
<form (ngSubmit)="addFollowing()">
|
|
||||||
<div class="form-group">
|
|
||||||
<label i18n for="hosts">1 host (without "http://") per line</label>
|
|
||||||
|
|
||||||
<textarea
|
|
||||||
type="text" class="form-control" placeholder="example.com" id="hosts" name="hosts"
|
|
||||||
[(ngModel)]="hostsString" (ngModelChange)="onHostsChanged()" [ngClass]="{ 'input-error': hostsError }"
|
|
||||||
></textarea>
|
|
||||||
|
|
||||||
<div *ngIf="hostsError" class="form-error">
|
|
||||||
{{ hostsError }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div i18n *ngIf="httpEnabled() === false" class="alert alert-warning">
|
|
||||||
It seems that you are not on a HTTPS server. Your webserver needs to have TLS activated in order to follow servers.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input type="submit" i18n-value value="Add following" [disabled]="hostsError || !hostsString" class="btn btn-secondary">
|
|
||||||
</form>
|
|
|
@ -1,11 +0,0 @@
|
||||||
@import '_variables';
|
|
||||||
@import '_mixins';
|
|
||||||
|
|
||||||
textarea {
|
|
||||||
height: 250px;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=submit] {
|
|
||||||
@include peertube-button;
|
|
||||||
@include orange-button;
|
|
||||||
}
|
|
|
@ -1,85 +0,0 @@
|
||||||
import { Component } from '@angular/core'
|
|
||||||
import { Router } from '@angular/router'
|
|
||||||
import { Notifier } from '@app/core'
|
|
||||||
import { ConfirmService } from '../../../core'
|
|
||||||
import { validateHost } from '../../../shared'
|
|
||||||
import { FollowService } from '@app/shared/instance/follow.service'
|
|
||||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'my-following-add',
|
|
||||||
templateUrl: './following-add.component.html',
|
|
||||||
styleUrls: [ './following-add.component.scss' ]
|
|
||||||
})
|
|
||||||
export class FollowingAddComponent {
|
|
||||||
hostsString = ''
|
|
||||||
hostsError: string = null
|
|
||||||
error: string = null
|
|
||||||
|
|
||||||
constructor (
|
|
||||||
private router: Router,
|
|
||||||
private notifier: Notifier,
|
|
||||||
private confirmService: ConfirmService,
|
|
||||||
private followService: FollowService,
|
|
||||||
private i18n: I18n
|
|
||||||
) {}
|
|
||||||
|
|
||||||
httpEnabled () {
|
|
||||||
return window.location.protocol === 'https:'
|
|
||||||
}
|
|
||||||
|
|
||||||
onHostsChanged () {
|
|
||||||
this.hostsError = null
|
|
||||||
|
|
||||||
const newHostsErrors = []
|
|
||||||
const hosts = this.getNotEmptyHosts()
|
|
||||||
|
|
||||||
for (const host of hosts) {
|
|
||||||
if (validateHost(host) === false) {
|
|
||||||
newHostsErrors.push(this.i18n('{{host}} is not valid', { host }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newHostsErrors.length !== 0) {
|
|
||||||
this.hostsError = newHostsErrors.join('. ')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async addFollowing () {
|
|
||||||
this.error = ''
|
|
||||||
|
|
||||||
const hosts = this.getNotEmptyHosts()
|
|
||||||
if (hosts.length === 0) {
|
|
||||||
this.error = this.i18n('You need to specify hosts to follow.')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.isHostsUnique(hosts)) {
|
|
||||||
this.error = this.i18n('Hosts need to be unique.')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const confirmMessage = this.i18n('If you confirm, you will send a follow request to:<br /> - ') + hosts.join('<br /> - ')
|
|
||||||
const res = await this.confirmService.confirm(confirmMessage, this.i18n('Follow new server(s)'))
|
|
||||||
if (res === false) return
|
|
||||||
|
|
||||||
this.followService.follow(hosts).subscribe(
|
|
||||||
() => {
|
|
||||||
this.notifier.success(this.i18n('Follow request(s) sent!'))
|
|
||||||
|
|
||||||
setTimeout(() => this.router.navigate([ '/admin/follows/following-list' ]), 500)
|
|
||||||
},
|
|
||||||
|
|
||||||
err => this.notifier.error(err.message)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private isHostsUnique (hosts: string[]) {
|
|
||||||
return hosts.every(host => hosts.indexOf(host) === hosts.lastIndexOf(host))
|
|
||||||
}
|
|
||||||
|
|
||||||
private getNotEmptyHosts () {
|
|
||||||
return this.hostsString
|
|
||||||
.split('\n')
|
|
||||||
.filter(host => host && host.length !== 0) // Eject empty hosts
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
export * from './following-add.component'
|
|
|
@ -4,12 +4,16 @@
|
||||||
>
|
>
|
||||||
<ng-template pTemplate="caption">
|
<ng-template pTemplate="caption">
|
||||||
<div class="caption">
|
<div class="caption">
|
||||||
<div>
|
<div class="ml-auto">
|
||||||
<input
|
<input
|
||||||
type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
|
type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
|
||||||
(keyup)="onSearch($event)"
|
(keyup)="onSearch($event)"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
<a class="ml-2 follow-button" (click)="addDomainsToFollow()" (key.enter)="addDomainsToFollow()">
|
||||||
|
<my-global-icon iconName="add"></my-global-icon>
|
||||||
|
<ng-container i18n>Follow domain</ng-container>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
|
@ -42,3 +46,5 @@
|
||||||
</tr>
|
</tr>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</p-table>
|
</p-table>
|
||||||
|
|
||||||
|
<my-batch-domains-modal #batchDomainsModal i18n-action action="Follow domains" (domains)="addFollowing($event)"></my-batch-domains-modal>
|
||||||
|
|
|
@ -8,3 +8,7 @@
|
||||||
@include peertube-input-text(250px);
|
@include peertube-input-text(250px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.follow-button {
|
||||||
|
@include create-button;
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Component, OnInit } from '@angular/core'
|
import { Component, OnInit, ViewChild } from '@angular/core'
|
||||||
import { Notifier } from '@app/core'
|
import { Notifier } from '@app/core'
|
||||||
import { SortMeta } from 'primeng/api'
|
import { SortMeta } from 'primeng/api'
|
||||||
import { ActorFollow } from '../../../../../../shared/models/actors/follow.model'
|
import { ActorFollow } from '../../../../../../shared/models/actors/follow.model'
|
||||||
|
@ -6,6 +6,7 @@ import { ConfirmService } from '../../../core/confirm/confirm.service'
|
||||||
import { RestPagination, RestTable } from '../../../shared'
|
import { RestPagination, RestTable } from '../../../shared'
|
||||||
import { FollowService } from '@app/shared/instance/follow.service'
|
import { FollowService } from '@app/shared/instance/follow.service'
|
||||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||||
|
import { BatchDomainsModalComponent } from '@app/+admin/config/shared/batch-domains-modal.component'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-followers-list',
|
selector: 'my-followers-list',
|
||||||
|
@ -13,10 +14,12 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||||
styleUrls: [ './following-list.component.scss' ]
|
styleUrls: [ './following-list.component.scss' ]
|
||||||
})
|
})
|
||||||
export class FollowingListComponent extends RestTable implements OnInit {
|
export class FollowingListComponent extends RestTable implements OnInit {
|
||||||
|
@ViewChild('batchDomainsModal') batchDomainsModal: BatchDomainsModalComponent
|
||||||
|
|
||||||
following: ActorFollow[] = []
|
following: ActorFollow[] = []
|
||||||
totalRecords = 0
|
totalRecords = 0
|
||||||
rowsPerPage = 10
|
rowsPerPage = 10
|
||||||
sort: SortMeta = { field: 'createdAt', order: 1 }
|
sort: SortMeta = { field: 'createdAt', order: -1 }
|
||||||
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
|
@ -36,6 +39,21 @@ export class FollowingListComponent extends RestTable implements OnInit {
|
||||||
return 'FollowingListComponent'
|
return 'FollowingListComponent'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addDomainsToFollow () {
|
||||||
|
this.batchDomainsModal.openModal()
|
||||||
|
}
|
||||||
|
|
||||||
|
async addFollowing (hosts: string[]) {
|
||||||
|
this.followService.follow(hosts).subscribe(
|
||||||
|
() => {
|
||||||
|
this.notifier.success(this.i18n('Follow request(s) sent!'))
|
||||||
|
this.loadData()
|
||||||
|
},
|
||||||
|
|
||||||
|
err => this.notifier.error(err.message)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
async removeFollowing (follow: ActorFollow) {
|
async removeFollowing (follow: ActorFollow) {
|
||||||
const res = await this.confirmService.confirm(
|
const res = await this.confirmService.confirm(
|
||||||
this.i18n('Do you really want to unfollow {{host}}?', { host: follow.following.host }),
|
this.i18n('Do you really want to unfollow {{host}}?', { host: follow.following.host }),
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
<div class="admin-sub-nav">
|
<div class="admin-sub-nav">
|
||||||
<a i18n routerLink="following-list" routerLinkActive="active">Following</a>
|
<a i18n routerLink="following-list" routerLinkActive="active">Following</a>
|
||||||
|
|
||||||
<a i18n routerLink="following-add" routerLinkActive="active">Follow</a>
|
|
||||||
|
|
||||||
<a i18n routerLink="followers-list" routerLinkActive="active">Followers</a>
|
<a i18n routerLink="followers-list" routerLinkActive="active">Followers</a>
|
||||||
|
|
||||||
<a i18n routerLink="video-redundancies-list" routerLinkActive="active">Video redundancies</a>
|
<a i18n routerLink="video-redundancies-list" routerLinkActive="active">Video redundancies</a>
|
||||||
|
|
|
@ -2,7 +2,6 @@ import { Routes } from '@angular/router'
|
||||||
|
|
||||||
import { UserRightGuard } from '../../core'
|
import { UserRightGuard } from '../../core'
|
||||||
import { FollowsComponent } from './follows.component'
|
import { FollowsComponent } from './follows.component'
|
||||||
import { FollowingAddComponent } from './following-add'
|
|
||||||
import { FollowersListComponent } from './followers-list'
|
import { FollowersListComponent } from './followers-list'
|
||||||
import { UserRight } from '../../../../../shared'
|
import { UserRight } from '../../../../../shared'
|
||||||
import { FollowingListComponent } from './following-list/following-list.component'
|
import { FollowingListComponent } from './following-list/following-list.component'
|
||||||
|
@ -42,12 +41,7 @@ export const FollowsRoutes: Routes = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'following-add',
|
path: 'following-add',
|
||||||
component: FollowingAddComponent,
|
redirectTo: 'following-list'
|
||||||
data: {
|
|
||||||
meta: {
|
|
||||||
title: 'Add follow'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'video-redundancies-list',
|
path: 'video-redundancies-list',
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
export * from './following-add'
|
|
||||||
export * from './followers-list'
|
export * from './followers-list'
|
||||||
export * from './following-list'
|
export * from './following-list'
|
||||||
export * from './video-redundancies-list'
|
export * from './video-redundancies-list'
|
||||||
|
|
|
@ -4,6 +4,14 @@
|
||||||
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
|
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
|
||||||
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} muted instances"
|
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} muted instances"
|
||||||
>
|
>
|
||||||
|
<ng-template pTemplate="caption">
|
||||||
|
<div class="caption">
|
||||||
|
<a class="ml-auto block-button" (click)="addServersToBlock()" (key.enter)="addServersToBlock()">
|
||||||
|
<my-global-icon iconName="add"></my-global-icon>
|
||||||
|
<ng-container i18n>Mute domain</ng-container>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
<ng-template pTemplate="header">
|
<ng-template pTemplate="header">
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -23,3 +31,11 @@
|
||||||
</tr>
|
</tr>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</p-table>
|
</p-table>
|
||||||
|
|
||||||
|
<my-batch-domains-modal #batchDomainsModal i18n-action action="Mute domains" (domains)="onDomainsToBlock($event)">
|
||||||
|
<ng-container ngProjectAs="warning">
|
||||||
|
<div i18n *ngIf="httpEnabled() === false" class="alert alert-warning">
|
||||||
|
It seems that you are not on a HTTPS server. Your webserver needs to have TLS activated in order to follow servers.
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
</my-batch-domains-modal>
|
||||||
|
|
|
@ -5,3 +5,7 @@
|
||||||
@include peertube-button;
|
@include peertube-button;
|
||||||
@include grey-button;
|
@include grey-button;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.block-button {
|
||||||
|
@include create-button;
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { Component, OnInit } from '@angular/core'
|
import { Component, OnInit, ViewChild } from '@angular/core'
|
||||||
import { Notifier } from '@app/core'
|
import { Notifier } from '@app/core'
|
||||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||||
import { RestPagination, RestTable } from '@app/shared'
|
import { RestPagination, RestTable } from '@app/shared'
|
||||||
import { SortMeta } from 'primeng/api'
|
import { SortMeta } from 'primeng/api'
|
||||||
import { BlocklistService } from '@app/shared/blocklist'
|
import { BlocklistService } from '@app/shared/blocklist'
|
||||||
import { ServerBlock } from '../../../../../../shared'
|
import { ServerBlock } from '../../../../../../shared'
|
||||||
|
import { BatchDomainsModalComponent } from '@app/+admin/config/shared/batch-domains-modal.component'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-instance-server-blocklist',
|
selector: 'my-instance-server-blocklist',
|
||||||
|
@ -12,6 +13,8 @@ import { ServerBlock } from '../../../../../../shared'
|
||||||
templateUrl: './instance-server-blocklist.component.html'
|
templateUrl: './instance-server-blocklist.component.html'
|
||||||
})
|
})
|
||||||
export class InstanceServerBlocklistComponent extends RestTable implements OnInit {
|
export class InstanceServerBlocklistComponent extends RestTable implements OnInit {
|
||||||
|
@ViewChild('batchDomainsModal') batchDomainsModal: BatchDomainsModalComponent
|
||||||
|
|
||||||
blockedServers: ServerBlock[] = []
|
blockedServers: ServerBlock[] = []
|
||||||
totalRecords = 0
|
totalRecords = 0
|
||||||
rowsPerPage = 10
|
rowsPerPage = 10
|
||||||
|
@ -47,6 +50,27 @@ export class InstanceServerBlocklistComponent extends RestTable implements OnIni
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
httpEnabled () {
|
||||||
|
return window.location.protocol === 'https:'
|
||||||
|
}
|
||||||
|
|
||||||
|
addServersToBlock () {
|
||||||
|
this.batchDomainsModal.openModal()
|
||||||
|
}
|
||||||
|
|
||||||
|
onDomainsToBlock (domains: string[]) {
|
||||||
|
domains.forEach(domain => {
|
||||||
|
this.blocklistService.blockServerByInstance(domain)
|
||||||
|
.subscribe(
|
||||||
|
() => {
|
||||||
|
this.notifier.success(this.i18n('Instance {{domain}} muted by your instance.', { domain }))
|
||||||
|
|
||||||
|
this.loadData()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
protected loadData () {
|
protected loadData () {
|
||||||
return this.blocklistService.getInstanceServerBlocklist(this.pagination, this.sort)
|
return this.blocklistService.getInstanceServerBlocklist(this.pagination, this.sort)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
|
|
|
@ -48,13 +48,13 @@
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td class="c-hand" [pRowToggler]="videoAbuse">
|
||||||
<span *ngIf="isVideoAbuseAccepted(videoAbuse)" [title]="videoAbuse.state.label" class="glyphicon glyphicon-ok"></span>
|
<span *ngIf="isVideoAbuseAccepted(videoAbuse)" [title]="videoAbuse.state.label" class="glyphicon glyphicon-ok"></span>
|
||||||
<span *ngIf="isVideoAbuseRejected(videoAbuse)" [title]="videoAbuse.state.label" class="glyphicon glyphicon-remove"></span>
|
<span *ngIf="isVideoAbuseRejected(videoAbuse)" [title]="videoAbuse.state.label" class="glyphicon glyphicon-remove"></span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="action-cell">
|
<td class="action-cell">
|
||||||
<my-action-dropdown placement="bottom-right" i18n-label label="Actions" [actions]="videoAbuseActions" [entry]="videoAbuse"></my-action-dropdown>
|
<my-action-dropdown placement="bottom-right auto" i18n-label label="Actions" [actions]="videoAbuseActions" [entry]="videoAbuse"></my-action-dropdown>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { Component, OnInit, ViewChild } from '@angular/core'
|
import { Component, OnInit, ViewChild } from '@angular/core'
|
||||||
import { Account } from '../../../shared/account/account.model'
|
import { Account } from '@app/shared/account/account.model'
|
||||||
import { Notifier } from '@app/core'
|
import { Notifier } from '@app/core'
|
||||||
import { SortMeta } from 'primeng/api'
|
import { SortMeta } from 'primeng/api'
|
||||||
import { VideoAbuse, VideoAbuseState } from '../../../../../../shared'
|
import { VideoAbuse, VideoAbuseState } from '../../../../../../shared'
|
||||||
import { RestPagination, RestTable, VideoAbuseService } from '../../../shared'
|
import { RestPagination, RestTable, VideoAbuseService, VideoBlacklistService } from '../../../shared'
|
||||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||||
import { DropdownAction } from '../../../shared/buttons/action-dropdown.component'
|
import { DropdownAction } from '../../../shared/buttons/action-dropdown.component'
|
||||||
import { ConfirmService } from '../../../core/index'
|
import { ConfirmService } from '../../../core/index'
|
||||||
|
@ -14,6 +14,7 @@ import { Actor } from '@app/shared/actor/actor.model'
|
||||||
import { buildVideoLink, buildVideoEmbed } from 'src/assets/player/utils'
|
import { buildVideoLink, buildVideoEmbed } from 'src/assets/player/utils'
|
||||||
import { getAbsoluteAPIUrl } from '@app/shared/misc/utils'
|
import { getAbsoluteAPIUrl } from '@app/shared/misc/utils'
|
||||||
import { DomSanitizer } from '@angular/platform-browser'
|
import { DomSanitizer } from '@angular/platform-browser'
|
||||||
|
import { BlocklistService } from '@app/shared/blocklist'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-video-abuse-list',
|
selector: 'my-video-abuse-list',
|
||||||
|
@ -29,11 +30,13 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
|
||||||
sort: SortMeta = { field: 'createdAt', order: 1 }
|
sort: SortMeta = { field: 'createdAt', order: 1 }
|
||||||
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
||||||
|
|
||||||
videoAbuseActions: DropdownAction<VideoAbuse>[] = []
|
videoAbuseActions: DropdownAction<VideoAbuse>[][] = []
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private notifier: Notifier,
|
private notifier: Notifier,
|
||||||
private videoAbuseService: VideoAbuseService,
|
private videoAbuseService: VideoAbuseService,
|
||||||
|
private blocklistService: BlocklistService,
|
||||||
|
private videoBlacklistService: VideoBlacklistService,
|
||||||
private confirmService: ConfirmService,
|
private confirmService: ConfirmService,
|
||||||
private i18n: I18n,
|
private i18n: I18n,
|
||||||
private markdownRenderer: MarkdownService,
|
private markdownRenderer: MarkdownService,
|
||||||
|
@ -42,30 +45,57 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
|
||||||
super()
|
super()
|
||||||
|
|
||||||
this.videoAbuseActions = [
|
this.videoAbuseActions = [
|
||||||
{
|
[
|
||||||
label: this.i18n('Delete this report'),
|
{
|
||||||
handler: videoAbuse => this.removeVideoAbuse(videoAbuse)
|
label: this.i18n('Internal actions'),
|
||||||
},
|
isHeader: true
|
||||||
{
|
},
|
||||||
label: this.i18n('Add note'),
|
{
|
||||||
handler: videoAbuse => this.openModerationCommentModal(videoAbuse),
|
label: this.i18n('Delete report'),
|
||||||
isDisplayed: videoAbuse => !videoAbuse.moderationComment
|
handler: videoAbuse => this.removeVideoAbuse(videoAbuse)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: this.i18n('Update note'),
|
label: this.i18n('Add note'),
|
||||||
handler: videoAbuse => this.openModerationCommentModal(videoAbuse),
|
handler: videoAbuse => this.openModerationCommentModal(videoAbuse),
|
||||||
isDisplayed: videoAbuse => !!videoAbuse.moderationComment
|
isDisplayed: videoAbuse => !videoAbuse.moderationComment
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: this.i18n('Mark as accepted'),
|
label: this.i18n('Update note'),
|
||||||
handler: videoAbuse => this.updateVideoAbuseState(videoAbuse, VideoAbuseState.ACCEPTED),
|
handler: videoAbuse => this.openModerationCommentModal(videoAbuse),
|
||||||
isDisplayed: videoAbuse => !this.isVideoAbuseAccepted(videoAbuse)
|
isDisplayed: videoAbuse => !!videoAbuse.moderationComment
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: this.i18n('Mark as rejected'),
|
label: this.i18n('Mark as accepted'),
|
||||||
handler: videoAbuse => this.updateVideoAbuseState(videoAbuse, VideoAbuseState.REJECTED),
|
handler: videoAbuse => this.updateVideoAbuseState(videoAbuse, VideoAbuseState.ACCEPTED),
|
||||||
isDisplayed: videoAbuse => !this.isVideoAbuseRejected(videoAbuse)
|
isDisplayed: videoAbuse => !this.isVideoAbuseAccepted(videoAbuse)
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
label: this.i18n('Mark as rejected'),
|
||||||
|
handler: videoAbuse => this.updateVideoAbuseState(videoAbuse, VideoAbuseState.REJECTED),
|
||||||
|
isDisplayed: videoAbuse => !this.isVideoAbuseRejected(videoAbuse)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
label: this.i18n('Actions for the video'),
|
||||||
|
isHeader: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.i18n('Blacklist video'),
|
||||||
|
handler: videoAbuse => {
|
||||||
|
this.videoBlacklistService.blacklistVideo(videoAbuse.video.id, undefined, true)
|
||||||
|
.subscribe(
|
||||||
|
() => {
|
||||||
|
this.notifier.success(this.i18n('Video blacklisted.'))
|
||||||
|
|
||||||
|
this.updateVideoAbuseState(videoAbuse, VideoAbuseState.ACCEPTED)
|
||||||
|
},
|
||||||
|
|
||||||
|
err => this.notifier.error(err.message)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
|
||||||
blacklist: (VideoBlacklist & { reasonHtml?: string })[] = []
|
blacklist: (VideoBlacklist & { reasonHtml?: string })[] = []
|
||||||
totalRecords = 0
|
totalRecords = 0
|
||||||
rowsPerPage = 10
|
rowsPerPage = 10
|
||||||
sort: SortMeta = { field: 'createdAt', order: 1 }
|
sort: SortMeta = { field: 'createdAt', order: -1 }
|
||||||
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
||||||
listBlacklistTypeFilter: VideoBlacklistType = undefined
|
listBlacklistTypeFilter: VideoBlacklistType = undefined
|
||||||
|
|
||||||
|
|
|
@ -24,17 +24,27 @@
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<a *ngIf="action.linkBuilder" [ngClass]="{ 'with-icon': !!action.iconName }" class="dropdown-item" [routerLink]="action.linkBuilder(entry)" [title]="action.title || ''">
|
<a
|
||||||
|
*ngIf="action.linkBuilder && !action.isHeader" [ngClass]="{ 'with-icon': !!action.iconName }"
|
||||||
|
class="dropdown-item" [routerLink]="action.linkBuilder(entry)" [title]="action.title || ''"
|
||||||
|
>
|
||||||
<ng-container *ngTemplateOutlet="templateActionLabel; context:{ $implicit: action }"></ng-container>
|
<ng-container *ngTemplateOutlet="templateActionLabel; context:{ $implicit: action }"></ng-container>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<span
|
<span
|
||||||
*ngIf="!action.linkBuilder" [ngClass]="{ 'with-icon': !!action.iconName }" (click)="action.handler(entry)"
|
*ngIf="!action.linkBuilder && !action.isHeader" [ngClass]="{ 'with-icon': !!action.iconName }"
|
||||||
class="custom-action dropdown-item" role="button" [title]="action.title || ''"
|
class="custom-action dropdown-item" role="button" [title]="action.title || ''" (click)="action.handler(entry)"
|
||||||
>
|
>
|
||||||
<ng-container *ngTemplateOutlet="templateActionLabel; context:{ $implicit: action }"></ng-container>
|
<ng-container *ngTemplateOutlet="templateActionLabel; context:{ $implicit: action }"></ng-container>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
<h6
|
||||||
|
*ngIf="!action.linkBuilder && action.isHeader" [ngClass]="{ 'with-icon': !!action.iconName }"
|
||||||
|
class="dropdown-header" role="button" [title]="action.title || ''" (click)="action.handler(entry)"
|
||||||
|
>
|
||||||
|
<ng-container *ngTemplateOutlet="templateActionLabel; context:{ $implicit: action }"></ng-container>
|
||||||
|
</h6>
|
||||||
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-menu {
|
.dropdown-menu {
|
||||||
|
.dropdown-header {
|
||||||
|
padding: 0.2rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
.dropdown-item {
|
.dropdown-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
|
@ -9,6 +9,7 @@ export type DropdownAction<T> = {
|
||||||
handler?: (a: T) => any
|
handler?: (a: T) => any
|
||||||
linkBuilder?: (a: T) => (string | number)[]
|
linkBuilder?: (a: T) => (string | number)[]
|
||||||
isDisplayed?: (a: T) => boolean
|
isDisplayed?: (a: T) => boolean
|
||||||
|
isHeader?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DropdownButtonSize = 'normal' | 'small'
|
export type DropdownButtonSize = 'normal' | 'small'
|
||||||
|
|
|
@ -107,6 +107,7 @@ import { InputSwitchModule } from 'primeng/inputswitch'
|
||||||
import { MyAccountVideoSettingsComponent } from '@app/+my-account/my-account-settings/my-account-video-settings'
|
import { MyAccountVideoSettingsComponent } from '@app/+my-account/my-account-settings/my-account-video-settings'
|
||||||
import { MyAccountInterfaceSettingsComponent } from '@app/+my-account/my-account-settings/my-account-interface'
|
import { MyAccountInterfaceSettingsComponent } from '@app/+my-account/my-account-settings/my-account-interface'
|
||||||
import { ActorAvatarInfoComponent } from '@app/+my-account/shared/actor-avatar-info.component'
|
import { ActorAvatarInfoComponent } from '@app/+my-account/shared/actor-avatar-info.component'
|
||||||
|
import { BatchDomainsValidatorsService } from '@app/+admin/config/shared/batch-domains-validators.service'
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
|
@ -297,6 +298,7 @@ import { ActorAvatarInfoComponent } from '@app/+my-account/shared/actor-avatar-i
|
||||||
LoginValidatorsService,
|
LoginValidatorsService,
|
||||||
ResetPasswordValidatorsService,
|
ResetPasswordValidatorsService,
|
||||||
UserValidatorsService,
|
UserValidatorsService,
|
||||||
|
BatchDomainsValidatorsService,
|
||||||
VideoPlaylistValidatorsService,
|
VideoPlaylistValidatorsService,
|
||||||
VideoAbuseValidatorsService,
|
VideoAbuseValidatorsService,
|
||||||
VideoChannelValidatorsService,
|
VideoChannelValidatorsService,
|
||||||
|
|
|
@ -11,7 +11,6 @@ import { VideoCommentService } from './video-comment.service'
|
||||||
import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
|
import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
|
||||||
import { VideoCommentValidatorsService } from '@app/shared/forms/form-validators/video-comment-validators.service'
|
import { VideoCommentValidatorsService } from '@app/shared/forms/form-validators/video-comment-validators.service'
|
||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { AuthService } from '@app/core/auth'
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-video-comment-add',
|
selector: 'my-video-comment-add',
|
||||||
|
@ -38,7 +37,6 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit {
|
||||||
private videoCommentValidatorsService: VideoCommentValidatorsService,
|
private videoCommentValidatorsService: VideoCommentValidatorsService,
|
||||||
private notifier: Notifier,
|
private notifier: Notifier,
|
||||||
private videoCommentService: VideoCommentService,
|
private videoCommentService: VideoCommentService,
|
||||||
private authService: AuthService,
|
|
||||||
private modalService: NgbModal,
|
private modalService: NgbModal,
|
||||||
private router: Router
|
private router: Router
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -84,11 +84,9 @@ const blockServerValidator = [
|
||||||
.end()
|
.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
const server = await ServerModel.loadByHost(host)
|
let server = await ServerModel.loadByHost(host)
|
||||||
if (!server) {
|
if (!server) {
|
||||||
return res.status(404)
|
server = await ServerModel.create({ host })
|
||||||
.send({ error: 'Server host not found.' })
|
|
||||||
.end()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res.locals.server = server
|
res.locals.server = server
|
||||||
|
|
|
@ -175,13 +175,13 @@ describe('Test blocklist API validators', function () {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should fail with an unknown server', async function () {
|
it('Should succeed with an unknown server', async function () {
|
||||||
await makePostBodyRequest({
|
await makePostBodyRequest({
|
||||||
url: server.url,
|
url: server.url,
|
||||||
token: server.accessToken,
|
token: server.accessToken,
|
||||||
path,
|
path,
|
||||||
fields: { host: 'localhost:9003' },
|
fields: { host: 'localhost:9003' },
|
||||||
statusCodeExpected: 404
|
statusCodeExpected: 204
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ describe('Test blocklist API validators', function () {
|
||||||
it('Should fail with an unknown server block', async function () {
|
it('Should fail with an unknown server block', async function () {
|
||||||
await makeDeleteRequest({
|
await makeDeleteRequest({
|
||||||
url: server.url,
|
url: server.url,
|
||||||
path: path + '/localhost:9003',
|
path: path + '/localhost:9004',
|
||||||
token: server.accessToken,
|
token: server.accessToken,
|
||||||
statusCodeExpected: 404
|
statusCodeExpected: 404
|
||||||
})
|
})
|
||||||
|
@ -415,13 +415,13 @@ describe('Test blocklist API validators', function () {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should fail with an unknown server', async function () {
|
it('Should succeed with an unknown server', async function () {
|
||||||
await makePostBodyRequest({
|
await makePostBodyRequest({
|
||||||
url: server.url,
|
url: server.url,
|
||||||
token: server.accessToken,
|
token: server.accessToken,
|
||||||
path,
|
path,
|
||||||
fields: { host: 'localhost:9003' },
|
fields: { host: 'localhost:9003' },
|
||||||
statusCodeExpected: 404
|
statusCodeExpected: 204
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -467,7 +467,7 @@ describe('Test blocklist API validators', function () {
|
||||||
it('Should fail with an unknown server block', async function () {
|
it('Should fail with an unknown server block', async function () {
|
||||||
await makeDeleteRequest({
|
await makeDeleteRequest({
|
||||||
url: server.url,
|
url: server.url,
|
||||||
path: path + '/localhost:9003',
|
path: path + '/localhost:9004',
|
||||||
token: server.accessToken,
|
token: server.accessToken,
|
||||||
statusCodeExpected: 404
|
statusCodeExpected: 404
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue