parent
37cb07eae2
commit
43df00a30d
|
@ -1,112 +0,0 @@
|
|||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
<a routerLink="/my-library/video-channels" i18n>My Channels</a>
|
||||
</li>
|
||||
|
||||
<ng-container *ngIf="isCreation()">
|
||||
<li class="breadcrumb-item active" i18n>Create</li>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!isCreation()">
|
||||
<li class="breadcrumb-item active" i18n>Edit</li>
|
||||
<li class="breadcrumb-item active" aria-current="page">
|
||||
<a *ngIf="videoChannel" [routerLink]="[ '/my-library/video-channels/update', videoChannel?.nameWithHost ]">{{ videoChannel?.displayName }}</a>
|
||||
</li>
|
||||
</ng-container>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
|
||||
|
||||
<form role="form" (ngSubmit)="formValidated()" [formGroup]="form">
|
||||
|
||||
<div class="form-row"> <!-- channel grid -->
|
||||
<div class="form-group col-12 col-lg-4 col-xl-3">
|
||||
<div *ngIf="isCreation()" class="video-channel-title" i18n>NEW CHANNEL</div>
|
||||
<div *ngIf="!isCreation() && videoChannel" class="video-channel-title" i18n>CHANNEL</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-12 col-lg-8 col-xl-9">
|
||||
<h6 i18n>Banner image of your channel</h6>
|
||||
|
||||
<my-actor-banner-edit
|
||||
*ngIf="videoChannel" [previewImage]="isCreation()"
|
||||
[actor]="videoChannel" (bannerChange)="onBannerChange($event)" (bannerDelete)="onBannerDelete()"
|
||||
></my-actor-banner-edit>
|
||||
|
||||
<my-actor-avatar-edit
|
||||
*ngIf="videoChannel" [previewImage]="isCreation()"
|
||||
[actor]="videoChannel" (avatarChange)="onAvatarChange($event)" (avatarDelete)="onAvatarDelete()"
|
||||
[displayUsername]="!isCreation()" [displaySubscribers]="!isCreation()"
|
||||
></my-actor-avatar-edit>
|
||||
|
||||
<div class="form-group" *ngIf="isCreation()">
|
||||
<label i18n for="name">Name</label>
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="text" id="name" i18n-placeholder placeholder="Example: my_channel"
|
||||
formControlName="name" [ngClass]="{ 'input-error': formErrors['name'] }" class="form-control"
|
||||
>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">@{{ instanceHost }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="formErrors['name']" class="form-error">
|
||||
{{ formErrors['name'] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label i18n for="display-name">Display name</label>
|
||||
<input
|
||||
type="text" id="display-name" class="form-control"
|
||||
formControlName="display-name" [ngClass]="{ 'input-error': formErrors['display-name'] }"
|
||||
>
|
||||
<div *ngIf="formErrors['display-name']" class="form-error">
|
||||
{{ formErrors['display-name'] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label i18n for="description">Description</label>
|
||||
<textarea
|
||||
id="description" formControlName="description" class="form-control"
|
||||
[ngClass]="{ 'input-error': formErrors['description'] }"
|
||||
></textarea>
|
||||
<div *ngIf="formErrors.description" class="form-error">
|
||||
{{ formErrors.description }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="support">Support</label>
|
||||
<my-help
|
||||
helpType="markdownEnhanced" i18n-preHtml preHtml="Short text to tell people how they can support your channel (membership platform...).<br /><br />
|
||||
When you will upload a video in this channel, the video support field will be automatically filled by this text."
|
||||
></my-help>
|
||||
<my-markdown-textarea
|
||||
id="support" formControlName="support" textareaMaxWidth="500px" markdownType="enhanced"
|
||||
[classes]="{ 'input-error': formErrors['support'] }"
|
||||
></my-markdown-textarea>
|
||||
<div *ngIf="formErrors.support" class="form-error">
|
||||
{{ formErrors.support }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" *ngIf="isBulkUpdateVideosDisplayed()">
|
||||
<my-peertube-checkbox
|
||||
inputName="bulkVideosSupportUpdate" formControlName="bulkVideosSupportUpdate"
|
||||
i18n-labelText labelText="Overwrite support field of all videos of this channel"
|
||||
></my-peertube-checkbox>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row"> <!-- submit placement block -->
|
||||
<div class="col-md-7 col-xl-5"></div>
|
||||
<div class="col-md-5 col-xl-5 d-inline-flex">
|
||||
<input type="submit" value="{{ getFormButtonTitle() }}" [disabled]="!form.valid">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
|
@ -1,7 +1,5 @@
|
|||
import { NgModule } from '@angular/core'
|
||||
import { RouterModule, Routes } from '@angular/router'
|
||||
import { MyVideoChannelUpdateComponent } from './my-video-channel-update.component'
|
||||
import { MyVideoChannelCreateComponent } from './my-video-channel-create.component'
|
||||
import { MyVideoChannelsComponent } from './my-video-channels.component'
|
||||
|
||||
const myVideoChannelsRoutes: Routes = [
|
||||
|
@ -13,24 +11,6 @@ const myVideoChannelsRoutes: Routes = [
|
|||
title: $localize`My video channels`
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
component: MyVideoChannelCreateComponent,
|
||||
data: {
|
||||
meta: {
|
||||
title: $localize`Create a new video channel`
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'update/:videoChannelId',
|
||||
component: MyVideoChannelUpdateComponent,
|
||||
data: {
|
||||
meta: {
|
||||
title: $localize`Update video channel`
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<div class="video-channels-header d-flex justify-content-between">
|
||||
<my-advanced-input-filter (search)="onSearch($event)"></my-advanced-input-filter>
|
||||
|
||||
<a class="create-button" routerLink="create">
|
||||
<a class="create-button" routerLink="/c/@create">
|
||||
<my-global-icon iconName="add" aria-hidden="true"></my-global-icon>
|
||||
<ng-container i18n>Create video channel</ng-container>
|
||||
</a>
|
||||
|
@ -37,7 +37,7 @@
|
|||
<div i18n class="video-channel-videos">{videoChannel.videosCount, plural, =0 {No videos} =1 {1 video} other {{{ videoChannel.videosCount }} videos}}</div>
|
||||
|
||||
<div class="video-channel-buttons">
|
||||
<my-edit-button label [routerLink]="[ 'update', videoChannel.nameWithHost ]"></my-edit-button>
|
||||
<my-edit-button label [routerLink]="[ '/c', videoChannel.nameWithHost, 'update' ]"></my-edit-button>
|
||||
<my-delete-button label (click)="deleteVideoChannel(videoChannel)"></my-delete-button>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
import { ChartModule } from 'primeng/chart'
|
||||
import { NgModule } from '@angular/core'
|
||||
import { SharedActorImageEditModule } from '@app/shared/shared-actor-image-edit'
|
||||
import { SharedFormModule } from '@app/shared/shared-forms'
|
||||
import { SharedGlobalIconModule } from '@app/shared/shared-icons'
|
||||
import { SharedMainModule } from '@app/shared/shared-main'
|
||||
import { MyVideoChannelCreateComponent } from './my-video-channel-create.component'
|
||||
import { MyVideoChannelUpdateComponent } from './my-video-channel-update.component'
|
||||
import { MyVideoChannelsRoutingModule } from './my-video-channels-routing.module'
|
||||
import { MyVideoChannelsComponent } from './my-video-channels.component'
|
||||
import { SharedActorImageModule } from '@app/shared/shared-actor-image/shared-actor-image.module'
|
||||
|
@ -19,14 +16,11 @@ import { SharedActorImageModule } from '@app/shared/shared-actor-image/shared-ac
|
|||
SharedMainModule,
|
||||
SharedFormModule,
|
||||
SharedGlobalIconModule,
|
||||
SharedActorImageEditModule,
|
||||
SharedActorImageModule
|
||||
],
|
||||
|
||||
declarations: [
|
||||
MyVideoChannelsComponent,
|
||||
MyVideoChannelCreateComponent,
|
||||
MyVideoChannelUpdateComponent
|
||||
MyVideoChannelsComponent
|
||||
],
|
||||
|
||||
exports: [],
|
||||
|
|
|
@ -12,11 +12,11 @@ import {
|
|||
import { FormValidatorService } from '@app/shared/shared-forms'
|
||||
import { VideoChannel, VideoChannelService } from '@app/shared/shared-main'
|
||||
import { HttpStatusCode, VideoChannelCreate } from '@shared/models'
|
||||
import { MyVideoChannelEdit } from './my-video-channel-edit'
|
||||
import { MyVideoChannelEdit } from './video-channel-edit'
|
||||
|
||||
@Component({
|
||||
templateUrl: './my-video-channel-edit.component.html',
|
||||
styleUrls: [ './my-video-channel-edit.component.scss' ]
|
||||
templateUrl: './video-channel-edit.component.html',
|
||||
styleUrls: [ './video-channel-edit.component.scss' ]
|
||||
})
|
||||
export class MyVideoChannelCreateComponent extends MyVideoChannelEdit implements OnInit {
|
||||
error: string
|
|
@ -0,0 +1,96 @@
|
|||
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
|
||||
|
||||
<div class="margin-content">
|
||||
<form role="form" (ngSubmit)="formValidated()" [formGroup]="form">
|
||||
|
||||
<div class="form-row"> <!-- channel grid -->
|
||||
<div class="form-group col-12 col-lg-4 col-xl-3">
|
||||
<div *ngIf="isCreation()" class="video-channel-title" i18n>NEW CHANNEL</div>
|
||||
<div *ngIf="!isCreation() && videoChannel" class="video-channel-title" i18n>CHANNEL</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-12 col-lg-8 col-xl-9">
|
||||
<h6 i18n>Banner image of the channel</h6>
|
||||
|
||||
<my-actor-banner-edit
|
||||
*ngIf="videoChannel" [previewImage]="isCreation()"
|
||||
[actor]="videoChannel" (bannerChange)="onBannerChange($event)" (bannerDelete)="onBannerDelete()"
|
||||
></my-actor-banner-edit>
|
||||
|
||||
<my-actor-avatar-edit
|
||||
*ngIf="videoChannel" [previewImage]="isCreation()"
|
||||
[actor]="videoChannel" (avatarChange)="onAvatarChange($event)" (avatarDelete)="onAvatarDelete()"
|
||||
[displayUsername]="!isCreation()" [displaySubscribers]="!isCreation()"
|
||||
></my-actor-avatar-edit>
|
||||
|
||||
<div class="form-group" *ngIf="isCreation()">
|
||||
<label i18n for="name">Name</label>
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="text" id="name" i18n-placeholder placeholder="Example: my_channel"
|
||||
formControlName="name" [ngClass]="{ 'input-error': formErrors['name'] }" class="form-control"
|
||||
>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">@{{ instanceHost }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="formErrors['name']" class="form-error">
|
||||
{{ formErrors['name'] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label i18n for="display-name">Display name</label>
|
||||
<input
|
||||
type="text" id="display-name" class="form-control"
|
||||
formControlName="display-name" [ngClass]="{ 'input-error': formErrors['display-name'] }"
|
||||
>
|
||||
<div *ngIf="formErrors['display-name']" class="form-error">
|
||||
{{ formErrors['display-name'] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label i18n for="description">Description</label>
|
||||
<textarea
|
||||
id="description" formControlName="description" class="form-control"
|
||||
[ngClass]="{ 'input-error': formErrors['description'] }"
|
||||
></textarea>
|
||||
<div *ngIf="formErrors.description" class="form-error">
|
||||
{{ formErrors.description }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="support">Support</label>
|
||||
<my-help
|
||||
helpType="markdownEnhanced" i18n-preHtml preHtml="Short text to tell people how they can support the channel (membership platform...).<br /><br />
|
||||
When a video is uploaded in this channel, the video support field will be automatically filled by this text."
|
||||
></my-help>
|
||||
<my-markdown-textarea
|
||||
id="support" formControlName="support" textareaMaxWidth="500px" markdownType="enhanced"
|
||||
[classes]="{ 'input-error': formErrors['support'] }"
|
||||
></my-markdown-textarea>
|
||||
<div *ngIf="formErrors.support" class="form-error">
|
||||
{{ formErrors.support }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" *ngIf="isBulkUpdateVideosDisplayed()">
|
||||
<my-peertube-checkbox
|
||||
inputName="bulkVideosSupportUpdate" formControlName="bulkVideosSupportUpdate"
|
||||
i18n-labelText labelText="Overwrite support field of all videos of this channel"
|
||||
></my-peertube-checkbox>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row"> <!-- submit placement block -->
|
||||
<div class="col-md-7 col-xl-5"></div>
|
||||
<div class="col-md-5 col-xl-5 d-inline-flex">
|
||||
<input type="submit" value="{{ getFormButtonTitle() }}" [disabled]="!form.valid">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
|
@ -1,6 +1,10 @@
|
|||
@use '_variables' as *;
|
||||
@use '_mixins' as *;
|
||||
|
||||
.margin-content {
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: $font-regular;
|
||||
font-size: 100%;
|
|
@ -12,14 +12,14 @@ import {
|
|||
import { FormValidatorService } from '@app/shared/shared-forms'
|
||||
import { VideoChannel, VideoChannelService } from '@app/shared/shared-main'
|
||||
import { HTMLServerConfig, VideoChannelUpdate } from '@shared/models'
|
||||
import { MyVideoChannelEdit } from './my-video-channel-edit'
|
||||
import { MyVideoChannelEdit } from './video-channel-edit'
|
||||
|
||||
@Component({
|
||||
selector: 'my-video-channel-update',
|
||||
templateUrl: './my-video-channel-edit.component.html',
|
||||
styleUrls: [ './my-video-channel-edit.component.scss' ]
|
||||
templateUrl: './video-channel-edit.component.html',
|
||||
styleUrls: [ './video-channel-edit.component.scss' ]
|
||||
})
|
||||
export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements OnInit, OnDestroy {
|
||||
export class VideoChannelUpdateComponent extends MyVideoChannelEdit implements OnInit, OnDestroy {
|
||||
error: string
|
||||
videoChannel: VideoChannel
|
||||
|
||||
|
@ -50,9 +50,9 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements
|
|||
})
|
||||
|
||||
this.paramsSub = this.route.params.subscribe(routeParams => {
|
||||
const videoChannelId = routeParams['videoChannelId']
|
||||
const videoChannelName = routeParams['videoChannelName']
|
||||
|
||||
this.videoChannelService.getVideoChannel(videoChannelId)
|
||||
this.videoChannelService.getVideoChannel(videoChannelName)
|
||||
.subscribe({
|
||||
next: videoChannelToUpdate => {
|
||||
this.videoChannel = videoChannelToUpdate
|
||||
|
@ -95,7 +95,7 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements
|
|||
|
||||
this.notifier.success($localize`Video channel ${videoChannelUpdate.displayName} updated.`)
|
||||
|
||||
this.router.navigate([ '/my-library', 'video-channels' ])
|
||||
this.router.navigate([ '/c', this.videoChannel.name ])
|
||||
},
|
||||
|
||||
error: err => {
|
|
@ -1,10 +1,21 @@
|
|||
import { NgModule } from '@angular/core'
|
||||
import { RouterModule, Routes } from '@angular/router'
|
||||
import { MyVideoChannelCreateComponent } from './video-channel-edit/video-channel-create.component'
|
||||
import { VideoChannelUpdateComponent } from './video-channel-edit/video-channel-update.component'
|
||||
import { VideoChannelPlaylistsComponent } from './video-channel-playlists/video-channel-playlists.component'
|
||||
import { VideoChannelVideosComponent } from './video-channel-videos/video-channel-videos.component'
|
||||
import { VideoChannelsComponent } from './video-channels.component'
|
||||
|
||||
const videoChannelsRoutes: Routes = [
|
||||
{
|
||||
path: '@create',
|
||||
component: MyVideoChannelCreateComponent,
|
||||
data: {
|
||||
meta: {
|
||||
title: $localize`Create a new video channel`
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
path: ':videoChannelName',
|
||||
component: VideoChannelsComponent,
|
||||
|
@ -37,6 +48,16 @@ const videoChannelsRoutes: Routes = [
|
|||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: ':videoChannelName/update',
|
||||
component: VideoChannelUpdateComponent,
|
||||
|
||||
data: {
|
||||
meta: {
|
||||
title: $localize`Update video channel`
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
<div class="channel-info">
|
||||
|
||||
<ng-template #buttonsTemplate>
|
||||
<a *ngIf="isManageable()" [routerLink]="[ '/my-library/video-channels/update', videoChannel.nameWithHost ]" class="peertube-button-link orange-button" i18n>
|
||||
<a *ngIf="isManageable()" [routerLink]="[ 'update' ]" class="peertube-button-link orange-button" i18n>
|
||||
Manage channel
|
||||
</a>
|
||||
|
||||
<my-subscribe-button *ngIf="!isManageable()" #subscribeButton [videoChannels]="[videoChannel]"></my-subscribe-button>
|
||||
<my-subscribe-button *ngIf="!isOwner()" #subscribeButton [videoChannels]="[videoChannel]"></my-subscribe-button>
|
||||
|
||||
<button *ngIf="videoChannel.support" (click)="showSupportModal()" class="support-button peertube-button orange-button-inverted">
|
||||
<my-global-icon iconName="support" aria-hidden="true"></my-global-icon>
|
||||
|
|
|
@ -7,7 +7,7 @@ import { AuthService, MarkdownService, Notifier, RestExtractor, ScreenService }
|
|||
import { ListOverflowItem, VideoChannel, VideoChannelService, VideoService } from '@app/shared/shared-main'
|
||||
import { SupportModalComponent } from '@app/shared/shared-support-modal'
|
||||
import { SubscribeButtonComponent } from '@app/shared/shared-user-subscription'
|
||||
import { HttpStatusCode } from '@shared/models'
|
||||
import { HttpStatusCode, UserRight } from '@shared/models'
|
||||
|
||||
@Component({
|
||||
templateUrl: './video-channels.component.html',
|
||||
|
@ -93,10 +93,14 @@ export class VideoChannelsComponent implements OnInit, OnDestroy {
|
|||
return this.authService.isLoggedIn()
|
||||
}
|
||||
|
||||
isOwner () {
|
||||
return this.videoChannel?.ownerAccount.userId === this.authService.getUser().id
|
||||
}
|
||||
|
||||
isManageable () {
|
||||
if (!this.isUserLoggedIn()) return false
|
||||
|
||||
return this.videoChannel?.ownerAccount.userId === this.authService.getUser().id
|
||||
return this.isOwner() || this.authService.getUser().hasRight(UserRight.MANAGE_VIDEO_CHANNELS)
|
||||
}
|
||||
|
||||
activateCopiedMessage () {
|
||||
|
|
|
@ -11,6 +11,9 @@ import { VideoChannelVideosComponent } from './video-channel-videos/video-channe
|
|||
import { VideoChannelsRoutingModule } from './video-channels-routing.module'
|
||||
import { VideoChannelsComponent } from './video-channels.component'
|
||||
import { SharedActorImageModule } from '../shared/shared-actor-image/shared-actor-image.module'
|
||||
import { MyVideoChannelCreateComponent } from './video-channel-edit/video-channel-create.component'
|
||||
import { VideoChannelUpdateComponent } from './video-channel-edit/video-channel-update.component'
|
||||
import { SharedActorImageEditModule } from '@app/shared/shared-actor-image-edit'
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
|
@ -23,13 +26,16 @@ import { SharedActorImageModule } from '../shared/shared-actor-image/shared-acto
|
|||
SharedUserSubscriptionModule,
|
||||
SharedGlobalIconModule,
|
||||
SharedSupportModal,
|
||||
SharedActorImageModule
|
||||
SharedActorImageModule,
|
||||
SharedActorImageEditModule
|
||||
],
|
||||
|
||||
declarations: [
|
||||
VideoChannelsComponent,
|
||||
VideoChannelVideosComponent,
|
||||
VideoChannelPlaylistsComponent
|
||||
VideoChannelPlaylistsComponent,
|
||||
MyVideoChannelCreateComponent,
|
||||
VideoChannelUpdateComponent
|
||||
],
|
||||
|
||||
exports: [
|
||||
|
|
|
@ -24,6 +24,7 @@ import {
|
|||
asyncRetryTransactionMiddleware,
|
||||
authenticate,
|
||||
commonVideosFiltersValidator,
|
||||
ensureUserCanManageChannel,
|
||||
optionalAuthenticate,
|
||||
paginationValidator,
|
||||
setDefaultPagination,
|
||||
|
@ -74,7 +75,7 @@ videoChannelRouter.post('/:nameWithHost/avatar/pick',
|
|||
authenticate,
|
||||
reqAvatarFile,
|
||||
asyncMiddleware(videoChannelsNameWithHostValidator),
|
||||
ensureAuthUserOwnsChannelValidator,
|
||||
ensureUserCanManageChannel,
|
||||
updateAvatarValidator,
|
||||
asyncMiddleware(updateVideoChannelAvatar)
|
||||
)
|
||||
|
@ -83,7 +84,7 @@ videoChannelRouter.post('/:nameWithHost/banner/pick',
|
|||
authenticate,
|
||||
reqBannerFile,
|
||||
asyncMiddleware(videoChannelsNameWithHostValidator),
|
||||
ensureAuthUserOwnsChannelValidator,
|
||||
ensureUserCanManageChannel,
|
||||
updateBannerValidator,
|
||||
asyncMiddleware(updateVideoChannelBanner)
|
||||
)
|
||||
|
@ -91,21 +92,21 @@ videoChannelRouter.post('/:nameWithHost/banner/pick',
|
|||
videoChannelRouter.delete('/:nameWithHost/avatar',
|
||||
authenticate,
|
||||
asyncMiddleware(videoChannelsNameWithHostValidator),
|
||||
ensureAuthUserOwnsChannelValidator,
|
||||
ensureUserCanManageChannel,
|
||||
asyncMiddleware(deleteVideoChannelAvatar)
|
||||
)
|
||||
|
||||
videoChannelRouter.delete('/:nameWithHost/banner',
|
||||
authenticate,
|
||||
asyncMiddleware(videoChannelsNameWithHostValidator),
|
||||
ensureAuthUserOwnsChannelValidator,
|
||||
ensureUserCanManageChannel,
|
||||
asyncMiddleware(deleteVideoChannelBanner)
|
||||
)
|
||||
|
||||
videoChannelRouter.put('/:nameWithHost',
|
||||
authenticate,
|
||||
asyncMiddleware(videoChannelsNameWithHostValidator),
|
||||
ensureAuthUserOwnsChannelValidator,
|
||||
ensureUserCanManageChannel,
|
||||
videoChannelsUpdateValidator,
|
||||
asyncRetryTransactionMiddleware(updateVideoChannel)
|
||||
)
|
||||
|
|
|
@ -20,8 +20,26 @@ function ensureUserHasRight (userRight: UserRight) {
|
|||
}
|
||||
}
|
||||
|
||||
function ensureUserCanManageChannel (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
const user = res.locals.oauth.token.user
|
||||
const isUserOwner = res.locals.videoChannel.Account.userId !== user.id
|
||||
|
||||
if (isUserOwner && user.hasRight(UserRight.MANAGE_VIDEO_CHANNELS) === false) {
|
||||
const message = `User ${user.username} does not have right to manage channel ${req.params.nameWithHost}.`
|
||||
logger.info(message)
|
||||
|
||||
return res.fail({
|
||||
status: HttpStatusCode.FORBIDDEN_403,
|
||||
message
|
||||
})
|
||||
}
|
||||
|
||||
return next()
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
ensureUserHasRight
|
||||
ensureUserHasRight,
|
||||
ensureUserCanManageChannel
|
||||
}
|
||||
|
|
|
@ -41,5 +41,7 @@ export const enum UserRight {
|
|||
MANAGE_VIDEOS_REDUNDANCIES,
|
||||
|
||||
MANAGE_VIDEO_FILES,
|
||||
RUN_VIDEO_TRANSCODING
|
||||
RUN_VIDEO_TRANSCODING,
|
||||
|
||||
MANAGE_VIDEO_CHANNELS
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue