From 1f30a1853e38c20a45722dbd6d38aaaec63839e8 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 22 Feb 2018 15:29:32 +0100 Subject: Add confirm when admin use custom js/css --- client/.angular-cli.json | 7 +- client/src/app/+admin/config/config.routes.ts | 2 +- .../edit-custom-config.component.ts | 32 ++++++++- .../following-add/following-add.component.ts | 21 +++--- .../following-list/following-list.component.ts | 21 +++--- .../+admin/users/user-list/user-list.component.ts | 25 +++---- .../video-blacklist-list.component.ts | 21 +++--- .../account-videos/account-videos.component.ts | 80 ++++++++++------------ client/src/app/core/confirm/confirm.component.html | 7 +- client/src/app/core/confirm/confirm.component.scss | 17 +++++ client/src/app/core/confirm/confirm.component.ts | 23 +++++-- client/src/app/core/confirm/confirm.service.ts | 13 +++- client/src/app/core/core.module.ts | 2 + .../shared/guards/can-deactivate-guard.service.ts | 2 +- .../comment/video-comments.component.ts | 55 +++++++-------- .../videos/+video-watch/video-watch.component.ts | 51 ++++++-------- server/controllers/client.ts | 2 +- 17 files changed, 208 insertions(+), 173 deletions(-) create mode 100644 client/src/app/core/confirm/confirm.component.scss diff --git a/client/.angular-cli.json b/client/.angular-cli.json index 643e1b319..cb387db0a 100644 --- a/client/.angular-cli.json +++ b/client/.angular-cli.json @@ -8,12 +8,7 @@ "root": "src", "outDir": "dist", "assets": [ - { - "glob": "**/*", - "input": "./assets/images", - "output": "./client/assets/images", - "allowOutsideOutDir": false - }, + "./assets/images", "./manifest.json" ], "deployUrl": "client/", diff --git a/client/src/app/+admin/config/config.routes.ts b/client/src/app/+admin/config/config.routes.ts index a46b0ddfd..2ca2f8fde 100644 --- a/client/src/app/+admin/config/config.routes.ts +++ b/client/src/app/+admin/config/config.routes.ts @@ -23,7 +23,7 @@ export const ConfigRoutes: Routes = [ component: EditCustomConfigComponent, data: { meta: { - title: 'Following list' + title: 'Edit custom configuration' } } } diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts index 027268536..ccec89a8e 100644 --- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts +++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts @@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core' import { FormBuilder, FormGroup } from '@angular/forms' import { Router } from '@angular/router' import { ConfigService } from '@app/+admin/config/shared/config.service' +import { ConfirmService } from '@app/core' import { ServerService } from '@app/core/server/server.service' import { FormReactive, USER_VIDEO_QUOTA } from '@app/shared' import { @@ -61,12 +62,16 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit { userVideoQuota: USER_VIDEO_QUOTA.MESSAGES } + private oldCustomJavascript: string + private oldCustomCSS: string + constructor ( private formBuilder: FormBuilder, private router: Router, private notificationsService: NotificationsService, private configService: ConfigService, - private serverService: ServerService + private serverService: ServerService, + private confirmService: ConfirmService ) { super() } @@ -109,6 +114,9 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit { res => { this.customConfig = res + this.oldCustomCSS = this.customConfig.instance.customizations.css + this.oldCustomJavascript = this.customConfig.instance.customizations.javascript + this.updateForm() }, @@ -124,7 +132,27 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit { return this.form.value['signupEnabled'] === true } - formValidated () { + async formValidated () { + const newCustomizationJavascript = this.form.value['customizationJavascript'] + const newCustomizationCSS = this.form.value['customizationCSS'] + + const customizations = [] + if (newCustomizationJavascript && newCustomizationJavascript !== this.oldCustomJavascript) customizations.push('JavaScript') + if (newCustomizationCSS && newCustomizationCSS !== this.oldCustomCSS) customizations.push('CSS') + + if (customizations.length !== 0) { + const customizationsText = customizations.join('/') + + const message = `You set custom ${customizationsText}. ` + + 'This could lead to security issues or bugs if you do not understand it. ' + + 'Are you sure you want to update the configuration?' + const label = `Please type "I understand the ${customizationsText} I set" to confirm.` + const expectedInputValue = `I understand the ${customizationsText} I set` + + const confirmRes = await this.confirmService.confirmWithInput(message, label, expectedInputValue) + if (confirmRes === false) return + } + const data = { instance: { name: this.form.value['instanceName'], diff --git a/client/src/app/+admin/follows/following-add/following-add.component.ts b/client/src/app/+admin/follows/following-add/following-add.component.ts index bf842129d..c296c8852 100644 --- a/client/src/app/+admin/follows/following-add/following-add.component.ts +++ b/client/src/app/+admin/follows/following-add/following-add.component.ts @@ -43,7 +43,7 @@ export class FollowingAddComponent { } } - addFollowing () { + async addFollowing () { this.error = '' const hosts = this.getNotEmptyHosts() @@ -57,20 +57,17 @@ export class FollowingAddComponent { } const confirmMessage = 'If you confirm, you will send a follow request to:
- ' + hosts.join('
- ') - this.confirmService.confirm(confirmMessage, 'Follow new server(s)').subscribe( - res => { - if (res === false) return + const res = await this.confirmService.confirm(confirmMessage, 'Follow new server(s)') + if (res === false) return - this.followService.follow(hosts).subscribe( - status => { - this.notificationsService.success('Success', 'Follow request(s) sent!') + this.followService.follow(hosts).subscribe( + () => { + this.notificationsService.success('Success', 'Follow request(s) sent!') - setTimeout(() => this.router.navigate([ '/admin/follows/following-list' ]), 500) - }, + setTimeout(() => this.router.navigate([ '/admin/follows/following-list' ]), 500) + }, - err => this.notificationsService.error('Error', err.message) - ) - } + err => this.notificationsService.error('Error', err.message) ) } diff --git a/client/src/app/+admin/follows/following-list/following-list.component.ts b/client/src/app/+admin/follows/following-list/following-list.component.ts index d4f8d0309..ad1bd4536 100644 --- a/client/src/app/+admin/follows/following-list/following-list.component.ts +++ b/client/src/app/+admin/follows/following-list/following-list.component.ts @@ -25,20 +25,17 @@ export class FollowingListComponent extends RestTable { super() } - removeFollowing (follow: AccountFollow) { - this.confirmService.confirm(`Do you really want to unfollow ${follow.following.host}?`, 'Unfollow').subscribe( - res => { - if (res === false) return + async removeFollowing (follow: AccountFollow) { + const res = await this.confirmService.confirm(`Do you really want to unfollow ${follow.following.host}?`, 'Unfollow') + if (res === false) return - this.followService.unfollow(follow).subscribe( - () => { - this.notificationsService.success('Success', `You are not following ${follow.following.host} anymore.`) - this.loadData() - }, + this.followService.unfollow(follow).subscribe( + () => { + this.notificationsService.success('Success', `You are not following ${follow.following.host} anymore.`) + this.loadData() + }, - err => this.notificationsService.error('Error', err.message) - ) - } + err => this.notificationsService.error('Error', err.message) ) } diff --git a/client/src/app/+admin/users/user-list/user-list.component.ts b/client/src/app/+admin/users/user-list/user-list.component.ts index 1e8e1af49..512152808 100644 --- a/client/src/app/+admin/users/user-list/user-list.component.ts +++ b/client/src/app/+admin/users/user-list/user-list.component.ts @@ -1,10 +1,10 @@ import { Component } from '@angular/core' -import { SortMeta } from 'primeng/components/common/sortmeta' import { NotificationsService } from 'angular2-notifications' +import { SortMeta } from 'primeng/components/common/sortmeta' import { ConfirmService } from '../../../core' -import { RestTable, RestPagination, User } from '../../../shared' +import { RestPagination, RestTable, User } from '../../../shared' import { UserService } from '../shared' @Component({ @@ -27,25 +27,22 @@ export class UserListComponent extends RestTable { super() } - removeUser (user: User) { + async removeUser (user: User) { if (user.username === 'root') { this.notificationsService.error('Error', 'You cannot delete root.') return } - this.confirmService.confirm('Do you really want to delete this user?', 'Delete').subscribe( - res => { - if (res === false) return + const res = await this.confirmService.confirm('Do you really want to delete this user?', 'Delete') + if (res === false) return - this.userService.removeUser(user).subscribe( - () => { - this.notificationsService.success('Success', `User ${user.username} deleted.`) - this.loadData() - }, + this.userService.removeUser(user).subscribe( + () => { + this.notificationsService.success('Success', `User ${user.username} deleted.`) + this.loadData() + }, - err => this.notificationsService.error('Error', err.message) - ) - } + err => this.notificationsService.error('Error', err.message) ) } diff --git a/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.ts b/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.ts index 56024b247..f4cf21259 100644 --- a/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.ts +++ b/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.ts @@ -31,22 +31,19 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit { this.loadData() } - removeVideoFromBlacklist (entry: BlacklistedVideo) { + async removeVideoFromBlacklist (entry: BlacklistedVideo) { const confirmMessage = 'Do you really want to remove this video from the blacklist ? It will be available again in the video list.' - this.confirmService.confirm(confirmMessage, 'Remove').subscribe( - res => { - if (res === false) return + const res = await this.confirmService.confirm(confirmMessage, 'Remove') + if (res === false) return - this.videoBlacklistService.removeVideoFromBlacklist(entry.videoId).subscribe( - status => { - this.notificationsService.success('Success', `Video ${entry.name} removed from the blacklist.`) - this.loadData() - }, + this.videoBlacklistService.removeVideoFromBlacklist(entry.videoId).subscribe( + () => { + this.notificationsService.success('Success', `Video ${entry.name} removed from the blacklist.`) + this.loadData() + }, - err => this.notificationsService.error('Error', err.message) - ) - } + err => this.notificationsService.error('Error', err.message) ) } diff --git a/client/src/app/account/account-videos/account-videos.component.ts b/client/src/app/account/account-videos/account-videos.component.ts index e9d044dbf..a286bad1c 100644 --- a/client/src/app/account/account-videos/account-videos.component.ts +++ b/client/src/app/account/account-videos/account-videos.component.ts @@ -56,55 +56,49 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit return this.videoService.getMyVideos(newPagination, this.sort) } - deleteSelectedVideos () { + async deleteSelectedVideos () { const toDeleteVideosIds = Object.keys(this.checkedVideos) .filter(k => this.checkedVideos[k] === true) .map(k => parseInt(k, 10)) - this.confirmService.confirm(`Do you really want to delete ${toDeleteVideosIds.length} videos?`, 'Delete').subscribe( - res => { - if (res === false) return - - const observables: Observable[] = [] - for (const videoId of toDeleteVideosIds) { - const o = this.videoService - .removeVideo(videoId) - .do(() => this.spliceVideosById(videoId)) - - observables.push(o) - } - - Observable.from(observables) - .concatAll() - .subscribe( - res => { - this.notificationsService.success('Success', `${toDeleteVideosIds.length} videos deleted.`) - this.buildVideoPages() - }, - - err => this.notificationsService.error('Error', err.message) - ) - } - ) + const res = await this.confirmService.confirm(`Do you really want to delete ${toDeleteVideosIds.length} videos?`, 'Delete') + if (res === false) return + + const observables: Observable[] = [] + for (const videoId of toDeleteVideosIds) { + const o = this.videoService + .removeVideo(videoId) + .do(() => this.spliceVideosById(videoId)) + + observables.push(o) + } + + Observable.from(observables) + .concatAll() + .subscribe( + res => { + this.notificationsService.success('Success', `${toDeleteVideosIds.length} videos deleted.`) + this.buildVideoPages() + }, + + err => this.notificationsService.error('Error', err.message) + ) } - deleteVideo (video: Video) { - this.confirmService.confirm(`Do you really want to delete ${video.name}?`, 'Delete').subscribe( - res => { - if (res === false) return - - this.videoService.removeVideo(video.id) - .subscribe( - status => { - this.notificationsService.success('Success', `Video ${video.name} deleted.`) - this.spliceVideosById(video.id) - this.buildVideoPages() - }, - - error => this.notificationsService.error('Error', error.message) - ) - } - ) + async deleteVideo (video: Video) { + const res = await this.confirmService.confirm(`Do you really want to delete ${video.name}?`, 'Delete') + if (res === false) return + + this.videoService.removeVideo(video.id) + .subscribe( + status => { + this.notificationsService.success('Success', `Video ${video.name} deleted.`) + this.spliceVideosById(video.id) + this.buildVideoPages() + }, + + error => this.notificationsService.error('Error', error.message) + ) } private spliceVideosById (id: number) { diff --git a/client/src/app/core/confirm/confirm.component.html b/client/src/app/core/confirm/confirm.component.html index cc2c28de2..90274b248 100644 --- a/client/src/app/core/confirm/confirm.component.html +++ b/client/src/app/core/confirm/confirm.component.html @@ -10,13 +10,18 @@