mirror of
https://github.com/Chocobozzz/PeerTube.git
synced 2024-08-17 17:30:32 +03:00
Support short uuid for GET video/playlist
This commit is contained in:
parent
62ddc31a9e
commit
d4a8e7a65f
@ -122,7 +122,7 @@ export class VideoBlockListComponent extends RestTable implements OnInit {
|
||||
}
|
||||
|
||||
getVideoUrl (videoBlock: VideoBlacklist) {
|
||||
return Video.buildClientUrl(videoBlock.video.uuid)
|
||||
return Video.buildWatchUrl(videoBlock.video)
|
||||
}
|
||||
|
||||
toHtml (text: string) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { SortMeta } from 'primeng/api'
|
||||
import { Component, OnInit } from '@angular/core'
|
||||
import { Notifier, RestPagination, RestTable } from '@app/core'
|
||||
import { VideoImportService } from '@app/shared/shared-main'
|
||||
import { Video, VideoImportService } from '@app/shared/shared-main'
|
||||
import { VideoImport, VideoImportState } from '@shared/models'
|
||||
|
||||
@Component({
|
||||
@ -55,11 +55,11 @@ export class MyVideoImportsComponent extends RestTable implements OnInit {
|
||||
}
|
||||
|
||||
getVideoUrl (video: { uuid: string }) {
|
||||
return '/w/' + video.uuid
|
||||
return Video.buildWatchUrl(video)
|
||||
}
|
||||
|
||||
getEditVideoUrl (video: { uuid: string }) {
|
||||
return '/videos/update/' + video.uuid
|
||||
return Video.buildUpdateUrl(video)
|
||||
}
|
||||
|
||||
protected reloadData () {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { forkJoin } from 'rxjs'
|
||||
import { Component, OnInit } from '@angular/core'
|
||||
import { ActivatedRoute, Router } from '@angular/router'
|
||||
import { VideoChannel } from '@app/shared/shared-main'
|
||||
import { Video, VideoChannel } from '@app/shared/shared-main'
|
||||
import { SearchService } from '@app/shared/shared-search'
|
||||
|
||||
@Component({
|
||||
@ -39,7 +39,7 @@ export class RemoteInteractionComponent implements OnInit {
|
||||
if (videoResult.data.length !== 0) {
|
||||
const video = videoResult.data[0]
|
||||
|
||||
redirectUrl = '/w/' + video.uuid
|
||||
redirectUrl = Video.buildWatchUrl(video)
|
||||
} else if (channelResult.data.length !== 0) {
|
||||
const channel = new VideoChannel(channelResult.data[0])
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Observable } from 'rxjs'
|
||||
import { map } from 'rxjs/operators'
|
||||
import { ActivatedRouteSnapshot, Resolve, Router } from '@angular/router'
|
||||
import { ResultList } from '@shared/models/result-list.model'
|
||||
import { ResultList } from '@shared/models'
|
||||
|
||||
export abstract class AbstractLazyLoadResolver <T> implements Resolve<any> {
|
||||
protected router: Router
|
||||
|
@ -19,6 +19,6 @@ export class PlaylistLazyLoadResolver extends AbstractLazyLoadResolver<VideoPlay
|
||||
}
|
||||
|
||||
protected buildUrl (playlist: VideoPlaylist) {
|
||||
return '/w/p/' + playlist.uuid
|
||||
return VideoPlaylist.buildWatchUrl(playlist)
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,6 @@ export class VideoLazyLoadResolver extends AbstractLazyLoadResolver<Video> {
|
||||
}
|
||||
|
||||
protected buildUrl (video: Video) {
|
||||
return '/w/' + video.uuid
|
||||
return Video.buildWatchUrl(video)
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
|
||||
import { forkJoin } from 'rxjs'
|
||||
import { AfterViewChecked, AfterViewInit, Component, EventEmitter, OnInit, Output } from '@angular/core'
|
||||
import { AfterViewInit, Component, EventEmitter, OnInit, Output } from '@angular/core'
|
||||
import { Router } from '@angular/router'
|
||||
import { AuthService, CanComponentDeactivate, HooksService, Notifier, ServerService } from '@app/core'
|
||||
import { scrollToTop } from '@app/helpers'
|
||||
import { FormValidatorService } from '@app/shared/shared-forms'
|
||||
import { VideoCaptionService, VideoEdit, VideoService } from '@app/shared/shared-main'
|
||||
import { Video, VideoCaptionService, VideoEdit, VideoService } from '@app/shared/shared-main'
|
||||
import { LiveVideoService } from '@app/shared/shared-video-live'
|
||||
import { LoadingBarService } from '@ngx-loading-bar/core'
|
||||
import { LiveVideo, LiveVideoCreate, LiveVideoUpdate, PeerTubeProblemDocument, ServerErrorCode, VideoPrivacy } from '@shared/models'
|
||||
@ -127,7 +127,7 @@ export class VideoGoLiveComponent extends VideoSend implements OnInit, AfterView
|
||||
() => {
|
||||
this.notifier.success($localize`Live published.`)
|
||||
|
||||
this.router.navigate(['/w', video.uuid])
|
||||
this.router.navigateByUrl(Video.buildWatchUrl(video))
|
||||
},
|
||||
|
||||
err => {
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { UploadState, UploadxOptions, UploadxService } from 'ngx-uploadx'
|
||||
import { HttpErrorResponse, HttpEventType, HttpHeaders } from '@angular/common/http'
|
||||
import { AfterViewInit, Component, ElementRef, EventEmitter, OnDestroy, OnInit, Output, ViewChild } from '@angular/core'
|
||||
import { Router } from '@angular/router'
|
||||
import { UploadxOptions, UploadState, UploadxService } from 'ngx-uploadx'
|
||||
import { UploaderXFormData } from './uploaderx-form-data'
|
||||
import { AuthService, CanComponentDeactivate, HooksService, Notifier, ServerService, UserService } from '@app/core'
|
||||
import { scrollToTop, genericUploadErrorHandler } from '@app/helpers'
|
||||
import { genericUploadErrorHandler, scrollToTop } from '@app/helpers'
|
||||
import { FormValidatorService } from '@app/shared/shared-forms'
|
||||
import { BytesPipe, VideoCaptionService, VideoEdit, VideoService } from '@app/shared/shared-main'
|
||||
import { BytesPipe, Video, VideoCaptionService, VideoEdit, VideoService } from '@app/shared/shared-main'
|
||||
import { LoadingBarService } from '@ngx-loading-bar/core'
|
||||
import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
|
||||
import { VideoPrivacy } from '@shared/models'
|
||||
import { UploaderXFormData } from './uploaderx-form-data'
|
||||
import { VideoSend } from './video-send'
|
||||
import { HttpErrorResponse, HttpEventType, HttpHeaders } from '@angular/common/http'
|
||||
|
||||
@Component({
|
||||
selector: 'my-video-upload',
|
||||
@ -243,7 +243,7 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
|
||||
this.isUploadingVideo = false
|
||||
|
||||
this.notifier.success($localize`Video published.`)
|
||||
this.router.navigate([ '/w', video.uuid ])
|
||||
this.router.navigateByUrl(Video.buildWatchUrl(video))
|
||||
},
|
||||
|
||||
err => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
<div class="margin-content">
|
||||
<div class="title-page title-page-single">
|
||||
<span class="mr-1" i18n>Update</span>
|
||||
<a [routerLink]="[ '/w', video.uuid ]">{{ video?.name }}</a>
|
||||
<a [routerLink]="getVideoUrl()">{{ video?.name }}</a>
|
||||
</div>
|
||||
|
||||
<form novalidate [formGroup]="form">
|
||||
|
@ -5,7 +5,7 @@ import { Component, HostListener, OnInit } from '@angular/core'
|
||||
import { ActivatedRoute, Router } from '@angular/router'
|
||||
import { Notifier } from '@app/core'
|
||||
import { FormReactive, FormValidatorService } from '@app/shared/shared-forms'
|
||||
import { VideoCaptionEdit, VideoCaptionService, VideoDetails, VideoEdit, VideoService } from '@app/shared/shared-main'
|
||||
import { Video, VideoCaptionEdit, VideoCaptionService, VideoDetails, VideoEdit, VideoService } from '@app/shared/shared-main'
|
||||
import { LiveVideoService } from '@app/shared/shared-video-live'
|
||||
import { LoadingBarService } from '@ngx-loading-bar/core'
|
||||
import { LiveVideo, LiveVideoUpdate, VideoPrivacy } from '@shared/models'
|
||||
@ -156,7 +156,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
|
||||
this.isUpdatingVideo = false
|
||||
this.loadingBar.useRef().complete()
|
||||
this.notifier.success($localize`Video updated.`)
|
||||
this.router.navigate([ '/w', this.video.uuid ])
|
||||
this.router.navigateByUrl(Video.buildWatchUrl(this.video))
|
||||
},
|
||||
|
||||
err => {
|
||||
@ -175,4 +175,8 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
|
||||
pluginData: this.video.pluginData
|
||||
})
|
||||
}
|
||||
|
||||
getVideoUrl () {
|
||||
return Video.buildWatchUrl(this.videoDetails)
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<a [routerLink]="['/w', video.uuid, { 'threadId': comment.threadId }]" class="comment-date" [title]="comment.createdAt">
|
||||
<a [routerLink]="['/w', video.shortUUID, { 'threadId': comment.threadId }]" class="comment-date" [title]="comment.createdAt">
|
||||
{{ comment.createdAt | myFromNow }}
|
||||
</a>
|
||||
</div>
|
||||
@ -45,7 +45,7 @@
|
||||
<ng-container *ngIf="comment.isDeleted">
|
||||
<div class="comment-account-date">
|
||||
<span class="comment-account" i18n>Deleted</span>
|
||||
<a [routerLink]="['/w', video.uuid, { 'threadId': comment.threadId }]"
|
||||
<a [routerLink]="['/w', video.shortUUID, { 'threadId': comment.threadId }]"
|
||||
class="comment-date">{{ comment.createdAt | myFromNow }}</a>
|
||||
</div>
|
||||
|
||||
|
@ -247,7 +247,7 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
this.componentPagination.totalItems = null
|
||||
this.totalNotDeletedComments = null
|
||||
|
||||
this.syndicationItems = this.videoCommentService.getVideoCommentsFeeds(this.video.uuid)
|
||||
this.syndicationItems = this.videoCommentService.getVideoCommentsFeeds(this.video)
|
||||
this.loadMoreThreads()
|
||||
}
|
||||
}
|
||||
|
@ -312,7 +312,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
||||
|
||||
getVideoUrl () {
|
||||
if (!this.video.url) {
|
||||
return this.video.originInstanceUrl + VideoDetails.buildClientUrl(this.video.uuid)
|
||||
return this.video.originInstanceUrl + VideoDetails.buildWatchUrl(this.video)
|
||||
}
|
||||
return this.video.url
|
||||
}
|
||||
@ -415,7 +415,10 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
||||
|
||||
private loadVideo (videoId: string) {
|
||||
// Video did not change
|
||||
if (this.video && this.video.uuid === videoId) return
|
||||
if (
|
||||
this.video &&
|
||||
(this.video.uuid === videoId || this.video.shortUUID === videoId)
|
||||
) return
|
||||
|
||||
if (this.player) this.player.pause()
|
||||
|
||||
@ -489,7 +492,10 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
||||
|
||||
private loadPlaylist (playlistId: string) {
|
||||
// Playlist did not change
|
||||
if (this.playlist && this.playlist.uuid === playlistId) return
|
||||
if (
|
||||
this.playlist &&
|
||||
(this.playlist.uuid === playlistId || this.playlist.shortUUID === playlistId)
|
||||
) return
|
||||
|
||||
this.playlistService.getVideoPlaylist(playlistId)
|
||||
.pipe(
|
||||
@ -772,13 +778,13 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
||||
|
||||
private flushPlayer () {
|
||||
// Remove player if it exists
|
||||
if (this.player) {
|
||||
try {
|
||||
this.player.dispose()
|
||||
this.player = undefined
|
||||
} catch (err) {
|
||||
console.error('Cannot dispose player.', err)
|
||||
}
|
||||
if (!this.player) return
|
||||
|
||||
try {
|
||||
this.player.dispose()
|
||||
this.player = undefined
|
||||
} catch (err) {
|
||||
console.error('Cannot dispose player.', err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,11 +116,11 @@ export class AbuseListTableComponent extends RestTable implements OnInit {
|
||||
}
|
||||
|
||||
getVideoUrl (abuse: AdminAbuse) {
|
||||
return Video.buildClientUrl(abuse.video.uuid)
|
||||
return Video.buildWatchUrl(abuse.video)
|
||||
}
|
||||
|
||||
getCommentUrl (abuse: AdminAbuse) {
|
||||
return Video.buildClientUrl(abuse.comment.video.uuid) + ';threadId=' + abuse.comment.threadId
|
||||
return Video.buildWatchUrl(abuse.comment.video) + ';threadId=' + abuse.comment.threadId
|
||||
}
|
||||
|
||||
getAccountUrl (abuse: ProcessedAbuse) {
|
||||
|
@ -6,7 +6,7 @@ import { Component, Input, ViewEncapsulation } from '@angular/core'
|
||||
templateUrl: './link.component.html'
|
||||
})
|
||||
export class LinkComponent {
|
||||
@Input() internalLink?: any[]
|
||||
@Input() internalLink?: string | any[]
|
||||
|
||||
@Input() href?: string
|
||||
@Input() target?: string
|
||||
|
@ -12,6 +12,7 @@ import {
|
||||
UserRight,
|
||||
VideoInfo
|
||||
} from '@shared/models'
|
||||
import { Video } from '../video'
|
||||
|
||||
export class UserNotification implements UserNotificationServer {
|
||||
id: number
|
||||
@ -238,7 +239,7 @@ export class UserNotification implements UserNotificationServer {
|
||||
}
|
||||
|
||||
private buildVideoUrl (video: { uuid: string }) {
|
||||
return '/w/' + video.uuid
|
||||
return Video.buildWatchUrl(video)
|
||||
}
|
||||
|
||||
private buildAccountUrl (account: { name: string, host: string }) {
|
||||
|
@ -26,12 +26,18 @@ export class Video implements VideoServerModel {
|
||||
licence: VideoConstant<number>
|
||||
language: VideoConstant<string>
|
||||
privacy: VideoConstant<VideoPrivacy>
|
||||
|
||||
description: string
|
||||
|
||||
duration: number
|
||||
durationLabel: string
|
||||
|
||||
id: number
|
||||
uuid: string
|
||||
shortUUID: string
|
||||
|
||||
isLocal: boolean
|
||||
|
||||
name: string
|
||||
serverHost: string
|
||||
thumbnailPath: string
|
||||
@ -85,8 +91,12 @@ export class Video implements VideoServerModel {
|
||||
|
||||
pluginData?: any
|
||||
|
||||
static buildClientUrl (videoUUID: string) {
|
||||
return '/w/' + videoUUID
|
||||
static buildWatchUrl (video: Partial<Pick<Video, 'uuid' | 'shortUUID'>>) {
|
||||
return '/w/' + (video.shortUUID || video.uuid)
|
||||
}
|
||||
|
||||
static buildUpdateUrl (video: Pick<Video, 'uuid'>) {
|
||||
return '/videos/update/' + video.uuid
|
||||
}
|
||||
|
||||
constructor (hash: VideoServerModel, translations = {}) {
|
||||
@ -109,6 +119,7 @@ export class Video implements VideoServerModel {
|
||||
|
||||
this.id = hash.id
|
||||
this.uuid = hash.uuid
|
||||
this.shortUUID = hash.shortUUID
|
||||
|
||||
this.isLocal = hash.isLocal
|
||||
this.name = hash.name
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Component, ElementRef, Input, ViewChild } from '@angular/core'
|
||||
import { VideoDetails } from '@app/shared/shared-main'
|
||||
import { Video, VideoDetails } from '@app/shared/shared-main'
|
||||
import { VideoPlaylist } from '@app/shared/shared-video-playlist'
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { VideoCaption } from '@shared/models'
|
||||
@ -98,14 +98,15 @@ export class VideoShareComponent {
|
||||
|
||||
getVideoUrl () {
|
||||
let baseUrl = this.customizations.originUrl ? this.video.originInstanceUrl : window.location.origin
|
||||
baseUrl += '/w/' + this.video.uuid
|
||||
baseUrl += Video.buildWatchUrl(this.video)
|
||||
|
||||
const options = this.getVideoOptions(baseUrl)
|
||||
|
||||
return buildVideoLink(options)
|
||||
}
|
||||
|
||||
getPlaylistUrl () {
|
||||
const base = window.location.origin + '/w/p/' + this.playlist.uuid
|
||||
const base = window.location.origin + VideoPlaylist.buildWatchUrl(this.playlist)
|
||||
|
||||
if (!this.includeVideoInPlaylist) return base
|
||||
|
||||
|
@ -12,7 +12,7 @@ export class VideoThumbnailComponent {
|
||||
@Input() video: Video
|
||||
@Input() nsfw = false
|
||||
|
||||
@Input() videoRouterLink: any[]
|
||||
@Input() videoRouterLink: string | any[]
|
||||
@Input() queryParams: { [ p: string ]: any }
|
||||
@Input() videoHref: string
|
||||
@Input() videoTarget: string
|
||||
@ -57,7 +57,7 @@ export class VideoThumbnailComponent {
|
||||
getVideoRouterLink () {
|
||||
if (this.videoRouterLink) return this.videoRouterLink
|
||||
|
||||
return [ '/w', this.video.uuid ]
|
||||
return Video.buildWatchUrl(this.video)
|
||||
}
|
||||
|
||||
onWatchLaterClick (event: Event) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { getAbsoluteAPIUrl } from '@app/helpers'
|
||||
import { Account, Actor } from '@app/shared/shared-main'
|
||||
import { Account, Actor, Video } from '@app/shared/shared-main'
|
||||
import { Account as AccountInterface, VideoComment as VideoCommentServerModel, VideoCommentAdmin as VideoCommentAdminServerModel } from '@shared/models'
|
||||
|
||||
export class VideoComment implements VideoCommentServerModel {
|
||||
@ -85,7 +85,7 @@ export class VideoCommentAdmin implements VideoCommentAdminServerModel {
|
||||
id: hash.video.id,
|
||||
uuid: hash.video.uuid,
|
||||
name: hash.video.name,
|
||||
localUrl: '/w/' + hash.video.uuid
|
||||
localUrl: Video.buildWatchUrl(hash.video)
|
||||
}
|
||||
|
||||
this.localUrl = this.video.localUrl + ';threadId=' + this.threadId
|
||||
|
@ -9,6 +9,7 @@ import {
|
||||
FeedFormat,
|
||||
ResultList,
|
||||
ThreadsResultList,
|
||||
Video,
|
||||
VideoComment as VideoCommentServerModel,
|
||||
VideoCommentAdmin,
|
||||
VideoCommentCreate,
|
||||
@ -127,7 +128,7 @@ export class VideoCommentService {
|
||||
)
|
||||
}
|
||||
|
||||
getVideoCommentsFeeds (videoUUID?: string) {
|
||||
getVideoCommentsFeeds (video: Pick<Video, 'uuid'>) {
|
||||
const feeds = [
|
||||
{
|
||||
format: FeedFormat.RSS,
|
||||
@ -146,9 +147,9 @@ export class VideoCommentService {
|
||||
}
|
||||
]
|
||||
|
||||
if (videoUUID !== undefined) {
|
||||
if (video !== undefined) {
|
||||
for (const feed of feeds) {
|
||||
feed.url += '?videoId=' + videoUUID
|
||||
feed.url += '?videoId=' + video.uuid
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ export class VideoMiniatureComponent implements OnInit {
|
||||
playlistElementId?: number
|
||||
}
|
||||
|
||||
videoRouterLink: any[] = []
|
||||
videoRouterLink: string | any[] = []
|
||||
videoHref: string
|
||||
videoTarget: string
|
||||
|
||||
@ -120,7 +120,7 @@ export class VideoMiniatureComponent implements OnInit {
|
||||
|
||||
buildVideoLink () {
|
||||
if (this.videoLinkType === 'internal' || !this.video.url) {
|
||||
this.videoRouterLink = [ '/w', this.video.uuid ]
|
||||
this.videoRouterLink = Video.buildWatchUrl(this.video)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ export class VideoPlaylistElementMiniatureComponent implements OnInit {
|
||||
buildRouterLink () {
|
||||
if (!this.playlist) return null
|
||||
|
||||
return [ '/w/p', this.playlist.uuid ]
|
||||
return VideoPlaylist.buildWatchUrl(this.playlist)
|
||||
}
|
||||
|
||||
buildRouterQuery () {
|
||||
|
@ -39,7 +39,7 @@ export class VideoPlaylistMiniatureComponent implements OnInit {
|
||||
}
|
||||
|
||||
if (this.linkType === 'internal' || !this.playlist.url) {
|
||||
this.routerLink = [ '/w/p', this.playlist.uuid ]
|
||||
this.routerLink = VideoPlaylist.buildWatchUrl(this.playlist)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,8 @@ import {
|
||||
export class VideoPlaylist implements ServerVideoPlaylist {
|
||||
id: number
|
||||
uuid: string
|
||||
shortUUID: string
|
||||
|
||||
isLocal: boolean
|
||||
|
||||
url: string
|
||||
@ -41,11 +43,17 @@ export class VideoPlaylist implements ServerVideoPlaylist {
|
||||
|
||||
videoChannelBy?: string
|
||||
|
||||
static buildWatchUrl (playlist: Pick<VideoPlaylist, 'uuid' | 'shortUUID'>) {
|
||||
return '/w/p/' + (playlist.uuid || playlist.shortUUID)
|
||||
}
|
||||
|
||||
constructor (hash: ServerVideoPlaylist, translations: {}) {
|
||||
const absoluteAPIUrl = getAbsoluteAPIUrl()
|
||||
|
||||
this.id = hash.id
|
||||
this.uuid = hash.uuid
|
||||
this.shortUUID = hash.shortUUID
|
||||
|
||||
this.url = hash.url
|
||||
this.isLocal = hash.isLocal
|
||||
|
||||
|
@ -131,6 +131,7 @@
|
||||
"sanitize-html": "2.x",
|
||||
"sequelize": "6.6.2",
|
||||
"sequelize-typescript": "^2.0.0-beta.1",
|
||||
"short-uuid": "^4.2.0",
|
||||
"sitemap": "^7.0.0",
|
||||
"socket.io": "^4.0.1",
|
||||
"sql-formatter": "^4.0.0-beta.0",
|
||||
@ -138,7 +139,6 @@
|
||||
"tsconfig-paths": "^3.9.0",
|
||||
"tslib": "^2.0.0",
|
||||
"useragent": "^2.3.0",
|
||||
"uuid": "^8.1.0",
|
||||
"validator": "^13.0.0",
|
||||
"webfinger.js": "^2.6.6",
|
||||
"webtorrent": "^1.0.0",
|
||||
|
@ -1,7 +1,7 @@
|
||||
import * as express from 'express'
|
||||
import * as RateLimit from 'express-rate-limit'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { logger } from '@server/helpers/logger'
|
||||
import { buildUUID } from '@server/helpers/uuid'
|
||||
import { CONFIG } from '@server/initializers/config'
|
||||
import { getAuthNameFromRefreshGrant, getBypassFromExternalAuth, getBypassFromPasswordGrant } from '@server/lib/auth/external-auth'
|
||||
import { handleOAuthToken } from '@server/lib/auth/oauth'
|
||||
@ -107,7 +107,7 @@ function getScopedTokens (req: express.Request, res: express.Response) {
|
||||
async function renewScopedTokens (req: express.Request, res: express.Response) {
|
||||
const user = res.locals.oauth.token.user
|
||||
|
||||
user.feedToken = uuidv4()
|
||||
user.feedToken = buildUUID()
|
||||
await user.save()
|
||||
|
||||
return res.json({
|
||||
|
@ -1,6 +1,8 @@
|
||||
import * as express from 'express'
|
||||
import { join } from 'path'
|
||||
import { uuidToShort } from '@server/helpers/uuid'
|
||||
import { scheduleRefreshIfNeeded } from '@server/lib/activitypub/playlists'
|
||||
import { Hooks } from '@server/lib/plugins/hooks'
|
||||
import { getServerActor } from '@server/models/application/application'
|
||||
import { MVideoPlaylistFull, MVideoPlaylistThumbnail, MVideoThumbnail } from '@server/types/models'
|
||||
import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
|
||||
@ -43,7 +45,6 @@ import {
|
||||
import { AccountModel } from '../../models/account/account'
|
||||
import { VideoPlaylistModel } from '../../models/video/video-playlist'
|
||||
import { VideoPlaylistElementModel } from '../../models/video/video-playlist-element'
|
||||
import { Hooks } from '@server/lib/plugins/hooks'
|
||||
|
||||
const reqThumbnailFile = createReqFiles([ 'thumbnailfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { thumbnailfile: CONFIG.STORAGE.TMP_DIR })
|
||||
|
||||
@ -199,6 +200,7 @@ async function addVideoPlaylist (req: express.Request, res: express.Response) {
|
||||
return res.json({
|
||||
videoPlaylist: {
|
||||
id: videoPlaylistCreated.id,
|
||||
shortUUID: uuidToShort(videoPlaylistCreated.uuid),
|
||||
uuid: videoPlaylistCreated.uuid
|
||||
}
|
||||
})
|
||||
|
@ -1,6 +1,6 @@
|
||||
import * as express from 'express'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { createReqFiles } from '@server/helpers/express-utils'
|
||||
import { buildUUID, uuidToShort } from '@server/helpers/uuid'
|
||||
import { CONFIG } from '@server/initializers/config'
|
||||
import { ASSETS_PATH, MIMETYPES } from '@server/initializers/constants'
|
||||
import { getLocalVideoActivityPubUrl } from '@server/lib/activitypub/url'
|
||||
@ -11,12 +11,12 @@ import { videoLiveAddValidator, videoLiveGetValidator, videoLiveUpdateValidator
|
||||
import { VideoLiveModel } from '@server/models/video/video-live'
|
||||
import { MVideoDetails, MVideoFullLight } from '@server/types/models'
|
||||
import { LiveVideoCreate, LiveVideoUpdate, VideoState } from '../../../../shared'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
import { logger } from '../../../helpers/logger'
|
||||
import { sequelizeTypescript } from '../../../initializers/database'
|
||||
import { updateVideoMiniatureFromExisting } from '../../../lib/thumbnail'
|
||||
import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate } from '../../../middlewares'
|
||||
import { VideoModel } from '../../../models/video/video'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
|
||||
const liveRouter = express.Router()
|
||||
|
||||
@ -94,7 +94,7 @@ async function addLiveVideo (req: express.Request, res: express.Response) {
|
||||
const videoLive = new VideoLiveModel()
|
||||
videoLive.saveReplay = videoInfo.saveReplay || false
|
||||
videoLive.permanentLive = videoInfo.permanentLive || false
|
||||
videoLive.streamKey = uuidv4()
|
||||
videoLive.streamKey = buildUUID()
|
||||
|
||||
const [ thumbnailModel, previewModel ] = await buildVideoThumbnailsFromReq({
|
||||
video,
|
||||
@ -138,6 +138,7 @@ async function addLiveVideo (req: express.Request, res: express.Response) {
|
||||
return res.json({
|
||||
video: {
|
||||
id: videoCreated.id,
|
||||
shortUUID: uuidToShort(videoCreated.uuid),
|
||||
uuid: videoCreated.uuid
|
||||
}
|
||||
})
|
||||
|
@ -2,6 +2,7 @@ import * as express from 'express'
|
||||
import { move } from 'fs-extra'
|
||||
import { getLowercaseExtension } from '@server/helpers/core-utils'
|
||||
import { deleteResumableUploadMetaFile, getResumableUploadPath } from '@server/helpers/upload'
|
||||
import { uuidToShort } from '@server/helpers/uuid'
|
||||
import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent'
|
||||
import { getLocalVideoActivityPubUrl } from '@server/lib/activitypub/url'
|
||||
import { addOptimizeOrMergeAudioJob, buildLocalVideoFromReq, buildVideoThumbnailsFromReq, setVideoTags } from '@server/lib/video'
|
||||
@ -218,6 +219,7 @@ async function addVideo (options: {
|
||||
return res.json({
|
||||
video: {
|
||||
id: videoCreated.id,
|
||||
shortUUID: uuidToShort(videoCreated.uuid),
|
||||
uuid: videoCreated.uuid
|
||||
}
|
||||
})
|
||||
|
@ -2,6 +2,7 @@ import 'multer'
|
||||
import { UploadFilesForCheck } from 'express'
|
||||
import { sep } from 'path'
|
||||
import validator from 'validator'
|
||||
import { isShortUUID, shortToUUID } from '../uuid'
|
||||
|
||||
function exists (value: any) {
|
||||
return value !== undefined && value !== null
|
||||
@ -50,42 +51,7 @@ function isIntOrNull (value: any) {
|
||||
return value === null || validator.isInt('' + value)
|
||||
}
|
||||
|
||||
function toIntOrNull (value: string) {
|
||||
const v = toValueOrNull(value)
|
||||
|
||||
if (v === null || v === undefined) return v
|
||||
if (typeof v === 'number') return v
|
||||
|
||||
return validator.toInt('' + v)
|
||||
}
|
||||
|
||||
function toBooleanOrNull (value: any) {
|
||||
const v = toValueOrNull(value)
|
||||
|
||||
if (v === null || v === undefined) return v
|
||||
if (typeof v === 'boolean') return v
|
||||
|
||||
return validator.toBoolean('' + v)
|
||||
}
|
||||
|
||||
function toValueOrNull (value: string) {
|
||||
if (value === 'null') return null
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
function toArray (value: any) {
|
||||
if (value && isArray(value) === false) return [ value ]
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
function toIntArray (value: any) {
|
||||
if (!value) return []
|
||||
if (isArray(value) === false) return [ validator.toInt(value) ]
|
||||
|
||||
return value.map(v => validator.toInt(v))
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function isFileFieldValid (
|
||||
files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[],
|
||||
@ -160,6 +126,51 @@ function isFileValid (
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function toCompleteUUID (value: string) {
|
||||
if (isShortUUID(value)) return shortToUUID(value)
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
function toIntOrNull (value: string) {
|
||||
const v = toValueOrNull(value)
|
||||
|
||||
if (v === null || v === undefined) return v
|
||||
if (typeof v === 'number') return v
|
||||
|
||||
return validator.toInt('' + v)
|
||||
}
|
||||
|
||||
function toBooleanOrNull (value: any) {
|
||||
const v = toValueOrNull(value)
|
||||
|
||||
if (v === null || v === undefined) return v
|
||||
if (typeof v === 'boolean') return v
|
||||
|
||||
return validator.toBoolean('' + v)
|
||||
}
|
||||
|
||||
function toValueOrNull (value: string) {
|
||||
if (value === 'null') return null
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
function toArray (value: any) {
|
||||
if (value && isArray(value) === false) return [ value ]
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
function toIntArray (value: any) {
|
||||
if (!value) return []
|
||||
if (isArray(value) === false) return [ validator.toInt(value) ]
|
||||
|
||||
return value.map(v => validator.toInt(v))
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
exists,
|
||||
isArrayOf,
|
||||
@ -169,6 +180,7 @@ export {
|
||||
isIdValid,
|
||||
isSafePath,
|
||||
isUUIDValid,
|
||||
toCompleteUUID,
|
||||
isIdOrUUIDValid,
|
||||
isDateValid,
|
||||
toValueOrNull,
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { copy, readFile, remove, rename } from 'fs-extra'
|
||||
import * as Jimp from 'jimp'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { getLowercaseExtension } from './core-utils'
|
||||
import { convertWebPToJPG, processGIF } from './ffmpeg-utils'
|
||||
import { logger } from './logger'
|
||||
import { buildUUID } from './uuid'
|
||||
|
||||
function generateImageFilename (extension = '.jpg') {
|
||||
return uuidv4() + extension
|
||||
return buildUUID() + extension
|
||||
}
|
||||
|
||||
async function processImage (
|
||||
|
32
server/helpers/uuid.ts
Normal file
32
server/helpers/uuid.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import * as short from 'short-uuid'
|
||||
|
||||
const translator = short()
|
||||
|
||||
function buildUUID () {
|
||||
return short.uuid()
|
||||
}
|
||||
|
||||
function uuidToShort (uuid: string) {
|
||||
if (!uuid) return uuid
|
||||
|
||||
return translator.fromUUID(uuid)
|
||||
}
|
||||
|
||||
function shortToUUID (shortUUID: string) {
|
||||
if (!shortUUID) return shortUUID
|
||||
|
||||
return translator.toUUID(shortUUID)
|
||||
}
|
||||
|
||||
function isShortUUID (value: string) {
|
||||
if (!value) return false
|
||||
|
||||
return value.length === translator.maxLength
|
||||
}
|
||||
|
||||
export {
|
||||
buildUUID,
|
||||
uuidToShort,
|
||||
shortToUUID,
|
||||
isShortUUID
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { buildUUID } from '@server/helpers/uuid'
|
||||
import * as Sequelize from 'sequelize'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
async function up (utils: {
|
||||
transaction: Sequelize.Transaction
|
||||
@ -23,7 +23,7 @@ async function up (utils: {
|
||||
{
|
||||
const authors = await utils.db.Author.findAll()
|
||||
for (const author of authors) {
|
||||
author.uuid = uuidv4()
|
||||
author.uuid = buildUUID()
|
||||
await author.save()
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import * as Sequelize from 'sequelize'
|
||||
import { buildUUID } from '@server/helpers/uuid'
|
||||
import { VideoPlaylistPrivacy, VideoPlaylistType } from '../../../shared/models/videos'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { WEBSERVER } from '../constants'
|
||||
|
||||
async function up (utils: {
|
||||
@ -57,7 +57,7 @@ CREATE TABLE IF NOT EXISTS "videoPlaylistElement"
|
||||
const usernames = userResult.map(r => r.username)
|
||||
|
||||
for (const username of usernames) {
|
||||
const uuid = uuidv4()
|
||||
const uuid = buildUUID()
|
||||
|
||||
const baseUrl = WEBSERVER.URL + '/video-playlists/' + uuid
|
||||
const query = `
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as Sequelize from 'sequelize'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { buildUUID } from '@server/helpers/uuid'
|
||||
|
||||
async function up (utils: {
|
||||
transaction: Sequelize.Transaction
|
||||
@ -26,7 +26,7 @@ async function up (utils: {
|
||||
const users = await utils.sequelize.query<any>(query, options)
|
||||
|
||||
for (const user of users) {
|
||||
const queryUpdate = `UPDATE "user" SET "feedToken" = '${uuidv4()}' WHERE id = ${user.id}`
|
||||
const queryUpdate = `UPDATE "user" SET "feedToken" = '${buildUUID()}' WHERE id = ${user.id}`
|
||||
await utils.sequelize.query(queryUpdate)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { getLowercaseExtension } from '@server/helpers/core-utils'
|
||||
import { isActivityPubUrlValid } from '@server/helpers/custom-validators/activitypub/misc'
|
||||
import { buildUUID } from '@server/helpers/uuid'
|
||||
import { MIMETYPES } from '@server/initializers/constants'
|
||||
import { ActorModel } from '@server/models/actor/actor'
|
||||
import { FilteredModelAttributes } from '@server/types'
|
||||
@ -51,7 +51,7 @@ function getImageInfoFromObject (actorObject: ActivityPubActor, type: ActorImage
|
||||
if (!extension) return undefined
|
||||
|
||||
return {
|
||||
name: uuidv4() + extension,
|
||||
name: buildUUID() + extension,
|
||||
fileUrl: icon.url,
|
||||
height: icon.height,
|
||||
width: icon.width,
|
||||
|
@ -27,6 +27,7 @@ import { VideoChannelModel } from '../models/video/video-channel'
|
||||
import { VideoPlaylistModel } from '../models/video/video-playlist'
|
||||
import { MAccountActor, MChannelActor } from '../types/models'
|
||||
import { ServerConfigManager } from './server-config-manager'
|
||||
import { toCompleteUUID } from '@server/helpers/custom-validators/misc'
|
||||
|
||||
type Tags = {
|
||||
ogType: string
|
||||
@ -78,7 +79,9 @@ class ClientHtml {
|
||||
return customHtml
|
||||
}
|
||||
|
||||
static async getWatchHTMLPage (videoId: string, req: express.Request, res: express.Response) {
|
||||
static async getWatchHTMLPage (videoIdArg: string, req: express.Request, res: express.Response) {
|
||||
const videoId = toCompleteUUID(videoIdArg)
|
||||
|
||||
// Let Angular application handle errors
|
||||
if (!validator.isInt(videoId) && !validator.isUUID(videoId, 4)) {
|
||||
res.status(HttpStatusCode.NOT_FOUND_404)
|
||||
@ -136,7 +139,9 @@ class ClientHtml {
|
||||
return customHtml
|
||||
}
|
||||
|
||||
static async getWatchPlaylistHTMLPage (videoPlaylistId: string, req: express.Request, res: express.Response) {
|
||||
static async getWatchPlaylistHTMLPage (videoPlaylistIdArg: string, req: express.Request, res: express.Response) {
|
||||
const videoPlaylistId = toCompleteUUID(videoPlaylistIdArg)
|
||||
|
||||
// Let Angular application handle errors
|
||||
if (!validator.isInt(videoPlaylistId) && !validator.isUUID(videoPlaylistId, 4)) {
|
||||
res.status(HttpStatusCode.NOT_FOUND_404)
|
||||
|
@ -2,8 +2,8 @@ import 'multer'
|
||||
import { queue } from 'async'
|
||||
import * as LRUCache from 'lru-cache'
|
||||
import { join } from 'path'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { getLowercaseExtension } from '@server/helpers/core-utils'
|
||||
import { buildUUID } from '@server/helpers/uuid'
|
||||
import { ActorModel } from '@server/models/actor/actor'
|
||||
import { ActivityPubActorType, ActorImageType } from '@shared/models'
|
||||
import { retryTransactionWrapper } from '../helpers/database-utils'
|
||||
@ -44,7 +44,7 @@ async function updateLocalActorImageFile (
|
||||
|
||||
const extension = getLowercaseExtension(imagePhysicalFile.filename)
|
||||
|
||||
const imageName = uuidv4() + extension
|
||||
const imageName = buildUUID() + extension
|
||||
const destination = join(CONFIG.STORAGE.ACTOR_IMAGES, imageName)
|
||||
await processImage(imagePhysicalFile.path, destination, imageSize)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Transaction } from 'sequelize/types'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { buildUUID } from '@server/helpers/uuid'
|
||||
import { UserModel } from '@server/models/user/user'
|
||||
import { MActorDefault } from '@server/types/models/actor'
|
||||
import { ActivityPubActorType } from '../../shared/models/activitypub'
|
||||
@ -210,7 +210,7 @@ async function buildChannelAttributes (user: MUser, transaction?: Transaction, c
|
||||
|
||||
// Conflict, generate uuid instead
|
||||
const actor = await ActorModel.loadLocalByName(channelName, transaction)
|
||||
if (actor) channelName = uuidv4()
|
||||
if (actor) channelName = buildUUID()
|
||||
|
||||
const videoChannelDisplayName = `Main ${user.username} channel`
|
||||
|
||||
|
@ -12,7 +12,7 @@ import {
|
||||
isAbuseTimestampValid,
|
||||
isAbuseVideoIsValid
|
||||
} from '@server/helpers/custom-validators/abuses'
|
||||
import { exists, isIdOrUUIDValid, isIdValid, toIntOrNull } from '@server/helpers/custom-validators/misc'
|
||||
import { exists, isIdOrUUIDValid, isIdValid, toCompleteUUID, toIntOrNull } from '@server/helpers/custom-validators/misc'
|
||||
import { logger } from '@server/helpers/logger'
|
||||
import { AbuseMessageModel } from '@server/models/abuse/abuse-message'
|
||||
import { AbuseCreate, UserRight } from '@shared/models'
|
||||
@ -27,6 +27,7 @@ const abuseReportValidator = [
|
||||
|
||||
body('video.id')
|
||||
.optional()
|
||||
.customSanitizer(toCompleteUUID)
|
||||
.custom(isIdOrUUIDValid)
|
||||
.withMessage('Should have a valid videoId'),
|
||||
body('video.startAt')
|
||||
|
@ -1,8 +1,9 @@
|
||||
import * as express from 'express'
|
||||
import { param, query } from 'express-validator'
|
||||
|
||||
import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
|
||||
import { isValidRSSFeed } from '../../helpers/custom-validators/feeds'
|
||||
import { exists, isIdOrUUIDValid, isIdValid } from '../../helpers/custom-validators/misc'
|
||||
import { exists, isIdOrUUIDValid, isIdValid, toCompleteUUID } from '../../helpers/custom-validators/misc'
|
||||
import { logger } from '../../helpers/logger'
|
||||
import {
|
||||
areValidationErrors,
|
||||
@ -98,7 +99,10 @@ const videoSubscriptionFeedsValidator = [
|
||||
]
|
||||
|
||||
const videoCommentsFeedsValidator = [
|
||||
query('videoId').optional().custom(isIdOrUUIDValid),
|
||||
query('videoId')
|
||||
.customSanitizer(toCompleteUUID)
|
||||
.optional()
|
||||
.custom(isIdOrUUIDValid),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug('Checking feeds parameters', { parameters: req.query })
|
||||
|
@ -11,7 +11,7 @@ export * from './sort'
|
||||
export * from './users'
|
||||
export * from './user-subscriptions'
|
||||
export * from './videos'
|
||||
export * from './webfinger'
|
||||
export * from './search'
|
||||
export * from './server'
|
||||
export * from './user-history'
|
||||
export * from './webfinger'
|
||||
|
@ -6,7 +6,7 @@ import { VideoPlaylistModel } from '@server/models/video/video-playlist'
|
||||
import { VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models'
|
||||
import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
|
||||
import { isTestInstance } from '../../helpers/core-utils'
|
||||
import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc'
|
||||
import { isIdOrUUIDValid, toCompleteUUID } from '../../helpers/custom-validators/misc'
|
||||
import { logger } from '../../helpers/logger'
|
||||
import { WEBSERVER } from '../../initializers/constants'
|
||||
import { areValidationErrors } from './shared'
|
||||
@ -79,7 +79,7 @@ const oembedValidator = [
|
||||
})
|
||||
}
|
||||
|
||||
const elementId = matches[1]
|
||||
const elementId = toCompleteUUID(matches[1])
|
||||
if (isIdOrUUIDValid(elementId) === false) {
|
||||
return res.fail({ message: 'Invalid video or playlist id.' })
|
||||
}
|
||||
|
@ -2,15 +2,24 @@ import * as express from 'express'
|
||||
import { body, param, query } from 'express-validator'
|
||||
import { isVideoRedundancyTarget } from '@server/helpers/custom-validators/video-redundancies'
|
||||
import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
|
||||
import { exists, isBooleanValid, isIdOrUUIDValid, isIdValid, toBooleanOrNull, toIntOrNull } from '../../helpers/custom-validators/misc'
|
||||
import {
|
||||
exists,
|
||||
isBooleanValid,
|
||||
isIdOrUUIDValid,
|
||||
isIdValid,
|
||||
toBooleanOrNull,
|
||||
toCompleteUUID,
|
||||
toIntOrNull
|
||||
} from '../../helpers/custom-validators/misc'
|
||||
import { isHostValid } from '../../helpers/custom-validators/servers'
|
||||
import { logger } from '../../helpers/logger'
|
||||
import { VideoRedundancyModel } from '../../models/redundancy/video-redundancy'
|
||||
import { ServerModel } from '../../models/server/server'
|
||||
import { areValidationErrors, doesVideoExist } from './shared'
|
||||
import { areValidationErrors, doesVideoExist, isValidVideoIdParam } from './shared'
|
||||
|
||||
const videoFileRedundancyGetValidator = [
|
||||
param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'),
|
||||
isValidVideoIdParam('videoId'),
|
||||
|
||||
param('resolution')
|
||||
.customSanitizer(toIntOrNull)
|
||||
.custom(exists).withMessage('Should have a valid resolution'),
|
||||
@ -56,9 +65,8 @@ const videoFileRedundancyGetValidator = [
|
||||
]
|
||||
|
||||
const videoPlaylistRedundancyGetValidator = [
|
||||
param('videoId')
|
||||
.custom(isIdOrUUIDValid)
|
||||
.not().isEmpty().withMessage('Should have a valid video id'),
|
||||
isValidVideoIdParam('videoId'),
|
||||
|
||||
param('streamingPlaylistType')
|
||||
.customSanitizer(toIntOrNull)
|
||||
.custom(exists).withMessage('Should have a valid streaming playlist type'),
|
||||
@ -135,7 +143,8 @@ const listVideoRedundanciesValidator = [
|
||||
|
||||
const addVideoRedundancyValidator = [
|
||||
body('videoId')
|
||||
.custom(isIdValid)
|
||||
.customSanitizer(toCompleteUUID)
|
||||
.custom(isIdOrUUIDValid)
|
||||
.withMessage('Should have a valid video id'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import * as express from 'express'
|
||||
import { query, validationResult } from 'express-validator'
|
||||
import { param, query, validationResult } from 'express-validator'
|
||||
import { isIdOrUUIDValid, toCompleteUUID } from '@server/helpers/custom-validators/misc'
|
||||
import { logger } from '../../../helpers/logger'
|
||||
|
||||
function areValidationErrors (req: express.Request, res: express.Response) {
|
||||
@ -41,10 +42,24 @@ function createSortableColumns (sortableColumns: string[]) {
|
||||
return sortableColumns.concat(sortableColumnDesc)
|
||||
}
|
||||
|
||||
function isValidVideoIdParam (paramName: string) {
|
||||
return param(paramName)
|
||||
.customSanitizer(toCompleteUUID)
|
||||
.custom(isIdOrUUIDValid).withMessage('Should have a valid video id')
|
||||
}
|
||||
|
||||
function isValidPlaylistIdParam (paramName: string) {
|
||||
return param(paramName)
|
||||
.customSanitizer(toCompleteUUID)
|
||||
.custom(isIdOrUUIDValid).withMessage('Should have a valid playlist id')
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
areValidationErrors,
|
||||
checkSort,
|
||||
createSortableColumns
|
||||
createSortableColumns,
|
||||
isValidVideoIdParam,
|
||||
isValidPlaylistIdParam
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-code
|
||||
import { UserRole } from '../../../shared/models/users'
|
||||
import { UserRegister } from '../../../shared/models/users/user-register.model'
|
||||
import { isActorPreferredUsernameValid } from '../../helpers/custom-validators/activitypub/actor'
|
||||
import { isIdOrUUIDValid, toBooleanOrNull, toIntOrNull } from '../../helpers/custom-validators/misc'
|
||||
import { toBooleanOrNull, toIntOrNull } from '../../helpers/custom-validators/misc'
|
||||
import { isThemeNameValid } from '../../helpers/custom-validators/plugins'
|
||||
import {
|
||||
isNoInstanceConfigWarningModal,
|
||||
@ -35,7 +35,7 @@ import { Redis } from '../../lib/redis'
|
||||
import { isSignupAllowed, isSignupAllowedForCurrentIP } from '../../lib/signup'
|
||||
import { ActorModel } from '../../models/actor/actor'
|
||||
import { UserModel } from '../../models/user/user'
|
||||
import { areValidationErrors, doesVideoExist } from './shared'
|
||||
import { areValidationErrors, doesVideoExist, isValidVideoIdParam } from './shared'
|
||||
|
||||
const usersListValidator = [
|
||||
query('blocked')
|
||||
@ -302,7 +302,7 @@ const usersGetValidator = [
|
||||
]
|
||||
|
||||
const usersVideoRatingValidator = [
|
||||
param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'),
|
||||
isValidVideoIdParam('videoId'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug('Checking usersVideoRating parameters', { parameters: req.params })
|
||||
|
@ -1,13 +1,13 @@
|
||||
import * as express from 'express'
|
||||
import { body, param, query } from 'express-validator'
|
||||
import { body, query } from 'express-validator'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
import { isBooleanValid, isIdOrUUIDValid, toBooleanOrNull, toIntOrNull } from '../../../helpers/custom-validators/misc'
|
||||
import { isBooleanValid, toBooleanOrNull, toIntOrNull } from '../../../helpers/custom-validators/misc'
|
||||
import { isVideoBlacklistReasonValid, isVideoBlacklistTypeValid } from '../../../helpers/custom-validators/video-blacklist'
|
||||
import { logger } from '../../../helpers/logger'
|
||||
import { areValidationErrors, doesVideoBlacklistExist, doesVideoExist } from '../shared'
|
||||
import { areValidationErrors, doesVideoBlacklistExist, doesVideoExist, isValidVideoIdParam } from '../shared'
|
||||
|
||||
const videosBlacklistRemoveValidator = [
|
||||
param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
|
||||
isValidVideoIdParam('videoId'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug('Checking blacklistRemove parameters.', { parameters: req.params })
|
||||
@ -21,7 +21,8 @@ const videosBlacklistRemoveValidator = [
|
||||
]
|
||||
|
||||
const videosBlacklistAddValidator = [
|
||||
param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
|
||||
isValidVideoIdParam('videoId'),
|
||||
|
||||
body('unfederate')
|
||||
.optional()
|
||||
.customSanitizer(toBooleanOrNull)
|
||||
@ -49,7 +50,8 @@ const videosBlacklistAddValidator = [
|
||||
]
|
||||
|
||||
const videosBlacklistUpdateValidator = [
|
||||
param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
|
||||
isValidVideoIdParam('videoId'),
|
||||
|
||||
body('reason')
|
||||
.optional()
|
||||
.custom(isVideoBlacklistReasonValid).withMessage('Should have a valid reason'),
|
||||
|
@ -1,16 +1,18 @@
|
||||
import * as express from 'express'
|
||||
import { body, param } from 'express-validator'
|
||||
import { UserRight } from '../../../../shared'
|
||||
import { isIdOrUUIDValid } from '../../../helpers/custom-validators/misc'
|
||||
import { isVideoCaptionFile, isVideoCaptionLanguageValid } from '../../../helpers/custom-validators/video-captions'
|
||||
import { cleanUpReqFiles } from '../../../helpers/express-utils'
|
||||
import { logger } from '../../../helpers/logger'
|
||||
import { CONSTRAINTS_FIELDS, MIMETYPES } from '../../../initializers/constants'
|
||||
import { areValidationErrors, checkUserCanManageVideo, doesVideoCaptionExist, doesVideoExist } from '../shared'
|
||||
import { areValidationErrors, checkUserCanManageVideo, doesVideoCaptionExist, doesVideoExist, isValidVideoIdParam } from '../shared'
|
||||
|
||||
const addVideoCaptionValidator = [
|
||||
param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'),
|
||||
param('captionLanguage').custom(isVideoCaptionLanguageValid).not().isEmpty().withMessage('Should have a valid caption language'),
|
||||
isValidVideoIdParam('videoId'),
|
||||
|
||||
param('captionLanguage')
|
||||
.custom(isVideoCaptionLanguageValid).not().isEmpty().withMessage('Should have a valid caption language'),
|
||||
|
||||
body('captionfile')
|
||||
.custom((_, { req }) => isVideoCaptionFile(req.files, 'captionfile'))
|
||||
.withMessage(
|
||||
@ -34,8 +36,10 @@ const addVideoCaptionValidator = [
|
||||
]
|
||||
|
||||
const deleteVideoCaptionValidator = [
|
||||
param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'),
|
||||
param('captionLanguage').custom(isVideoCaptionLanguageValid).not().isEmpty().withMessage('Should have a valid caption language'),
|
||||
isValidVideoIdParam('videoId'),
|
||||
|
||||
param('captionLanguage')
|
||||
.custom(isVideoCaptionLanguageValid).not().isEmpty().withMessage('Should have a valid caption language'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug('Checking deleteVideoCaption parameters', { parameters: req.params })
|
||||
@ -53,7 +57,7 @@ const deleteVideoCaptionValidator = [
|
||||
]
|
||||
|
||||
const listVideoCaptionsValidator = [
|
||||
param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'),
|
||||
isValidVideoIdParam('videoId'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug('Checking listVideoCaptions parameters', { parameters: req.params })
|
||||
|
@ -3,13 +3,13 @@ import { body, param, query } from 'express-validator'
|
||||
import { MUserAccountUrl } from '@server/types/models'
|
||||
import { UserRight } from '../../../../shared'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
import { exists, isBooleanValid, isIdOrUUIDValid, isIdValid, toBooleanOrNull } from '../../../helpers/custom-validators/misc'
|
||||
import { exists, isBooleanValid, isIdValid, toBooleanOrNull } from '../../../helpers/custom-validators/misc'
|
||||
import { isValidVideoCommentText } from '../../../helpers/custom-validators/video-comments'
|
||||
import { logger } from '../../../helpers/logger'
|
||||
import { AcceptResult, isLocalVideoCommentReplyAccepted, isLocalVideoThreadAccepted } from '../../../lib/moderation'
|
||||
import { Hooks } from '../../../lib/plugins/hooks'
|
||||
import { MCommentOwnerVideoReply, MVideo, MVideoFullLight } from '../../../types/models/video'
|
||||
import { areValidationErrors, doesVideoCommentExist, doesVideoCommentThreadExist, doesVideoExist } from '../shared'
|
||||
import { areValidationErrors, doesVideoCommentExist, doesVideoCommentThreadExist, doesVideoExist, isValidVideoIdParam } from '../shared'
|
||||
|
||||
const listVideoCommentsValidator = [
|
||||
query('isLocal')
|
||||
@ -40,7 +40,7 @@ const listVideoCommentsValidator = [
|
||||
]
|
||||
|
||||
const listVideoCommentThreadsValidator = [
|
||||
param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
|
||||
isValidVideoIdParam('videoId'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug('Checking listVideoCommentThreads parameters.', { parameters: req.params })
|
||||
@ -53,8 +53,10 @@ const listVideoCommentThreadsValidator = [
|
||||
]
|
||||
|
||||
const listVideoThreadCommentsValidator = [
|
||||
param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
|
||||
param('threadId').custom(isIdValid).not().isEmpty().withMessage('Should have a valid threadId'),
|
||||
isValidVideoIdParam('videoId'),
|
||||
|
||||
param('threadId')
|
||||
.custom(isIdValid).not().isEmpty().withMessage('Should have a valid threadId'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug('Checking listVideoThreadComments parameters.', { parameters: req.params })
|
||||
@ -68,8 +70,10 @@ const listVideoThreadCommentsValidator = [
|
||||
]
|
||||
|
||||
const addVideoCommentThreadValidator = [
|
||||
param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
|
||||
body('text').custom(isValidVideoCommentText).not().isEmpty().withMessage('Should have a valid comment text'),
|
||||
isValidVideoIdParam('videoId'),
|
||||
|
||||
body('text')
|
||||
.custom(isValidVideoCommentText).not().isEmpty().withMessage('Should have a valid comment text'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug('Checking addVideoCommentThread parameters.', { parameters: req.params, body: req.body })
|
||||
@ -84,8 +88,10 @@ const addVideoCommentThreadValidator = [
|
||||
]
|
||||
|
||||
const addVideoCommentReplyValidator = [
|
||||
param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
|
||||
isValidVideoIdParam('videoId'),
|
||||
|
||||
param('commentId').custom(isIdValid).not().isEmpty().withMessage('Should have a valid commentId'),
|
||||
|
||||
body('text').custom(isValidVideoCommentText).not().isEmpty().withMessage('Should have a valid comment text'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
@ -102,8 +108,10 @@ const addVideoCommentReplyValidator = [
|
||||
]
|
||||
|
||||
const videoCommentGetValidator = [
|
||||
param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
|
||||
param('commentId').custom(isIdValid).not().isEmpty().withMessage('Should have a valid commentId'),
|
||||
isValidVideoIdParam('videoId'),
|
||||
|
||||
param('commentId')
|
||||
.custom(isIdValid).not().isEmpty().withMessage('Should have a valid commentId'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug('Checking videoCommentGetValidator parameters.', { parameters: req.params })
|
||||
@ -117,7 +125,8 @@ const videoCommentGetValidator = [
|
||||
]
|
||||
|
||||
const removeVideoCommentValidator = [
|
||||
param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
|
||||
isValidVideoIdParam('videoId'),
|
||||
|
||||
param('commentId').custom(isIdValid).not().isEmpty().withMessage('Should have a valid commentId'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as express from 'express'
|
||||
import { body, param } from 'express-validator'
|
||||
import { body } from 'express-validator'
|
||||
import { CONSTRAINTS_FIELDS } from '@server/initializers/constants'
|
||||
import { isLocalLiveVideoAccepted } from '@server/lib/moderation'
|
||||
import { Hooks } from '@server/lib/plugins/hooks'
|
||||
@ -7,16 +7,22 @@ import { VideoModel } from '@server/models/video/video'
|
||||
import { VideoLiveModel } from '@server/models/video/video-live'
|
||||
import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
|
||||
import { ServerErrorCode, UserRight, VideoState } from '@shared/models'
|
||||
import { isBooleanValid, isIdOrUUIDValid, isIdValid, toBooleanOrNull, toIntOrNull } from '../../../helpers/custom-validators/misc'
|
||||
import { isBooleanValid, isIdValid, toBooleanOrNull, toIntOrNull } from '../../../helpers/custom-validators/misc'
|
||||
import { isVideoNameValid } from '../../../helpers/custom-validators/videos'
|
||||
import { cleanUpReqFiles } from '../../../helpers/express-utils'
|
||||
import { logger } from '../../../helpers/logger'
|
||||
import { CONFIG } from '../../../initializers/config'
|
||||
import { areValidationErrors, checkUserCanManageVideo, doesVideoChannelOfAccountExist, doesVideoExist } from '../shared'
|
||||
import {
|
||||
areValidationErrors,
|
||||
checkUserCanManageVideo,
|
||||
doesVideoChannelOfAccountExist,
|
||||
doesVideoExist,
|
||||
isValidVideoIdParam
|
||||
} from '../shared'
|
||||
import { getCommonVideoEditAttributes } from './videos'
|
||||
|
||||
const videoLiveGetValidator = [
|
||||
param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
|
||||
isValidVideoIdParam('videoId'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug('Checking videoLiveGetValidator parameters', { parameters: req.params, user: res.locals.oauth.token.User.username })
|
||||
|
@ -1,6 +1,6 @@
|
||||
import * as express from 'express'
|
||||
import { param } from 'express-validator'
|
||||
import { isIdOrUUIDValid } from '@server/helpers/custom-validators/misc'
|
||||
import { isIdValid } from '@server/helpers/custom-validators/misc'
|
||||
import { checkUserCanTerminateOwnershipChange } from '@server/helpers/custom-validators/video-ownership'
|
||||
import { logger } from '@server/helpers/logger'
|
||||
import { isAbleToUploadVideo } from '@server/lib/user'
|
||||
@ -13,11 +13,12 @@ import {
|
||||
checkUserCanManageVideo,
|
||||
doesChangeVideoOwnershipExist,
|
||||
doesVideoChannelOfAccountExist,
|
||||
doesVideoExist
|
||||
doesVideoExist,
|
||||
isValidVideoIdParam
|
||||
} from '../shared'
|
||||
|
||||
const videosChangeOwnershipValidator = [
|
||||
param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
|
||||
isValidVideoIdParam('videoId'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug('Checking changeOwnership parameters', { parameters: req.params })
|
||||
@ -40,7 +41,8 @@ const videosChangeOwnershipValidator = [
|
||||
]
|
||||
|
||||
const videosTerminateChangeOwnershipValidator = [
|
||||
param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
|
||||
param('id')
|
||||
.custom(isIdValid).withMessage('Should have a valid id'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug('Checking changeOwnership parameters', { parameters: req.params })
|
||||
|
@ -11,6 +11,7 @@ import {
|
||||
isIdOrUUIDValid,
|
||||
isIdValid,
|
||||
isUUIDValid,
|
||||
toCompleteUUID,
|
||||
toIntArray,
|
||||
toIntOrNull,
|
||||
toValueOrNull
|
||||
@ -29,7 +30,14 @@ import { CONSTRAINTS_FIELDS } from '../../../initializers/constants'
|
||||
import { VideoPlaylistElementModel } from '../../../models/video/video-playlist-element'
|
||||
import { MVideoPlaylist } from '../../../types/models/video/video-playlist'
|
||||
import { authenticatePromiseIfNeeded } from '../../auth'
|
||||
import { areValidationErrors, doesVideoChannelIdExist, doesVideoExist, doesVideoPlaylistExist, VideoPlaylistFetchType } from '../shared'
|
||||
import {
|
||||
areValidationErrors,
|
||||
doesVideoChannelIdExist,
|
||||
doesVideoExist,
|
||||
doesVideoPlaylistExist,
|
||||
isValidPlaylistIdParam,
|
||||
VideoPlaylistFetchType
|
||||
} from '../shared'
|
||||
|
||||
const videoPlaylistsAddValidator = getCommonPlaylistEditAttributes().concat([
|
||||
body('displayName')
|
||||
@ -43,10 +51,13 @@ const videoPlaylistsAddValidator = getCommonPlaylistEditAttributes().concat([
|
||||
const body: VideoPlaylistCreate = req.body
|
||||
if (body.videoChannelId && !await doesVideoChannelIdExist(body.videoChannelId, res)) return cleanUpReqFiles(req)
|
||||
|
||||
if (body.privacy === VideoPlaylistPrivacy.PUBLIC && !body.videoChannelId) {
|
||||
if (
|
||||
!body.videoChannelId &&
|
||||
(body.privacy === VideoPlaylistPrivacy.PUBLIC || body.privacy === VideoPlaylistPrivacy.UNLISTED)
|
||||
) {
|
||||
cleanUpReqFiles(req)
|
||||
|
||||
return res.fail({ message: 'Cannot set "public" a playlist that is not assigned to a channel.' })
|
||||
return res.fail({ message: 'Cannot set "public" or "unlisted" a playlist that is not assigned to a channel.' })
|
||||
}
|
||||
|
||||
return next()
|
||||
@ -54,8 +65,7 @@ const videoPlaylistsAddValidator = getCommonPlaylistEditAttributes().concat([
|
||||
])
|
||||
|
||||
const videoPlaylistsUpdateValidator = getCommonPlaylistEditAttributes().concat([
|
||||
param('playlistId')
|
||||
.custom(isIdOrUUIDValid).withMessage('Should have a valid playlist id/uuid'),
|
||||
isValidPlaylistIdParam('playlistId'),
|
||||
|
||||
body('displayName')
|
||||
.optional()
|
||||
@ -101,8 +111,7 @@ const videoPlaylistsUpdateValidator = getCommonPlaylistEditAttributes().concat([
|
||||
])
|
||||
|
||||
const videoPlaylistsDeleteValidator = [
|
||||
param('playlistId')
|
||||
.custom(isIdOrUUIDValid).withMessage('Should have a valid playlist id/uuid'),
|
||||
isValidPlaylistIdParam('playlistId'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug('Checking videoPlaylistsDeleteValidator parameters', { parameters: req.params })
|
||||
@ -126,8 +135,7 @@ const videoPlaylistsDeleteValidator = [
|
||||
|
||||
const videoPlaylistsGetValidator = (fetchType: VideoPlaylistFetchType) => {
|
||||
return [
|
||||
param('playlistId')
|
||||
.custom(isIdOrUUIDValid).withMessage('Should have a valid playlist id/uuid'),
|
||||
isValidPlaylistIdParam('playlistId'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug('Checking videoPlaylistsGetValidator parameters', { parameters: req.params })
|
||||
@ -184,9 +192,10 @@ const videoPlaylistsSearchValidator = [
|
||||
]
|
||||
|
||||
const videoPlaylistsAddVideoValidator = [
|
||||
param('playlistId')
|
||||
.custom(isIdOrUUIDValid).withMessage('Should have a valid playlist id/uuid'),
|
||||
isValidPlaylistIdParam('playlistId'),
|
||||
|
||||
body('videoId')
|
||||
.customSanitizer(toCompleteUUID)
|
||||
.custom(isIdOrUUIDValid).withMessage('Should have a valid video id/uuid'),
|
||||
body('startTimestamp')
|
||||
.optional()
|
||||
@ -214,9 +223,9 @@ const videoPlaylistsAddVideoValidator = [
|
||||
]
|
||||
|
||||
const videoPlaylistsUpdateOrRemoveVideoValidator = [
|
||||
param('playlistId')
|
||||
.custom(isIdOrUUIDValid).withMessage('Should have a valid playlist id/uuid'),
|
||||
isValidPlaylistIdParam('playlistId'),
|
||||
param('playlistElementId')
|
||||
.customSanitizer(toCompleteUUID)
|
||||
.custom(isIdValid).withMessage('Should have an element id/uuid'),
|
||||
body('startTimestamp')
|
||||
.optional()
|
||||
@ -251,8 +260,7 @@ const videoPlaylistsUpdateOrRemoveVideoValidator = [
|
||||
]
|
||||
|
||||
const videoPlaylistElementAPGetValidator = [
|
||||
param('playlistId')
|
||||
.custom(isIdOrUUIDValid).withMessage('Should have a valid playlist id/uuid'),
|
||||
isValidPlaylistIdParam('playlistId'),
|
||||
param('playlistElementId')
|
||||
.custom(isIdValid).withMessage('Should have an playlist element id'),
|
||||
|
||||
@ -287,8 +295,7 @@ const videoPlaylistElementAPGetValidator = [
|
||||
]
|
||||
|
||||
const videoPlaylistsReorderVideosValidator = [
|
||||
param('playlistId')
|
||||
.custom(isIdOrUUIDValid).withMessage('Should have a valid playlist id/uuid'),
|
||||
isValidPlaylistIdParam('playlistId'),
|
||||
body('startPosition')
|
||||
.isInt({ min: 1 }).withMessage('Should have a valid start position'),
|
||||
body('insertAfterPosition')
|
||||
|
@ -3,15 +3,16 @@ import { body, param, query } from 'express-validator'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
import { VideoRateType } from '../../../../shared/models/videos'
|
||||
import { isAccountNameValid } from '../../../helpers/custom-validators/accounts'
|
||||
import { isIdOrUUIDValid, isIdValid } from '../../../helpers/custom-validators/misc'
|
||||
import { isIdValid } from '../../../helpers/custom-validators/misc'
|
||||
import { isRatingValid } from '../../../helpers/custom-validators/video-rates'
|
||||
import { isVideoRatingTypeValid } from '../../../helpers/custom-validators/videos'
|
||||
import { logger } from '../../../helpers/logger'
|
||||
import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
|
||||
import { areValidationErrors, doesVideoExist } from '../shared'
|
||||
import { areValidationErrors, doesVideoExist, isValidVideoIdParam } from '../shared'
|
||||
|
||||
const videoUpdateRateValidator = [
|
||||
param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
|
||||
isValidVideoIdParam('id'),
|
||||
|
||||
body('rating').custom(isVideoRatingTypeValid).withMessage('Should have a valid rate type'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
|
@ -1,14 +1,16 @@
|
||||
import * as express from 'express'
|
||||
import { param } from 'express-validator'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
import { isIdOrUUIDValid, isIdValid } from '../../../helpers/custom-validators/misc'
|
||||
import { isIdValid } from '../../../helpers/custom-validators/misc'
|
||||
import { logger } from '../../../helpers/logger'
|
||||
import { VideoShareModel } from '../../../models/video/video-share'
|
||||
import { areValidationErrors, doesVideoExist } from '../shared'
|
||||
import { areValidationErrors, doesVideoExist, isValidVideoIdParam } from '../shared'
|
||||
|
||||
const videosShareValidator = [
|
||||
param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
|
||||
param('actorId').custom(isIdValid).not().isEmpty().withMessage('Should have a valid actor id'),
|
||||
isValidVideoIdParam('id'),
|
||||
|
||||
param('actorId')
|
||||
.custom(isIdValid).not().isEmpty().withMessage('Should have a valid actor id'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug('Checking videoShare parameters', { parameters: req.params })
|
||||
|
@ -1,12 +1,13 @@
|
||||
import * as express from 'express'
|
||||
import { body, param } from 'express-validator'
|
||||
import { body } from 'express-validator'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
import { isIdOrUUIDValid, toIntOrNull } from '../../../helpers/custom-validators/misc'
|
||||
import { toIntOrNull } from '../../../helpers/custom-validators/misc'
|
||||
import { logger } from '../../../helpers/logger'
|
||||
import { areValidationErrors, doesVideoExist } from '../shared'
|
||||
import { areValidationErrors, doesVideoExist, isValidVideoIdParam } from '../shared'
|
||||
|
||||
const videoWatchingValidator = [
|
||||
param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
|
||||
isValidVideoIdParam('videoId'),
|
||||
|
||||
body('currentTime')
|
||||
.customSanitizer(toIntOrNull)
|
||||
.isInt().withMessage('Should have correct current time'),
|
||||
|
@ -12,7 +12,6 @@ import {
|
||||
isBooleanValid,
|
||||
isDateValid,
|
||||
isFileFieldValid,
|
||||
isIdOrUUIDValid,
|
||||
isIdValid,
|
||||
isUUIDValid,
|
||||
toArray,
|
||||
@ -53,7 +52,8 @@ import {
|
||||
checkUserCanManageVideo,
|
||||
doesVideoChannelOfAccountExist,
|
||||
doesVideoExist,
|
||||
doesVideoFileOfVideoExist
|
||||
doesVideoFileOfVideoExist,
|
||||
isValidVideoIdParam
|
||||
} from '../shared'
|
||||
|
||||
const videosAddLegacyValidator = getCommonVideoEditAttributes().concat([
|
||||
@ -195,7 +195,8 @@ const videosAddResumableInitValidator = getCommonVideoEditAttributes().concat([
|
||||
])
|
||||
|
||||
const videosUpdateValidator = getCommonVideoEditAttributes().concat([
|
||||
param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
|
||||
isValidVideoIdParam('id'),
|
||||
|
||||
body('name')
|
||||
.optional()
|
||||
.trim()
|
||||
@ -258,7 +259,7 @@ const videosCustomGetValidator = (
|
||||
authenticateInQuery = false
|
||||
) => {
|
||||
return [
|
||||
param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
|
||||
isValidVideoIdParam('id'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug('Checking videosGet parameters', { parameters: req.params })
|
||||
@ -309,8 +310,10 @@ const videosGetValidator = videosCustomGetValidator('all')
|
||||
const videosDownloadValidator = videosCustomGetValidator('all', true)
|
||||
|
||||
const videoFileMetadataGetValidator = getCommonVideoEditAttributes().concat([
|
||||
param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
|
||||
param('videoFileId').custom(isIdValid).not().isEmpty().withMessage('Should have a valid videoFileId'),
|
||||
isValidVideoIdParam('id'),
|
||||
|
||||
param('videoFileId')
|
||||
.custom(isIdValid).not().isEmpty().withMessage('Should have a valid videoFileId'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug('Checking videoFileMetadataGet parameters', { parameters: req.params })
|
||||
@ -323,7 +326,7 @@ const videoFileMetadataGetValidator = getCommonVideoEditAttributes().concat([
|
||||
])
|
||||
|
||||
const videosRemoveValidator = [
|
||||
param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
|
||||
isValidVideoIdParam('id'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug('Checking videosRemove parameters', { parameters: req.params })
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { uuidToShort } from '@server/helpers/uuid'
|
||||
import { generateMagnetUri } from '@server/helpers/webtorrent'
|
||||
import { getLocalVideoFileMetadataUrl } from '@server/lib/video-paths'
|
||||
import { VideoFile } from '@shared/models/videos/video-file.model'
|
||||
@ -47,6 +48,8 @@ function videoModelToFormattedJSON (video: MVideoFormattable, options?: VideoFor
|
||||
const videoObject: Video = {
|
||||
id: video.id,
|
||||
uuid: video.uuid,
|
||||
shortUUID: uuidToShort(video.uuid),
|
||||
|
||||
name: video.name,
|
||||
category: {
|
||||
id: video.category,
|
||||
|
@ -15,7 +15,7 @@ import {
|
||||
Table,
|
||||
UpdatedAt
|
||||
} from 'sequelize-typescript'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { buildUUID } from '@server/helpers/uuid'
|
||||
import { MVideo, MVideoCaption, MVideoCaptionFormattable, MVideoCaptionVideo } from '@server/types/models'
|
||||
import { AttributesOnly } from '@shared/core-utils'
|
||||
import { VideoCaption } from '../../../shared/models/videos/caption/video-caption.model'
|
||||
@ -182,7 +182,7 @@ export class VideoCaptionModel extends Model<Partial<AttributesOnly<VideoCaption
|
||||
}
|
||||
|
||||
static generateCaptionName (language: string) {
|
||||
return `${uuidv4()}-${language}.vtt`
|
||||
return `${buildUUID()}-${language}.vtt`
|
||||
}
|
||||
|
||||
isOwned () {
|
||||
|
@ -17,8 +17,8 @@ import {
|
||||
Table,
|
||||
UpdatedAt
|
||||
} from 'sequelize-typescript'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { setAsUpdated } from '@server/helpers/database-utils'
|
||||
import { buildUUID, uuidToShort } from '@server/helpers/uuid'
|
||||
import { MAccountId, MChannelId } from '@server/types/models'
|
||||
import { AttributesOnly } from '@shared/core-utils'
|
||||
import { ActivityIconObject } from '../../../shared/models/activitypub/objects'
|
||||
@ -545,7 +545,7 @@ export class VideoPlaylistModel extends Model<Partial<AttributesOnly<VideoPlayli
|
||||
generateThumbnailName () {
|
||||
const extension = '.jpg'
|
||||
|
||||
return 'playlist-' + uuidv4() + extension
|
||||
return 'playlist-' + buildUUID() + extension
|
||||
}
|
||||
|
||||
getThumbnailUrl () {
|
||||
@ -617,6 +617,8 @@ export class VideoPlaylistModel extends Model<Partial<AttributesOnly<VideoPlayli
|
||||
return {
|
||||
id: this.id,
|
||||
uuid: this.uuid,
|
||||
shortUUID: uuidToShort(this.uuid),
|
||||
|
||||
isLocal: this.isOwned(),
|
||||
|
||||
url: this.url,
|
||||
|
@ -1,23 +1,65 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
|
||||
|
||||
import * as chai from 'chai'
|
||||
import 'mocha'
|
||||
import * as chai from 'chai'
|
||||
import { VideoPlaylistPrivacy } from '@shared/models'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
import {
|
||||
cleanupTests,
|
||||
createVideoPlaylist,
|
||||
doubleFollow,
|
||||
flushAndRunMultipleServers,
|
||||
makeActivityPubGetRequest,
|
||||
ServerInfo,
|
||||
setAccessTokensToServers,
|
||||
uploadVideo
|
||||
setDefaultVideoChannel,
|
||||
uploadVideoAndGetId
|
||||
} from '../../../../shared/extra-utils'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
|
||||
const expect = chai.expect
|
||||
|
||||
describe('Test activitypub', function () {
|
||||
let servers: ServerInfo[] = []
|
||||
let videoUUID: string
|
||||
let video: { id: number, uuid: string, shortUUID: string }
|
||||
let playlist: { id: number, uuid: string, shortUUID: string }
|
||||
|
||||
async function testAccount (path: string) {
|
||||
const res = await makeActivityPubGetRequest(servers[0].url, path)
|
||||
const object = res.body
|
||||
|
||||
expect(object.type).to.equal('Person')
|
||||
expect(object.id).to.equal('http://localhost:' + servers[0].port + '/accounts/root')
|
||||
expect(object.name).to.equal('root')
|
||||
expect(object.preferredUsername).to.equal('root')
|
||||
}
|
||||
|
||||
async function testChannel (path: string) {
|
||||
const res = await makeActivityPubGetRequest(servers[0].url, path)
|
||||
const object = res.body
|
||||
|
||||
expect(object.type).to.equal('Group')
|
||||
expect(object.id).to.equal('http://localhost:' + servers[0].port + '/video-channels/root_channel')
|
||||
expect(object.name).to.equal('Main root channel')
|
||||
expect(object.preferredUsername).to.equal('root_channel')
|
||||
}
|
||||
|
||||
async function testVideo (path: string) {
|
||||
const res = await makeActivityPubGetRequest(servers[0].url, path)
|
||||
const object = res.body
|
||||
|
||||
expect(object.type).to.equal('Video')
|
||||
expect(object.id).to.equal('http://localhost:' + servers[0].port + '/videos/watch/' + video.uuid)
|
||||
expect(object.name).to.equal('video')
|
||||
}
|
||||
|
||||
async function testPlaylist (path: string) {
|
||||
const res = await makeActivityPubGetRequest(servers[0].url, path)
|
||||
const object = res.body
|
||||
|
||||
expect(object.type).to.equal('Playlist')
|
||||
expect(object.id).to.equal('http://localhost:' + servers[0].port + '/video-playlists/' + playlist.uuid)
|
||||
expect(object.name).to.equal('playlist')
|
||||
}
|
||||
|
||||
before(async function () {
|
||||
this.timeout(30000)
|
||||
@ -25,38 +67,56 @@ describe('Test activitypub', function () {
|
||||
servers = await flushAndRunMultipleServers(2)
|
||||
|
||||
await setAccessTokensToServers(servers)
|
||||
await setDefaultVideoChannel(servers)
|
||||
|
||||
{
|
||||
const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video' })
|
||||
videoUUID = res.body.video.uuid
|
||||
video = await uploadVideoAndGetId({ server: servers[0], videoName: 'video' })
|
||||
}
|
||||
|
||||
{
|
||||
const playlistAttrs = { displayName: 'playlist', privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: servers[0].videoChannel.id }
|
||||
const resCreate = await createVideoPlaylist({ url: servers[0].url, token: servers[0].accessToken, playlistAttrs })
|
||||
playlist = resCreate.body.videoPlaylist
|
||||
}
|
||||
|
||||
await doubleFollow(servers[0], servers[1])
|
||||
})
|
||||
|
||||
it('Should return the account object', async function () {
|
||||
const res = await makeActivityPubGetRequest(servers[0].url, '/accounts/root')
|
||||
const object = res.body
|
||||
await testAccount('/accounts/root')
|
||||
await testAccount('/a/root')
|
||||
})
|
||||
|
||||
expect(object.type).to.equal('Person')
|
||||
expect(object.id).to.equal('http://localhost:' + servers[0].port + '/accounts/root')
|
||||
expect(object.name).to.equal('root')
|
||||
expect(object.preferredUsername).to.equal('root')
|
||||
it('Should return the channel object', async function () {
|
||||
await testChannel('/video-channels/root_channel')
|
||||
await testChannel('/c/root_channel')
|
||||
})
|
||||
|
||||
it('Should return the video object', async function () {
|
||||
const res = await makeActivityPubGetRequest(servers[0].url, '/videos/watch/' + videoUUID)
|
||||
const object = res.body
|
||||
await testVideo('/videos/watch/' + video.id)
|
||||
await testVideo('/videos/watch/' + video.uuid)
|
||||
await testVideo('/videos/watch/' + video.shortUUID)
|
||||
await testVideo('/w/' + video.id)
|
||||
await testVideo('/w/' + video.uuid)
|
||||
await testVideo('/w/' + video.shortUUID)
|
||||
})
|
||||
|
||||
expect(object.type).to.equal('Video')
|
||||
expect(object.id).to.equal('http://localhost:' + servers[0].port + '/videos/watch/' + videoUUID)
|
||||
expect(object.name).to.equal('video')
|
||||
it('Should return the playlist object', async function () {
|
||||
await testPlaylist('/video-playlists/' + playlist.id)
|
||||
await testPlaylist('/video-playlists/' + playlist.uuid)
|
||||
await testPlaylist('/video-playlists/' + playlist.shortUUID)
|
||||
await testPlaylist('/w/p/' + playlist.id)
|
||||
await testPlaylist('/w/p/' + playlist.uuid)
|
||||
await testPlaylist('/w/p/' + playlist.shortUUID)
|
||||
await testPlaylist('/videos/watch/playlist/' + playlist.id)
|
||||
await testPlaylist('/videos/watch/playlist/' + playlist.uuid)
|
||||
await testPlaylist('/videos/watch/playlist/' + playlist.shortUUID)
|
||||
})
|
||||
|
||||
it('Should redirect to the origin video object', async function () {
|
||||
const res = await makeActivityPubGetRequest(servers[1].url, '/videos/watch/' + videoUUID, HttpStatusCode.FOUND_302)
|
||||
const res = await makeActivityPubGetRequest(servers[1].url, '/videos/watch/' + video.uuid, HttpStatusCode.FOUND_302)
|
||||
|
||||
expect(res.header.location).to.equal('http://localhost:' + servers[0].port + '/videos/watch/' + videoUUID)
|
||||
expect(res.header.location).to.equal('http://localhost:' + servers[0].port + '/videos/watch/' + video.uuid)
|
||||
})
|
||||
|
||||
after(async function () {
|
||||
|
@ -258,7 +258,7 @@ describe('Test abuses API validators', function () {
|
||||
})
|
||||
|
||||
it('Should succeed with the correct parameters (basic)', async function () {
|
||||
const fields: AbuseCreate = { video: { id: server.video.id }, reason: 'my super reason' }
|
||||
const fields: AbuseCreate = { video: { id: server.video.shortUUID }, reason: 'my super reason' }
|
||||
|
||||
const res = await makePostBodyRequest({
|
||||
url: server.url,
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
import 'mocha'
|
||||
import { omit } from 'lodash'
|
||||
import { LiveVideo, VideoPrivacy } from '@shared/models'
|
||||
import { LiveVideo, VideoCreateResult, VideoPrivacy } from '@shared/models'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
import {
|
||||
buildAbsoluteFixturePath,
|
||||
@ -31,7 +31,7 @@ describe('Test video lives API validator', function () {
|
||||
let server: ServerInfo
|
||||
let userAccessToken = ''
|
||||
let channelId: number
|
||||
let videoId: number
|
||||
let video: VideoCreateResult
|
||||
let videoIdNotLive: number
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
@ -230,7 +230,7 @@ describe('Test video lives API validator', function () {
|
||||
statusCodeExpected: HttpStatusCode.OK_200
|
||||
})
|
||||
|
||||
videoId = res.body.video.id
|
||||
video = res.body.video
|
||||
})
|
||||
|
||||
it('Should forbid if live is disabled', async function () {
|
||||
@ -326,15 +326,15 @@ describe('Test video lives API validator', function () {
|
||||
describe('When getting live information', function () {
|
||||
|
||||
it('Should fail without access token', async function () {
|
||||
await getLive(server.url, '', videoId, HttpStatusCode.UNAUTHORIZED_401)
|
||||
await getLive(server.url, '', video.id, HttpStatusCode.UNAUTHORIZED_401)
|
||||
})
|
||||
|
||||
it('Should fail with a bad access token', async function () {
|
||||
await getLive(server.url, 'toto', videoId, HttpStatusCode.UNAUTHORIZED_401)
|
||||
await getLive(server.url, 'toto', video.id, HttpStatusCode.UNAUTHORIZED_401)
|
||||
})
|
||||
|
||||
it('Should fail with access token of another user', async function () {
|
||||
await getLive(server.url, userAccessToken, videoId, HttpStatusCode.FORBIDDEN_403)
|
||||
await getLive(server.url, userAccessToken, video.id, HttpStatusCode.FORBIDDEN_403)
|
||||
})
|
||||
|
||||
it('Should fail with a bad video id', async function () {
|
||||
@ -350,22 +350,23 @@ describe('Test video lives API validator', function () {
|
||||
})
|
||||
|
||||
it('Should succeed with the correct params', async function () {
|
||||
await getLive(server.url, server.accessToken, videoId)
|
||||
await getLive(server.url, server.accessToken, video.id)
|
||||
await getLive(server.url, server.accessToken, video.shortUUID)
|
||||
})
|
||||
})
|
||||
|
||||
describe('When updating live information', async function () {
|
||||
|
||||
it('Should fail without access token', async function () {
|
||||
await updateLive(server.url, '', videoId, {}, HttpStatusCode.UNAUTHORIZED_401)
|
||||
await updateLive(server.url, '', video.id, {}, HttpStatusCode.UNAUTHORIZED_401)
|
||||
})
|
||||
|
||||
it('Should fail with a bad access token', async function () {
|
||||
await updateLive(server.url, 'toto', videoId, {}, HttpStatusCode.UNAUTHORIZED_401)
|
||||
await updateLive(server.url, 'toto', video.id, {}, HttpStatusCode.UNAUTHORIZED_401)
|
||||
})
|
||||
|
||||
it('Should fail with access token of another user', async function () {
|
||||
await updateLive(server.url, userAccessToken, videoId, {}, HttpStatusCode.FORBIDDEN_403)
|
||||
await updateLive(server.url, userAccessToken, video.id, {}, HttpStatusCode.FORBIDDEN_403)
|
||||
})
|
||||
|
||||
it('Should fail with a bad video id', async function () {
|
||||
@ -383,11 +384,12 @@ describe('Test video lives API validator', function () {
|
||||
it('Should fail with save replay and permanent live set to true', async function () {
|
||||
const fields = { saveReplay: true, permanentLive: true }
|
||||
|
||||
await updateLive(server.url, server.accessToken, videoId, fields, HttpStatusCode.BAD_REQUEST_400)
|
||||
await updateLive(server.url, server.accessToken, video.id, fields, HttpStatusCode.BAD_REQUEST_400)
|
||||
})
|
||||
|
||||
it('Should succeed with the correct params', async function () {
|
||||
await updateLive(server.url, server.accessToken, videoId, { saveReplay: false })
|
||||
await updateLive(server.url, server.accessToken, video.id, { saveReplay: false })
|
||||
await updateLive(server.url, server.accessToken, video.shortUUID, { saveReplay: false })
|
||||
})
|
||||
|
||||
it('Should fail to update replay status if replay is not allowed on the instance', async function () {
|
||||
@ -398,19 +400,19 @@ describe('Test video lives API validator', function () {
|
||||
}
|
||||
})
|
||||
|
||||
await updateLive(server.url, server.accessToken, videoId, { saveReplay: true }, HttpStatusCode.FORBIDDEN_403)
|
||||
await updateLive(server.url, server.accessToken, video.id, { saveReplay: true }, HttpStatusCode.FORBIDDEN_403)
|
||||
})
|
||||
|
||||
it('Should fail to update a live if it has already started', async function () {
|
||||
this.timeout(40000)
|
||||
|
||||
const resLive = await getLive(server.url, server.accessToken, videoId)
|
||||
const resLive = await getLive(server.url, server.accessToken, video.id)
|
||||
const live: LiveVideo = resLive.body
|
||||
|
||||
const command = sendRTMPStream(live.rtmpUrl, live.streamKey)
|
||||
|
||||
await waitUntilLivePublished(server.url, server.accessToken, videoId)
|
||||
await updateLive(server.url, server.accessToken, videoId, {}, HttpStatusCode.BAD_REQUEST_400)
|
||||
await waitUntilLivePublished(server.url, server.accessToken, video.id)
|
||||
await updateLive(server.url, server.accessToken, video.id, {}, HttpStatusCode.BAD_REQUEST_400)
|
||||
|
||||
await stopFfmpeg(command)
|
||||
})
|
||||
@ -418,14 +420,14 @@ describe('Test video lives API validator', function () {
|
||||
it('Should fail to stream twice in the save live', async function () {
|
||||
this.timeout(40000)
|
||||
|
||||
const resLive = await getLive(server.url, server.accessToken, videoId)
|
||||
const resLive = await getLive(server.url, server.accessToken, video.id)
|
||||
const live: LiveVideo = resLive.body
|
||||
|
||||
const command = sendRTMPStream(live.rtmpUrl, live.streamKey)
|
||||
|
||||
await waitUntilLivePublished(server.url, server.accessToken, videoId)
|
||||
await waitUntilLivePublished(server.url, server.accessToken, video.id)
|
||||
|
||||
await runAndTestFfmpegStreamError(server.url, server.accessToken, videoId, true)
|
||||
await runAndTestFfmpegStreamError(server.url, server.accessToken, video.id, true)
|
||||
|
||||
await stopFfmpeg(command)
|
||||
})
|
||||
|
@ -1,7 +1,8 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
|
||||
|
||||
import 'mocha'
|
||||
|
||||
import { VideoCreateResult } from '@shared/models'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
import {
|
||||
checkBadCountPagination,
|
||||
checkBadSortPagination,
|
||||
@ -9,20 +10,24 @@ import {
|
||||
cleanupTests,
|
||||
createUser,
|
||||
doubleFollow,
|
||||
flushAndRunMultipleServers, makeDeleteRequest,
|
||||
makeGetRequest, makePostBodyRequest,
|
||||
flushAndRunMultipleServers,
|
||||
getVideo,
|
||||
makeDeleteRequest,
|
||||
makeGetRequest,
|
||||
makePostBodyRequest,
|
||||
makePutBodyRequest,
|
||||
ServerInfo,
|
||||
setAccessTokensToServers, uploadVideoAndGetId,
|
||||
userLogin, waitJobs, getVideoIdFromUUID
|
||||
setAccessTokensToServers,
|
||||
uploadVideoAndGetId,
|
||||
userLogin,
|
||||
waitJobs
|
||||
} from '../../../../shared/extra-utils'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
|
||||
describe('Test server redundancy API validators', function () {
|
||||
let servers: ServerInfo[]
|
||||
let userAccessToken = null
|
||||
let videoIdLocal: number
|
||||
let videoIdRemote: number
|
||||
let videoRemote: VideoCreateResult
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
@ -48,7 +53,8 @@ describe('Test server redundancy API validators', function () {
|
||||
|
||||
await waitJobs(servers)
|
||||
|
||||
videoIdRemote = await getVideoIdFromUUID(servers[0].url, remoteUUID)
|
||||
const resVideo = await getVideo(servers[0].url, remoteUUID)
|
||||
videoRemote = resVideo.body
|
||||
})
|
||||
|
||||
describe('When listing redundancies', function () {
|
||||
@ -131,7 +137,13 @@ describe('Test server redundancy API validators', function () {
|
||||
})
|
||||
|
||||
it('Should succeed with the correct params', async function () {
|
||||
await makePostBodyRequest({ url, path, token, fields: { videoId: videoIdRemote }, statusCodeExpected: HttpStatusCode.NO_CONTENT_204 })
|
||||
await makePostBodyRequest({
|
||||
url,
|
||||
path,
|
||||
token,
|
||||
fields: { videoId: videoRemote.shortUUID },
|
||||
statusCodeExpected: HttpStatusCode.NO_CONTENT_204
|
||||
})
|
||||
})
|
||||
|
||||
it('Should fail if the video is already duplicated', async function () {
|
||||
@ -139,7 +151,13 @@ describe('Test server redundancy API validators', function () {
|
||||
|
||||
await waitJobs(servers)
|
||||
|
||||
await makePostBodyRequest({ url, path, token, fields: { videoId: videoIdRemote }, statusCodeExpected: HttpStatusCode.CONFLICT_409 })
|
||||
await makePostBodyRequest({
|
||||
url,
|
||||
path,
|
||||
token,
|
||||
fields: { videoId: videoRemote.uuid },
|
||||
statusCodeExpected: HttpStatusCode.CONFLICT_409
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
import 'mocha'
|
||||
import { omit } from 'lodash'
|
||||
import { User, UserRole } from '../../../../shared'
|
||||
import { User, UserRole, VideoCreateResult } from '../../../../shared'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
import {
|
||||
addVideoChannel,
|
||||
@ -45,7 +45,7 @@ describe('Test users API validators', function () {
|
||||
let userId: number
|
||||
let rootId: number
|
||||
let moderatorId: number
|
||||
let videoId: number
|
||||
let video: VideoCreateResult
|
||||
let server: ServerInfo
|
||||
let serverWithRegistrationDisabled: ServerInfo
|
||||
let userAccessToken = ''
|
||||
@ -126,7 +126,7 @@ describe('Test users API validators', function () {
|
||||
|
||||
{
|
||||
const res = await uploadVideo(server.url, server.accessToken, {})
|
||||
videoId = res.body.video.id
|
||||
video = res.body.video
|
||||
}
|
||||
|
||||
{
|
||||
@ -829,7 +829,7 @@ describe('Test users API validators', function () {
|
||||
|
||||
describe('When getting my video rating', function () {
|
||||
it('Should fail with a non authenticated user', async function () {
|
||||
await getMyUserVideoRating(server.url, 'fake_token', videoId, HttpStatusCode.UNAUTHORIZED_401)
|
||||
await getMyUserVideoRating(server.url, 'fake_token', video.id, HttpStatusCode.UNAUTHORIZED_401)
|
||||
})
|
||||
|
||||
it('Should fail with an incorrect video uuid', async function () {
|
||||
@ -841,7 +841,9 @@ describe('Test users API validators', function () {
|
||||
})
|
||||
|
||||
it('Should succeed with the correct parameters', async function () {
|
||||
await getMyUserVideoRating(server.url, server.accessToken, videoId)
|
||||
await getMyUserVideoRating(server.url, server.accessToken, video.id)
|
||||
await getMyUserVideoRating(server.url, server.accessToken, video.uuid)
|
||||
await getMyUserVideoRating(server.url, server.accessToken, video.shortUUID)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -191,7 +191,7 @@ describe('Test video blacklist API validators', function () {
|
||||
})
|
||||
|
||||
it('Should succeed with the correct params', async function () {
|
||||
const path = basePath + servers[0].video.uuid + '/blacklist'
|
||||
const path = basePath + servers[0].video.shortUUID + '/blacklist'
|
||||
const fields = { reason: 'hello' }
|
||||
|
||||
await makePutBodyRequest({
|
||||
@ -222,10 +222,14 @@ describe('Test video blacklist API validators', function () {
|
||||
})
|
||||
|
||||
it('Should succeed with an admin', async function () {
|
||||
const res = await getVideoWithToken(servers[0].url, servers[0].accessToken, servers[0].video.uuid, HttpStatusCode.OK_200)
|
||||
const video: VideoDetails = res.body
|
||||
const video = servers[0].video
|
||||
|
||||
expect(video.blacklisted).to.be.true
|
||||
for (const id of [ video.id, video.uuid, video.shortUUID ]) {
|
||||
const res = await getVideoWithToken(servers[0].url, servers[0].accessToken, id, HttpStatusCode.OK_200)
|
||||
const video: VideoDetails = res.body
|
||||
|
||||
expect(video.blacklisted).to.be.true
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
|
||||
|
||||
import 'mocha'
|
||||
|
||||
import { VideoCreateResult } from '@shared/models'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
import {
|
||||
buildAbsoluteFixturePath,
|
||||
@ -23,7 +23,7 @@ describe('Test video captions API validator', function () {
|
||||
|
||||
let server: ServerInfo
|
||||
let userAccessToken: string
|
||||
let videoUUID: string
|
||||
let video: VideoCreateResult
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
@ -36,7 +36,7 @@ describe('Test video captions API validator', function () {
|
||||
|
||||
{
|
||||
const res = await uploadVideo(server.url, server.accessToken, {})
|
||||
videoUUID = res.body.video.uuid
|
||||
video = res.body.video
|
||||
}
|
||||
|
||||
{
|
||||
@ -79,7 +79,7 @@ describe('Test video captions API validator', function () {
|
||||
})
|
||||
|
||||
it('Should fail with a missing language in path', async function () {
|
||||
const captionPath = path + videoUUID + '/captions'
|
||||
const captionPath = path + video.uuid + '/captions'
|
||||
await makeUploadRequest({
|
||||
method: 'PUT',
|
||||
url: server.url,
|
||||
@ -91,7 +91,7 @@ describe('Test video captions API validator', function () {
|
||||
})
|
||||
|
||||
it('Should fail with an unknown language', async function () {
|
||||
const captionPath = path + videoUUID + '/captions/15'
|
||||
const captionPath = path + video.uuid + '/captions/15'
|
||||
await makeUploadRequest({
|
||||
method: 'PUT',
|
||||
url: server.url,
|
||||
@ -103,7 +103,7 @@ describe('Test video captions API validator', function () {
|
||||
})
|
||||
|
||||
it('Should fail without access token', async function () {
|
||||
const captionPath = path + videoUUID + '/captions/fr'
|
||||
const captionPath = path + video.uuid + '/captions/fr'
|
||||
await makeUploadRequest({
|
||||
method: 'PUT',
|
||||
url: server.url,
|
||||
@ -115,7 +115,7 @@ describe('Test video captions API validator', function () {
|
||||
})
|
||||
|
||||
it('Should fail with a bad access token', async function () {
|
||||
const captionPath = path + videoUUID + '/captions/fr'
|
||||
const captionPath = path + video.uuid + '/captions/fr'
|
||||
await makeUploadRequest({
|
||||
method: 'PUT',
|
||||
url: server.url,
|
||||
@ -133,7 +133,7 @@ describe('Test video captions API validator', function () {
|
||||
// 'captionfile': buildAbsoluteFixturePath('subtitle-bad.txt')
|
||||
// }
|
||||
//
|
||||
// const captionPath = path + videoUUID + '/captions/fr'
|
||||
// const captionPath = path + video.uuid + '/captions/fr'
|
||||
// await makeUploadRequest({
|
||||
// method: 'PUT',
|
||||
// url: server.url,
|
||||
@ -151,7 +151,7 @@ describe('Test video captions API validator', function () {
|
||||
// url: server.url,
|
||||
// accessToken: server.accessToken,
|
||||
// language: 'zh',
|
||||
// videoId: videoUUID,
|
||||
// videoId: video.uuid,
|
||||
// fixture: 'subtitle-bad.txt',
|
||||
// mimeType: 'application/octet-stream',
|
||||
// statusCodeExpected: HttpStatusCode.BAD_REQUEST_400
|
||||
@ -163,7 +163,7 @@ describe('Test video captions API validator', function () {
|
||||
url: server.url,
|
||||
accessToken: server.accessToken,
|
||||
language: 'zh',
|
||||
videoId: videoUUID,
|
||||
videoId: video.uuid,
|
||||
fixture: 'subtitle-good.srt',
|
||||
mimeType: 'application/octet-stream'
|
||||
})
|
||||
@ -175,7 +175,7 @@ describe('Test video captions API validator', function () {
|
||||
// 'captionfile': buildAbsoluteFixturePath('subtitle-bad.srt')
|
||||
// }
|
||||
//
|
||||
// const captionPath = path + videoUUID + '/captions/fr'
|
||||
// const captionPath = path + video.uuid + '/captions/fr'
|
||||
// await makeUploadRequest({
|
||||
// method: 'PUT',
|
||||
// url: server.url,
|
||||
@ -188,7 +188,7 @@ describe('Test video captions API validator', function () {
|
||||
// })
|
||||
|
||||
it('Should success with the correct parameters', async function () {
|
||||
const captionPath = path + videoUUID + '/captions/fr'
|
||||
const captionPath = path + video.uuid + '/captions/fr'
|
||||
await makeUploadRequest({
|
||||
method: 'PUT',
|
||||
url: server.url,
|
||||
@ -215,7 +215,7 @@ describe('Test video captions API validator', function () {
|
||||
})
|
||||
|
||||
it('Should success with the correct parameters', async function () {
|
||||
await makeGetRequest({ url: server.url, path: path + videoUUID + '/captions', statusCodeExpected: HttpStatusCode.OK_200 })
|
||||
await makeGetRequest({ url: server.url, path: path + video.shortUUID + '/captions', statusCodeExpected: HttpStatusCode.OK_200 })
|
||||
})
|
||||
})
|
||||
|
||||
@ -246,27 +246,27 @@ describe('Test video captions API validator', function () {
|
||||
})
|
||||
|
||||
it('Should fail with a missing language', async function () {
|
||||
const captionPath = path + videoUUID + '/captions'
|
||||
const captionPath = path + video.shortUUID + '/captions'
|
||||
await makeDeleteRequest({ url: server.url, path: captionPath, token: server.accessToken })
|
||||
})
|
||||
|
||||
it('Should fail with an unknown language', async function () {
|
||||
const captionPath = path + videoUUID + '/captions/15'
|
||||
const captionPath = path + video.shortUUID + '/captions/15'
|
||||
await makeDeleteRequest({ url: server.url, path: captionPath, token: server.accessToken })
|
||||
})
|
||||
|
||||
it('Should fail without access token', async function () {
|
||||
const captionPath = path + videoUUID + '/captions/fr'
|
||||
const captionPath = path + video.shortUUID + '/captions/fr'
|
||||
await makeDeleteRequest({ url: server.url, path: captionPath, statusCodeExpected: HttpStatusCode.UNAUTHORIZED_401 })
|
||||
})
|
||||
|
||||
it('Should fail with a bad access token', async function () {
|
||||
const captionPath = path + videoUUID + '/captions/fr'
|
||||
const captionPath = path + video.shortUUID + '/captions/fr'
|
||||
await makeDeleteRequest({ url: server.url, path: captionPath, token: 'coucou', statusCodeExpected: HttpStatusCode.UNAUTHORIZED_401 })
|
||||
})
|
||||
|
||||
it('Should fail with another user', async function () {
|
||||
const captionPath = path + videoUUID + '/captions/fr'
|
||||
const captionPath = path + video.shortUUID + '/captions/fr'
|
||||
await makeDeleteRequest({
|
||||
url: server.url,
|
||||
path: captionPath,
|
||||
@ -276,7 +276,7 @@ describe('Test video captions API validator', function () {
|
||||
})
|
||||
|
||||
it('Should success with the correct parameters', async function () {
|
||||
const captionPath = path + videoUUID + '/captions/fr'
|
||||
const captionPath = path + video.shortUUID + '/captions/fr'
|
||||
await makeDeleteRequest({
|
||||
url: server.url,
|
||||
path: captionPath,
|
||||
|
@ -1,7 +1,9 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
|
||||
|
||||
import * as chai from 'chai'
|
||||
import 'mocha'
|
||||
import * as chai from 'chai'
|
||||
import { VideoCreateResult } from '@shared/models'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
import {
|
||||
cleanupTests,
|
||||
createUser,
|
||||
@ -20,7 +22,6 @@ import {
|
||||
checkBadStartPagination
|
||||
} from '../../../../shared/extra-utils/requests/check-api-params'
|
||||
import { addVideoCommentThread } from '../../../../shared/extra-utils/videos/video-comments'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
|
||||
const expect = chai.expect
|
||||
|
||||
@ -28,7 +29,7 @@ describe('Test video comments API validator', function () {
|
||||
let pathThread: string
|
||||
let pathComment: string
|
||||
let server: ServerInfo
|
||||
let videoUUID: string
|
||||
let video: VideoCreateResult
|
||||
let userAccessToken: string
|
||||
let userAccessToken2: string
|
||||
let commentId: number
|
||||
@ -44,14 +45,14 @@ describe('Test video comments API validator', function () {
|
||||
|
||||
{
|
||||
const res = await uploadVideo(server.url, server.accessToken, {})
|
||||
videoUUID = res.body.video.uuid
|
||||
pathThread = '/api/v1/videos/' + videoUUID + '/comment-threads'
|
||||
video = res.body.video
|
||||
pathThread = '/api/v1/videos/' + video.uuid + '/comment-threads'
|
||||
}
|
||||
|
||||
{
|
||||
const res = await addVideoCommentThread(server.url, server.accessToken, videoUUID, 'coucou')
|
||||
const res = await addVideoCommentThread(server.url, server.accessToken, video.uuid, 'coucou')
|
||||
commentId = res.body.comment.id
|
||||
pathComment = '/api/v1/videos/' + videoUUID + '/comments/' + commentId
|
||||
pathComment = '/api/v1/videos/' + video.uuid + '/comments/' + commentId
|
||||
}
|
||||
|
||||
{
|
||||
@ -101,7 +102,7 @@ describe('Test video comments API validator', function () {
|
||||
it('Should fail with an incorrect thread id', async function () {
|
||||
await makeGetRequest({
|
||||
url: server.url,
|
||||
path: '/api/v1/videos/' + videoUUID + '/comment-threads/156',
|
||||
path: '/api/v1/videos/' + video.shortUUID + '/comment-threads/156',
|
||||
statusCodeExpected: HttpStatusCode.NOT_FOUND_404
|
||||
})
|
||||
})
|
||||
@ -109,7 +110,7 @@ describe('Test video comments API validator', function () {
|
||||
it('Should success with the correct params', async function () {
|
||||
await makeGetRequest({
|
||||
url: server.url,
|
||||
path: '/api/v1/videos/' + videoUUID + '/comment-threads/' + commentId,
|
||||
path: '/api/v1/videos/' + video.shortUUID + '/comment-threads/' + commentId,
|
||||
statusCodeExpected: HttpStatusCode.OK_200
|
||||
})
|
||||
})
|
||||
@ -225,7 +226,7 @@ describe('Test video comments API validator', function () {
|
||||
})
|
||||
|
||||
it('Should fail with an incorrect comment', async function () {
|
||||
const path = '/api/v1/videos/' + videoUUID + '/comments/124'
|
||||
const path = '/api/v1/videos/' + video.uuid + '/comments/124'
|
||||
const fields = {
|
||||
text: 'super comment'
|
||||
}
|
||||
@ -272,7 +273,7 @@ describe('Test video comments API validator', function () {
|
||||
})
|
||||
|
||||
it('Should fail with an incorrect comment', async function () {
|
||||
const path = '/api/v1/videos/' + videoUUID + '/comments/124'
|
||||
const path = '/api/v1/videos/' + video.uuid + '/comments/124'
|
||||
await makeDeleteRequest({ url: server.url, path, token: server.accessToken, statusCodeExpected: HttpStatusCode.NOT_FOUND_404 })
|
||||
})
|
||||
|
||||
@ -280,11 +281,11 @@ describe('Test video comments API validator', function () {
|
||||
let commentToDelete: number
|
||||
|
||||
{
|
||||
const res = await addVideoCommentThread(server.url, userAccessToken, videoUUID, 'hello')
|
||||
const res = await addVideoCommentThread(server.url, userAccessToken, video.uuid, 'hello')
|
||||
commentToDelete = res.body.comment.id
|
||||
}
|
||||
|
||||
const path = '/api/v1/videos/' + videoUUID + '/comments/' + commentToDelete
|
||||
const path = '/api/v1/videos/' + video.uuid + '/comments/' + commentToDelete
|
||||
|
||||
await makeDeleteRequest({ url: server.url, path, token: userAccessToken2, statusCodeExpected: HttpStatusCode.FORBIDDEN_403 })
|
||||
await makeDeleteRequest({ url: server.url, path, token: userAccessToken, statusCodeExpected: HttpStatusCode.NO_CONTENT_204 })
|
||||
@ -323,8 +324,8 @@ describe('Test video comments API validator', function () {
|
||||
describe('When a video has comments disabled', function () {
|
||||
before(async function () {
|
||||
const res = await uploadVideo(server.url, server.accessToken, { commentsEnabled: false })
|
||||
videoUUID = res.body.video.uuid
|
||||
pathThread = '/api/v1/videos/' + videoUUID + '/comment-threads'
|
||||
video = res.body.video
|
||||
pathThread = '/api/v1/videos/' + video.uuid + '/comment-threads'
|
||||
})
|
||||
|
||||
it('Should return an empty thread list', async function () {
|
||||
|
@ -1,8 +1,13 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
|
||||
|
||||
import 'mocha'
|
||||
import { VideoPlaylistCreateResult, VideoPlaylistPrivacy, VideoPlaylistType } from '@shared/models'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
import {
|
||||
addVideoInPlaylist,
|
||||
checkBadCountPagination,
|
||||
checkBadSortPagination,
|
||||
checkBadStartPagination,
|
||||
cleanupTests,
|
||||
createVideoPlaylist,
|
||||
deleteVideoPlaylist,
|
||||
@ -21,20 +26,14 @@ import {
|
||||
updateVideoPlaylistElement,
|
||||
uploadVideoAndGetId
|
||||
} from '../../../../shared/extra-utils'
|
||||
import {
|
||||
checkBadCountPagination,
|
||||
checkBadSortPagination,
|
||||
checkBadStartPagination
|
||||
} from '../../../../shared/extra-utils/requests/check-api-params'
|
||||
import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model'
|
||||
import { VideoPlaylistType } from '../../../../shared/models/videos/playlist/video-playlist-type.model'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
|
||||
describe('Test video playlists API validator', function () {
|
||||
let server: ServerInfo
|
||||
let userAccessToken: string
|
||||
let playlistUUID: string
|
||||
|
||||
let playlist: VideoPlaylistCreateResult
|
||||
let privatePlaylistUUID: string
|
||||
|
||||
let watchLaterPlaylistId: number
|
||||
let videoId: number
|
||||
let playlistElementId: number
|
||||
@ -67,7 +66,7 @@ describe('Test video playlists API validator', function () {
|
||||
videoChannelId: server.videoChannel.id
|
||||
}
|
||||
})
|
||||
playlistUUID = res.body.videoPlaylist.uuid
|
||||
playlist = res.body.videoPlaylist
|
||||
}
|
||||
|
||||
{
|
||||
@ -150,15 +149,15 @@ describe('Test video playlists API validator', function () {
|
||||
const path = '/api/v1/video-playlists/'
|
||||
|
||||
it('Should fail with a bad start pagination', async function () {
|
||||
await checkBadStartPagination(server.url, path + playlistUUID + '/videos', server.accessToken)
|
||||
await checkBadStartPagination(server.url, path + playlist.shortUUID + '/videos', server.accessToken)
|
||||
})
|
||||
|
||||
it('Should fail with a bad count pagination', async function () {
|
||||
await checkBadCountPagination(server.url, path + playlistUUID + '/videos', server.accessToken)
|
||||
await checkBadCountPagination(server.url, path + playlist.shortUUID + '/videos', server.accessToken)
|
||||
})
|
||||
|
||||
it('Should success with the correct parameters', async function () {
|
||||
await makeGetRequest({ url: server.url, path: path + playlistUUID + '/videos', statusCodeExpected: HttpStatusCode.OK_200 })
|
||||
await makeGetRequest({ url: server.url, path: path + playlist.shortUUID + '/videos', statusCodeExpected: HttpStatusCode.OK_200 })
|
||||
})
|
||||
})
|
||||
|
||||
@ -177,6 +176,7 @@ describe('Test video playlists API validator', function () {
|
||||
token: server.accessToken,
|
||||
playlistAttrs: {
|
||||
displayName: 'super playlist',
|
||||
videoChannelId: server.videoChannel.id,
|
||||
privacy: VideoPlaylistPrivacy.UNLISTED
|
||||
}
|
||||
})
|
||||
@ -187,7 +187,7 @@ describe('Test video playlists API validator', function () {
|
||||
})
|
||||
|
||||
it('Should succeed with the correct params', async function () {
|
||||
await getVideoPlaylist(server.url, playlistUUID, HttpStatusCode.OK_200)
|
||||
await getVideoPlaylist(server.url, playlist.uuid, HttpStatusCode.OK_200)
|
||||
})
|
||||
})
|
||||
|
||||
@ -213,7 +213,7 @@ describe('Test video playlists API validator', function () {
|
||||
const params = getBase({}, { token: null, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
|
||||
|
||||
await createVideoPlaylist(params)
|
||||
await updateVideoPlaylist(getUpdate(params, playlistUUID))
|
||||
await updateVideoPlaylist(getUpdate(params, playlist.shortUUID))
|
||||
})
|
||||
|
||||
it('Should fail without displayName', async function () {
|
||||
@ -226,42 +226,42 @@ describe('Test video playlists API validator', function () {
|
||||
const params = getBase({ displayName: 's'.repeat(300) })
|
||||
|
||||
await createVideoPlaylist(params)
|
||||
await updateVideoPlaylist(getUpdate(params, playlistUUID))
|
||||
await updateVideoPlaylist(getUpdate(params, playlist.shortUUID))
|
||||
})
|
||||
|
||||
it('Should fail with an incorrect description', async function () {
|
||||
const params = getBase({ description: 't' })
|
||||
|
||||
await createVideoPlaylist(params)
|
||||
await updateVideoPlaylist(getUpdate(params, playlistUUID))
|
||||
await updateVideoPlaylist(getUpdate(params, playlist.shortUUID))
|
||||
})
|
||||
|
||||
it('Should fail with an incorrect privacy', async function () {
|
||||
const params = getBase({ privacy: 45 })
|
||||
|
||||
await createVideoPlaylist(params)
|
||||
await updateVideoPlaylist(getUpdate(params, playlistUUID))
|
||||
await updateVideoPlaylist(getUpdate(params, playlist.shortUUID))
|
||||
})
|
||||
|
||||
it('Should fail with an unknown video channel id', async function () {
|
||||
const params = getBase({ videoChannelId: 42 }, { expectedStatus: HttpStatusCode.NOT_FOUND_404 })
|
||||
|
||||
await createVideoPlaylist(params)
|
||||
await updateVideoPlaylist(getUpdate(params, playlistUUID))
|
||||
await updateVideoPlaylist(getUpdate(params, playlist.shortUUID))
|
||||
})
|
||||
|
||||
it('Should fail with an incorrect thumbnail file', async function () {
|
||||
const params = getBase({ thumbnailfile: 'video_short.mp4' })
|
||||
|
||||
await createVideoPlaylist(params)
|
||||
await updateVideoPlaylist(getUpdate(params, playlistUUID))
|
||||
await updateVideoPlaylist(getUpdate(params, playlist.shortUUID))
|
||||
})
|
||||
|
||||
it('Should fail with a thumbnail file too big', async function () {
|
||||
const params = getBase({ thumbnailfile: 'preview-big.png' })
|
||||
|
||||
await createVideoPlaylist(params)
|
||||
await updateVideoPlaylist(getUpdate(params, playlistUUID))
|
||||
await updateVideoPlaylist(getUpdate(params, playlist.shortUUID))
|
||||
})
|
||||
|
||||
it('Should fail to set "public" a playlist not assigned to a channel', async function () {
|
||||
@ -272,8 +272,8 @@ describe('Test video playlists API validator', function () {
|
||||
await createVideoPlaylist(params)
|
||||
await createVideoPlaylist(params2)
|
||||
await updateVideoPlaylist(getUpdate(params, privatePlaylistUUID))
|
||||
await updateVideoPlaylist(getUpdate(params2, playlistUUID))
|
||||
await updateVideoPlaylist(getUpdate(params3, playlistUUID))
|
||||
await updateVideoPlaylist(getUpdate(params2, playlist.shortUUID))
|
||||
await updateVideoPlaylist(getUpdate(params3, playlist.shortUUID))
|
||||
})
|
||||
|
||||
it('Should fail with an unknown playlist to update', async function () {
|
||||
@ -286,7 +286,7 @@ describe('Test video playlists API validator', function () {
|
||||
it('Should fail to update a playlist of another user', async function () {
|
||||
await updateVideoPlaylist(getUpdate(
|
||||
getBase({}, { token: userAccessToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 }),
|
||||
playlistUUID
|
||||
playlist.shortUUID
|
||||
))
|
||||
})
|
||||
|
||||
@ -305,7 +305,7 @@ describe('Test video playlists API validator', function () {
|
||||
|
||||
{
|
||||
const params = getBase({}, { expectedStatus: HttpStatusCode.NO_CONTENT_204 })
|
||||
await updateVideoPlaylist(getUpdate(params, playlistUUID))
|
||||
await updateVideoPlaylist(getUpdate(params, playlist.shortUUID))
|
||||
}
|
||||
})
|
||||
})
|
||||
@ -316,7 +316,7 @@ describe('Test video playlists API validator', function () {
|
||||
expectedStatus: HttpStatusCode.BAD_REQUEST_400,
|
||||
url: server.url,
|
||||
token: server.accessToken,
|
||||
playlistId: playlistUUID,
|
||||
playlistId: playlist.id,
|
||||
elementAttrs: Object.assign({
|
||||
videoId,
|
||||
startTimestamp: 2,
|
||||
@ -381,7 +381,7 @@ describe('Test video playlists API validator', function () {
|
||||
stopTimestamp: 2
|
||||
}, elementAttrs),
|
||||
playlistElementId,
|
||||
playlistId: playlistUUID,
|
||||
playlistId: playlist.id,
|
||||
expectedStatus: HttpStatusCode.BAD_REQUEST_400
|
||||
}, wrapper)
|
||||
}
|
||||
@ -451,7 +451,7 @@ describe('Test video playlists API validator', function () {
|
||||
return Object.assign({
|
||||
url: server.url,
|
||||
token: server.accessToken,
|
||||
playlistId: playlistUUID,
|
||||
playlistId: playlist.shortUUID,
|
||||
elementAttrs: Object.assign({
|
||||
startPosition: 1,
|
||||
insertAfterPosition: 2,
|
||||
@ -469,7 +469,7 @@ describe('Test video playlists API validator', function () {
|
||||
await addVideoInPlaylist({
|
||||
url: server.url,
|
||||
token: server.accessToken,
|
||||
playlistId: playlistUUID,
|
||||
playlistId: playlist.shortUUID,
|
||||
elementAttrs: { videoId: id }
|
||||
})
|
||||
}
|
||||
@ -606,7 +606,7 @@ describe('Test video playlists API validator', function () {
|
||||
url: server.url,
|
||||
token: server.accessToken,
|
||||
playlistElementId,
|
||||
playlistId: playlistUUID,
|
||||
playlistId: playlist.uuid,
|
||||
expectedStatus: HttpStatusCode.BAD_REQUEST_400
|
||||
}, wrapper)
|
||||
}
|
||||
@ -662,7 +662,7 @@ describe('Test video playlists API validator', function () {
|
||||
})
|
||||
|
||||
it('Should fail with a playlist of another user', async function () {
|
||||
await deleteVideoPlaylist(server.url, userAccessToken, playlistUUID, HttpStatusCode.FORBIDDEN_403)
|
||||
await deleteVideoPlaylist(server.url, userAccessToken, playlist.uuid, HttpStatusCode.FORBIDDEN_403)
|
||||
})
|
||||
|
||||
it('Should fail with the watch later playlist', async function () {
|
||||
@ -670,7 +670,7 @@ describe('Test video playlists API validator', function () {
|
||||
})
|
||||
|
||||
it('Should succeed with the correct params', async function () {
|
||||
await deleteVideoPlaylist(server.url, server.accessToken, playlistUUID)
|
||||
await deleteVideoPlaylist(server.url, server.accessToken, playlist.uuid)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -5,7 +5,7 @@ import * as chai from 'chai'
|
||||
import { omit } from 'lodash'
|
||||
import { join } from 'path'
|
||||
import { randomInt } from '@shared/core-utils'
|
||||
import { PeerTubeProblemDocument } from '@shared/models'
|
||||
import { PeerTubeProblemDocument, VideoCreateResult } from '@shared/models'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
import {
|
||||
checkUploadVideoParam,
|
||||
@ -42,7 +42,7 @@ describe('Test videos API validator', function () {
|
||||
let accountName: string
|
||||
let channelId: number
|
||||
let channelName: string
|
||||
let videoId
|
||||
let video: VideoCreateResult
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
@ -490,7 +490,7 @@ describe('Test videos API validator', function () {
|
||||
|
||||
before(async function () {
|
||||
const res = await getVideosList(server.url)
|
||||
videoId = res.body.data[0].uuid
|
||||
video = res.body.data[0]
|
||||
})
|
||||
|
||||
it('Should fail with nothing', async function () {
|
||||
@ -518,79 +518,79 @@ describe('Test videos API validator', function () {
|
||||
it('Should fail with a long name', async function () {
|
||||
const fields = immutableAssign(baseCorrectParams, { name: 'super'.repeat(65) })
|
||||
|
||||
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
|
||||
await makePutBodyRequest({ url: server.url, path: path + video.shortUUID, token: server.accessToken, fields })
|
||||
})
|
||||
|
||||
it('Should fail with a bad category', async function () {
|
||||
const fields = immutableAssign(baseCorrectParams, { category: 125 })
|
||||
|
||||
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
|
||||
await makePutBodyRequest({ url: server.url, path: path + video.shortUUID, token: server.accessToken, fields })
|
||||
})
|
||||
|
||||
it('Should fail with a bad licence', async function () {
|
||||
const fields = immutableAssign(baseCorrectParams, { licence: 125 })
|
||||
|
||||
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
|
||||
await makePutBodyRequest({ url: server.url, path: path + video.shortUUID, token: server.accessToken, fields })
|
||||
})
|
||||
|
||||
it('Should fail with a bad language', async function () {
|
||||
const fields = immutableAssign(baseCorrectParams, { language: 'a'.repeat(15) })
|
||||
|
||||
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
|
||||
await makePutBodyRequest({ url: server.url, path: path + video.shortUUID, token: server.accessToken, fields })
|
||||
})
|
||||
|
||||
it('Should fail with a long description', async function () {
|
||||
const fields = immutableAssign(baseCorrectParams, { description: 'super'.repeat(2500) })
|
||||
|
||||
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
|
||||
await makePutBodyRequest({ url: server.url, path: path + video.shortUUID, token: server.accessToken, fields })
|
||||
})
|
||||
|
||||
it('Should fail with a long support text', async function () {
|
||||
const fields = immutableAssign(baseCorrectParams, { support: 'super'.repeat(201) })
|
||||
|
||||
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
|
||||
await makePutBodyRequest({ url: server.url, path: path + video.shortUUID, token: server.accessToken, fields })
|
||||
})
|
||||
|
||||
it('Should fail with a bad channel', async function () {
|
||||
const fields = immutableAssign(baseCorrectParams, { channelId: 545454 })
|
||||
|
||||
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
|
||||
await makePutBodyRequest({ url: server.url, path: path + video.shortUUID, token: server.accessToken, fields })
|
||||
})
|
||||
|
||||
it('Should fail with too many tags', async function () {
|
||||
const fields = immutableAssign(baseCorrectParams, { tags: [ 'tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6' ] })
|
||||
|
||||
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
|
||||
await makePutBodyRequest({ url: server.url, path: path + video.shortUUID, token: server.accessToken, fields })
|
||||
})
|
||||
|
||||
it('Should fail with a tag length too low', async function () {
|
||||
const fields = immutableAssign(baseCorrectParams, { tags: [ 'tag1', 't' ] })
|
||||
|
||||
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
|
||||
await makePutBodyRequest({ url: server.url, path: path + video.shortUUID, token: server.accessToken, fields })
|
||||
})
|
||||
|
||||
it('Should fail with a tag length too big', async function () {
|
||||
const fields = immutableAssign(baseCorrectParams, { tags: [ 'tag1', 'my_super_tag_too_long_long_long_long_long_long' ] })
|
||||
|
||||
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
|
||||
await makePutBodyRequest({ url: server.url, path: path + video.shortUUID, token: server.accessToken, fields })
|
||||
})
|
||||
|
||||
it('Should fail with a bad schedule update (miss updateAt)', async function () {
|
||||
const fields = immutableAssign(baseCorrectParams, { scheduleUpdate: { privacy: VideoPrivacy.PUBLIC } })
|
||||
|
||||
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
|
||||
await makePutBodyRequest({ url: server.url, path: path + video.shortUUID, token: server.accessToken, fields })
|
||||
})
|
||||
|
||||
it('Should fail with a bad schedule update (wrong updateAt)', async function () {
|
||||
const fields = immutableAssign(baseCorrectParams, { scheduleUpdate: { updateAt: 'toto', privacy: VideoPrivacy.PUBLIC } })
|
||||
|
||||
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
|
||||
await makePutBodyRequest({ url: server.url, path: path + video.shortUUID, token: server.accessToken, fields })
|
||||
})
|
||||
|
||||
it('Should fail with a bad originally published at param', async function () {
|
||||
const fields = immutableAssign(baseCorrectParams, { originallyPublishedAt: 'toto' })
|
||||
|
||||
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
|
||||
await makePutBodyRequest({ url: server.url, path: path + video.shortUUID, token: server.accessToken, fields })
|
||||
})
|
||||
|
||||
it('Should fail with an incorrect thumbnail file', async function () {
|
||||
@ -602,7 +602,7 @@ describe('Test videos API validator', function () {
|
||||
await makeUploadRequest({
|
||||
url: server.url,
|
||||
method: 'PUT',
|
||||
path: path + videoId,
|
||||
path: path + video.shortUUID,
|
||||
token: server.accessToken,
|
||||
fields,
|
||||
attaches
|
||||
@ -618,7 +618,7 @@ describe('Test videos API validator', function () {
|
||||
await makeUploadRequest({
|
||||
url: server.url,
|
||||
method: 'PUT',
|
||||
path: path + videoId,
|
||||
path: path + video.shortUUID,
|
||||
token: server.accessToken,
|
||||
fields,
|
||||
attaches
|
||||
@ -634,7 +634,7 @@ describe('Test videos API validator', function () {
|
||||
await makeUploadRequest({
|
||||
url: server.url,
|
||||
method: 'PUT',
|
||||
path: path + videoId,
|
||||
path: path + video.shortUUID,
|
||||
token: server.accessToken,
|
||||
fields,
|
||||
attaches
|
||||
@ -650,7 +650,7 @@ describe('Test videos API validator', function () {
|
||||
await makeUploadRequest({
|
||||
url: server.url,
|
||||
method: 'PUT',
|
||||
path: path + videoId,
|
||||
path: path + video.shortUUID,
|
||||
token: server.accessToken,
|
||||
fields,
|
||||
attaches
|
||||
@ -662,7 +662,7 @@ describe('Test videos API validator', function () {
|
||||
|
||||
await makePutBodyRequest({
|
||||
url: server.url,
|
||||
path: path + videoId,
|
||||
path: path + video.shortUUID,
|
||||
token: userAccessToken,
|
||||
fields,
|
||||
statusCodeExpected: HttpStatusCode.FORBIDDEN_403
|
||||
@ -674,7 +674,7 @@ describe('Test videos API validator', function () {
|
||||
it('Shoud report the appropriate error', async function () {
|
||||
const fields = immutableAssign(baseCorrectParams, { licence: 125 })
|
||||
|
||||
const res = await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
|
||||
const res = await makePutBodyRequest({ url: server.url, path: path + video.shortUUID, token: server.accessToken, fields })
|
||||
const error = res.body as PeerTubeProblemDocument
|
||||
|
||||
expect(error.docs).to.equal('https://docs.joinpeertube.org/api-rest-reference.html#operation/putVideo')
|
||||
@ -694,7 +694,7 @@ describe('Test videos API validator', function () {
|
||||
|
||||
await makePutBodyRequest({
|
||||
url: server.url,
|
||||
path: path + videoId,
|
||||
path: path + video.shortUUID,
|
||||
token: server.accessToken,
|
||||
fields,
|
||||
statusCodeExpected: HttpStatusCode.NO_CONTENT_204
|
||||
@ -739,7 +739,7 @@ describe('Test videos API validator', function () {
|
||||
})
|
||||
|
||||
it('Should succeed with the correct parameters', async function () {
|
||||
await getVideo(server.url, videoId)
|
||||
await getVideo(server.url, video.shortUUID)
|
||||
})
|
||||
})
|
||||
|
||||
@ -810,7 +810,7 @@ describe('Test videos API validator', function () {
|
||||
})
|
||||
|
||||
it('Should fail with a video of another user without the appropriate right', async function () {
|
||||
await removeVideo(server.url, userAccessToken, videoId, HttpStatusCode.FORBIDDEN_403)
|
||||
await removeVideo(server.url, userAccessToken, video.uuid, HttpStatusCode.FORBIDDEN_403)
|
||||
})
|
||||
|
||||
it('Should fail with a video of another server')
|
||||
@ -832,7 +832,7 @@ describe('Test videos API validator', function () {
|
||||
})
|
||||
|
||||
it('Should succeed with the correct parameters', async function () {
|
||||
await removeVideo(server.url, server.accessToken, videoId)
|
||||
await removeVideo(server.url, server.accessToken, video.uuid)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
|
||||
|
||||
import 'mocha'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { buildUUID } from '@server/helpers/uuid'
|
||||
import { AbuseState } from '@shared/models'
|
||||
import {
|
||||
addAbuseMessage,
|
||||
@ -85,7 +85,7 @@ describe('Test moderation notifications', function () {
|
||||
it('Should send a notification to moderators on local video abuse', async function () {
|
||||
this.timeout(20000)
|
||||
|
||||
const name = 'video for abuse ' + uuidv4()
|
||||
const name = 'video for abuse ' + buildUUID()
|
||||
const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
|
||||
const video = resVideo.body.video
|
||||
|
||||
@ -98,7 +98,7 @@ describe('Test moderation notifications', function () {
|
||||
it('Should send a notification to moderators on remote video abuse', async function () {
|
||||
this.timeout(20000)
|
||||
|
||||
const name = 'video for abuse ' + uuidv4()
|
||||
const name = 'video for abuse ' + buildUUID()
|
||||
const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
|
||||
const video = resVideo.body.video
|
||||
|
||||
@ -114,10 +114,10 @@ describe('Test moderation notifications', function () {
|
||||
it('Should send a notification to moderators on local comment abuse', async function () {
|
||||
this.timeout(20000)
|
||||
|
||||
const name = 'video for abuse ' + uuidv4()
|
||||
const name = 'video for abuse ' + buildUUID()
|
||||
const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
|
||||
const video = resVideo.body.video
|
||||
const resComment = await addVideoCommentThread(servers[0].url, userAccessToken, video.id, 'comment abuse ' + uuidv4())
|
||||
const resComment = await addVideoCommentThread(servers[0].url, userAccessToken, video.id, 'comment abuse ' + buildUUID())
|
||||
const comment = resComment.body.comment
|
||||
|
||||
await waitJobs(servers)
|
||||
@ -131,10 +131,10 @@ describe('Test moderation notifications', function () {
|
||||
it('Should send a notification to moderators on remote comment abuse', async function () {
|
||||
this.timeout(20000)
|
||||
|
||||
const name = 'video for abuse ' + uuidv4()
|
||||
const name = 'video for abuse ' + buildUUID()
|
||||
const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
|
||||
const video = resVideo.body.video
|
||||
await addVideoCommentThread(servers[0].url, userAccessToken, video.id, 'comment abuse ' + uuidv4())
|
||||
await addVideoCommentThread(servers[0].url, userAccessToken, video.id, 'comment abuse ' + buildUUID())
|
||||
|
||||
await waitJobs(servers)
|
||||
|
||||
@ -188,7 +188,7 @@ describe('Test moderation notifications', function () {
|
||||
token: userAccessToken
|
||||
}
|
||||
|
||||
const name = 'abuse ' + uuidv4()
|
||||
const name = 'abuse ' + buildUUID()
|
||||
const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
|
||||
const video = resVideo.body.video
|
||||
|
||||
@ -236,7 +236,7 @@ describe('Test moderation notifications', function () {
|
||||
token: servers[0].accessToken
|
||||
}
|
||||
|
||||
const name = 'abuse ' + uuidv4()
|
||||
const name = 'abuse ' + buildUUID()
|
||||
const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
|
||||
const video = resVideo.body.video
|
||||
|
||||
@ -307,7 +307,7 @@ describe('Test moderation notifications', function () {
|
||||
it('Should send a notification to video owner on blacklist', async function () {
|
||||
this.timeout(10000)
|
||||
|
||||
const name = 'video for abuse ' + uuidv4()
|
||||
const name = 'video for abuse ' + buildUUID()
|
||||
const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
|
||||
const uuid = resVideo.body.video.uuid
|
||||
|
||||
@ -320,7 +320,7 @@ describe('Test moderation notifications', function () {
|
||||
it('Should send a notification to video owner on unblacklist', async function () {
|
||||
this.timeout(10000)
|
||||
|
||||
const name = 'video for abuse ' + uuidv4()
|
||||
const name = 'video for abuse ' + buildUUID()
|
||||
const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
|
||||
const uuid = resVideo.body.video.uuid
|
||||
|
||||
@ -507,7 +507,7 @@ describe('Test moderation notifications', function () {
|
||||
it('Should send notification to moderators on new video with auto-blacklist', async function () {
|
||||
this.timeout(40000)
|
||||
|
||||
videoName = 'video with auto-blacklist ' + uuidv4()
|
||||
videoName = 'video with auto-blacklist ' + buildUUID()
|
||||
const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: videoName })
|
||||
videoUUID = resVideo.body.video.uuid
|
||||
|
||||
@ -553,7 +553,7 @@ describe('Test moderation notifications', function () {
|
||||
|
||||
const updateAt = new Date(new Date().getTime() + 1000000)
|
||||
|
||||
const name = 'video with auto-blacklist and future schedule ' + uuidv4()
|
||||
const name = 'video with auto-blacklist and future schedule ' + buildUUID()
|
||||
|
||||
const data = {
|
||||
name,
|
||||
@ -586,7 +586,7 @@ describe('Test moderation notifications', function () {
|
||||
// In 2 seconds
|
||||
const updateAt = new Date(new Date().getTime() + 2000)
|
||||
|
||||
const name = 'video with schedule done and still auto-blacklisted ' + uuidv4()
|
||||
const name = 'video with schedule done and still auto-blacklisted ' + buildUUID()
|
||||
|
||||
const data = {
|
||||
name,
|
||||
@ -609,7 +609,7 @@ describe('Test moderation notifications', function () {
|
||||
it('Should not send a notification to moderators on new video without auto-blacklist', async function () {
|
||||
this.timeout(60000)
|
||||
|
||||
const name = 'video without auto-blacklist ' + uuidv4()
|
||||
const name = 'video without auto-blacklist ' + buildUUID()
|
||||
|
||||
// admin with blacklist right will not be auto-blacklisted
|
||||
const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name })
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
import 'mocha'
|
||||
import * as chai from 'chai'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { buildUUID } from '@server/helpers/uuid'
|
||||
import {
|
||||
cleanupTests,
|
||||
updateMyUser,
|
||||
@ -207,7 +207,7 @@ describe('Test user notifications', function () {
|
||||
it('Should send a new video notification after a video import', async function () {
|
||||
this.timeout(100000)
|
||||
|
||||
const name = 'video import ' + uuidv4()
|
||||
const name = 'video import ' + buildUUID()
|
||||
|
||||
const attributes = {
|
||||
name,
|
||||
@ -278,7 +278,7 @@ describe('Test user notifications', function () {
|
||||
it('Should send a notification when an imported video is transcoded', async function () {
|
||||
this.timeout(50000)
|
||||
|
||||
const name = 'video import ' + uuidv4()
|
||||
const name = 'video import ' + buildUUID()
|
||||
|
||||
const attributes = {
|
||||
name,
|
||||
@ -347,7 +347,7 @@ describe('Test user notifications', function () {
|
||||
it('Should send a notification when the video import failed', async function () {
|
||||
this.timeout(70000)
|
||||
|
||||
const name = 'video import ' + uuidv4()
|
||||
const name = 'video import ' + buildUUID()
|
||||
|
||||
const attributes = {
|
||||
name,
|
||||
@ -365,7 +365,7 @@ describe('Test user notifications', function () {
|
||||
it('Should send a notification when the video import succeeded', async function () {
|
||||
this.timeout(70000)
|
||||
|
||||
const name = 'video import ' + uuidv4()
|
||||
const name = 'video import ' + buildUUID()
|
||||
|
||||
const attributes = {
|
||||
name,
|
||||
|
@ -47,7 +47,7 @@ describe('Test handle downs', function () {
|
||||
let missedVideo2: Video
|
||||
let unlistedVideo: Video
|
||||
|
||||
const videoIdsServer1: number[] = []
|
||||
const videoIdsServer1: string[] = []
|
||||
|
||||
const videoAttributes = {
|
||||
name: 'my super name for server 1',
|
||||
|
@ -56,7 +56,7 @@ import {
|
||||
removeServerFromServerBlocklist
|
||||
} from '../../../../shared/extra-utils/users/blocklist'
|
||||
import { User } from '../../../../shared/models/users'
|
||||
import { VideoPrivacy } from '../../../../shared/models/videos'
|
||||
import { VideoPlaylistCreateResult, VideoPrivacy } from '../../../../shared/models/videos'
|
||||
import { VideoExistInPlaylist } from '../../../../shared/models/videos/playlist/video-exist-in-playlist.model'
|
||||
import { VideoPlaylistElement, VideoPlaylistElementType } from '../../../../shared/models/videos/playlist/video-playlist-element.model'
|
||||
import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model'
|
||||
@ -427,31 +427,45 @@ describe('Test video playlists', function () {
|
||||
expect(data).to.have.lengthOf(0)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('Should not list unlisted or private playlists', async function () {
|
||||
describe('Playlist rights', function () {
|
||||
let unlistedPlaylist: VideoPlaylistCreateResult
|
||||
let privatePlaylist: VideoPlaylistCreateResult
|
||||
|
||||
before(async function () {
|
||||
this.timeout(30000)
|
||||
|
||||
await createVideoPlaylist({
|
||||
url: servers[1].url,
|
||||
token: servers[1].accessToken,
|
||||
playlistAttrs: {
|
||||
displayName: 'playlist unlisted',
|
||||
privacy: VideoPlaylistPrivacy.UNLISTED
|
||||
}
|
||||
})
|
||||
{
|
||||
const res = await createVideoPlaylist({
|
||||
url: servers[1].url,
|
||||
token: servers[1].accessToken,
|
||||
playlistAttrs: {
|
||||
displayName: 'playlist unlisted',
|
||||
privacy: VideoPlaylistPrivacy.UNLISTED,
|
||||
videoChannelId: servers[1].videoChannel.id
|
||||
}
|
||||
})
|
||||
unlistedPlaylist = res.body.videoPlaylist
|
||||
}
|
||||
|
||||
await createVideoPlaylist({
|
||||
url: servers[1].url,
|
||||
token: servers[1].accessToken,
|
||||
playlistAttrs: {
|
||||
displayName: 'playlist private',
|
||||
privacy: VideoPlaylistPrivacy.PRIVATE
|
||||
}
|
||||
})
|
||||
{
|
||||
const res = await createVideoPlaylist({
|
||||
url: servers[1].url,
|
||||
token: servers[1].accessToken,
|
||||
playlistAttrs: {
|
||||
displayName: 'playlist private',
|
||||
privacy: VideoPlaylistPrivacy.PRIVATE
|
||||
}
|
||||
})
|
||||
privatePlaylist = res.body.videoPlaylist
|
||||
}
|
||||
|
||||
await waitJobs(servers)
|
||||
await wait(3000)
|
||||
})
|
||||
|
||||
it('Should not list unlisted or private playlists', async function () {
|
||||
for (const server of servers) {
|
||||
const results = [
|
||||
await getAccountPlaylistsList(server.url, 'root@localhost:' + servers[1].port, 0, 5, '-createdAt'),
|
||||
@ -469,6 +483,27 @@ describe('Test video playlists', function () {
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
it('Should not get unlisted playlist using only the id', async function () {
|
||||
await getVideoPlaylist(servers[1].url, unlistedPlaylist.id, 404)
|
||||
})
|
||||
|
||||
it('Should get unlisted plyaylist using uuid or shortUUID', async function () {
|
||||
await getVideoPlaylist(servers[1].url, unlistedPlaylist.uuid)
|
||||
await getVideoPlaylist(servers[1].url, unlistedPlaylist.shortUUID)
|
||||
})
|
||||
|
||||
it('Should not get private playlist without token', async function () {
|
||||
for (const id of [ privatePlaylist.id, privatePlaylist.uuid, privatePlaylist.shortUUID ]) {
|
||||
await getVideoPlaylist(servers[1].url, id, 401)
|
||||
}
|
||||
})
|
||||
|
||||
it('Should get private playlist with a token', async function () {
|
||||
for (const id of [ privatePlaylist.id, privatePlaylist.uuid, privatePlaylist.shortUUID ]) {
|
||||
await getVideoPlaylistWithToken(servers[1].url, servers[1].accessToken, id)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('Update playlists', function () {
|
||||
|
@ -1,8 +1,9 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
|
||||
|
||||
import * as chai from 'chai'
|
||||
import 'mocha'
|
||||
import { VideoPrivacy } from '../../../../shared/models/videos/video-privacy.enum'
|
||||
import * as chai from 'chai'
|
||||
import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
|
||||
import { Video, VideoCreateResult } from '@shared/models'
|
||||
import {
|
||||
cleanupTests,
|
||||
flushAndRunServer,
|
||||
@ -13,12 +14,11 @@ import {
|
||||
uploadVideo
|
||||
} from '../../../../shared/extra-utils/index'
|
||||
import { doubleFollow } from '../../../../shared/extra-utils/server/follows'
|
||||
import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
|
||||
import { userLogin } from '../../../../shared/extra-utils/users/login'
|
||||
import { createUser } from '../../../../shared/extra-utils/users/users'
|
||||
import { getMyVideos, getVideo, getVideoWithToken, updateVideo } from '../../../../shared/extra-utils/videos/videos'
|
||||
import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
|
||||
import { Video } from '@shared/models'
|
||||
import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
|
||||
import { VideoPrivacy } from '../../../../shared/models/videos/video-privacy.enum'
|
||||
|
||||
const expect = chai.expect
|
||||
|
||||
@ -32,7 +32,7 @@ describe('Test video privacy', function () {
|
||||
let internalVideoId: number
|
||||
let internalVideoUUID: string
|
||||
|
||||
let unlistedVideoUUID: string
|
||||
let unlistedVideo: VideoCreateResult
|
||||
let nonFederatedUnlistedVideoUUID: string
|
||||
|
||||
let now: number
|
||||
@ -59,231 +59,246 @@ describe('Test video privacy', function () {
|
||||
await doubleFollow(servers[0], servers[1])
|
||||
})
|
||||
|
||||
it('Should upload a private and internal videos on server 1', async function () {
|
||||
this.timeout(10000)
|
||||
describe('Private and internal videos', function () {
|
||||
|
||||
for (const privacy of [ VideoPrivacy.PRIVATE, VideoPrivacy.INTERNAL ]) {
|
||||
const attributes = { privacy }
|
||||
await uploadVideo(servers[0].url, servers[0].accessToken, attributes)
|
||||
}
|
||||
it('Should upload a private and internal videos on server 1', async function () {
|
||||
this.timeout(10000)
|
||||
|
||||
await waitJobs(servers)
|
||||
})
|
||||
for (const privacy of [ VideoPrivacy.PRIVATE, VideoPrivacy.INTERNAL ]) {
|
||||
const attributes = { privacy }
|
||||
await uploadVideo(servers[0].url, servers[0].accessToken, attributes)
|
||||
}
|
||||
|
||||
it('Should not have these private and internal videos on server 2', async function () {
|
||||
const res = await getVideosList(servers[1].url)
|
||||
await waitJobs(servers)
|
||||
})
|
||||
|
||||
expect(res.body.total).to.equal(0)
|
||||
expect(res.body.data).to.have.lengthOf(0)
|
||||
})
|
||||
|
||||
it('Should not list the private and internal videos for an unauthenticated user on server 1', async function () {
|
||||
const res = await getVideosList(servers[0].url)
|
||||
|
||||
expect(res.body.total).to.equal(0)
|
||||
expect(res.body.data).to.have.lengthOf(0)
|
||||
})
|
||||
|
||||
it('Should not list the private video and list the internal video for an authenticated user on server 1', async function () {
|
||||
const res = await getVideosListWithToken(servers[0].url, servers[0].accessToken)
|
||||
|
||||
expect(res.body.total).to.equal(1)
|
||||
expect(res.body.data).to.have.lengthOf(1)
|
||||
|
||||
expect(res.body.data[0].privacy.id).to.equal(VideoPrivacy.INTERNAL)
|
||||
})
|
||||
|
||||
it('Should list my (private and internal) videos', async function () {
|
||||
const res = await getMyVideos(servers[0].url, servers[0].accessToken, 0, 10)
|
||||
|
||||
expect(res.body.total).to.equal(2)
|
||||
expect(res.body.data).to.have.lengthOf(2)
|
||||
|
||||
const videos: Video[] = res.body.data
|
||||
|
||||
const privateVideo = videos.find(v => v.privacy.id === VideoPrivacy.PRIVATE)
|
||||
privateVideoId = privateVideo.id
|
||||
privateVideoUUID = privateVideo.uuid
|
||||
|
||||
const internalVideo = videos.find(v => v.privacy.id === VideoPrivacy.INTERNAL)
|
||||
internalVideoId = internalVideo.id
|
||||
internalVideoUUID = internalVideo.uuid
|
||||
})
|
||||
|
||||
it('Should not be able to watch the private/internal video with non authenticated user', async function () {
|
||||
await getVideo(servers[0].url, privateVideoUUID, HttpStatusCode.UNAUTHORIZED_401)
|
||||
await getVideo(servers[0].url, internalVideoUUID, HttpStatusCode.UNAUTHORIZED_401)
|
||||
})
|
||||
|
||||
it('Should not be able to watch the private video with another user', async function () {
|
||||
this.timeout(10000)
|
||||
|
||||
const user = {
|
||||
username: 'hello',
|
||||
password: 'super password'
|
||||
}
|
||||
await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password })
|
||||
|
||||
anotherUserToken = await userLogin(servers[0], user)
|
||||
await getVideoWithToken(servers[0].url, anotherUserToken, privateVideoUUID, HttpStatusCode.FORBIDDEN_403)
|
||||
})
|
||||
|
||||
it('Should be able to watch the internal video with another user', async function () {
|
||||
await getVideoWithToken(servers[0].url, anotherUserToken, internalVideoUUID, HttpStatusCode.OK_200)
|
||||
})
|
||||
|
||||
it('Should be able to watch the private video with the correct user', async function () {
|
||||
await getVideoWithToken(servers[0].url, servers[0].accessToken, privateVideoUUID, HttpStatusCode.OK_200)
|
||||
})
|
||||
|
||||
it('Should upload an unlisted video on server 2', async function () {
|
||||
this.timeout(60000)
|
||||
|
||||
const attributes = {
|
||||
name: 'unlisted video',
|
||||
privacy: VideoPrivacy.UNLISTED
|
||||
}
|
||||
await uploadVideo(servers[1].url, servers[1].accessToken, attributes)
|
||||
|
||||
// Server 2 has transcoding enabled
|
||||
await waitJobs(servers)
|
||||
})
|
||||
|
||||
it('Should not have this unlisted video listed on server 1 and 2', async function () {
|
||||
for (const server of servers) {
|
||||
const res = await getVideosList(server.url)
|
||||
it('Should not have these private and internal videos on server 2', async function () {
|
||||
const res = await getVideosList(servers[1].url)
|
||||
|
||||
expect(res.body.total).to.equal(0)
|
||||
expect(res.body.data).to.have.lengthOf(0)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('Should list my (unlisted) videos', async function () {
|
||||
const res = await getMyVideos(servers[1].url, servers[1].accessToken, 0, 1)
|
||||
it('Should not list the private and internal videos for an unauthenticated user on server 1', async function () {
|
||||
const res = await getVideosList(servers[0].url)
|
||||
|
||||
expect(res.body.total).to.equal(1)
|
||||
expect(res.body.data).to.have.lengthOf(1)
|
||||
expect(res.body.total).to.equal(0)
|
||||
expect(res.body.data).to.have.lengthOf(0)
|
||||
})
|
||||
|
||||
unlistedVideoUUID = res.body.data[0].uuid
|
||||
})
|
||||
it('Should not list the private video and list the internal video for an authenticated user on server 1', async function () {
|
||||
const res = await getVideosListWithToken(servers[0].url, servers[0].accessToken)
|
||||
|
||||
it('Should be able to get this unlisted video', async function () {
|
||||
for (const server of servers) {
|
||||
const res = await getVideo(server.url, unlistedVideoUUID)
|
||||
expect(res.body.total).to.equal(1)
|
||||
expect(res.body.data).to.have.lengthOf(1)
|
||||
|
||||
expect(res.body.name).to.equal('unlisted video')
|
||||
}
|
||||
})
|
||||
expect(res.body.data[0].privacy.id).to.equal(VideoPrivacy.INTERNAL)
|
||||
})
|
||||
|
||||
it('Should upload a non-federating unlisted video to server 1', async function () {
|
||||
this.timeout(30000)
|
||||
it('Should list my (private and internal) videos', async function () {
|
||||
const res = await getMyVideos(servers[0].url, servers[0].accessToken, 0, 10)
|
||||
|
||||
const attributes = {
|
||||
name: 'unlisted video',
|
||||
privacy: VideoPrivacy.UNLISTED
|
||||
}
|
||||
await uploadVideo(servers[0].url, servers[0].accessToken, attributes)
|
||||
|
||||
await waitJobs(servers)
|
||||
})
|
||||
|
||||
it('Should list my new unlisted video', async function () {
|
||||
const res = await getMyVideos(servers[0].url, servers[0].accessToken, 0, 3)
|
||||
|
||||
expect(res.body.total).to.equal(3)
|
||||
expect(res.body.data).to.have.lengthOf(3)
|
||||
|
||||
nonFederatedUnlistedVideoUUID = res.body.data[0].uuid
|
||||
})
|
||||
|
||||
it('Should be able to get non-federated unlisted video from origin', async function () {
|
||||
const res = await getVideo(servers[0].url, nonFederatedUnlistedVideoUUID)
|
||||
|
||||
expect(res.body.name).to.equal('unlisted video')
|
||||
})
|
||||
|
||||
it('Should not be able to get non-federated unlisted video from federated server', async function () {
|
||||
await getVideo(servers[1].url, nonFederatedUnlistedVideoUUID, HttpStatusCode.NOT_FOUND_404)
|
||||
})
|
||||
|
||||
it('Should update the private and internal videos to public on server 1', async function () {
|
||||
this.timeout(10000)
|
||||
|
||||
now = Date.now()
|
||||
|
||||
{
|
||||
const attribute = {
|
||||
name: 'private video becomes public',
|
||||
privacy: VideoPrivacy.PUBLIC
|
||||
}
|
||||
|
||||
await updateVideo(servers[0].url, servers[0].accessToken, privateVideoId, attribute)
|
||||
}
|
||||
|
||||
{
|
||||
const attribute = {
|
||||
name: 'internal video becomes public',
|
||||
privacy: VideoPrivacy.PUBLIC
|
||||
}
|
||||
await updateVideo(servers[0].url, servers[0].accessToken, internalVideoId, attribute)
|
||||
}
|
||||
|
||||
await waitJobs(servers)
|
||||
})
|
||||
|
||||
it('Should have this new public video listed on server 1 and 2', async function () {
|
||||
for (const server of servers) {
|
||||
const res = await getVideosList(server.url)
|
||||
expect(res.body.total).to.equal(2)
|
||||
expect(res.body.data).to.have.lengthOf(2)
|
||||
|
||||
const videos: Video[] = res.body.data
|
||||
const privateVideo = videos.find(v => v.name === 'private video becomes public')
|
||||
const internalVideo = videos.find(v => v.name === 'internal video becomes public')
|
||||
|
||||
expect(privateVideo).to.not.be.undefined
|
||||
expect(internalVideo).to.not.be.undefined
|
||||
const privateVideo = videos.find(v => v.privacy.id === VideoPrivacy.PRIVATE)
|
||||
privateVideoId = privateVideo.id
|
||||
privateVideoUUID = privateVideo.uuid
|
||||
|
||||
expect(new Date(privateVideo.publishedAt).getTime()).to.be.at.least(now)
|
||||
// We don't change the publish date of internal videos
|
||||
expect(new Date(internalVideo.publishedAt).getTime()).to.be.below(now)
|
||||
const internalVideo = videos.find(v => v.privacy.id === VideoPrivacy.INTERNAL)
|
||||
internalVideoId = internalVideo.id
|
||||
internalVideoUUID = internalVideo.uuid
|
||||
})
|
||||
|
||||
expect(privateVideo.privacy.id).to.equal(VideoPrivacy.PUBLIC)
|
||||
expect(internalVideo.privacy.id).to.equal(VideoPrivacy.PUBLIC)
|
||||
}
|
||||
it('Should not be able to watch the private/internal video with non authenticated user', async function () {
|
||||
await getVideo(servers[0].url, privateVideoUUID, HttpStatusCode.UNAUTHORIZED_401)
|
||||
await getVideo(servers[0].url, internalVideoUUID, HttpStatusCode.UNAUTHORIZED_401)
|
||||
})
|
||||
|
||||
it('Should not be able to watch the private video with another user', async function () {
|
||||
this.timeout(10000)
|
||||
|
||||
const user = {
|
||||
username: 'hello',
|
||||
password: 'super password'
|
||||
}
|
||||
await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password })
|
||||
|
||||
anotherUserToken = await userLogin(servers[0], user)
|
||||
await getVideoWithToken(servers[0].url, anotherUserToken, privateVideoUUID, HttpStatusCode.FORBIDDEN_403)
|
||||
})
|
||||
|
||||
it('Should be able to watch the internal video with another user', async function () {
|
||||
await getVideoWithToken(servers[0].url, anotherUserToken, internalVideoUUID, HttpStatusCode.OK_200)
|
||||
})
|
||||
|
||||
it('Should be able to watch the private video with the correct user', async function () {
|
||||
await getVideoWithToken(servers[0].url, servers[0].accessToken, privateVideoUUID, HttpStatusCode.OK_200)
|
||||
})
|
||||
})
|
||||
|
||||
it('Should set these videos as private and internal', async function () {
|
||||
this.timeout(10000)
|
||||
describe('Unlisted videos', function () {
|
||||
|
||||
await updateVideo(servers[0].url, servers[0].accessToken, internalVideoId, { privacy: VideoPrivacy.PRIVATE })
|
||||
await updateVideo(servers[0].url, servers[0].accessToken, privateVideoId, { privacy: VideoPrivacy.INTERNAL })
|
||||
it('Should upload an unlisted video on server 2', async function () {
|
||||
this.timeout(60000)
|
||||
|
||||
await waitJobs(servers)
|
||||
const attributes = {
|
||||
name: 'unlisted video',
|
||||
privacy: VideoPrivacy.UNLISTED
|
||||
}
|
||||
await uploadVideo(servers[1].url, servers[1].accessToken, attributes)
|
||||
|
||||
for (const server of servers) {
|
||||
const res = await getVideosList(server.url)
|
||||
// Server 2 has transcoding enabled
|
||||
await waitJobs(servers)
|
||||
})
|
||||
|
||||
expect(res.body.total).to.equal(0)
|
||||
expect(res.body.data).to.have.lengthOf(0)
|
||||
}
|
||||
it('Should not have this unlisted video listed on server 1 and 2', async function () {
|
||||
for (const server of servers) {
|
||||
const res = await getVideosList(server.url)
|
||||
|
||||
{
|
||||
const res = await getMyVideos(servers[0].url, servers[0].accessToken, 0, 5)
|
||||
const videos = res.body.data
|
||||
expect(res.body.total).to.equal(0)
|
||||
expect(res.body.data).to.have.lengthOf(0)
|
||||
}
|
||||
})
|
||||
|
||||
it('Should list my (unlisted) videos', async function () {
|
||||
const res = await getMyVideos(servers[1].url, servers[1].accessToken, 0, 1)
|
||||
|
||||
expect(res.body.total).to.equal(1)
|
||||
expect(res.body.data).to.have.lengthOf(1)
|
||||
|
||||
unlistedVideo = res.body.data[0]
|
||||
})
|
||||
|
||||
it('Should not be able to get this unlisted video using its id', async function () {
|
||||
await getVideo(servers[1].url, unlistedVideo.id, 404)
|
||||
})
|
||||
|
||||
it('Should be able to get this unlisted video using its uuid/shortUUID', async function () {
|
||||
for (const server of servers) {
|
||||
for (const id of [ unlistedVideo.uuid, unlistedVideo.shortUUID ]) {
|
||||
const res = await getVideo(server.url, id)
|
||||
|
||||
expect(res.body.name).to.equal('unlisted video')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
it('Should upload a non-federating unlisted video to server 1', async function () {
|
||||
this.timeout(30000)
|
||||
|
||||
const attributes = {
|
||||
name: 'unlisted video',
|
||||
privacy: VideoPrivacy.UNLISTED
|
||||
}
|
||||
await uploadVideo(servers[0].url, servers[0].accessToken, attributes)
|
||||
|
||||
await waitJobs(servers)
|
||||
})
|
||||
|
||||
it('Should list my new unlisted video', async function () {
|
||||
const res = await getMyVideos(servers[0].url, servers[0].accessToken, 0, 3)
|
||||
|
||||
expect(res.body.total).to.equal(3)
|
||||
expect(videos).to.have.lengthOf(3)
|
||||
expect(res.body.data).to.have.lengthOf(3)
|
||||
|
||||
const privateVideo = videos.find(v => v.name === 'private video becomes public')
|
||||
const internalVideo = videos.find(v => v.name === 'internal video becomes public')
|
||||
nonFederatedUnlistedVideoUUID = res.body.data[0].uuid
|
||||
})
|
||||
|
||||
expect(privateVideo).to.not.be.undefined
|
||||
expect(internalVideo).to.not.be.undefined
|
||||
it('Should be able to get non-federated unlisted video from origin', async function () {
|
||||
const res = await getVideo(servers[0].url, nonFederatedUnlistedVideoUUID)
|
||||
|
||||
expect(privateVideo.privacy.id).to.equal(VideoPrivacy.INTERNAL)
|
||||
expect(internalVideo.privacy.id).to.equal(VideoPrivacy.PRIVATE)
|
||||
}
|
||||
expect(res.body.name).to.equal('unlisted video')
|
||||
})
|
||||
|
||||
it('Should not be able to get non-federated unlisted video from federated server', async function () {
|
||||
await getVideo(servers[1].url, nonFederatedUnlistedVideoUUID, HttpStatusCode.NOT_FOUND_404)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Privacy update', function () {
|
||||
|
||||
it('Should update the private and internal videos to public on server 1', async function () {
|
||||
this.timeout(10000)
|
||||
|
||||
now = Date.now()
|
||||
|
||||
{
|
||||
const attribute = {
|
||||
name: 'private video becomes public',
|
||||
privacy: VideoPrivacy.PUBLIC
|
||||
}
|
||||
|
||||
await updateVideo(servers[0].url, servers[0].accessToken, privateVideoId, attribute)
|
||||
}
|
||||
|
||||
{
|
||||
const attribute = {
|
||||
name: 'internal video becomes public',
|
||||
privacy: VideoPrivacy.PUBLIC
|
||||
}
|
||||
await updateVideo(servers[0].url, servers[0].accessToken, internalVideoId, attribute)
|
||||
}
|
||||
|
||||
await waitJobs(servers)
|
||||
})
|
||||
|
||||
it('Should have this new public video listed on server 1 and 2', async function () {
|
||||
for (const server of servers) {
|
||||
const res = await getVideosList(server.url)
|
||||
expect(res.body.total).to.equal(2)
|
||||
expect(res.body.data).to.have.lengthOf(2)
|
||||
|
||||
const videos: Video[] = res.body.data
|
||||
const privateVideo = videos.find(v => v.name === 'private video becomes public')
|
||||
const internalVideo = videos.find(v => v.name === 'internal video becomes public')
|
||||
|
||||
expect(privateVideo).to.not.be.undefined
|
||||
expect(internalVideo).to.not.be.undefined
|
||||
|
||||
expect(new Date(privateVideo.publishedAt).getTime()).to.be.at.least(now)
|
||||
// We don't change the publish date of internal videos
|
||||
expect(new Date(internalVideo.publishedAt).getTime()).to.be.below(now)
|
||||
|
||||
expect(privateVideo.privacy.id).to.equal(VideoPrivacy.PUBLIC)
|
||||
expect(internalVideo.privacy.id).to.equal(VideoPrivacy.PUBLIC)
|
||||
}
|
||||
})
|
||||
|
||||
it('Should set these videos as private and internal', async function () {
|
||||
this.timeout(10000)
|
||||
|
||||
await updateVideo(servers[0].url, servers[0].accessToken, internalVideoId, { privacy: VideoPrivacy.PRIVATE })
|
||||
await updateVideo(servers[0].url, servers[0].accessToken, privateVideoId, { privacy: VideoPrivacy.INTERNAL })
|
||||
|
||||
await waitJobs(servers)
|
||||
|
||||
for (const server of servers) {
|
||||
const res = await getVideosList(server.url)
|
||||
|
||||
expect(res.body.total).to.equal(0)
|
||||
expect(res.body.data).to.have.lengthOf(0)
|
||||
}
|
||||
|
||||
{
|
||||
const res = await getMyVideos(servers[0].url, servers[0].accessToken, 0, 5)
|
||||
const videos = res.body.data
|
||||
|
||||
expect(res.body.total).to.equal(3)
|
||||
expect(videos).to.have.lengthOf(3)
|
||||
|
||||
const privateVideo = videos.find(v => v.name === 'private video becomes public')
|
||||
const internalVideo = videos.find(v => v.name === 'internal video becomes public')
|
||||
|
||||
expect(privateVideo).to.not.be.undefined
|
||||
expect(internalVideo).to.not.be.undefined
|
||||
|
||||
expect(privateVideo.privacy.id).to.equal(VideoPrivacy.INTERNAL)
|
||||
expect(internalVideo.privacy.id).to.equal(VideoPrivacy.PRIVATE)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
after(async function () {
|
||||
|
@ -2,7 +2,10 @@
|
||||
|
||||
import 'mocha'
|
||||
import * as chai from 'chai'
|
||||
import { waitJobs } from '../../../shared/extra-utils/server/jobs'
|
||||
import { createFile, readdir } from 'fs-extra'
|
||||
import { join } from 'path'
|
||||
import { buildUUID } from '@server/helpers/uuid'
|
||||
import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
|
||||
import {
|
||||
buildServerDirectory,
|
||||
cleanupTests,
|
||||
@ -21,11 +24,8 @@ import {
|
||||
uploadVideo,
|
||||
wait
|
||||
} from '../../../shared/extra-utils'
|
||||
import { waitJobs } from '../../../shared/extra-utils/server/jobs'
|
||||
import { Account, VideoPlaylistPrivacy } from '../../../shared/models'
|
||||
import { createFile, readdir } from 'fs-extra'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { join } from 'path'
|
||||
import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
|
||||
|
||||
const expect = chai.expect
|
||||
|
||||
@ -131,8 +131,8 @@ describe('Test prune storage scripts', function () {
|
||||
{
|
||||
const base = buildServerDirectory(servers[0], 'videos')
|
||||
|
||||
const n1 = uuidv4() + '.mp4'
|
||||
const n2 = uuidv4() + '.webm'
|
||||
const n1 = buildUUID() + '.mp4'
|
||||
const n2 = buildUUID() + '.webm'
|
||||
|
||||
await createFile(join(base, n1))
|
||||
await createFile(join(base, n2))
|
||||
@ -143,8 +143,8 @@ describe('Test prune storage scripts', function () {
|
||||
{
|
||||
const base = buildServerDirectory(servers[0], 'torrents')
|
||||
|
||||
const n1 = uuidv4() + '-240.torrent'
|
||||
const n2 = uuidv4() + '-480.torrent'
|
||||
const n1 = buildUUID() + '-240.torrent'
|
||||
const n2 = buildUUID() + '-480.torrent'
|
||||
|
||||
await createFile(join(base, n1))
|
||||
await createFile(join(base, n2))
|
||||
@ -155,8 +155,8 @@ describe('Test prune storage scripts', function () {
|
||||
{
|
||||
const base = buildServerDirectory(servers[0], 'thumbnails')
|
||||
|
||||
const n1 = uuidv4() + '.jpg'
|
||||
const n2 = uuidv4() + '.jpg'
|
||||
const n1 = buildUUID() + '.jpg'
|
||||
const n2 = buildUUID() + '.jpg'
|
||||
|
||||
await createFile(join(base, n1))
|
||||
await createFile(join(base, n2))
|
||||
@ -167,8 +167,8 @@ describe('Test prune storage scripts', function () {
|
||||
{
|
||||
const base = buildServerDirectory(servers[0], 'previews')
|
||||
|
||||
const n1 = uuidv4() + '.jpg'
|
||||
const n2 = uuidv4() + '.jpg'
|
||||
const n1 = buildUUID() + '.jpg'
|
||||
const n2 = buildUUID() + '.jpg'
|
||||
|
||||
await createFile(join(base, n1))
|
||||
await createFile(join(base, n2))
|
||||
@ -179,8 +179,8 @@ describe('Test prune storage scripts', function () {
|
||||
{
|
||||
const base = buildServerDirectory(servers[0], 'avatars')
|
||||
|
||||
const n1 = uuidv4() + '.png'
|
||||
const n2 = uuidv4() + '.jpg'
|
||||
const n1 = buildUUID() + '.png'
|
||||
const n2 = buildUUID() + '.jpg'
|
||||
|
||||
await createFile(join(base, n1))
|
||||
await createFile(join(base, n2))
|
||||
|
@ -3,9 +3,8 @@
|
||||
import 'mocha'
|
||||
import * as chai from 'chai'
|
||||
import { omit } from 'lodash'
|
||||
import * as request from 'supertest'
|
||||
import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
|
||||
import { Account, CustomConfig, HTMLServerConfig, ServerConfig, VideoPlaylistPrivacy } from '@shared/models'
|
||||
import { Account, CustomConfig, HTMLServerConfig, ServerConfig, VideoPlaylistCreateResult, VideoPlaylistPrivacy } from '@shared/models'
|
||||
import {
|
||||
addVideoInPlaylist,
|
||||
cleanupTests,
|
||||
@ -50,13 +49,16 @@ describe('Test a client controllers', function () {
|
||||
|
||||
const playlistName = 'super playlist name'
|
||||
const playlistDescription = 'super playlist description'
|
||||
let playlistUUID: string
|
||||
let playlist: VideoPlaylistCreateResult
|
||||
|
||||
const channelDescription = 'my super channel description'
|
||||
|
||||
const watchVideoBasePaths = [ '/videos/watch/', '/w/' ]
|
||||
const watchPlaylistBasePaths = [ '/videos/watch/playlist/', '/w/p/' ]
|
||||
|
||||
let videoIds: (string | number)[] = []
|
||||
let playlistIds: (string | number)[] = []
|
||||
|
||||
before(async function () {
|
||||
this.timeout(120000)
|
||||
|
||||
@ -79,7 +81,9 @@ describe('Test a client controllers', function () {
|
||||
const videos = resVideosRequest.body.data
|
||||
expect(videos.length).to.equal(1)
|
||||
|
||||
servers[0].video = videos[0]
|
||||
const video = videos[0]
|
||||
servers[0].video = video
|
||||
videoIds = [ video.id, video.uuid, video.shortUUID ]
|
||||
|
||||
// Playlist
|
||||
|
||||
@ -91,16 +95,14 @@ describe('Test a client controllers', function () {
|
||||
}
|
||||
|
||||
const resVideoPlaylistRequest = await createVideoPlaylist({ url: servers[0].url, token: servers[0].accessToken, playlistAttrs })
|
||||
|
||||
const playlist = resVideoPlaylistRequest.body.videoPlaylist
|
||||
const playlistId = playlist.id
|
||||
playlistUUID = playlist.uuid
|
||||
playlist = resVideoPlaylistRequest.body.videoPlaylist
|
||||
playlistIds = [ playlist.id, playlist.shortUUID, playlist.uuid ]
|
||||
|
||||
await addVideoInPlaylist({
|
||||
url: servers[0].url,
|
||||
token: servers[0].accessToken,
|
||||
playlistId,
|
||||
elementAttrs: { videoId: servers[0].video.id }
|
||||
playlistId: playlist.shortUUID,
|
||||
elementAttrs: { videoId: video.id }
|
||||
})
|
||||
|
||||
// Account
|
||||
@ -117,36 +119,43 @@ describe('Test a client controllers', function () {
|
||||
|
||||
it('Should have valid oEmbed discovery tags for videos', async function () {
|
||||
for (const basePath of watchVideoBasePaths) {
|
||||
const path = basePath + servers[0].video.uuid
|
||||
const res = await request(servers[0].url)
|
||||
.get(path)
|
||||
.set('Accept', 'text/html')
|
||||
.expect(HttpStatusCode.OK_200)
|
||||
for (const id of videoIds) {
|
||||
const res = await makeGetRequest({
|
||||
url: servers[0].url,
|
||||
path: basePath + id,
|
||||
accept: 'text/html',
|
||||
statusCodeExpected: HttpStatusCode.OK_200
|
||||
})
|
||||
|
||||
const port = servers[0].port
|
||||
const port = servers[0].port
|
||||
|
||||
const expectedLink = '<link rel="alternate" type="application/json+oembed" href="http://localhost:' + port + '/services/oembed?' +
|
||||
`url=http%3A%2F%2Flocalhost%3A${port}%2Fw%2F${servers[0].video.uuid}" ` +
|
||||
`title="${servers[0].video.name}" />`
|
||||
const expectedLink = '<link rel="alternate" type="application/json+oembed" href="http://localhost:' + port + '/services/oembed?' +
|
||||
`url=http%3A%2F%2Flocalhost%3A${port}%2Fw%2F${servers[0].video.uuid}" ` +
|
||||
`title="${servers[0].video.name}" />`
|
||||
|
||||
expect(res.text).to.contain(expectedLink)
|
||||
expect(res.text).to.contain(expectedLink)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
it('Should have valid oEmbed discovery tags for a playlist', async function () {
|
||||
for (const basePath of watchPlaylistBasePaths) {
|
||||
const res = await request(servers[0].url)
|
||||
.get(basePath + playlistUUID)
|
||||
.set('Accept', 'text/html')
|
||||
.expect(HttpStatusCode.OK_200)
|
||||
for (const id of playlistIds) {
|
||||
const res = await makeGetRequest({
|
||||
url: servers[0].url,
|
||||
path: basePath + id,
|
||||
accept: 'text/html',
|
||||
statusCodeExpected: HttpStatusCode.OK_200
|
||||
})
|
||||
|
||||
const port = servers[0].port
|
||||
const port = servers[0].port
|
||||
|
||||
const expectedLink = '<link rel="alternate" type="application/json+oembed" href="http://localhost:' + port + '/services/oembed?' +
|
||||
`url=http%3A%2F%2Flocalhost%3A${port}%2Fw%2Fp%2F${playlistUUID}" ` +
|
||||
`title="${playlistName}" />`
|
||||
const expectedLink = '<link rel="alternate" type="application/json+oembed" href="http://localhost:' + port + '/services/oembed?' +
|
||||
`url=http%3A%2F%2Flocalhost%3A${port}%2Fw%2Fp%2F${playlist.uuid}" ` +
|
||||
`title="${playlistName}" />`
|
||||
|
||||
expect(res.text).to.contain(expectedLink)
|
||||
expect(res.text).to.contain(expectedLink)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
@ -190,7 +199,7 @@ describe('Test a client controllers', function () {
|
||||
expect(text).to.contain(`<meta property="og:title" content="${playlistName}" />`)
|
||||
expect(text).to.contain(`<meta property="og:description" content="${playlistDescription}" />`)
|
||||
expect(text).to.contain('<meta property="og:type" content="video" />')
|
||||
expect(text).to.contain(`<meta property="og:url" content="${servers[0].url}/w/p/${playlistUUID}" />`)
|
||||
expect(text).to.contain(`<meta property="og:url" content="${servers[0].url}/w/p/${playlist.uuid}" />`)
|
||||
}
|
||||
|
||||
it('Should have valid Open Graph tags on the account page', async function () {
|
||||
@ -206,15 +215,19 @@ describe('Test a client controllers', function () {
|
||||
})
|
||||
|
||||
it('Should have valid Open Graph tags on the watch page', async function () {
|
||||
await watchVideoPageTest('/videos/watch/' + servers[0].video.id)
|
||||
await watchVideoPageTest('/videos/watch/' + servers[0].video.uuid)
|
||||
await watchVideoPageTest('/w/' + servers[0].video.uuid)
|
||||
await watchVideoPageTest('/w/' + servers[0].video.id)
|
||||
for (const path of watchVideoBasePaths) {
|
||||
for (const id of videoIds) {
|
||||
await watchVideoPageTest(path + id)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
it('Should have valid Open Graph tags on the watch playlist page', async function () {
|
||||
await watchPlaylistPageTest('/videos/watch/playlist/' + playlistUUID)
|
||||
await watchPlaylistPageTest('/w/p/' + playlistUUID)
|
||||
for (const path of watchPlaylistBasePaths) {
|
||||
for (const id of playlistIds) {
|
||||
await watchPlaylistPageTest(path + id)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@ -263,15 +276,19 @@ describe('Test a client controllers', function () {
|
||||
}
|
||||
|
||||
it('Should have valid twitter card on the watch video page', async function () {
|
||||
await watchVideoPageTest('/videos/watch/' + servers[0].video.id)
|
||||
await watchVideoPageTest('/videos/watch/' + servers[0].video.uuid)
|
||||
await watchVideoPageTest('/w/' + servers[0].video.uuid)
|
||||
await watchVideoPageTest('/w/' + servers[0].video.id)
|
||||
for (const path of watchVideoBasePaths) {
|
||||
for (const id of videoIds) {
|
||||
await watchVideoPageTest(path + id)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
it('Should have valid twitter card on the watch playlist page', async function () {
|
||||
await watchPlaylistPageTest('/videos/watch/playlist/' + playlistUUID)
|
||||
await watchPlaylistPageTest('/w/p/' + playlistUUID)
|
||||
for (const path of watchPlaylistBasePaths) {
|
||||
for (const id of playlistIds) {
|
||||
await watchPlaylistPageTest(path + id)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
it('Should have valid twitter card on the account page', async function () {
|
||||
@ -333,15 +350,19 @@ describe('Test a client controllers', function () {
|
||||
}
|
||||
|
||||
it('Should have valid twitter card on the watch video page', async function () {
|
||||
await watchVideoPageTest('/videos/watch/' + servers[0].video.id)
|
||||
await watchVideoPageTest('/videos/watch/' + servers[0].video.uuid)
|
||||
await watchVideoPageTest('/w/' + servers[0].video.uuid)
|
||||
await watchVideoPageTest('/w/' + servers[0].video.id)
|
||||
for (const path of watchVideoBasePaths) {
|
||||
for (const id of videoIds) {
|
||||
await watchVideoPageTest(path + id)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
it('Should have valid twitter card on the watch playlist page', async function () {
|
||||
await watchPlaylistPageTest('/videos/watch/playlist/' + playlistUUID)
|
||||
await watchPlaylistPageTest('/w/p/' + playlistUUID)
|
||||
for (const path of watchPlaylistBasePaths) {
|
||||
for (const id of playlistIds) {
|
||||
await watchPlaylistPageTest(path + id)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
it('Should have valid twitter card on the account page', async function () {
|
||||
@ -399,8 +420,10 @@ describe('Test a client controllers', function () {
|
||||
|
||||
it('Should use the original video URL for the canonical tag', async function () {
|
||||
for (const basePath of watchVideoBasePaths) {
|
||||
const res = await makeHTMLRequest(servers[1].url, basePath + servers[0].video.uuid)
|
||||
expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/videos/watch/${servers[0].video.uuid}" />`)
|
||||
for (const id of videoIds) {
|
||||
const res = await makeHTMLRequest(servers[1].url, basePath + id)
|
||||
expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/videos/watch/${servers[0].video.uuid}" />`)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -426,8 +449,10 @@ describe('Test a client controllers', function () {
|
||||
|
||||
it('Should use the original playlist URL for the canonical tag', async function () {
|
||||
for (const basePath of watchPlaylistBasePaths) {
|
||||
const res = await makeHTMLRequest(servers[1].url, basePath + playlistUUID)
|
||||
expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/video-playlists/${playlistUUID}" />`)
|
||||
for (const id of playlistIds) {
|
||||
const res = await makeHTMLRequest(servers[1].url, basePath + id)
|
||||
expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/video-playlists/${playlist.uuid}" />`)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
@ -4,7 +4,6 @@ registerTSPaths()
|
||||
import * as repl from 'repl'
|
||||
import * as path from 'path'
|
||||
import * as _ from 'lodash'
|
||||
import { uuidv1, uuidv3, uuidv4, uuidv5 } from 'uuid'
|
||||
import * as Sequelize from 'sequelize'
|
||||
import * as YoutubeDL from 'youtube-dl'
|
||||
import { initDatabaseModels, sequelizeTypescript } from '../initializers/database'
|
||||
@ -31,10 +30,6 @@ const start = async () => {
|
||||
env: process.env,
|
||||
lodash: _,
|
||||
path,
|
||||
uuidv1,
|
||||
uuidv3,
|
||||
uuidv4,
|
||||
uuidv5,
|
||||
cli,
|
||||
logger,
|
||||
constants,
|
||||
|
@ -43,6 +43,7 @@ interface ServerInfo {
|
||||
video?: {
|
||||
id: number
|
||||
uuid: string
|
||||
shortUUID: string
|
||||
name?: string
|
||||
url?: string
|
||||
|
||||
|
@ -6,9 +6,9 @@ import got, { Response as GotResponse } from 'got/dist/source'
|
||||
import * as parseTorrent from 'parse-torrent'
|
||||
import { join } from 'path'
|
||||
import * as request from 'supertest'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import validator from 'validator'
|
||||
import { getLowercaseExtension } from '@server/helpers/core-utils'
|
||||
import { buildUUID } from '@server/helpers/uuid'
|
||||
import { HttpStatusCode } from '@shared/core-utils'
|
||||
import { VideosCommonQuery } from '@shared/models'
|
||||
import { loadLanguages, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../server/initializers/constants'
|
||||
@ -806,7 +806,7 @@ async function uploadVideoAndGetId (options: {
|
||||
|
||||
const res = await uploadVideo(options.server.url, options.token || options.server.accessToken, videoAttrs)
|
||||
|
||||
return { id: res.body.video.id, uuid: res.body.video.uuid }
|
||||
return res.body.video as { id: number, uuid: string, shortUUID: string }
|
||||
}
|
||||
|
||||
async function getLocalIdByUUID (url: string, uuid: string) {
|
||||
@ -827,7 +827,7 @@ async function uploadRandomVideoOnServers (servers: ServerInfo[], serverNumber:
|
||||
|
||||
async function uploadRandomVideo (server: ServerInfo, wait = true, additionalParams: any = {}) {
|
||||
const prefixName = additionalParams.prefixName || ''
|
||||
const name = prefixName + uuidv4()
|
||||
const name = prefixName + buildUUID()
|
||||
|
||||
const data = Object.assign({ name }, additionalParams)
|
||||
const res = await uploadVideo(server.url, server.accessToken, data)
|
||||
|
1
shared/models/common/index.ts
Normal file
1
shared/models/common/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './result-list.model'
|
@ -1,16 +1,16 @@
|
||||
export * from './activitypub'
|
||||
export * from './actors'
|
||||
export * from './moderation'
|
||||
export * from './custom-markup'
|
||||
export * from './bulk'
|
||||
export * from './redundancy'
|
||||
export * from './users'
|
||||
export * from './videos'
|
||||
export * from './common'
|
||||
export * from './custom-markup'
|
||||
export * from './feeds'
|
||||
export * from './joinpeertube'
|
||||
export * from './moderation'
|
||||
export * from './overviews'
|
||||
export * from './plugins'
|
||||
export * from './redundancy'
|
||||
export * from './search'
|
||||
export * from './server'
|
||||
export * from './oauth-client-local.model'
|
||||
export * from './result-list.model'
|
||||
export * from './tokens'
|
||||
export * from './users'
|
||||
export * from './videos'
|
||||
|
@ -10,7 +10,7 @@ export interface AbuseCreate {
|
||||
}
|
||||
|
||||
video?: {
|
||||
id: number
|
||||
id: number | string
|
||||
startAt?: number
|
||||
endAt?: number
|
||||
}
|
||||
|
1
shared/models/tokens/index.ts
Normal file
1
shared/models/tokens/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './oauth-client-local.model'
|
@ -35,3 +35,4 @@ export * from './video-transcoding-fps.model'
|
||||
|
||||
export * from './video-update.model'
|
||||
export * from './video.model'
|
||||
export * from './video-create-result.model'
|
||||
|
@ -1,4 +1,5 @@
|
||||
export * from './video-exist-in-playlist.model'
|
||||
export * from './video-playlist-create-result.model'
|
||||
export * from './video-playlist-create.model'
|
||||
export * from './video-playlist-element-create.model'
|
||||
export * from './video-playlist-element-update.model'
|
||||
|
@ -0,0 +1,5 @@
|
||||
export interface VideoPlaylistCreateResult {
|
||||
id: number
|
||||
uuid: string
|
||||
shortUUID: string
|
||||
}
|
@ -6,6 +6,8 @@ import { VideoPlaylistType } from './video-playlist-type.model'
|
||||
export interface VideoPlaylist {
|
||||
id: number
|
||||
uuid: string
|
||||
shortUUID: string
|
||||
|
||||
isLocal: boolean
|
||||
|
||||
url: string
|
||||
|
5
shared/models/videos/video-create-result.model.ts
Normal file
5
shared/models/videos/video-create-result.model.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export interface VideoCreateResult {
|
||||
id: number
|
||||
uuid: string
|
||||
shortUUID: string
|
||||
}
|
@ -10,6 +10,8 @@ import { VideoStreamingPlaylist } from './video-streaming-playlist.model'
|
||||
export interface Video {
|
||||
id: number
|
||||
uuid: string
|
||||
shortUUID: string
|
||||
|
||||
createdAt: Date | string
|
||||
updatedAt: Date | string
|
||||
publishedAt: Date | string
|
||||
|
@ -3003,6 +3003,8 @@ paths:
|
||||
$ref: '#/components/schemas/VideoPlaylist/properties/id'
|
||||
uuid:
|
||||
$ref: '#/components/schemas/VideoPlaylist/properties/uuid'
|
||||
shortUUID:
|
||||
$ref: '#/components/schemas/VideoPlaylist/properties/shortUUID'
|
||||
requestBody:
|
||||
content:
|
||||
multipart/form-data:
|
||||
@ -4543,11 +4545,12 @@ components:
|
||||
name: id
|
||||
in: path
|
||||
required: true
|
||||
description: The object id or uuid
|
||||
description: The object id, uuid or short uuid
|
||||
schema:
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/id'
|
||||
- $ref: '#/components/schemas/UUIDv4'
|
||||
- $ref: '#/components/schemas/shortUUID'
|
||||
playlistId:
|
||||
name: playlistId
|
||||
in: path
|
||||
@ -4812,6 +4815,10 @@ components:
|
||||
pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$'
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
shortUUID:
|
||||
type: string
|
||||
description: translation of a uuid v4 with a bigger alphabet to have a shorter uuid
|
||||
example: 2y84q2MQUMWPbiEcxNXMgC
|
||||
username:
|
||||
type: string
|
||||
description: immutable name of the user, used to find or mention its actor
|
||||
@ -5141,6 +5148,9 @@ components:
|
||||
description: universal identifier for the video, that can be used across instances
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/UUIDv4'
|
||||
shortUUID:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/shortUUID'
|
||||
isLive:
|
||||
type: boolean
|
||||
createdAt:
|
||||
@ -5520,6 +5530,9 @@ components:
|
||||
$ref: '#/components/schemas/id'
|
||||
uuid:
|
||||
$ref: '#/components/schemas/UUIDv4'
|
||||
shortUUID:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/shortUUID'
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
@ -6295,6 +6308,8 @@ components:
|
||||
$ref: '#/components/schemas/Video/properties/id'
|
||||
uuid:
|
||||
$ref: '#/components/schemas/Video/properties/uuid'
|
||||
shortUUID:
|
||||
$ref: '#/components/schemas/Video/properties/shortUUID'
|
||||
CommentThreadResponse:
|
||||
properties:
|
||||
total:
|
||||
|
@ -7260,6 +7260,14 @@ shebang-regex@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
|
||||
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
|
||||
|
||||
short-uuid@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/short-uuid/-/short-uuid-4.2.0.tgz#3706d9e7287ac589dc5ffe324d3e34817a07540b"
|
||||
integrity sha512-r3cxuPPZSuF0QkKsK9bBR7u+7cwuCRzWzgjPh07F5N2iIUNgblnMHepBY16xgj5t1lG9iOP9k/TEafY1qhRzaw==
|
||||
dependencies:
|
||||
any-base "^1.1.0"
|
||||
uuid "^8.3.2"
|
||||
|
||||
side-channel@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
|
||||
|
Loading…
Reference in New Issue
Block a user