diff --git a/client/src/app/+admin/users/user-edit/user-edit.ts b/client/src/app/+admin/users/user-edit/user-edit.ts index bdbb10814..787f4b689 100644 --- a/client/src/app/+admin/users/user-edit/user-edit.ts +++ b/client/src/app/+admin/users/user-edit/user-edit.ts @@ -6,6 +6,7 @@ import { USER_ROLE_LABELS } from '@shared/core-utils/users' import { ServerConfig, UserAdminFlag, UserRole, VideoResolution } from '@shared/models' @Directive() +// tslint:disable-next-line: directive-class-suffix export abstract class UserEdit extends FormReactive implements OnInit { videoQuotaOptions: { value: string, label: string, disabled?: boolean }[] = [] videoQuotaDailyOptions: { value: string, label: string, disabled?: boolean }[] = [] diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.ts b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.ts index 668a23d8f..ba95b6c8b 100644 --- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.ts +++ b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.ts @@ -1,5 +1,5 @@ import { Subject } from 'rxjs' -import { debounceTime, flatMap } from 'rxjs/operators' +import { debounceTime, mergeMap } from 'rxjs/operators' import { Component, OnInit } from '@angular/core' import { AuthService, ComponentPagination, ConfirmService, Notifier, User } from '@app/core' import { VideoPlaylist, VideoPlaylistService } from '@app/shared/shared-video-playlist' @@ -95,7 +95,7 @@ export class MyAccountVideoPlaylistsComponent implements OnInit { private loadVideoPlaylists (reset = false) { this.authService.userInformationLoaded - .pipe(flatMap(() => { + .pipe(mergeMap(() => { return this.videoPlaylistService.listAccountPlaylists(this.user.account, this.pagination, '-updatedAt', this.videoPlaylistsSearch) })) .subscribe(res => { diff --git a/client/src/app/+videos/+video-edit/video-add-components/video-import-torrent.component.ts b/client/src/app/+videos/+video-edit/video-add-components/video-import-torrent.component.ts index 538a187a8..3a8e6eecc 100644 --- a/client/src/app/+videos/+video-edit/video-add-components/video-import-torrent.component.ts +++ b/client/src/app/+videos/+video-edit/video-add-components/video-import-torrent.component.ts @@ -84,11 +84,11 @@ export class VideoImportTorrentComponent extends VideoSend implements OnInit, Ca channelId: this.firstStepChannelId } - this.loadingBar.start() + this.loadingBar.useRef().start() this.videoImportService.importVideoTorrent(torrentfile || this.magnetUri, videoUpdate).subscribe( res => { - this.loadingBar.complete() + this.loadingBar.useRef().complete() this.firstStepDone.emit(res.video.name) this.isImportingVideo = false this.hasImportedVideo = true @@ -105,7 +105,7 @@ export class VideoImportTorrentComponent extends VideoSend implements OnInit, Ca }, err => { - this.loadingBar.complete() + this.loadingBar.useRef().complete() this.isImportingVideo = false this.firstStepError.emit() this.notifier.error(err.message) diff --git a/client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.ts b/client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.ts index 6508eef7e..da25663d7 100644 --- a/client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.ts +++ b/client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.ts @@ -71,7 +71,7 @@ export class VideoImportUrlComponent extends VideoSend implements OnInit, CanCom channelId: this.firstStepChannelId } - this.loadingBar.start() + this.loadingBar.useRef().start() this.videoImportService .importVideoUrl(this.targetUrl, videoUpdate) @@ -86,7 +86,7 @@ export class VideoImportUrlComponent extends VideoSend implements OnInit, CanCom ) .subscribe( ({ video, videoCaptions }) => { - this.loadingBar.complete() + this.loadingBar.useRef().complete() this.firstStepDone.emit(video.name) this.isImportingVideo = false this.hasImportedVideo = true @@ -115,7 +115,7 @@ export class VideoImportUrlComponent extends VideoSend implements OnInit, CanCom }, err => { - this.loadingBar.complete() + this.loadingBar.useRef().complete() this.isImportingVideo = false this.firstStepError.emit() this.notifier.error(err.message) diff --git a/client/src/app/+videos/+video-edit/video-add-components/video-send.ts b/client/src/app/+videos/+video-edit/video-add-components/video-send.ts index 5d11ba7ce..2e658dfae 100644 --- a/client/src/app/+videos/+video-edit/video-add-components/video-send.ts +++ b/client/src/app/+videos/+video-edit/video-add-components/video-send.ts @@ -1,5 +1,5 @@ import { catchError, switchMap, tap } from 'rxjs/operators' -import { EventEmitter, OnInit, Directive } from '@angular/core' +import { Directive, EventEmitter, OnInit } from '@angular/core' import { AuthService, CanComponentDeactivateResult, Notifier, ServerService } from '@app/core' import { populateAsyncUserVideoChannels } from '@app/helpers' import { FormReactive } from '@app/shared/shared-forms' @@ -8,6 +8,7 @@ import { LoadingBarService } from '@ngx-loading-bar/core' import { ServerConfig, VideoConstant, VideoPrivacy } from '@shared/models' @Directive() +// tslint:disable-next-line: directive-class-suffix export abstract class VideoSend extends FormReactive implements OnInit { userVideoChannels: { id: number, label: string, support: string }[] = [] videoPrivacies: VideoConstant[] = [] @@ -56,15 +57,15 @@ export abstract class VideoSend extends FormReactive implements OnInit { } protected updateVideoAndCaptions (video: VideoEdit) { - this.loadingBar.start() + this.loadingBar.useRef().start() return this.videoService.updateVideo(video) .pipe( // Then update captions switchMap(() => this.videoCaptionService.updateCaptions(video.id, this.videoCaptions)), - tap(() => this.loadingBar.complete()), + tap(() => this.loadingBar.useRef().complete()), catchError(err => { - this.loadingBar.complete() + this.loadingBar.useRef().complete() throw err }) ) diff --git a/client/src/app/+videos/+video-edit/video-update.component.ts b/client/src/app/+videos/+video-edit/video-update.component.ts index 7bd6eb553..581199d65 100644 --- a/client/src/app/+videos/+video-edit/video-update.component.ts +++ b/client/src/app/+videos/+video-edit/video-update.component.ts @@ -101,7 +101,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit { this.video.patch(this.form.value) - this.loadingBar.start() + this.loadingBar.useRef().start() this.isUpdatingVideo = true // Update the video @@ -114,13 +114,13 @@ export class VideoUpdateComponent extends FormReactive implements OnInit { () => { this.updateDone = true this.isUpdatingVideo = false - this.loadingBar.complete() + this.loadingBar.useRef().complete() this.notifier.success(this.i18n('Video updated.')) this.router.navigate([ '/videos/watch', this.video.uuid ]) }, err => { - this.loadingBar.complete() + this.loadingBar.useRef().complete() this.isUpdatingVideo = false this.notifier.error(err.message) console.error(err) diff --git a/client/src/app/core/auth/auth-user.model.ts b/client/src/app/core/auth/auth-user.model.ts index 5efc6e1ab..5679d28a9 100644 --- a/client/src/app/core/auth/auth-user.model.ts +++ b/client/src/app/core/auth/auth-user.model.ts @@ -1,7 +1,7 @@ import { Observable, of } from 'rxjs' import { map } from 'rxjs/operators' import { User } from '@app/core/users/user.model' -import { peertubeLocalStorage } from '@app/helpers/peertube-web-storage' +import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage' import { hasUserRight } from '@shared/core-utils/users' import { MyUser as ServerMyUserModel, @@ -12,7 +12,7 @@ import { UserRole, UserVideoQuota } from '@shared/models' -import { TokenOptions, Tokens } from '../../../root-helpers/pure-auth-user.model' +import { TokenOptions, Tokens } from '@root-helpers/pure-auth-user.model' export class AuthUser extends User implements ServerMyUserModel { tokens: Tokens diff --git a/client/src/app/shared/shared-moderation/account-blocklist.component.ts b/client/src/app/shared/shared-moderation/account-blocklist.component.ts index 11e554978..a5a3c27cd 100644 --- a/client/src/app/shared/shared-moderation/account-blocklist.component.ts +++ b/client/src/app/shared/shared-moderation/account-blocklist.component.ts @@ -7,6 +7,7 @@ import { AccountBlock } from './account-block.model' import { BlocklistComponentType, BlocklistService } from './blocklist.service' @Directive() +// tslint:disable-next-line: directive-class-suffix export class GenericAccountBlocklistComponent extends RestTable implements OnInit { // @ts-ignore: "Abstract methods can only appear within an abstract class" abstract mode: BlocklistComponentType diff --git a/client/src/app/shared/shared-moderation/server-blocklist.component.ts b/client/src/app/shared/shared-moderation/server-blocklist.component.ts index 694b03762..8f65cdb71 100644 --- a/client/src/app/shared/shared-moderation/server-blocklist.component.ts +++ b/client/src/app/shared/shared-moderation/server-blocklist.component.ts @@ -1,12 +1,13 @@ import { SortMeta } from 'primeng/api' -import { OnInit, ViewChild, Directive } from '@angular/core' -import { BatchDomainsModalComponent } from '@app/shared/shared-moderation/batch-domains-modal.component' +import { Directive, OnInit, ViewChild } from '@angular/core' import { Notifier, RestPagination, RestTable } from '@app/core' +import { BatchDomainsModalComponent } from '@app/shared/shared-moderation/batch-domains-modal.component' import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerBlock } from '@shared/models' import { BlocklistComponentType, BlocklistService } from './blocklist.service' @Directive() +// tslint:disable-next-line: directive-class-suffix export class GenericServerBlocklistComponent extends RestTable implements OnInit { @ViewChild('batchDomainsModal') batchDomainsModal: BatchDomainsModalComponent diff --git a/client/src/app/shared/shared-video-miniature/abstract-video-list.ts b/client/src/app/shared/shared-video-miniature/abstract-video-list.ts index 405af5fa6..e18002b74 100644 --- a/client/src/app/shared/shared-video-miniature/abstract-video-list.ts +++ b/client/src/app/shared/shared-video-miniature/abstract-video-list.ts @@ -1,6 +1,6 @@ import { fromEvent, Observable, Subject, Subscription } from 'rxjs' import { debounceTime, switchMap, tap } from 'rxjs/operators' -import { OnDestroy, OnInit, Directive } from '@angular/core' +import { Directive, OnDestroy, OnInit } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' import { AuthService, @@ -31,6 +31,7 @@ enum GroupDate { } @Directive() +// tslint:disable-next-line: directive-class-suffix export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableForReuseHook { pagination: ComponentPaginationLight = { currentPage: 1, diff --git a/server/middlewares/validators/plugins.ts b/server/middlewares/validators/plugins.ts index 2cb49ec43..cba261dc0 100644 --- a/server/middlewares/validators/plugins.ts +++ b/server/middlewares/validators/plugins.ts @@ -4,7 +4,7 @@ import { logger } from '../../helpers/logger' import { areValidationErrors } from './utils' import { isNpmPluginNameValid, isPluginNameValid, isPluginTypeValid, isPluginVersionValid } from '../../helpers/custom-validators/plugins' import { PluginManager } from '../../lib/plugins/plugin-manager' -import { isBooleanValid, isSafePath, toBooleanOrNull, exists } from '../../helpers/custom-validators/misc' +import { isBooleanValid, isSafePath, toBooleanOrNull, exists, toIntOrNull } from '../../helpers/custom-validators/misc' import { PluginModel } from '../../models/server/plugin' import { InstallOrUpdatePlugin } from '../../../shared/models/plugins/install-plugin.model' import { PluginType } from '../../../shared/models/plugins/plugin.type' @@ -75,6 +75,7 @@ const pluginStaticDirectoryValidator = [ const listPluginsValidator = [ query('pluginType') .optional() + .customSanitizer(toIntOrNull) .custom(isPluginTypeValid).withMessage('Should have a valid plugin type'), query('uninstalled') .optional() @@ -165,6 +166,7 @@ const listAvailablePluginsValidator = [ .exists().withMessage('Should have a valid search'), query('pluginType') .optional() + .customSanitizer(toIntOrNull) .custom(isPluginTypeValid).withMessage('Should have a valid plugin type'), query('currentPeerTubeEngine') .optional() diff --git a/server/middlewares/validators/videos/video-blacklist.ts b/server/middlewares/validators/videos/video-blacklist.ts index 4bd6a8333..808fefc25 100644 --- a/server/middlewares/validators/videos/video-blacklist.ts +++ b/server/middlewares/validators/videos/video-blacklist.ts @@ -1,10 +1,10 @@ import * as express from 'express' import { body, param, query } from 'express-validator' -import { isBooleanValid, isIdOrUUIDValid, toBooleanOrNull } from '../../../helpers/custom-validators/misc' -import { logger } from '../../../helpers/logger' -import { areValidationErrors } from '../utils' +import { isBooleanValid, isIdOrUUIDValid, toBooleanOrNull, toIntOrNull } from '../../../helpers/custom-validators/misc' import { isVideoBlacklistReasonValid, isVideoBlacklistTypeValid } from '../../../helpers/custom-validators/video-blacklist' +import { logger } from '../../../helpers/logger' import { doesVideoBlacklistExist, doesVideoExist } from '../../../helpers/middlewares' +import { areValidationErrors } from '../utils' const videosBlacklistRemoveValidator = [ param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'), @@ -67,7 +67,8 @@ const videosBlacklistUpdateValidator = [ const videosBlacklistFiltersValidator = [ query('type') - .optional() + .optional() + .customSanitizer(toIntOrNull) .custom(isVideoBlacklistTypeValid).withMessage('Should have a valid video blacklist type attribute'), query('search') .optional() diff --git a/server/tests/api/check-params/abuses.ts b/server/tests/api/check-params/abuses.ts index 1f040bbcf..8dadd9922 100644 --- a/server/tests/api/check-params/abuses.ts +++ b/server/tests/api/check-params/abuses.ts @@ -421,6 +421,10 @@ describe('Test abuses API validators', function () { it('Should fail when creating abuse message of a remote abuse', async function () { await addAbuseMessage(server.url, server.accessToken, remoteAbuseId, 'message', 400) }) + + after(async function () { + await cleanupTests([ anotherServer ]) + }) }) after(async function () {