diff options
author | Rigel Kent <sendmemail@rigelk.eu> | 2020-12-08 21:16:10 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-08 21:16:10 +0100 |
commit | f2eb23cd87cf32b8fe545178143b5f49e06a58da (patch) | |
tree | af7d59945af70e28fd85047e2c688c59a908f548 | |
parent | c977fd3ec931c059111ddb2b8d6ddbb20b6b99a1 (diff) | |
download | PeerTube-f2eb23cd87cf32b8fe545178143b5f49e06a58da.tar.gz PeerTube-f2eb23cd87cf32b8fe545178143b5f49e06a58da.tar.zst PeerTube-f2eb23cd87cf32b8fe545178143b5f49e06a58da.zip |
emit more specific status codes on video upload (#3423)
- reduce http status codes list to potentially useful codes
- convert more codes to typed ones
- factorize html generator for error responses
53 files changed, 503 insertions, 307 deletions
diff --git a/client/src/app/+about/about-instance/contact-admin-modal.component.ts b/client/src/app/+about/about-instance/contact-admin-modal.component.ts index 11e442f6b..ac2a6c980 100644 --- a/client/src/app/+about/about-instance/contact-admin-modal.component.ts +++ b/client/src/app/+about/about-instance/contact-admin-modal.component.ts | |||
@@ -10,6 +10,7 @@ import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' | |||
10 | import { InstanceService } from '@app/shared/shared-instance' | 10 | import { InstanceService } from '@app/shared/shared-instance' |
11 | import { NgbModal } from '@ng-bootstrap/ng-bootstrap' | 11 | import { NgbModal } from '@ng-bootstrap/ng-bootstrap' |
12 | import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' | 12 | import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' |
13 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | ||
13 | import { ServerConfig } from '@shared/models' | 14 | import { ServerConfig } from '@shared/models' |
14 | 15 | ||
15 | @Component({ | 16 | @Component({ |
@@ -78,7 +79,7 @@ export class ContactAdminModalComponent extends FormReactive implements OnInit { | |||
78 | }, | 79 | }, |
79 | 80 | ||
80 | err => { | 81 | err => { |
81 | this.error = err.status === 403 | 82 | this.error = err.status === HttpStatusCode.FORBIDDEN_403 |
82 | ? $localize`You already sent this form recently` | 83 | ? $localize`You already sent this form recently` |
83 | : err.message | 84 | : err.message |
84 | } | 85 | } |
diff --git a/client/src/app/+accounts/accounts.component.ts b/client/src/app/+accounts/accounts.component.ts index dbc7c8887..4820eaf32 100644 --- a/client/src/app/+accounts/accounts.component.ts +++ b/client/src/app/+accounts/accounts.component.ts | |||
@@ -6,6 +6,7 @@ import { AuthService, Notifier, RedirectService, RestExtractor, ScreenService, U | |||
6 | import { Account, AccountService, DropdownAction, ListOverflowItem, VideoChannel, VideoChannelService } from '@app/shared/shared-main' | 6 | import { Account, AccountService, DropdownAction, ListOverflowItem, VideoChannel, VideoChannelService } from '@app/shared/shared-main' |
7 | import { AccountReportComponent } from '@app/shared/shared-moderation' | 7 | import { AccountReportComponent } from '@app/shared/shared-moderation' |
8 | import { User, UserRight } from '@shared/models' | 8 | import { User, UserRight } from '@shared/models' |
9 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | ||
9 | 10 | ||
10 | @Component({ | 11 | @Component({ |
11 | templateUrl: './accounts.component.html', | 12 | templateUrl: './accounts.component.html', |
@@ -47,7 +48,10 @@ export class AccountsComponent implements OnInit, OnDestroy { | |||
47 | switchMap(accountId => this.accountService.getAccount(accountId)), | 48 | switchMap(accountId => this.accountService.getAccount(accountId)), |
48 | tap(account => this.onAccount(account)), | 49 | tap(account => this.onAccount(account)), |
49 | switchMap(account => this.videoChannelService.listAccountVideoChannels(account)), | 50 | switchMap(account => this.videoChannelService.listAccountVideoChannels(account)), |
50 | catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ 400, 404 ])) | 51 | catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ |
52 | HttpStatusCode.BAD_REQUEST_400, | ||
53 | HttpStatusCode.NOT_FOUND_404 | ||
54 | ])) | ||
51 | ) | 55 | ) |
52 | .subscribe( | 56 | .subscribe( |
53 | videoChannels => this.videoChannels = videoChannels.data, | 57 | videoChannels => this.videoChannels = videoChannels.data, |
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts b/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts index 1d0cbf246..a625493de 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts +++ b/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts | |||
@@ -10,6 +10,7 @@ import { | |||
10 | import { FormValidatorService } from '@app/shared/shared-forms' | 10 | import { FormValidatorService } from '@app/shared/shared-forms' |
11 | import { VideoChannelService } from '@app/shared/shared-main' | 11 | import { VideoChannelService } from '@app/shared/shared-main' |
12 | import { VideoChannelCreate } from '@shared/models' | 12 | import { VideoChannelCreate } from '@shared/models' |
13 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | ||
13 | import { MyVideoChannelEdit } from './my-video-channel-edit' | 14 | import { MyVideoChannelEdit } from './my-video-channel-edit' |
14 | 15 | ||
15 | @Component({ | 16 | @Component({ |
@@ -58,7 +59,7 @@ export class MyVideoChannelCreateComponent extends MyVideoChannelEdit implements | |||
58 | }, | 59 | }, |
59 | 60 | ||
60 | err => { | 61 | err => { |
61 | if (err.status === 409) { | 62 | if (err.status === HttpStatusCode.CONFLICT_409) { |
62 | this.error = $localize`This name already exists on this instance.` | 63 | this.error = $localize`This name already exists on this instance.` |
63 | return | 64 | return |
64 | } | 65 | } |
diff --git a/client/src/app/+video-channels/video-channels.component.ts b/client/src/app/+video-channels/video-channels.component.ts index ea8bda1cf..d2fd265c4 100644 --- a/client/src/app/+video-channels/video-channels.component.ts +++ b/client/src/app/+video-channels/video-channels.component.ts | |||
@@ -6,6 +6,7 @@ import { ActivatedRoute } from '@angular/router' | |||
6 | import { AuthService, Notifier, RestExtractor, ScreenService } from '@app/core' | 6 | import { AuthService, Notifier, RestExtractor, ScreenService } from '@app/core' |
7 | import { ListOverflowItem, VideoChannel, VideoChannelService } from '@app/shared/shared-main' | 7 | import { ListOverflowItem, VideoChannel, VideoChannelService } from '@app/shared/shared-main' |
8 | import { SubscribeButtonComponent } from '@app/shared/shared-user-subscription' | 8 | import { SubscribeButtonComponent } from '@app/shared/shared-user-subscription' |
9 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | ||
9 | 10 | ||
10 | @Component({ | 11 | @Component({ |
11 | templateUrl: './video-channels.component.html', | 12 | templateUrl: './video-channels.component.html', |
@@ -37,7 +38,10 @@ export class VideoChannelsComponent implements OnInit, OnDestroy { | |||
37 | map(params => params[ 'videoChannelName' ]), | 38 | map(params => params[ 'videoChannelName' ]), |
38 | distinctUntilChanged(), | 39 | distinctUntilChanged(), |
39 | switchMap(videoChannelName => this.videoChannelService.getVideoChannel(videoChannelName)), | 40 | switchMap(videoChannelName => this.videoChannelService.getVideoChannel(videoChannelName)), |
40 | catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ 400, 404 ])) | 41 | catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ |
42 | HttpStatusCode.BAD_REQUEST_400, | ||
43 | HttpStatusCode.NOT_FOUND_404 | ||
44 | ])) | ||
41 | ) | 45 | ) |
42 | .subscribe(videoChannel => { | 46 | .subscribe(videoChannel => { |
43 | this.videoChannel = videoChannel | 47 | this.videoChannel = videoChannel |
diff --git a/client/src/app/+videos/+video-edit/video-add-components/video-upload.component.ts b/client/src/app/+videos/+video-edit/video-add-components/video-upload.component.ts index bee3679f7..cafb030b9 100644 --- a/client/src/app/+videos/+video-edit/video-add-components/video-upload.component.ts +++ b/client/src/app/+videos/+video-edit/video-add-components/video-upload.component.ts | |||
@@ -9,6 +9,7 @@ import { BytesPipe, VideoCaptionService, VideoEdit, VideoService } from '@app/sh | |||
9 | import { LoadingBarService } from '@ngx-loading-bar/core' | 9 | import { LoadingBarService } from '@ngx-loading-bar/core' |
10 | import { VideoPrivacy } from '@shared/models' | 10 | import { VideoPrivacy } from '@shared/models' |
11 | import { VideoSend } from './video-send' | 11 | import { VideoSend } from './video-send' |
12 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | ||
12 | 13 | ||
13 | @Component({ | 14 | @Component({ |
14 | selector: 'my-video-upload', | 15 | selector: 'my-video-upload', |
@@ -129,17 +130,17 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy | |||
129 | cancelUpload () { | 130 | cancelUpload () { |
130 | if (this.videoUploadObservable !== null) { | 131 | if (this.videoUploadObservable !== null) { |
131 | this.videoUploadObservable.unsubscribe() | 132 | this.videoUploadObservable.unsubscribe() |
133 | } | ||
132 | 134 | ||
133 | this.isUploadingVideo = false | 135 | this.isUploadingVideo = false |
134 | this.videoUploadPercents = 0 | 136 | this.videoUploadPercents = 0 |
135 | this.videoUploadObservable = null | 137 | this.videoUploadObservable = null |
136 | 138 | ||
137 | this.firstStepError.emit() | 139 | this.firstStepError.emit() |
138 | this.enableRetryAfterError = false | 140 | this.enableRetryAfterError = false |
139 | this.error = '' | 141 | this.error = '' |
140 | 142 | ||
141 | this.notifier.info($localize`Upload cancelled`) | 143 | this.notifier.info($localize`Upload cancelled`) |
142 | } | ||
143 | } | 144 | } |
144 | 145 | ||
145 | uploadFirstStep (clickedOnButton = false) { | 146 | uploadFirstStep (clickedOnButton = false) { |
@@ -229,6 +230,11 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy | |||
229 | notifier: this.notifier, | 230 | notifier: this.notifier, |
230 | sticky: false | 231 | sticky: false |
231 | }) | 232 | }) |
233 | |||
234 | if (err.status === HttpStatusCode.PAYLOAD_TOO_LARGE_413 || | ||
235 | err.status === HttpStatusCode.UNSUPPORTED_MEDIA_TYPE_415) { | ||
236 | this.cancelUpload() | ||
237 | } | ||
232 | } | 238 | } |
233 | ) | 239 | ) |
234 | } | 240 | } |
diff --git a/client/src/app/+videos/+video-watch/video-watch.component.ts b/client/src/app/+videos/+video-watch/video-watch.component.ts index b15de2a79..33de901c0 100644 --- a/client/src/app/+videos/+video-watch/video-watch.component.ts +++ b/client/src/app/+videos/+video-watch/video-watch.component.ts | |||
@@ -39,6 +39,7 @@ import { isWebRTCDisabled, timeToInt } from '../../../assets/player/utils' | |||
39 | import { environment } from '../../../environments/environment' | 39 | import { environment } from '../../../environments/environment' |
40 | import { VideoSupportComponent } from './modal/video-support.component' | 40 | import { VideoSupportComponent } from './modal/video-support.component' |
41 | import { VideoWatchPlaylistComponent } from './video-watch-playlist.component' | 41 | import { VideoWatchPlaylistComponent } from './video-watch-playlist.component' |
42 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | ||
42 | 43 | ||
43 | type URLOptions = CustomizationOptions & { playerMode: PlayerMode } | 44 | type URLOptions = CustomizationOptions & { playerMode: PlayerMode } |
44 | 45 | ||
@@ -412,13 +413,25 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
412 | $localize`This video is not available on this instance. Do you want to be redirected on the origin instance: <a href="${originUrl}">${originUrl}</a>?`, | 413 | $localize`This video is not available on this instance. Do you want to be redirected on the origin instance: <a href="${originUrl}">${originUrl}</a>?`, |
413 | $localize`Redirection` | 414 | $localize`Redirection` |
414 | ).then(res => { | 415 | ).then(res => { |
415 | if (res === false) return this.restExtractor.redirectTo404IfNotFound(err, [ 400, 401, 403, 404 ]) | 416 | if (res === false) { |
417 | return this.restExtractor.redirectTo404IfNotFound(err, [ | ||
418 | HttpStatusCode.BAD_REQUEST_400, | ||
419 | HttpStatusCode.UNAUTHORIZED_401, | ||
420 | HttpStatusCode.FORBIDDEN_403, | ||
421 | HttpStatusCode.NOT_FOUND_404 | ||
422 | ]) | ||
423 | } | ||
416 | 424 | ||
417 | return window.location.href = originUrl | 425 | return window.location.href = originUrl |
418 | }) | 426 | }) |
419 | } | 427 | } |
420 | 428 | ||
421 | return this.restExtractor.redirectTo404IfNotFound(err, [ 400, 401, 403, 404 ]) | 429 | return this.restExtractor.redirectTo404IfNotFound(err, [ |
430 | HttpStatusCode.BAD_REQUEST_400, | ||
431 | HttpStatusCode.UNAUTHORIZED_401, | ||
432 | HttpStatusCode.FORBIDDEN_403, | ||
433 | HttpStatusCode.NOT_FOUND_404 | ||
434 | ]) | ||
422 | }) | 435 | }) |
423 | ) | 436 | ) |
424 | .subscribe(([ video, captionsResult ]) => { | 437 | .subscribe(([ video, captionsResult ]) => { |
@@ -450,7 +463,12 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
450 | this.playlistService.getVideoPlaylist(playlistId) | 463 | this.playlistService.getVideoPlaylist(playlistId) |
451 | .pipe( | 464 | .pipe( |
452 | // If 401, the video is private or blocked so redirect to 404 | 465 | // If 401, the video is private or blocked so redirect to 404 |
453 | catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ 400, 401, 403, 404 ])) | 466 | catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ |
467 | HttpStatusCode.BAD_REQUEST_400, | ||
468 | HttpStatusCode.UNAUTHORIZED_401, | ||
469 | HttpStatusCode.FORBIDDEN_403, | ||
470 | HttpStatusCode.NOT_FOUND_404 | ||
471 | ])) | ||
454 | ) | 472 | ) |
455 | .subscribe(playlist => { | 473 | .subscribe(playlist => { |
456 | this.playlist = playlist | 474 | this.playlist = playlist |
diff --git a/client/src/app/core/auth/auth.service.ts b/client/src/app/core/auth/auth.service.ts index fd6062d3f..cdf13186b 100644 --- a/client/src/app/core/auth/auth.service.ts +++ b/client/src/app/core/auth/auth.service.ts | |||
@@ -11,6 +11,7 @@ import { environment } from '../../../environments/environment' | |||
11 | import { RestExtractor } from '../rest/rest-extractor.service' | 11 | import { RestExtractor } from '../rest/rest-extractor.service' |
12 | import { AuthStatus } from './auth-status.model' | 12 | import { AuthStatus } from './auth-status.model' |
13 | import { AuthUser } from './auth-user.model' | 13 | import { AuthUser } from './auth-user.model' |
14 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | ||
14 | 15 | ||
15 | interface UserLoginWithUsername extends UserLogin { | 16 | interface UserLoginWithUsername extends UserLogin { |
16 | access_token: string | 17 | access_token: string |
@@ -94,7 +95,7 @@ export class AuthService { | |||
94 | error => { | 95 | error => { |
95 | let errorMessage = error.message | 96 | let errorMessage = error.message |
96 | 97 | ||
97 | if (error.status === 403) { | 98 | if (error.status === HttpStatusCode.FORBIDDEN_403) { |
98 | errorMessage = $localize`Cannot retrieve OAuth Client credentials: ${error.text}. | 99 | errorMessage = $localize`Cannot retrieve OAuth Client credentials: ${error.text}. |
99 | Ensure you have correctly configured PeerTube (config/ directory), in particular the "webserver" section.` | 100 | Ensure you have correctly configured PeerTube (config/ directory), in particular the "webserver" section.` |
100 | } | 101 | } |
diff --git a/client/src/app/core/rest/rest-extractor.service.ts b/client/src/app/core/rest/rest-extractor.service.ts index 4b8c1e155..84d9ed074 100644 --- a/client/src/app/core/rest/rest-extractor.service.ts +++ b/client/src/app/core/rest/rest-extractor.service.ts | |||
@@ -3,6 +3,7 @@ import { Injectable } from '@angular/core' | |||
3 | import { Router } from '@angular/router' | 3 | import { Router } from '@angular/router' |
4 | import { dateToHuman } from '@app/helpers' | 4 | import { dateToHuman } from '@app/helpers' |
5 | import { ResultList } from '@shared/models' | 5 | import { ResultList } from '@shared/models' |
6 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | ||
6 | 7 | ||
7 | @Injectable() | 8 | @Injectable() |
8 | export class RestExtractor { | 9 | export class RestExtractor { |
@@ -57,9 +58,9 @@ export class RestExtractor { | |||
57 | errorMessage = errorsArray.join('. ') | 58 | errorMessage = errorsArray.join('. ') |
58 | } else if (err.error && err.error.error) { | 59 | } else if (err.error && err.error.error) { |
59 | errorMessage = err.error.error | 60 | errorMessage = err.error.error |
60 | } else if (err.status === 413) { | 61 | } else if (err.status === HttpStatusCode.PAYLOAD_TOO_LARGE_413) { |
61 | errorMessage = $localize`Media is too large for the server. Please contact you administrator if you want to increase the limit size.` | 62 | errorMessage = $localize`Media is too large for the server. Please contact you administrator if you want to increase the limit size.` |
62 | } else if (err.status === 429) { | 63 | } else if (err.status === HttpStatusCode.TOO_MANY_REQUESTS_429) { |
63 | const secondsLeft = err.headers.get('retry-after') | 64 | const secondsLeft = err.headers.get('retry-after') |
64 | if (secondsLeft) { | 65 | if (secondsLeft) { |
65 | const minutesLeft = Math.floor(parseInt(secondsLeft, 10) / 60) | 66 | const minutesLeft = Math.floor(parseInt(secondsLeft, 10) / 60) |
@@ -67,7 +68,7 @@ export class RestExtractor { | |||
67 | } else { | 68 | } else { |
68 | errorMessage = $localize`Too many attempts, please try again later.` | 69 | errorMessage = $localize`Too many attempts, please try again later.` |
69 | } | 70 | } |
70 | } else if (err.status === 500) { | 71 | } else if (err.status === HttpStatusCode.INTERNAL_SERVER_ERROR_500) { |
71 | errorMessage = $localize`Server error. Please retry later.` | 72 | errorMessage = $localize`Server error. Please retry later.` |
72 | } | 73 | } |
73 | 74 | ||
@@ -92,7 +93,7 @@ export class RestExtractor { | |||
92 | return observableThrowError(errorObj) | 93 | return observableThrowError(errorObj) |
93 | } | 94 | } |
94 | 95 | ||
95 | redirectTo404IfNotFound (obj: { status: number }, status = [ 404 ]) { | 96 | redirectTo404IfNotFound (obj: { status: number }, status = [ HttpStatusCode.NOT_FOUND_404 ]) { |
96 | if (obj && obj.status && status.indexOf(obj.status) !== -1) { | 97 | if (obj && obj.status && status.indexOf(obj.status) !== -1) { |
97 | // Do not use redirectService to avoid circular dependencies | 98 | // Do not use redirectService to avoid circular dependencies |
98 | this.router.navigate([ '/404' ], { skipLocationChange: true }) | 99 | this.router.navigate([ '/404' ], { skipLocationChange: true }) |
diff --git a/client/src/standalone/videos/embed.ts b/client/src/standalone/videos/embed.ts index 48f7e7749..1709d44e7 100644 --- a/client/src/standalone/videos/embed.ts +++ b/client/src/standalone/videos/embed.ts | |||
@@ -13,6 +13,7 @@ import { | |||
13 | PluginType, | 13 | PluginType, |
14 | ClientHookName | 14 | ClientHookName |
15 | } from '../../../../shared/models' | 15 | } from '../../../../shared/models' |
16 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
16 | import { P2PMediaLoaderOptions, PeertubePlayerManagerOptions, PlayerMode } from '../../assets/player/peertube-player-manager' | 17 | import { P2PMediaLoaderOptions, PeertubePlayerManagerOptions, PlayerMode } from '../../assets/player/peertube-player-manager' |
17 | import { VideoJSCaption } from '../../assets/player/peertube-videojs-typings' | 18 | import { VideoJSCaption } from '../../assets/player/peertube-videojs-typings' |
18 | import { TranslationsManager } from '../../assets/player/translations-manager' | 19 | import { TranslationsManager } from '../../assets/player/translations-manager' |
@@ -85,7 +86,7 @@ export class PeerTubeEmbed { | |||
85 | refreshFetch (url: string, options?: RequestInit) { | 86 | refreshFetch (url: string, options?: RequestInit) { |
86 | return fetch(url, options) | 87 | return fetch(url, options) |
87 | .then((res: Response) => { | 88 | .then((res: Response) => { |
88 | if (res.status !== 401) return res | 89 | if (res.status !== HttpStatusCode.UNAUTHORIZED_401) return res |
89 | 90 | ||
90 | const refreshingTokenPromise = new Promise((resolve, reject) => { | 91 | const refreshingTokenPromise = new Promise((resolve, reject) => { |
91 | const clientId: string = peertubeLocalStorage.getItem(this.LOCAL_STORAGE_OAUTH_CLIENT_KEYS.CLIENT_ID) | 92 | const clientId: string = peertubeLocalStorage.getItem(this.LOCAL_STORAGE_OAUTH_CLIENT_KEYS.CLIENT_ID) |
@@ -107,7 +108,7 @@ export class PeerTubeEmbed { | |||
107 | method: 'POST', | 108 | method: 'POST', |
108 | body: objectToUrlEncoded(data) | 109 | body: objectToUrlEncoded(data) |
109 | }).then(res => { | 110 | }).then(res => { |
110 | if (res.status === 401) return undefined | 111 | if (res.status === HttpStatusCode.UNAUTHORIZED_401) return undefined |
111 | 112 | ||
112 | return res.json() | 113 | return res.json() |
113 | }).then((obj: UserRefreshToken & { code: 'invalid_grant'}) => { | 114 | }).then((obj: UserRefreshToken & { code: 'invalid_grant'}) => { |
@@ -338,7 +339,7 @@ export class PeerTubeEmbed { | |||
338 | 339 | ||
339 | try { | 340 | try { |
340 | playlistResponse = await playlistPromise | 341 | playlistResponse = await playlistPromise |
341 | isResponseOk = playlistResponse.status === 200 | 342 | isResponseOk = playlistResponse.status === HttpStatusCode.OK_200 |
342 | } catch (err) { | 343 | } catch (err) { |
343 | console.error(err) | 344 | console.error(err) |
344 | isResponseOk = false | 345 | isResponseOk = false |
@@ -347,7 +348,7 @@ export class PeerTubeEmbed { | |||
347 | if (!isResponseOk) { | 348 | if (!isResponseOk) { |
348 | const serverTranslations = await this.translationsPromise | 349 | const serverTranslations = await this.translationsPromise |
349 | 350 | ||
350 | if (playlistResponse?.status === 404) { | 351 | if (playlistResponse?.status === HttpStatusCode.NOT_FOUND_404) { |
351 | this.playlistNotFound(serverTranslations) | 352 | this.playlistNotFound(serverTranslations) |
352 | return undefined | 353 | return undefined |
353 | } | 354 | } |
@@ -367,7 +368,7 @@ export class PeerTubeEmbed { | |||
367 | 368 | ||
368 | try { | 369 | try { |
369 | videoResponse = await videoPromise | 370 | videoResponse = await videoPromise |
370 | isResponseOk = videoResponse.status === 200 | 371 | isResponseOk = videoResponse.status === HttpStatusCode.OK_200 |
371 | } catch (err) { | 372 | } catch (err) { |
372 | console.error(err) | 373 | console.error(err) |
373 | 374 | ||
@@ -377,7 +378,7 @@ export class PeerTubeEmbed { | |||
377 | if (!isResponseOk) { | 378 | if (!isResponseOk) { |
378 | const serverTranslations = await this.translationsPromise | 379 | const serverTranslations = await this.translationsPromise |
379 | 380 | ||
380 | if (videoResponse?.status === 404) { | 381 | if (videoResponse?.status === HttpStatusCode.NOT_FOUND_404) { |
381 | this.videoNotFound(serverTranslations) | 382 | this.videoNotFound(serverTranslations) |
382 | return undefined | 383 | return undefined |
383 | } | 384 | } |
diff --git a/server/controllers/client.ts b/server/controllers/client.ts index 49e6fd661..bd1f19f8c 100644 --- a/server/controllers/client.ts +++ b/server/controllers/client.ts | |||
@@ -3,12 +3,11 @@ import { constants, promises as fs } from 'fs' | |||
3 | import { join } from 'path' | 3 | import { join } from 'path' |
4 | import { CONFIG } from '@server/initializers/config' | 4 | import { CONFIG } from '@server/initializers/config' |
5 | import { buildFileLocale, getCompleteLocale, is18nLocale, LOCALE_FILES } from '@shared/core-utils/i18n' | 5 | import { buildFileLocale, getCompleteLocale, is18nLocale, LOCALE_FILES } from '@shared/core-utils/i18n' |
6 | import { HttpStatusCode } from '@shared/core-utils' | ||
6 | import { root } from '../helpers/core-utils' | 7 | import { root } from '../helpers/core-utils' |
7 | import { logger } from '../helpers/logger' | 8 | import { STATIC_MAX_AGE } from '../initializers/constants' |
8 | import { ACCEPT_HEADERS, STATIC_MAX_AGE } from '../initializers/constants' | 9 | import { ClientHtml, sendHTML, serveIndexHTML } from '../lib/client-html' |
9 | import { ClientHtml } from '../lib/client-html' | ||
10 | import { asyncMiddleware, embedCSP } from '../middlewares' | 10 | import { asyncMiddleware, embedCSP } from '../middlewares' |
11 | import { HttpStatusCode } from '@shared/core-utils' | ||
12 | 11 | ||
13 | const clientsRouter = express.Router() | 12 | const clientsRouter = express.Router() |
14 | 13 | ||
@@ -118,31 +117,12 @@ function serveServerTranslations (req: express.Request, res: express.Response) { | |||
118 | return res.sendStatus(HttpStatusCode.NOT_FOUND_404) | 117 | return res.sendStatus(HttpStatusCode.NOT_FOUND_404) |
119 | } | 118 | } |
120 | 119 | ||
121 | async function serveIndexHTML (req: express.Request, res: express.Response) { | ||
122 | if (req.accepts(ACCEPT_HEADERS) === 'html') { | ||
123 | try { | ||
124 | await generateHTMLPage(req, res, req.params.language) | ||
125 | return | ||
126 | } catch (err) { | ||
127 | logger.error('Cannot generate HTML page.', err) | ||
128 | } | ||
129 | } | ||
130 | |||
131 | return res.status(HttpStatusCode.INTERNAL_SERVER_ERROR_500).end() | ||
132 | } | ||
133 | |||
134 | async function generateEmbedHtmlPage (req: express.Request, res: express.Response) { | 120 | async function generateEmbedHtmlPage (req: express.Request, res: express.Response) { |
135 | const html = await ClientHtml.getEmbedHTML() | 121 | const html = await ClientHtml.getEmbedHTML() |
136 | 122 | ||
137 | return sendHTML(html, res) | 123 | return sendHTML(html, res) |
138 | } | 124 | } |
139 | 125 | ||
140 | async function generateHTMLPage (req: express.Request, res: express.Response, paramLang?: string) { | ||
141 | const html = await ClientHtml.getDefaultHTMLPage(req, res, paramLang) | ||
142 | |||
143 | return sendHTML(html, res) | ||
144 | } | ||
145 | |||
146 | async function generateWatchHtmlPage (req: express.Request, res: express.Response) { | 126 | async function generateWatchHtmlPage (req: express.Request, res: express.Response) { |
147 | const html = await ClientHtml.getWatchHTMLPage(req.params.id + '', req, res) | 127 | const html = await ClientHtml.getWatchHTMLPage(req.params.id + '', req, res) |
148 | 128 | ||
@@ -167,12 +147,6 @@ async function generateVideoChannelHtmlPage (req: express.Request, res: express. | |||
167 | return sendHTML(html, res) | 147 | return sendHTML(html, res) |
168 | } | 148 | } |
169 | 149 | ||
170 | function sendHTML (html: string, res: express.Response) { | ||
171 | res.set('Content-Type', 'text/html; charset=UTF-8') | ||
172 | |||
173 | return res.send(html) | ||
174 | } | ||
175 | |||
176 | async function generateManifest (req: express.Request, res: express.Response) { | 150 | async function generateManifest (req: express.Request, res: express.Response) { |
177 | const manifestPhysicalPath = join(root(), 'client', 'dist', 'manifest.webmanifest') | 151 | const manifestPhysicalPath = join(root(), 'client', 'dist', 'manifest.webmanifest') |
178 | const manifestJson = await fs.readFile(manifestPhysicalPath, 'utf8') | 152 | const manifestJson = await fs.readFile(manifestPhysicalPath, 'utf8') |
diff --git a/server/controllers/static.ts b/server/controllers/static.ts index ff77452dd..f12f00e1b 100644 --- a/server/controllers/static.ts +++ b/server/controllers/static.ts | |||
@@ -27,6 +27,7 @@ import { getTorrentFilePath, getVideoFilePath } from '@server/lib/video-paths' | |||
27 | import { getThemeOrDefault } from '../lib/plugins/theme-utils' | 27 | import { getThemeOrDefault } from '../lib/plugins/theme-utils' |
28 | import { getEnabledResolutions, getRegisteredPlugins, getRegisteredThemes } from '@server/controllers/api/config' | 28 | import { getEnabledResolutions, getRegisteredPlugins, getRegisteredThemes } from '@server/controllers/api/config' |
29 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | 29 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' |
30 | import { serveIndexHTML } from '@server/lib/client-html' | ||
30 | 31 | ||
31 | const staticRouter = express.Router() | 32 | const staticRouter = express.Router() |
32 | 33 | ||
@@ -119,6 +120,11 @@ staticRouter.get('/robots.txt', | |||
119 | } | 120 | } |
120 | ) | 121 | ) |
121 | 122 | ||
123 | staticRouter.all('/teapot', | ||
124 | getCup, | ||
125 | asyncMiddleware(serveIndexHTML) | ||
126 | ) | ||
127 | |||
122 | // security.txt service | 128 | // security.txt service |
123 | staticRouter.get('/security.txt', | 129 | staticRouter.get('/security.txt', |
124 | (_, res: express.Response) => { | 130 | (_, res: express.Response) => { |
@@ -391,3 +397,11 @@ function getHLSPlaylist (video: MVideoFullLight) { | |||
391 | 397 | ||
392 | return Object.assign(playlist, { Video: video }) | 398 | return Object.assign(playlist, { Video: video }) |
393 | } | 399 | } |
400 | |||
401 | function getCup (req: express.Request, res: express.Response, next: express.NextFunction) { | ||
402 | res.status(HttpStatusCode.I_AM_A_TEAPOT_418) | ||
403 | res.setHeader('Accept-Additions', 'Non-Dairy;1,Sugar;1') | ||
404 | res.setHeader('Safe', 'if-sepia-awake') | ||
405 | |||
406 | return next() | ||
407 | } | ||
diff --git a/server/helpers/custom-validators/misc.ts b/server/helpers/custom-validators/misc.ts index 61c03f0c9..effdd98cb 100644 --- a/server/helpers/custom-validators/misc.ts +++ b/server/helpers/custom-validators/misc.ts | |||
@@ -86,6 +86,50 @@ function toIntArray (value: any) { | |||
86 | return value.map(v => validator.toInt(v)) | 86 | return value.map(v => validator.toInt(v)) |
87 | } | 87 | } |
88 | 88 | ||
89 | function isFileFieldValid ( | ||
90 | files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], | ||
91 | field: string, | ||
92 | optional = false | ||
93 | ) { | ||
94 | // Should have files | ||
95 | if (!files) return optional | ||
96 | if (isArray(files)) return optional | ||
97 | |||
98 | // Should have a file | ||
99 | const fileArray = files[field] | ||
100 | if (!fileArray || fileArray.length === 0) { | ||
101 | return optional | ||
102 | } | ||
103 | |||
104 | // The file should exist | ||
105 | const file = fileArray[0] | ||
106 | if (!file || !file.originalname) return false | ||
107 | return file | ||
108 | } | ||
109 | |||
110 | function isFileMimeTypeValid ( | ||
111 | files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], | ||
112 | mimeTypeRegex: string, | ||
113 | field: string, | ||
114 | optional = false | ||
115 | ) { | ||
116 | // Should have files | ||
117 | if (!files) return optional | ||
118 | if (isArray(files)) return optional | ||
119 | |||
120 | // Should have a file | ||
121 | const fileArray = files[field] | ||
122 | if (!fileArray || fileArray.length === 0) { | ||
123 | return optional | ||
124 | } | ||
125 | |||
126 | // The file should exist | ||
127 | const file = fileArray[0] | ||
128 | if (!file || !file.originalname) return false | ||
129 | |||
130 | return new RegExp(`^${mimeTypeRegex}$`, 'i').test(file.mimetype) | ||
131 | } | ||
132 | |||
89 | function isFileValid ( | 133 | function isFileValid ( |
90 | files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], | 134 | files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], |
91 | mimeTypeRegex: string, | 135 | mimeTypeRegex: string, |
@@ -132,5 +176,7 @@ export { | |||
132 | toIntOrNull, | 176 | toIntOrNull, |
133 | toArray, | 177 | toArray, |
134 | toIntArray, | 178 | toIntArray, |
179 | isFileFieldValid, | ||
180 | isFileMimeTypeValid, | ||
135 | isFileValid | 181 | isFileValid |
136 | } | 182 | } |
diff --git a/server/helpers/custom-validators/videos.ts b/server/helpers/custom-validators/videos.ts index 8b309ae42..87966798f 100644 --- a/server/helpers/custom-validators/videos.ts +++ b/server/helpers/custom-validators/videos.ts | |||
@@ -11,7 +11,7 @@ import { | |||
11 | VIDEO_STATES, | 11 | VIDEO_STATES, |
12 | VIDEO_LIVE | 12 | VIDEO_LIVE |
13 | } from '../../initializers/constants' | 13 | } from '../../initializers/constants' |
14 | import { exists, isArray, isDateValid, isFileValid } from './misc' | 14 | import { exists, isArray, isDateValid, isFileMimeTypeValid, isFileValid } from './misc' |
15 | import * as magnetUtil from 'magnet-uri' | 15 | import * as magnetUtil from 'magnet-uri' |
16 | 16 | ||
17 | const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS | 17 | const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS |
@@ -81,8 +81,8 @@ function isVideoFileExtnameValid (value: string) { | |||
81 | return exists(value) && (value === VIDEO_LIVE.EXTENSION || MIMETYPES.VIDEO.EXT_MIMETYPE[value] !== undefined) | 81 | return exists(value) && (value === VIDEO_LIVE.EXTENSION || MIMETYPES.VIDEO.EXT_MIMETYPE[value] !== undefined) |
82 | } | 82 | } |
83 | 83 | ||
84 | function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) { | 84 | function isVideoFileMimeTypeValid (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) { |
85 | return isFileValid(files, MIMETYPES.VIDEO.MIMETYPES_REGEX, 'videofile', null) | 85 | return isFileMimeTypeValid(files, MIMETYPES.VIDEO.MIMETYPES_REGEX, 'videofile') |
86 | } | 86 | } |
87 | 87 | ||
88 | const videoImageTypes = CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME | 88 | const videoImageTypes = CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME |
@@ -143,12 +143,12 @@ export { | |||
143 | isVideoFPSResolutionValid, | 143 | isVideoFPSResolutionValid, |
144 | isScheduleVideoUpdatePrivacyValid, | 144 | isScheduleVideoUpdatePrivacyValid, |
145 | isVideoOriginallyPublishedAtValid, | 145 | isVideoOriginallyPublishedAtValid, |
146 | isVideoFile, | ||
147 | isVideoMagnetUriValid, | 146 | isVideoMagnetUriValid, |
148 | isVideoStateValid, | 147 | isVideoStateValid, |
149 | isVideoViewsValid, | 148 | isVideoViewsValid, |
150 | isVideoRatingTypeValid, | 149 | isVideoRatingTypeValid, |
151 | isVideoFileExtnameValid, | 150 | isVideoFileExtnameValid, |
151 | isVideoFileMimeTypeValid, | ||
152 | isVideoDurationValid, | 152 | isVideoDurationValid, |
153 | isVideoTagValid, | 153 | isVideoTagValid, |
154 | isVideoPrivacyValid, | 154 | isVideoPrivacyValid, |
diff --git a/server/helpers/youtube-dl.ts b/server/helpers/youtube-dl.ts index 302b2e206..9e8ef90d8 100644 --- a/server/helpers/youtube-dl.ts +++ b/server/helpers/youtube-dl.ts | |||
@@ -7,6 +7,7 @@ import { ensureDir, remove, writeFile } from 'fs-extra' | |||
7 | import * as request from 'request' | 7 | import * as request from 'request' |
8 | import { createWriteStream } from 'fs' | 8 | import { createWriteStream } from 'fs' |
9 | import { CONFIG } from '@server/initializers/config' | 9 | import { CONFIG } from '@server/initializers/config' |
10 | import { HttpStatusCode } from '../../shared/core-utils/miscs/http-error-codes' | ||
10 | 11 | ||
11 | export type YoutubeDLInfo = { | 12 | export type YoutubeDLInfo = { |
12 | name?: string | 13 | name?: string |
@@ -154,7 +155,7 @@ async function updateYoutubeDLBinary () { | |||
154 | return res() | 155 | return res() |
155 | } | 156 | } |
156 | 157 | ||
157 | if (result.statusCode !== 302) { | 158 | if (result.statusCode !== HttpStatusCode.FOUND_302) { |
158 | logger.error('youtube-dl update error: did not get redirect for the latest version link. Status %d', result.statusCode) | 159 | logger.error('youtube-dl update error: did not get redirect for the latest version link. Status %d', result.statusCode) |
159 | return res() | 160 | return res() |
160 | } | 161 | } |
@@ -164,7 +165,7 @@ async function updateYoutubeDLBinary () { | |||
164 | const newVersion = /yt-dl\.org\/downloads\/(\d{4}\.\d\d\.\d\d(\.\d)?)\/youtube-dl/.exec(url)[1] | 165 | const newVersion = /yt-dl\.org\/downloads\/(\d{4}\.\d\d\.\d\d(\.\d)?)\/youtube-dl/.exec(url)[1] |
165 | 166 | ||
166 | downloadFile.on('response', result => { | 167 | downloadFile.on('response', result => { |
167 | if (result.statusCode !== 200) { | 168 | if (result.statusCode !== HttpStatusCode.OK_200) { |
168 | logger.error('Cannot update youtube-dl: new version response is not 200, it\'s %d.', result.statusCode) | 169 | logger.error('Cannot update youtube-dl: new version response is not 200, it\'s %d.', result.statusCode) |
169 | return res() | 170 | return res() |
170 | } | 171 | } |
diff --git a/server/lib/activitypub/actor.ts b/server/lib/activitypub/actor.ts index fb5558ff6..52547536c 100644 --- a/server/lib/activitypub/actor.ts +++ b/server/lib/activitypub/actor.ts | |||
@@ -36,6 +36,7 @@ import { | |||
36 | } from '../../types/models' | 36 | } from '../../types/models' |
37 | import { extname } from 'path' | 37 | import { extname } from 'path' |
38 | import { getServerActor } from '@server/models/application/application' | 38 | import { getServerActor } from '@server/models/application/application' |
39 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | ||
39 | 40 | ||
40 | // Set account keys, this could be long so process after the account creation and do not block the client | 41 | // Set account keys, this could be long so process after the account creation and do not block the client |
41 | function setAsyncActorKeys <T extends MActor> (actor: T) { | 42 | function setAsyncActorKeys <T extends MActor> (actor: T) { |
@@ -277,7 +278,7 @@ async function refreshActorIfNeeded <T extends MActorFull | MActorAccountChannel | |||
277 | 278 | ||
278 | const { result, statusCode } = await fetchRemoteActor(actorUrl) | 279 | const { result, statusCode } = await fetchRemoteActor(actorUrl) |
279 | 280 | ||
280 | if (statusCode === 404) { | 281 | if (statusCode === HttpStatusCode.NOT_FOUND_404) { |
281 | logger.info('Deleting actor %s because there is a 404 in refresh actor.', actor.url) | 282 | logger.info('Deleting actor %s because there is a 404 in refresh actor.', actor.url) |
282 | actor.Account | 283 | actor.Account |
283 | ? await actor.Account.destroy() | 284 | ? await actor.Account.destroy() |
diff --git a/server/lib/activitypub/playlist.ts b/server/lib/activitypub/playlist.ts index bd442b223..53298e968 100644 --- a/server/lib/activitypub/playlist.ts +++ b/server/lib/activitypub/playlist.ts | |||
@@ -18,6 +18,7 @@ import { createPlaylistMiniatureFromUrl } from '../thumbnail' | |||
18 | import { FilteredModelAttributes } from '../../types/sequelize' | 18 | import { FilteredModelAttributes } from '../../types/sequelize' |
19 | import { MAccountDefault, MAccountId, MVideoId } from '../../types/models' | 19 | import { MAccountDefault, MAccountId, MVideoId } from '../../types/models' |
20 | import { MVideoPlaylist, MVideoPlaylistId, MVideoPlaylistOwner } from '../../types/models/video/video-playlist' | 20 | import { MVideoPlaylist, MVideoPlaylistId, MVideoPlaylistOwner } from '../../types/models/video/video-playlist' |
21 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | ||
21 | 22 | ||
22 | function playlistObjectToDBAttributes (playlistObject: PlaylistObject, byAccount: MAccountId, to: string[]) { | 23 | function playlistObjectToDBAttributes (playlistObject: PlaylistObject, byAccount: MAccountId, to: string[]) { |
23 | const privacy = to.includes(ACTIVITY_PUB.PUBLIC) | 24 | const privacy = to.includes(ACTIVITY_PUB.PUBLIC) |
@@ -120,7 +121,7 @@ async function refreshVideoPlaylistIfNeeded (videoPlaylist: MVideoPlaylistOwner) | |||
120 | 121 | ||
121 | try { | 122 | try { |
122 | const { statusCode, playlistObject } = await fetchRemoteVideoPlaylist(videoPlaylist.url) | 123 | const { statusCode, playlistObject } = await fetchRemoteVideoPlaylist(videoPlaylist.url) |
123 | if (statusCode === 404) { | 124 | if (statusCode === HttpStatusCode.NOT_FOUND_404) { |
124 | logger.info('Cannot refresh remote video playlist %s: it does not exist anymore. Deleting it.', videoPlaylist.url) | 125 | logger.info('Cannot refresh remote video playlist %s: it does not exist anymore. Deleting it.', videoPlaylist.url) |
125 | 126 | ||
126 | await videoPlaylist.destroy() | 127 | await videoPlaylist.destroy() |
diff --git a/server/lib/activitypub/videos.ts b/server/lib/activitypub/videos.ts index 04f0bfc23..b15d5da1c 100644 --- a/server/lib/activitypub/videos.ts +++ b/server/lib/activitypub/videos.ts | |||
@@ -76,6 +76,7 @@ import { sendCreateVideo, sendUpdateVideo } from './send' | |||
76 | import { addVideoShares, shareVideoByServerAndChannel } from './share' | 76 | import { addVideoShares, shareVideoByServerAndChannel } from './share' |
77 | import { addVideoComments } from './video-comments' | 77 | import { addVideoComments } from './video-comments' |
78 | import { createRates } from './video-rates' | 78 | import { createRates } from './video-rates' |
79 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | ||
79 | 80 | ||
80 | async function federateVideoIfNeeded (videoArg: MVideoAPWithoutCaption, isNewVideo: boolean, transaction?: sequelize.Transaction) { | 81 | async function federateVideoIfNeeded (videoArg: MVideoAPWithoutCaption, isNewVideo: boolean, transaction?: sequelize.Transaction) { |
81 | const video = videoArg as MVideoAP | 82 | const video = videoArg as MVideoAP |
@@ -488,7 +489,7 @@ async function refreshVideoIfNeeded (options: { | |||
488 | 489 | ||
489 | try { | 490 | try { |
490 | const { response, videoObject } = await fetchRemoteVideo(video.url) | 491 | const { response, videoObject } = await fetchRemoteVideo(video.url) |
491 | if (response.statusCode === 404) { | 492 | if (response.statusCode === HttpStatusCode.NOT_FOUND_404) { |
492 | logger.info('Cannot refresh remote video %s: video does not exist anymore. Deleting it.', video.url) | 493 | logger.info('Cannot refresh remote video %s: video does not exist anymore. Deleting it.', video.url) |
493 | 494 | ||
494 | // Video does not exist anymore | 495 | // Video does not exist anymore |
diff --git a/server/lib/client-html.ts b/server/lib/client-html.ts index d97d23180..32f5d29ab 100644 --- a/server/lib/client-html.ts +++ b/server/lib/client-html.ts | |||
@@ -1,4 +1,5 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import * as Bluebird from 'bluebird' | ||
2 | import { buildFileLocale, getDefaultLocale, is18nLocale, POSSIBLE_LOCALES } from '../../shared/core-utils/i18n/i18n' | 3 | import { buildFileLocale, getDefaultLocale, is18nLocale, POSSIBLE_LOCALES } from '../../shared/core-utils/i18n/i18n' |
3 | import { | 4 | import { |
4 | AVATARS_SIZE, | 5 | AVATARS_SIZE, |
@@ -6,7 +7,8 @@ import { | |||
6 | EMBED_SIZE, | 7 | EMBED_SIZE, |
7 | PLUGIN_GLOBAL_CSS_PATH, | 8 | PLUGIN_GLOBAL_CSS_PATH, |
8 | WEBSERVER, | 9 | WEBSERVER, |
9 | FILES_CONTENT_HASH | 10 | FILES_CONTENT_HASH, |
11 | ACCEPT_HEADERS | ||
10 | } from '../initializers/constants' | 12 | } from '../initializers/constants' |
11 | import { join } from 'path' | 13 | import { join } from 'path' |
12 | import { escapeHTML, isTestInstance, sha256 } from '../helpers/core-utils' | 14 | import { escapeHTML, isTestInstance, sha256 } from '../helpers/core-utils' |
@@ -18,7 +20,6 @@ import { readFile } from 'fs-extra' | |||
18 | import { getActivityStreamDuration } from '../models/video/video-format-utils' | 20 | import { getActivityStreamDuration } from '../models/video/video-format-utils' |
19 | import { AccountModel } from '../models/account/account' | 21 | import { AccountModel } from '../models/account/account' |
20 | import { VideoChannelModel } from '../models/video/video-channel' | 22 | import { VideoChannelModel } from '../models/video/video-channel' |
21 | import * as Bluebird from 'bluebird' | ||
22 | import { CONFIG } from '../initializers/config' | 23 | import { CONFIG } from '../initializers/config' |
23 | import { logger } from '../helpers/logger' | 24 | import { logger } from '../helpers/logger' |
24 | import { MAccountActor, MChannelActor } from '../types/models' | 25 | import { MAccountActor, MChannelActor } from '../types/models' |
@@ -53,7 +54,7 @@ type Tags = { | |||
53 | } | 54 | } |
54 | } | 55 | } |
55 | 56 | ||
56 | export class ClientHtml { | 57 | class ClientHtml { |
57 | 58 | ||
58 | private static htmlCache: { [path: string]: string } = {} | 59 | private static htmlCache: { [path: string]: string } = {} |
59 | 60 | ||
@@ -505,3 +506,38 @@ export class ClientHtml { | |||
505 | return htmlStringPage.replace(CUSTOM_HTML_TAG_COMMENTS.META_TAGS, tagsString) | 506 | return htmlStringPage.replace(CUSTOM_HTML_TAG_COMMENTS.META_TAGS, tagsString) |
506 | } | 507 | } |
507 | } | 508 | } |
509 | |||
510 | function sendHTML (html: string, res: express.Response) { | ||
511 | res.set('Content-Type', 'text/html; charset=UTF-8') | ||
512 | |||
513 | return res.send(html) | ||
514 | } | ||
515 | |||
516 | async function serveIndexHTML (req: express.Request, res: express.Response) { | ||
517 | if (req.accepts(ACCEPT_HEADERS) === 'html' || | ||
518 | !req.headers.accept) { | ||
519 | try { | ||
520 | await generateHTMLPage(req, res, req.params.language) | ||
521 | return | ||
522 | } catch (err) { | ||
523 | logger.error('Cannot generate HTML page.', err) | ||
524 | return res.sendStatus(HttpStatusCode.INTERNAL_SERVER_ERROR_500) | ||
525 | } | ||
526 | } | ||
527 | |||
528 | return res.sendStatus(HttpStatusCode.NOT_ACCEPTABLE_406) | ||
529 | } | ||
530 | |||
531 | // --------------------------------------------------------------------------- | ||
532 | |||
533 | export { | ||
534 | ClientHtml, | ||
535 | sendHTML, | ||
536 | serveIndexHTML | ||
537 | } | ||
538 | |||
539 | async function generateHTMLPage (req: express.Request, res: express.Response, paramLang?: string) { | ||
540 | const html = await ClientHtml.getDefaultHTMLPage(req, res, paramLang) | ||
541 | |||
542 | return sendHTML(html, res) | ||
543 | } | ||
diff --git a/server/middlewares/cache.ts b/server/middlewares/cache.ts index cb24d9e0e..0708ee8e8 100644 --- a/server/middlewares/cache.ts +++ b/server/middlewares/cache.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | import { Redis } from '../lib/redis' | 1 | import { Redis } from '../lib/redis' |
2 | import * as apicache from 'apicache' | 2 | import * as apicache from 'apicache' |
3 | import { HttpStatusCode } from '../../shared/core-utils/miscs/http-error-codes' | ||
3 | 4 | ||
4 | // Ensure Redis is initialized | 5 | // Ensure Redis is initialized |
5 | Redis.Instance.init() | 6 | Redis.Instance.init() |
@@ -8,7 +9,10 @@ const defaultOptions = { | |||
8 | redisClient: Redis.Instance.getClient(), | 9 | redisClient: Redis.Instance.getClient(), |
9 | appendKey: () => Redis.Instance.getPrefix(), | 10 | appendKey: () => Redis.Instance.getPrefix(), |
10 | statusCodes: { | 11 | statusCodes: { |
11 | exclude: [ 404, 403 ] | 12 | exclude: [ |
13 | HttpStatusCode.FORBIDDEN_403, | ||
14 | HttpStatusCode.NOT_FOUND_404 | ||
15 | ] | ||
12 | } | 16 | } |
13 | } | 17 | } |
14 | 18 | ||
diff --git a/server/middlewares/validators/videos/videos.ts b/server/middlewares/validators/videos/videos.ts index 9834f714b..8bc37b0ab 100644 --- a/server/middlewares/validators/videos/videos.ts +++ b/server/middlewares/validators/videos/videos.ts | |||
@@ -8,6 +8,7 @@ import { VideoChangeOwnershipAccept } from '../../../../shared/models/videos/vid | |||
8 | import { | 8 | import { |
9 | isBooleanValid, | 9 | isBooleanValid, |
10 | isDateValid, | 10 | isDateValid, |
11 | isFileFieldValid, | ||
11 | isIdOrUUIDValid, | 12 | isIdOrUUIDValid, |
12 | isIdValid, | 13 | isIdValid, |
13 | isUUIDValid, | 14 | isUUIDValid, |
@@ -22,7 +23,8 @@ import { | |||
22 | isScheduleVideoUpdatePrivacyValid, | 23 | isScheduleVideoUpdatePrivacyValid, |
23 | isVideoCategoryValid, | 24 | isVideoCategoryValid, |
24 | isVideoDescriptionValid, | 25 | isVideoDescriptionValid, |
25 | isVideoFile, | 26 | isVideoFileMimeTypeValid, |
27 | isVideoFileSizeValid, | ||
26 | isVideoFilterValid, | 28 | isVideoFilterValid, |
27 | isVideoImage, | 29 | isVideoImage, |
28 | isVideoLanguageValid, | 30 | isVideoLanguageValid, |
@@ -55,11 +57,11 @@ import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-c | |||
55 | 57 | ||
56 | const videosAddValidator = getCommonVideoEditAttributes().concat([ | 58 | const videosAddValidator = getCommonVideoEditAttributes().concat([ |
57 | body('videofile') | 59 | body('videofile') |
58 | .custom((value, { req }) => isVideoFile(req.files)).withMessage( | 60 | .custom((value, { req }) => isFileFieldValid(req.files, 'videofile')) |
59 | 'This file is not supported or too large. Please, make sure it is of the following type: ' + | 61 | .withMessage('Should have a file'), |
60 | CONSTRAINTS_FIELDS.VIDEOS.EXTNAME.join(', ') | 62 | body('name') |
61 | ), | 63 | .custom(isVideoNameValid) |
62 | body('name').custom(isVideoNameValid).withMessage('Should have a valid name'), | 64 | .withMessage('Should have a valid name'), |
63 | body('channelId') | 65 | body('channelId') |
64 | .customSanitizer(toIntOrNull) | 66 | .customSanitizer(toIntOrNull) |
65 | .custom(isIdValid).withMessage('Should have correct video channel id'), | 67 | .custom(isIdValid).withMessage('Should have correct video channel id'), |
@@ -75,8 +77,27 @@ const videosAddValidator = getCommonVideoEditAttributes().concat([ | |||
75 | 77 | ||
76 | if (!await doesVideoChannelOfAccountExist(req.body.channelId, user, res)) return cleanUpReqFiles(req) | 78 | if (!await doesVideoChannelOfAccountExist(req.body.channelId, user, res)) return cleanUpReqFiles(req) |
77 | 79 | ||
80 | if (!isVideoFileMimeTypeValid(req.files)) { | ||
81 | res.status(HttpStatusCode.UNSUPPORTED_MEDIA_TYPE_415) | ||
82 | .json({ | ||
83 | error: 'This file is not supported. Please, make sure it is of the following type: ' + | ||
84 | CONSTRAINTS_FIELDS.VIDEOS.EXTNAME.join(', ') | ||
85 | }) | ||
86 | |||
87 | return cleanUpReqFiles(req) | ||
88 | } | ||
89 | |||
90 | if (!isVideoFileSizeValid(videoFile.size.toString())) { | ||
91 | res.status(HttpStatusCode.PAYLOAD_TOO_LARGE_413) | ||
92 | .json({ | ||
93 | error: 'This file is too large.' | ||
94 | }) | ||
95 | |||
96 | return cleanUpReqFiles(req) | ||
97 | } | ||
98 | |||
78 | if (await isAbleToUploadVideo(user.id, videoFile.size) === false) { | 99 | if (await isAbleToUploadVideo(user.id, videoFile.size) === false) { |
79 | res.status(HttpStatusCode.FORBIDDEN_403) | 100 | res.status(HttpStatusCode.PAYLOAD_TOO_LARGE_413) |
80 | .json({ error: 'The user video quota is exceeded with this video.' }) | 101 | .json({ error: 'The user video quota is exceeded with this video.' }) |
81 | 102 | ||
82 | return cleanUpReqFiles(req) | 103 | return cleanUpReqFiles(req) |
@@ -88,8 +109,8 @@ const videosAddValidator = getCommonVideoEditAttributes().concat([ | |||
88 | duration = await getDurationFromVideoFile(videoFile.path) | 109 | duration = await getDurationFromVideoFile(videoFile.path) |
89 | } catch (err) { | 110 | } catch (err) { |
90 | logger.error('Invalid input file in videosAddValidator.', { err }) | 111 | logger.error('Invalid input file in videosAddValidator.', { err }) |
91 | res.status(HttpStatusCode.BAD_REQUEST_400) | 112 | res.status(HttpStatusCode.UNPROCESSABLE_ENTITY_422) |
92 | .json({ error: 'Invalid input file.' }) | 113 | .json({ error: 'Video file unreadable.' }) |
93 | 114 | ||
94 | return cleanUpReqFiles(req) | 115 | return cleanUpReqFiles(req) |
95 | } | 116 | } |
@@ -295,7 +316,7 @@ const videosAcceptChangeOwnershipValidator = [ | |||
295 | const videoChangeOwnership = res.locals.videoChangeOwnership | 316 | const videoChangeOwnership = res.locals.videoChangeOwnership |
296 | const isAble = await isAbleToUploadVideo(user.id, videoChangeOwnership.Video.getMaxQualityFile().size) | 317 | const isAble = await isAbleToUploadVideo(user.id, videoChangeOwnership.Video.getMaxQualityFile().size) |
297 | if (isAble === false) { | 318 | if (isAble === false) { |
298 | res.status(HttpStatusCode.FORBIDDEN_403) | 319 | res.status(HttpStatusCode.PAYLOAD_TOO_LARGE_413) |
299 | .json({ error: 'The user video quota is exceeded with this video.' }) | 320 | .json({ error: 'The user video quota is exceeded with this video.' }) |
300 | 321 | ||
301 | return | 322 | return |
diff --git a/server/tests/api/activitypub/client.ts b/server/tests/api/activitypub/client.ts index d16f05108..b6c538e19 100644 --- a/server/tests/api/activitypub/client.ts +++ b/server/tests/api/activitypub/client.ts | |||
@@ -11,6 +11,7 @@ import { | |||
11 | setAccessTokensToServers, | 11 | setAccessTokensToServers, |
12 | uploadVideo | 12 | uploadVideo |
13 | } from '../../../../shared/extra-utils' | 13 | } from '../../../../shared/extra-utils' |
14 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
14 | 15 | ||
15 | const expect = chai.expect | 16 | const expect = chai.expect |
16 | 17 | ||
@@ -53,7 +54,7 @@ describe('Test activitypub', function () { | |||
53 | }) | 54 | }) |
54 | 55 | ||
55 | it('Should redirect to the origin video object', async function () { | 56 | it('Should redirect to the origin video object', async function () { |
56 | const res = await makeActivityPubGetRequest(servers[1].url, '/videos/watch/' + videoUUID, 302) | 57 | const res = await makeActivityPubGetRequest(servers[1].url, '/videos/watch/' + videoUUID, HttpStatusCode.FOUND_302) |
57 | 58 | ||
58 | expect(res.header.location).to.equal('http://localhost:' + servers[0].port + '/videos/watch/' + videoUUID) | 59 | expect(res.header.location).to.equal('http://localhost:' + servers[0].port + '/videos/watch/' + videoUUID) |
59 | }) | 60 | }) |
diff --git a/server/tests/api/activitypub/refresher.ts b/server/tests/api/activitypub/refresher.ts index 232c5d823..c717f1a30 100644 --- a/server/tests/api/activitypub/refresher.ts +++ b/server/tests/api/activitypub/refresher.ts | |||
@@ -24,6 +24,7 @@ import { | |||
24 | } from '../../../../shared/extra-utils' | 24 | } from '../../../../shared/extra-utils' |
25 | import { getAccount } from '../../../../shared/extra-utils/users/accounts' | 25 | import { getAccount } from '../../../../shared/extra-utils/users/accounts' |
26 | import { VideoPlaylistPrivacy } from '../../../../shared/models/videos' | 26 | import { VideoPlaylistPrivacy } from '../../../../shared/models/videos' |
27 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
27 | 28 | ||
28 | describe('Test AP refresher', function () { | 29 | describe('Test AP refresher', function () { |
29 | let servers: ServerInfo[] = [] | 30 | let servers: ServerInfo[] = [] |
@@ -86,8 +87,8 @@ describe('Test AP refresher', function () { | |||
86 | 87 | ||
87 | await waitJobs(servers) | 88 | await waitJobs(servers) |
88 | 89 | ||
89 | await getVideo(servers[0].url, videoUUID1, 404) | 90 | await getVideo(servers[0].url, videoUUID1, HttpStatusCode.NOT_FOUND_404) |
90 | await getVideo(servers[0].url, videoUUID2, 200) | 91 | await getVideo(servers[0].url, videoUUID2, HttpStatusCode.OK_200) |
91 | }) | 92 | }) |
92 | 93 | ||
93 | it('Should not update a remote video if the remote instance is down', async function () { | 94 | it('Should not update a remote video if the remote instance is down', async function () { |
@@ -106,7 +107,7 @@ describe('Test AP refresher', function () { | |||
106 | 107 | ||
107 | await reRunServer(servers[1]) | 108 | await reRunServer(servers[1]) |
108 | 109 | ||
109 | await getVideo(servers[0].url, videoUUID3, 200) | 110 | await getVideo(servers[0].url, videoUUID3, HttpStatusCode.OK_200) |
110 | }) | 111 | }) |
111 | }) | 112 | }) |
112 | 113 | ||
@@ -126,8 +127,8 @@ describe('Test AP refresher', function () { | |||
126 | 127 | ||
127 | await waitJobs(servers) | 128 | await waitJobs(servers) |
128 | 129 | ||
129 | await getAccount(servers[0].url, 'user1@localhost:' + servers[1].port, 200) | 130 | await getAccount(servers[0].url, 'user1@localhost:' + servers[1].port, HttpStatusCode.OK_200) |
130 | await getAccount(servers[0].url, 'user2@localhost:' + servers[1].port, 404) | 131 | await getAccount(servers[0].url, 'user2@localhost:' + servers[1].port, HttpStatusCode.NOT_FOUND_404) |
131 | }) | 132 | }) |
132 | }) | 133 | }) |
133 | 134 | ||
@@ -146,8 +147,8 @@ describe('Test AP refresher', function () { | |||
146 | 147 | ||
147 | await waitJobs(servers) | 148 | await waitJobs(servers) |
148 | 149 | ||
149 | await getVideoPlaylist(servers[0].url, playlistUUID1, 200) | 150 | await getVideoPlaylist(servers[0].url, playlistUUID1, HttpStatusCode.OK_200) |
150 | await getVideoPlaylist(servers[0].url, playlistUUID2, 404) | 151 | await getVideoPlaylist(servers[0].url, playlistUUID2, HttpStatusCode.NOT_FOUND_404) |
151 | }) | 152 | }) |
152 | }) | 153 | }) |
153 | 154 | ||
diff --git a/server/tests/api/check-params/accounts.ts b/server/tests/api/check-params/accounts.ts index c29af7cd7..d1712cff6 100644 --- a/server/tests/api/check-params/accounts.ts +++ b/server/tests/api/check-params/accounts.ts | |||
@@ -9,6 +9,7 @@ import { | |||
9 | checkBadStartPagination | 9 | checkBadStartPagination |
10 | } from '../../../../shared/extra-utils/requests/check-api-params' | 10 | } from '../../../../shared/extra-utils/requests/check-api-params' |
11 | import { getAccount } from '../../../../shared/extra-utils/users/accounts' | 11 | import { getAccount } from '../../../../shared/extra-utils/users/accounts' |
12 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
12 | 13 | ||
13 | describe('Test accounts API validators', function () { | 14 | describe('Test accounts API validators', function () { |
14 | const path = '/api/v1/accounts/' | 15 | const path = '/api/v1/accounts/' |
@@ -38,7 +39,7 @@ describe('Test accounts API validators', function () { | |||
38 | 39 | ||
39 | describe('When getting an account', function () { | 40 | describe('When getting an account', function () { |
40 | it('Should return 404 with a non existing name', async function () { | 41 | it('Should return 404 with a non existing name', async function () { |
41 | await getAccount(server.url, 'arfaze', 404) | 42 | await getAccount(server.url, 'arfaze', HttpStatusCode.NOT_FOUND_404) |
42 | }) | 43 | }) |
43 | }) | 44 | }) |
44 | 45 | ||
diff --git a/server/tests/api/check-params/contact-form.ts b/server/tests/api/check-params/contact-form.ts index b2126b9b0..c7f9c1b47 100644 --- a/server/tests/api/check-params/contact-form.ts +++ b/server/tests/api/check-params/contact-form.ts | |||
@@ -5,6 +5,7 @@ import 'mocha' | |||
5 | import { cleanupTests, flushAndRunServer, immutableAssign, killallServers, reRunServer, ServerInfo } from '../../../../shared/extra-utils' | 5 | import { cleanupTests, flushAndRunServer, immutableAssign, killallServers, reRunServer, ServerInfo } from '../../../../shared/extra-utils' |
6 | import { sendContactForm } from '../../../../shared/extra-utils/server/contact-form' | 6 | import { sendContactForm } from '../../../../shared/extra-utils/server/contact-form' |
7 | import { MockSmtpServer } from '../../../../shared/extra-utils/miscs/email' | 7 | import { MockSmtpServer } from '../../../../shared/extra-utils/miscs/email' |
8 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
8 | 9 | ||
9 | describe('Test contact form API validators', function () { | 10 | describe('Test contact form API validators', function () { |
10 | let server: ServerInfo | 11 | let server: ServerInfo |
@@ -29,7 +30,7 @@ describe('Test contact form API validators', function () { | |||
29 | }) | 30 | }) |
30 | 31 | ||
31 | it('Should not accept a contact form if emails are disabled', async function () { | 32 | it('Should not accept a contact form if emails are disabled', async function () { |
32 | await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 409 })) | 33 | await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: HttpStatusCode.CONFLICT_409 })) |
33 | }) | 34 | }) |
34 | 35 | ||
35 | it('Should not accept a contact form if it is disabled in the configuration', async function () { | 36 | it('Should not accept a contact form if it is disabled in the configuration', async function () { |
@@ -39,7 +40,7 @@ describe('Test contact form API validators', function () { | |||
39 | 40 | ||
40 | // Contact form is disabled | 41 | // Contact form is disabled |
41 | await reRunServer(server, { smtp: { hostname: 'localhost', port: emailPort }, contact_form: { enabled: false } }) | 42 | await reRunServer(server, { smtp: { hostname: 'localhost', port: emailPort }, contact_form: { enabled: false } }) |
42 | await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 409 })) | 43 | await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: HttpStatusCode.CONFLICT_409 })) |
43 | }) | 44 | }) |
44 | 45 | ||
45 | it('Should not accept a contact form if from email is invalid', async function () { | 46 | it('Should not accept a contact form if from email is invalid', async function () { |
@@ -50,21 +51,57 @@ describe('Test contact form API validators', function () { | |||
50 | // Email & contact form enabled | 51 | // Email & contact form enabled |
51 | await reRunServer(server, { smtp: { hostname: 'localhost', port: emailPort } }) | 52 | await reRunServer(server, { smtp: { hostname: 'localhost', port: emailPort } }) |
52 | 53 | ||
53 | await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromEmail: 'badEmail' })) | 54 | await sendContactForm(immutableAssign(defaultBody, { |
54 | await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromEmail: 'badEmail@' })) | 55 | url: server.url, |
55 | await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromEmail: undefined })) | 56 | expectedStatus: HttpStatusCode.BAD_REQUEST_400, |
57 | fromEmail: 'badEmail' | ||
58 | })) | ||
59 | await sendContactForm(immutableAssign(defaultBody, { | ||
60 | url: server.url, | ||
61 | expectedStatus: HttpStatusCode.BAD_REQUEST_400, | ||
62 | fromEmail: 'badEmail@' | ||
63 | })) | ||
64 | await sendContactForm(immutableAssign(defaultBody, { | ||
65 | url: server.url, | ||
66 | expectedStatus: HttpStatusCode.BAD_REQUEST_400, | ||
67 | fromEmail: undefined | ||
68 | })) | ||
56 | }) | 69 | }) |
57 | 70 | ||
58 | it('Should not accept a contact form if from name is invalid', async function () { | 71 | it('Should not accept a contact form if from name is invalid', async function () { |
59 | await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromName: 'name'.repeat(100) })) | 72 | await sendContactForm(immutableAssign(defaultBody, { |
60 | await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromName: '' })) | 73 | url: server.url, |
61 | await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromName: undefined })) | 74 | expectedStatus: HttpStatusCode.BAD_REQUEST_400, |
75 | fromName: 'name'.repeat(100) | ||
76 | })) | ||
77 | await sendContactForm(immutableAssign(defaultBody, { | ||
78 | url: server.url, | ||
79 | expectedStatus: HttpStatusCode.BAD_REQUEST_400, | ||
80 | fromName: '' | ||
81 | })) | ||
82 | await sendContactForm(immutableAssign(defaultBody, { | ||
83 | url: server.url, | ||
84 | expectedStatus: HttpStatusCode.BAD_REQUEST_400, | ||
85 | fromName: undefined | ||
86 | })) | ||
62 | }) | 87 | }) |
63 | 88 | ||
64 | it('Should not accept a contact form if body is invalid', async function () { | 89 | it('Should not accept a contact form if body is invalid', async function () { |
65 | await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, body: 'body'.repeat(5000) })) | 90 | await sendContactForm(immutableAssign(defaultBody, { |
66 | await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, body: 'a' })) | 91 | url: server.url, |
67 | await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, body: undefined })) | 92 | expectedStatus: HttpStatusCode.BAD_REQUEST_400, |
93 | body: 'body'.repeat(5000) | ||
94 | })) | ||
95 | await sendContactForm(immutableAssign(defaultBody, { | ||
96 | url: server.url, | ||
97 | expectedStatus: HttpStatusCode.BAD_REQUEST_400, | ||
98 | body: 'a' | ||
99 | })) | ||
100 | await sendContactForm(immutableAssign(defaultBody, { | ||
101 | url: server.url, | ||
102 | expectedStatus: HttpStatusCode.BAD_REQUEST_400, | ||
103 | body: undefined | ||
104 | })) | ||
68 | }) | 105 | }) |
69 | 106 | ||
70 | it('Should accept a contact form with the correct parameters', async function () { | 107 | it('Should accept a contact form with the correct parameters', async function () { |
diff --git a/server/tests/api/check-params/users.ts b/server/tests/api/check-params/users.ts index 21ace36aa..0a13f5b67 100644 --- a/server/tests/api/check-params/users.ts +++ b/server/tests/api/check-params/users.ts | |||
@@ -1102,7 +1102,7 @@ describe('Test users API validators', function () { | |||
1102 | videoQuota: 42 | 1102 | videoQuota: 42 |
1103 | }) | 1103 | }) |
1104 | 1104 | ||
1105 | await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.FORBIDDEN_403) | 1105 | await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413) |
1106 | }) | 1106 | }) |
1107 | 1107 | ||
1108 | it('Should fail with a registered user having too many videos', async function () { | 1108 | it('Should fail with a registered user having too many videos', async function () { |
@@ -1120,7 +1120,7 @@ describe('Test users API validators', function () { | |||
1120 | await uploadVideo(server.url, userAccessToken, videoAttributes) | 1120 | await uploadVideo(server.url, userAccessToken, videoAttributes) |
1121 | await uploadVideo(server.url, userAccessToken, videoAttributes) | 1121 | await uploadVideo(server.url, userAccessToken, videoAttributes) |
1122 | await uploadVideo(server.url, userAccessToken, videoAttributes) | 1122 | await uploadVideo(server.url, userAccessToken, videoAttributes) |
1123 | await uploadVideo(server.url, userAccessToken, videoAttributes, HttpStatusCode.FORBIDDEN_403) | 1123 | await uploadVideo(server.url, userAccessToken, videoAttributes, HttpStatusCode.PAYLOAD_TOO_LARGE_413) |
1124 | }) | 1124 | }) |
1125 | 1125 | ||
1126 | it('Should fail to import with HTTP/Torrent/magnet', async function () { | 1126 | it('Should fail to import with HTTP/Torrent/magnet', async function () { |
@@ -1151,7 +1151,7 @@ describe('Test users API validators', function () { | |||
1151 | }) | 1151 | }) |
1152 | 1152 | ||
1153 | describe('When having a daily video quota', function () { | 1153 | describe('When having a daily video quota', function () { |
1154 | it('Should fail with a user having too many videos', async function () { | 1154 | it('Should fail with a user having too many videos daily', async function () { |
1155 | await updateUser({ | 1155 | await updateUser({ |
1156 | url: server.url, | 1156 | url: server.url, |
1157 | userId: rootId, | 1157 | userId: rootId, |
@@ -1159,7 +1159,7 @@ describe('Test users API validators', function () { | |||
1159 | videoQuotaDaily: 42 | 1159 | videoQuotaDaily: 42 |
1160 | }) | 1160 | }) |
1161 | 1161 | ||
1162 | await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.FORBIDDEN_403) | 1162 | await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413) |
1163 | }) | 1163 | }) |
1164 | }) | 1164 | }) |
1165 | 1165 | ||
@@ -1173,7 +1173,7 @@ describe('Test users API validators', function () { | |||
1173 | videoQuotaDaily: 1024 * 1024 * 1024 | 1173 | videoQuotaDaily: 1024 * 1024 * 1024 |
1174 | }) | 1174 | }) |
1175 | 1175 | ||
1176 | await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.FORBIDDEN_403) | 1176 | await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413) |
1177 | }) | 1177 | }) |
1178 | 1178 | ||
1179 | it('Should fail if exceeding daily quota', async function () { | 1179 | it('Should fail if exceeding daily quota', async function () { |
@@ -1185,7 +1185,7 @@ describe('Test users API validators', function () { | |||
1185 | videoQuotaDaily: 42 | 1185 | videoQuotaDaily: 42 |
1186 | }) | 1186 | }) |
1187 | 1187 | ||
1188 | await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.FORBIDDEN_403) | 1188 | await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413) |
1189 | }) | 1189 | }) |
1190 | }) | 1190 | }) |
1191 | 1191 | ||
diff --git a/server/tests/api/check-params/videos.ts b/server/tests/api/check-params/videos.ts index d60546917..5faba82c4 100644 --- a/server/tests/api/check-params/videos.ts +++ b/server/tests/api/check-params/videos.ts | |||
@@ -348,12 +348,26 @@ describe('Test videos API validator', function () { | |||
348 | let attaches = { | 348 | let attaches = { |
349 | videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short_fake.webm') | 349 | videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short_fake.webm') |
350 | } | 350 | } |
351 | await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) | 351 | await makeUploadRequest({ |
352 | url: server.url, | ||
353 | path: path + '/upload', | ||
354 | token: server.accessToken, | ||
355 | fields, | ||
356 | attaches, | ||
357 | statusCodeExpected: HttpStatusCode.UNPROCESSABLE_ENTITY_422 | ||
358 | }) | ||
352 | 359 | ||
353 | attaches = { | 360 | attaches = { |
354 | videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short.mkv') | 361 | videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short.mkv') |
355 | } | 362 | } |
356 | await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) | 363 | await makeUploadRequest({ |
364 | url: server.url, | ||
365 | path: path + '/upload', | ||
366 | token: server.accessToken, | ||
367 | fields, | ||
368 | attaches, | ||
369 | statusCodeExpected: HttpStatusCode.UNSUPPORTED_MEDIA_TYPE_415 | ||
370 | }) | ||
357 | }) | 371 | }) |
358 | 372 | ||
359 | it('Should fail with an incorrect thumbnail file', async function () { | 373 | it('Should fail with an incorrect thumbnail file', async function () { |
diff --git a/server/tests/api/live/live-save-replay.ts b/server/tests/api/live/live-save-replay.ts index 3ffa0c093..e300ec345 100644 --- a/server/tests/api/live/live-save-replay.ts +++ b/server/tests/api/live/live-save-replay.ts | |||
@@ -25,6 +25,7 @@ import { | |||
25 | waitJobs, | 25 | waitJobs, |
26 | waitUntilLiveStarts | 26 | waitUntilLiveStarts |
27 | } from '../../../../shared/extra-utils' | 27 | } from '../../../../shared/extra-utils' |
28 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
28 | 29 | ||
29 | const expect = chai.expect | 30 | const expect = chai.expect |
30 | 31 | ||
@@ -118,7 +119,7 @@ describe('Save replay setting', function () { | |||
118 | 119 | ||
119 | await waitJobs(servers) | 120 | await waitJobs(servers) |
120 | 121 | ||
121 | await checkVideosExist(liveVideoUUID, false, 200) | 122 | await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200) |
122 | await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE) | 123 | await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE) |
123 | }) | 124 | }) |
124 | 125 | ||
@@ -130,7 +131,7 @@ describe('Save replay setting', function () { | |||
130 | 131 | ||
131 | await waitJobs(servers) | 132 | await waitJobs(servers) |
132 | 133 | ||
133 | await checkVideosExist(liveVideoUUID, true, 200) | 134 | await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200) |
134 | await checkVideoState(liveVideoUUID, VideoState.PUBLISHED) | 135 | await checkVideoState(liveVideoUUID, VideoState.PUBLISHED) |
135 | }) | 136 | }) |
136 | 137 | ||
@@ -142,7 +143,7 @@ describe('Save replay setting', function () { | |||
142 | await waitJobs(servers) | 143 | await waitJobs(servers) |
143 | 144 | ||
144 | // Live still exist, but cannot be played anymore | 145 | // Live still exist, but cannot be played anymore |
145 | await checkVideosExist(liveVideoUUID, false, 200) | 146 | await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200) |
146 | await checkVideoState(liveVideoUUID, VideoState.LIVE_ENDED) | 147 | await checkVideoState(liveVideoUUID, VideoState.LIVE_ENDED) |
147 | 148 | ||
148 | // No resolutions saved since we did not save replay | 149 | // No resolutions saved since we did not save replay |
@@ -158,7 +159,7 @@ describe('Save replay setting', function () { | |||
158 | await waitUntilLiveStarts(servers[0].url, servers[0].accessToken, liveVideoUUID) | 159 | await waitUntilLiveStarts(servers[0].url, servers[0].accessToken, liveVideoUUID) |
159 | 160 | ||
160 | await waitJobs(servers) | 161 | await waitJobs(servers) |
161 | await checkVideosExist(liveVideoUUID, true, 200) | 162 | await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200) |
162 | 163 | ||
163 | await Promise.all([ | 164 | await Promise.all([ |
164 | addVideoToBlacklist(servers[0].url, servers[0].accessToken, liveVideoUUID, 'bad live', true), | 165 | addVideoToBlacklist(servers[0].url, servers[0].accessToken, liveVideoUUID, 'bad live', true), |
@@ -169,8 +170,8 @@ describe('Save replay setting', function () { | |||
169 | 170 | ||
170 | await checkVideosExist(liveVideoUUID, false) | 171 | await checkVideosExist(liveVideoUUID, false) |
171 | 172 | ||
172 | await getVideo(servers[0].url, liveVideoUUID, 401) | 173 | await getVideo(servers[0].url, liveVideoUUID, HttpStatusCode.UNAUTHORIZED_401) |
173 | await getVideo(servers[1].url, liveVideoUUID, 404) | 174 | await getVideo(servers[1].url, liveVideoUUID, HttpStatusCode.NOT_FOUND_404) |
174 | 175 | ||
175 | await checkLiveCleanup(servers[0], liveVideoUUID, []) | 176 | await checkLiveCleanup(servers[0], liveVideoUUID, []) |
176 | }) | 177 | }) |
@@ -184,7 +185,7 @@ describe('Save replay setting', function () { | |||
184 | await waitUntilLiveStarts(servers[0].url, servers[0].accessToken, liveVideoUUID) | 185 | await waitUntilLiveStarts(servers[0].url, servers[0].accessToken, liveVideoUUID) |
185 | 186 | ||
186 | await waitJobs(servers) | 187 | await waitJobs(servers) |
187 | await checkVideosExist(liveVideoUUID, true, 200) | 188 | await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200) |
188 | 189 | ||
189 | await Promise.all([ | 190 | await Promise.all([ |
190 | testFfmpegStreamError(ffmpegCommand, true), | 191 | testFfmpegStreamError(ffmpegCommand, true), |
@@ -193,7 +194,7 @@ describe('Save replay setting', function () { | |||
193 | 194 | ||
194 | await waitJobs(servers) | 195 | await waitJobs(servers) |
195 | 196 | ||
196 | await checkVideosExist(liveVideoUUID, false, 404) | 197 | await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404) |
197 | await checkLiveCleanup(servers[0], liveVideoUUID, []) | 198 | await checkLiveCleanup(servers[0], liveVideoUUID, []) |
198 | }) | 199 | }) |
199 | }) | 200 | }) |
@@ -207,7 +208,7 @@ describe('Save replay setting', function () { | |||
207 | 208 | ||
208 | await waitJobs(servers) | 209 | await waitJobs(servers) |
209 | 210 | ||
210 | await checkVideosExist(liveVideoUUID, false, 200) | 211 | await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200) |
211 | await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE) | 212 | await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE) |
212 | }) | 213 | }) |
213 | 214 | ||
@@ -219,7 +220,7 @@ describe('Save replay setting', function () { | |||
219 | 220 | ||
220 | await waitJobs(servers) | 221 | await waitJobs(servers) |
221 | 222 | ||
222 | await checkVideosExist(liveVideoUUID, true, 200) | 223 | await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200) |
223 | await checkVideoState(liveVideoUUID, VideoState.PUBLISHED) | 224 | await checkVideoState(liveVideoUUID, VideoState.PUBLISHED) |
224 | }) | 225 | }) |
225 | 226 | ||
@@ -231,7 +232,7 @@ describe('Save replay setting', function () { | |||
231 | await waitJobs(servers) | 232 | await waitJobs(servers) |
232 | 233 | ||
233 | // Live has been transcoded | 234 | // Live has been transcoded |
234 | await checkVideosExist(liveVideoUUID, true, 200) | 235 | await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200) |
235 | await checkVideoState(liveVideoUUID, VideoState.PUBLISHED) | 236 | await checkVideoState(liveVideoUUID, VideoState.PUBLISHED) |
236 | }) | 237 | }) |
237 | 238 | ||
@@ -261,7 +262,7 @@ describe('Save replay setting', function () { | |||
261 | await waitUntilLiveStarts(servers[0].url, servers[0].accessToken, liveVideoUUID) | 262 | await waitUntilLiveStarts(servers[0].url, servers[0].accessToken, liveVideoUUID) |
262 | 263 | ||
263 | await waitJobs(servers) | 264 | await waitJobs(servers) |
264 | await checkVideosExist(liveVideoUUID, true, 200) | 265 | await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200) |
265 | 266 | ||
266 | await Promise.all([ | 267 | await Promise.all([ |
267 | addVideoToBlacklist(servers[0].url, servers[0].accessToken, liveVideoUUID, 'bad live', true), | 268 | addVideoToBlacklist(servers[0].url, servers[0].accessToken, liveVideoUUID, 'bad live', true), |
@@ -272,8 +273,8 @@ describe('Save replay setting', function () { | |||
272 | 273 | ||
273 | await checkVideosExist(liveVideoUUID, false) | 274 | await checkVideosExist(liveVideoUUID, false) |
274 | 275 | ||
275 | await getVideo(servers[0].url, liveVideoUUID, 401) | 276 | await getVideo(servers[0].url, liveVideoUUID, HttpStatusCode.UNAUTHORIZED_401) |
276 | await getVideo(servers[1].url, liveVideoUUID, 404) | 277 | await getVideo(servers[1].url, liveVideoUUID, HttpStatusCode.NOT_FOUND_404) |
277 | 278 | ||
278 | await checkLiveCleanup(servers[0], liveVideoUUID, [ 720 ]) | 279 | await checkLiveCleanup(servers[0], liveVideoUUID, [ 720 ]) |
279 | }) | 280 | }) |
@@ -287,7 +288,7 @@ describe('Save replay setting', function () { | |||
287 | await waitUntilLiveStarts(servers[0].url, servers[0].accessToken, liveVideoUUID) | 288 | await waitUntilLiveStarts(servers[0].url, servers[0].accessToken, liveVideoUUID) |
288 | 289 | ||
289 | await waitJobs(servers) | 290 | await waitJobs(servers) |
290 | await checkVideosExist(liveVideoUUID, true, 200) | 291 | await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200) |
291 | 292 | ||
292 | await Promise.all([ | 293 | await Promise.all([ |
293 | removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID), | 294 | removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID), |
@@ -296,7 +297,7 @@ describe('Save replay setting', function () { | |||
296 | 297 | ||
297 | await waitJobs(servers) | 298 | await waitJobs(servers) |
298 | 299 | ||
299 | await checkVideosExist(liveVideoUUID, false, 404) | 300 | await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404) |
300 | await checkLiveCleanup(servers[0], liveVideoUUID, []) | 301 | await checkLiveCleanup(servers[0], liveVideoUUID, []) |
301 | }) | 302 | }) |
302 | }) | 303 | }) |
diff --git a/server/tests/api/live/live.ts b/server/tests/api/live/live.ts index d784650b5..fdfc6105f 100644 --- a/server/tests/api/live/live.ts +++ b/server/tests/api/live/live.ts | |||
@@ -44,6 +44,7 @@ import { | |||
44 | waitUntilLiveStarts, | 44 | waitUntilLiveStarts, |
45 | waitUntilLog | 45 | waitUntilLog |
46 | } from '../../../../shared/extra-utils' | 46 | } from '../../../../shared/extra-utils' |
47 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
47 | 48 | ||
48 | const expect = chai.expect | 49 | const expect = chai.expect |
49 | 50 | ||
@@ -164,8 +165,8 @@ describe('Test live', function () { | |||
164 | expect(video.privacy.id).to.equal(VideoPrivacy.UNLISTED) | 165 | expect(video.privacy.id).to.equal(VideoPrivacy.UNLISTED) |
165 | expect(video.nsfw).to.be.true | 166 | expect(video.nsfw).to.be.true |
166 | 167 | ||
167 | await makeRawRequest(server.url + video.thumbnailPath, 200) | 168 | await makeRawRequest(server.url + video.thumbnailPath, HttpStatusCode.OK_200) |
168 | await makeRawRequest(server.url + video.previewPath, 200) | 169 | await makeRawRequest(server.url + video.previewPath, HttpStatusCode.OK_200) |
169 | } | 170 | } |
170 | }) | 171 | }) |
171 | 172 | ||
@@ -179,7 +180,7 @@ describe('Test live', function () { | |||
179 | }) | 180 | }) |
180 | 181 | ||
181 | it('Should not be able to update a live of another server', async function () { | 182 | it('Should not be able to update a live of another server', async function () { |
182 | await updateLive(servers[1].url, servers[1].accessToken, liveVideoUUID, { saveReplay: false }, 403) | 183 | await updateLive(servers[1].url, servers[1].accessToken, liveVideoUUID, { saveReplay: false }, HttpStatusCode.FORBIDDEN_403) |
183 | }) | 184 | }) |
184 | 185 | ||
185 | it('Should update the live', async function () { | 186 | it('Should update the live', async function () { |
@@ -215,8 +216,8 @@ describe('Test live', function () { | |||
215 | 216 | ||
216 | it('Should have the live deleted', async function () { | 217 | it('Should have the live deleted', async function () { |
217 | for (const server of servers) { | 218 | for (const server of servers) { |
218 | await getVideo(server.url, liveVideoUUID, 404) | 219 | await getVideo(server.url, liveVideoUUID, HttpStatusCode.NOT_FOUND_404) |
219 | await getLive(server.url, server.accessToken, liveVideoUUID, 404) | 220 | await getLive(server.url, server.accessToken, liveVideoUUID, HttpStatusCode.NOT_FOUND_404) |
220 | } | 221 | } |
221 | }) | 222 | }) |
222 | }) | 223 | }) |
@@ -430,8 +431,8 @@ describe('Test live', function () { | |||
430 | expect(video.files).to.have.lengthOf(0) | 431 | expect(video.files).to.have.lengthOf(0) |
431 | 432 | ||
432 | const hlsPlaylist = video.streamingPlaylists.find(s => s.type === VideoStreamingPlaylistType.HLS) | 433 | const hlsPlaylist = video.streamingPlaylists.find(s => s.type === VideoStreamingPlaylistType.HLS) |
433 | await makeRawRequest(hlsPlaylist.playlistUrl, 200) | 434 | await makeRawRequest(hlsPlaylist.playlistUrl, HttpStatusCode.OK_200) |
434 | await makeRawRequest(hlsPlaylist.segmentsSha256Url, 200) | 435 | await makeRawRequest(hlsPlaylist.segmentsSha256Url, HttpStatusCode.OK_200) |
435 | 436 | ||
436 | expect(hlsPlaylist.files).to.have.lengthOf(resolutions.length) | 437 | expect(hlsPlaylist.files).to.have.lengthOf(resolutions.length) |
437 | 438 | ||
@@ -455,8 +456,8 @@ describe('Test live', function () { | |||
455 | 456 | ||
456 | expect(probe.format.bit_rate).to.be.below(bitrateLimits[videoStream.height]) | 457 | expect(probe.format.bit_rate).to.be.below(bitrateLimits[videoStream.height]) |
457 | 458 | ||
458 | await makeRawRequest(file.torrentUrl, 200) | 459 | await makeRawRequest(file.torrentUrl, HttpStatusCode.OK_200) |
459 | await makeRawRequest(file.fileUrl, 200) | 460 | await makeRawRequest(file.fileUrl, HttpStatusCode.OK_200) |
460 | } | 461 | } |
461 | } | 462 | } |
462 | }) | 463 | }) |
diff --git a/server/tests/api/server/config.ts b/server/tests/api/server/config.ts index eb51d8909..a505b8ede 100644 --- a/server/tests/api/server/config.ts +++ b/server/tests/api/server/config.ts | |||
@@ -21,6 +21,7 @@ import { | |||
21 | uploadVideo | 21 | uploadVideo |
22 | } from '../../../../shared/extra-utils' | 22 | } from '../../../../shared/extra-utils' |
23 | import { ServerConfig } from '../../../../shared/models' | 23 | import { ServerConfig } from '../../../../shared/models' |
24 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
24 | 25 | ||
25 | const expect = chai.expect | 26 | const expect = chai.expect |
26 | 27 | ||
@@ -237,8 +238,8 @@ describe('Test config', function () { | |||
237 | expect(data.video.file.extensions).to.contain('.webm') | 238 | expect(data.video.file.extensions).to.contain('.webm') |
238 | expect(data.video.file.extensions).to.contain('.ogv') | 239 | expect(data.video.file.extensions).to.contain('.ogv') |
239 | 240 | ||
240 | await uploadVideo(server.url, server.accessToken, { fixture: 'video_short.mkv' }, 400) | 241 | await uploadVideo(server.url, server.accessToken, { fixture: 'video_short.mkv' }, HttpStatusCode.UNSUPPORTED_MEDIA_TYPE_415) |
241 | await uploadVideo(server.url, server.accessToken, { fixture: 'sample.ogg' }, 400) | 242 | await uploadVideo(server.url, server.accessToken, { fixture: 'sample.ogg' }, HttpStatusCode.UNSUPPORTED_MEDIA_TYPE_415) |
242 | 243 | ||
243 | expect(data.contactForm.enabled).to.be.true | 244 | expect(data.contactForm.enabled).to.be.true |
244 | }) | 245 | }) |
@@ -427,8 +428,8 @@ describe('Test config', function () { | |||
427 | expect(data.video.file.extensions).to.contain('.ogg') | 428 | expect(data.video.file.extensions).to.contain('.ogg') |
428 | expect(data.video.file.extensions).to.contain('.flac') | 429 | expect(data.video.file.extensions).to.contain('.flac') |
429 | 430 | ||
430 | await uploadVideo(server.url, server.accessToken, { fixture: 'video_short.mkv' }, 200) | 431 | await uploadVideo(server.url, server.accessToken, { fixture: 'video_short.mkv' }, HttpStatusCode.OK_200) |
431 | await uploadVideo(server.url, server.accessToken, { fixture: 'sample.ogg' }, 200) | 432 | await uploadVideo(server.url, server.accessToken, { fixture: 'sample.ogg' }, HttpStatusCode.OK_200) |
432 | }) | 433 | }) |
433 | 434 | ||
434 | it('Should have the configuration updated after a restart', async function () { | 435 | it('Should have the configuration updated after a restart', async function () { |
diff --git a/server/tests/api/server/contact-form.ts b/server/tests/api/server/contact-form.ts index c0965d9d1..9b4af1915 100644 --- a/server/tests/api/server/contact-form.ts +++ b/server/tests/api/server/contact-form.ts | |||
@@ -6,6 +6,7 @@ import { cleanupTests, flushAndRunServer, ServerInfo, setAccessTokensToServers, | |||
6 | import { MockSmtpServer } from '../../../../shared/extra-utils/miscs/email' | 6 | import { MockSmtpServer } from '../../../../shared/extra-utils/miscs/email' |
7 | import { waitJobs } from '../../../../shared/extra-utils/server/jobs' | 7 | import { waitJobs } from '../../../../shared/extra-utils/server/jobs' |
8 | import { sendContactForm } from '../../../../shared/extra-utils/server/contact-form' | 8 | import { sendContactForm } from '../../../../shared/extra-utils/server/contact-form' |
9 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
9 | 10 | ||
10 | const expect = chai.expect | 11 | const expect = chai.expect |
11 | 12 | ||
@@ -67,7 +68,7 @@ describe('Test contact form', function () { | |||
67 | body: 'my super message', | 68 | body: 'my super message', |
68 | fromName: 'Super toto', | 69 | fromName: 'Super toto', |
69 | subject: 'my subject', | 70 | subject: 'my subject', |
70 | expectedStatus: 403 | 71 | expectedStatus: HttpStatusCode.FORBIDDEN_403 |
71 | }) | 72 | }) |
72 | }) | 73 | }) |
73 | 74 | ||
diff --git a/server/tests/api/server/email.ts b/server/tests/api/server/email.ts index 53f96a94f..17d9e902c 100644 --- a/server/tests/api/server/email.ts +++ b/server/tests/api/server/email.ts | |||
@@ -22,6 +22,7 @@ import { | |||
22 | } from '../../../../shared/extra-utils' | 22 | } from '../../../../shared/extra-utils' |
23 | import { MockSmtpServer } from '../../../../shared/extra-utils/miscs/email' | 23 | import { MockSmtpServer } from '../../../../shared/extra-utils/miscs/email' |
24 | import { waitJobs } from '../../../../shared/extra-utils/server/jobs' | 24 | import { waitJobs } from '../../../../shared/extra-utils/server/jobs' |
25 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
25 | 26 | ||
26 | const expect = chai.expect | 27 | const expect = chai.expect |
27 | 28 | ||
@@ -116,7 +117,7 @@ describe('Test emails', function () { | |||
116 | }) | 117 | }) |
117 | 118 | ||
118 | it('Should not reset the password with an invalid verification string', async function () { | 119 | it('Should not reset the password with an invalid verification string', async function () { |
119 | await resetPassword(server.url, userId, verificationString + 'b', 'super_password2', 403) | 120 | await resetPassword(server.url, userId, verificationString + 'b', 'super_password2', HttpStatusCode.FORBIDDEN_403) |
120 | }) | 121 | }) |
121 | 122 | ||
122 | it('Should reset the password', async function () { | 123 | it('Should reset the password', async function () { |
@@ -124,7 +125,7 @@ describe('Test emails', function () { | |||
124 | }) | 125 | }) |
125 | 126 | ||
126 | it('Should not reset the password with the same verification string', async function () { | 127 | it('Should not reset the password with the same verification string', async function () { |
127 | await resetPassword(server.url, userId, verificationString, 'super_password3', 403) | 128 | await resetPassword(server.url, userId, verificationString, 'super_password3', HttpStatusCode.FORBIDDEN_403) |
128 | }) | 129 | }) |
129 | 130 | ||
130 | it('Should login with this new password', async function () { | 131 | it('Should login with this new password', async function () { |
@@ -169,7 +170,7 @@ describe('Test emails', function () { | |||
169 | }) | 170 | }) |
170 | 171 | ||
171 | it('Should not reset the password with an invalid verification string', async function () { | 172 | it('Should not reset the password with an invalid verification string', async function () { |
172 | await resetPassword(server.url, userId2, verificationString2 + 'c', 'newly_created_password', 403) | 173 | await resetPassword(server.url, userId2, verificationString2 + 'c', 'newly_created_password', HttpStatusCode.FORBIDDEN_403) |
173 | }) | 174 | }) |
174 | 175 | ||
175 | it('Should reset the password', async function () { | 176 | it('Should reset the password', async function () { |
@@ -210,7 +211,7 @@ describe('Test emails', function () { | |||
210 | this.timeout(10000) | 211 | this.timeout(10000) |
211 | 212 | ||
212 | const reason = 'my super bad reason' | 213 | const reason = 'my super bad reason' |
213 | await blockUser(server.url, userId, server.accessToken, 204, reason) | 214 | await blockUser(server.url, userId, server.accessToken, HttpStatusCode.NO_CONTENT_204, reason) |
214 | 215 | ||
215 | await waitJobs(server) | 216 | await waitJobs(server) |
216 | expect(emails).to.have.lengthOf(4) | 217 | expect(emails).to.have.lengthOf(4) |
@@ -228,7 +229,7 @@ describe('Test emails', function () { | |||
228 | it('Should send the notification email when unblocking a user', async function () { | 229 | it('Should send the notification email when unblocking a user', async function () { |
229 | this.timeout(10000) | 230 | this.timeout(10000) |
230 | 231 | ||
231 | await unblockUser(server.url, userId, server.accessToken, 204) | 232 | await unblockUser(server.url, userId, server.accessToken, HttpStatusCode.NO_CONTENT_204) |
232 | 233 | ||
233 | await waitJobs(server) | 234 | await waitJobs(server) |
234 | expect(emails).to.have.lengthOf(5) | 235 | expect(emails).to.have.lengthOf(5) |
@@ -317,7 +318,7 @@ describe('Test emails', function () { | |||
317 | }) | 318 | }) |
318 | 319 | ||
319 | it('Should not verify the email with an invalid verification string', async function () { | 320 | it('Should not verify the email with an invalid verification string', async function () { |
320 | await verifyEmail(server.url, userId, verificationString + 'b', false, 403) | 321 | await verifyEmail(server.url, userId, verificationString + 'b', false, HttpStatusCode.FORBIDDEN_403) |
321 | }) | 322 | }) |
322 | 323 | ||
323 | it('Should verify the email', async function () { | 324 | it('Should verify the email', async function () { |
diff --git a/server/tests/api/server/follow-constraints.ts b/server/tests/api/server/follow-constraints.ts index a73440286..0846b04f4 100644 --- a/server/tests/api/server/follow-constraints.ts +++ b/server/tests/api/server/follow-constraints.ts | |||
@@ -17,6 +17,7 @@ import { | |||
17 | import { unfollow } from '../../../../shared/extra-utils/server/follows' | 17 | import { unfollow } from '../../../../shared/extra-utils/server/follows' |
18 | import { userLogin } from '../../../../shared/extra-utils/users/login' | 18 | import { userLogin } from '../../../../shared/extra-utils/users/login' |
19 | import { createUser } from '../../../../shared/extra-utils/users/users' | 19 | import { createUser } from '../../../../shared/extra-utils/users/users' |
20 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
20 | 21 | ||
21 | const expect = chai.expect | 22 | const expect = chai.expect |
22 | 23 | ||
@@ -58,11 +59,11 @@ describe('Test follow constraints', function () { | |||
58 | describe('With an unlogged user', function () { | 59 | describe('With an unlogged user', function () { |
59 | 60 | ||
60 | it('Should get the local video', async function () { | 61 | it('Should get the local video', async function () { |
61 | await getVideo(servers[0].url, video1UUID, 200) | 62 | await getVideo(servers[0].url, video1UUID, HttpStatusCode.OK_200) |
62 | }) | 63 | }) |
63 | 64 | ||
64 | it('Should get the remote video', async function () { | 65 | it('Should get the remote video', async function () { |
65 | await getVideo(servers[0].url, video2UUID, 200) | 66 | await getVideo(servers[0].url, video2UUID, HttpStatusCode.OK_200) |
66 | }) | 67 | }) |
67 | 68 | ||
68 | it('Should list local account videos', async function () { | 69 | it('Should list local account videos', async function () { |
@@ -98,11 +99,11 @@ describe('Test follow constraints', function () { | |||
98 | 99 | ||
99 | describe('With a logged user', function () { | 100 | describe('With a logged user', function () { |
100 | it('Should get the local video', async function () { | 101 | it('Should get the local video', async function () { |
101 | await getVideoWithToken(servers[0].url, userAccessToken, video1UUID, 200) | 102 | await getVideoWithToken(servers[0].url, userAccessToken, video1UUID, HttpStatusCode.OK_200) |
102 | }) | 103 | }) |
103 | 104 | ||
104 | it('Should get the remote video', async function () { | 105 | it('Should get the remote video', async function () { |
105 | await getVideoWithToken(servers[0].url, userAccessToken, video2UUID, 200) | 106 | await getVideoWithToken(servers[0].url, userAccessToken, video2UUID, HttpStatusCode.OK_200) |
106 | }) | 107 | }) |
107 | 108 | ||
108 | it('Should list local account videos', async function () { | 109 | it('Should list local account videos', async function () { |
@@ -148,11 +149,11 @@ describe('Test follow constraints', function () { | |||
148 | describe('With an unlogged user', function () { | 149 | describe('With an unlogged user', function () { |
149 | 150 | ||
150 | it('Should get the local video', async function () { | 151 | it('Should get the local video', async function () { |
151 | await getVideo(servers[0].url, video1UUID, 200) | 152 | await getVideo(servers[0].url, video1UUID, HttpStatusCode.OK_200) |
152 | }) | 153 | }) |
153 | 154 | ||
154 | it('Should not get the remote video', async function () { | 155 | it('Should not get the remote video', async function () { |
155 | await getVideo(servers[0].url, video2UUID, 403) | 156 | await getVideo(servers[0].url, video2UUID, HttpStatusCode.FORBIDDEN_403) |
156 | }) | 157 | }) |
157 | 158 | ||
158 | it('Should list local account videos', async function () { | 159 | it('Should list local account videos', async function () { |
@@ -188,11 +189,11 @@ describe('Test follow constraints', function () { | |||
188 | 189 | ||
189 | describe('With a logged user', function () { | 190 | describe('With a logged user', function () { |
190 | it('Should get the local video', async function () { | 191 | it('Should get the local video', async function () { |
191 | await getVideoWithToken(servers[0].url, userAccessToken, video1UUID, 200) | 192 | await getVideoWithToken(servers[0].url, userAccessToken, video1UUID, HttpStatusCode.OK_200) |
192 | }) | 193 | }) |
193 | 194 | ||
194 | it('Should get the remote video', async function () { | 195 | it('Should get the remote video', async function () { |
195 | await getVideoWithToken(servers[0].url, userAccessToken, video2UUID, 200) | 196 | await getVideoWithToken(servers[0].url, userAccessToken, video2UUID, HttpStatusCode.OK_200) |
196 | }) | 197 | }) |
197 | 198 | ||
198 | it('Should list local account videos', async function () { | 199 | it('Should list local account videos', async function () { |
diff --git a/server/tests/api/server/handle-down.ts b/server/tests/api/server/handle-down.ts index 2cf6e15ad..043754e70 100644 --- a/server/tests/api/server/handle-down.ts +++ b/server/tests/api/server/handle-down.ts | |||
@@ -33,6 +33,7 @@ import { | |||
33 | getVideoCommentThreads, | 33 | getVideoCommentThreads, |
34 | getVideoThreadComments | 34 | getVideoThreadComments |
35 | } from '../../../../shared/extra-utils/videos/video-comments' | 35 | } from '../../../../shared/extra-utils/videos/video-comments' |
36 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
36 | 37 | ||
37 | const expect = chai.expect | 38 | const expect = chai.expect |
38 | 39 | ||
@@ -352,7 +353,7 @@ describe('Test handle downs', function () { | |||
352 | } | 353 | } |
353 | 354 | ||
354 | for (const id of videoIdsServer1) { | 355 | for (const id of videoIdsServer1) { |
355 | await getVideo(servers[1].url, id, 403) | 356 | await getVideo(servers[1].url, id, HttpStatusCode.FORBIDDEN_403) |
356 | } | 357 | } |
357 | }) | 358 | }) |
358 | 359 | ||
diff --git a/server/tests/api/server/no-client.ts b/server/tests/api/server/no-client.ts index d0450aba0..d589f51f3 100644 --- a/server/tests/api/server/no-client.ts +++ b/server/tests/api/server/no-client.ts | |||
@@ -2,6 +2,7 @@ import 'mocha' | |||
2 | import * as request from 'supertest' | 2 | import * as request from 'supertest' |
3 | import { ServerInfo } from '../../../../shared/extra-utils' | 3 | import { ServerInfo } from '../../../../shared/extra-utils' |
4 | import { cleanupTests, flushAndRunServer } from '../../../../shared/extra-utils/server/servers' | 4 | import { cleanupTests, flushAndRunServer } from '../../../../shared/extra-utils/server/servers' |
5 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
5 | 6 | ||
6 | describe('Start and stop server without web client routes', function () { | 7 | describe('Start and stop server without web client routes', function () { |
7 | let server: ServerInfo | 8 | let server: ServerInfo |
@@ -16,7 +17,7 @@ describe('Start and stop server without web client routes', function () { | |||
16 | const req = request(server.url) | 17 | const req = request(server.url) |
17 | .get('/') | 18 | .get('/') |
18 | 19 | ||
19 | return req.expect(404) | 20 | return req.expect(HttpStatusCode.NOT_FOUND_404) |
20 | }) | 21 | }) |
21 | 22 | ||
22 | after(async function () { | 23 | after(async function () { |
diff --git a/server/tests/api/server/reverse-proxy.ts b/server/tests/api/server/reverse-proxy.ts index d0d79c4f6..17d1ee4a5 100644 --- a/server/tests/api/server/reverse-proxy.ts +++ b/server/tests/api/server/reverse-proxy.ts | |||
@@ -4,6 +4,7 @@ import 'mocha' | |||
4 | import * as chai from 'chai' | 4 | import * as chai from 'chai' |
5 | import { cleanupTests, getVideo, registerUser, uploadVideo, userLogin, viewVideo, wait } from '../../../../shared/extra-utils' | 5 | import { cleanupTests, getVideo, registerUser, uploadVideo, userLogin, viewVideo, wait } from '../../../../shared/extra-utils' |
6 | import { flushAndRunServer, setAccessTokensToServers } from '../../../../shared/extra-utils/index' | 6 | import { flushAndRunServer, setAccessTokensToServers } from '../../../../shared/extra-utils/index' |
7 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
7 | 8 | ||
8 | const expect = chai.expect | 9 | const expect = chai.expect |
9 | 10 | ||
@@ -56,8 +57,8 @@ describe('Test application behind a reverse proxy', function () { | |||
56 | it('Should view a video 2 times with the X-Forwarded-For header set', async function () { | 57 | it('Should view a video 2 times with the X-Forwarded-For header set', async function () { |
57 | this.timeout(20000) | 58 | this.timeout(20000) |
58 | 59 | ||
59 | await viewVideo(server.url, videoId, 204, '0.0.0.1,127.0.0.1') | 60 | await viewVideo(server.url, videoId, HttpStatusCode.NO_CONTENT_204, '0.0.0.1,127.0.0.1') |
60 | await viewVideo(server.url, videoId, 204, '0.0.0.2,127.0.0.1') | 61 | await viewVideo(server.url, videoId, HttpStatusCode.NO_CONTENT_204, '0.0.0.2,127.0.0.1') |
61 | 62 | ||
62 | // Wait the repeatable job | 63 | // Wait the repeatable job |
63 | await wait(8000) | 64 | await wait(8000) |
@@ -69,8 +70,8 @@ describe('Test application behind a reverse proxy', function () { | |||
69 | it('Should view a video only once with the same client IP in the X-Forwarded-For header', async function () { | 70 | it('Should view a video only once with the same client IP in the X-Forwarded-For header', async function () { |
70 | this.timeout(20000) | 71 | this.timeout(20000) |
71 | 72 | ||
72 | await viewVideo(server.url, videoId, 204, '0.0.0.4,0.0.0.3,::ffff:127.0.0.1') | 73 | await viewVideo(server.url, videoId, HttpStatusCode.NO_CONTENT_204, '0.0.0.4,0.0.0.3,::ffff:127.0.0.1') |
73 | await viewVideo(server.url, videoId, 204, '0.0.0.5,0.0.0.3,127.0.0.1') | 74 | await viewVideo(server.url, videoId, HttpStatusCode.NO_CONTENT_204, '0.0.0.5,0.0.0.3,127.0.0.1') |
74 | 75 | ||
75 | // Wait the repeatable job | 76 | // Wait the repeatable job |
76 | await wait(8000) | 77 | await wait(8000) |
@@ -82,8 +83,8 @@ describe('Test application behind a reverse proxy', function () { | |||
82 | it('Should view a video two times with a different client IP in the X-Forwarded-For header', async function () { | 83 | it('Should view a video two times with a different client IP in the X-Forwarded-For header', async function () { |
83 | this.timeout(20000) | 84 | this.timeout(20000) |
84 | 85 | ||
85 | await viewVideo(server.url, videoId, 204, '0.0.0.8,0.0.0.6,127.0.0.1') | 86 | await viewVideo(server.url, videoId, HttpStatusCode.NO_CONTENT_204, '0.0.0.8,0.0.0.6,127.0.0.1') |
86 | await viewVideo(server.url, videoId, 204, '0.0.0.8,0.0.0.7,127.0.0.1') | 87 | await viewVideo(server.url, videoId, HttpStatusCode.NO_CONTENT_204, '0.0.0.8,0.0.0.7,127.0.0.1') |
87 | 88 | ||
88 | // Wait the repeatable job | 89 | // Wait the repeatable job |
89 | await wait(8000) | 90 | await wait(8000) |
@@ -96,10 +97,10 @@ describe('Test application behind a reverse proxy', function () { | |||
96 | const user = { username: 'root', password: 'fail' } | 97 | const user = { username: 'root', password: 'fail' } |
97 | 98 | ||
98 | for (let i = 0; i < 19; i++) { | 99 | for (let i = 0; i < 19; i++) { |
99 | await userLogin(server, user, 400) | 100 | await userLogin(server, user, HttpStatusCode.BAD_REQUEST_400) |
100 | } | 101 | } |
101 | 102 | ||
102 | await userLogin(server, user, 429) | 103 | await userLogin(server, user, HttpStatusCode.TOO_MANY_REQUESTS_429) |
103 | }) | 104 | }) |
104 | 105 | ||
105 | it('Should rate limit signup', async function () { | 106 | it('Should rate limit signup', async function () { |
@@ -111,7 +112,7 @@ describe('Test application behind a reverse proxy', function () { | |||
111 | } | 112 | } |
112 | } | 113 | } |
113 | 114 | ||
114 | await registerUser(server.url, 'test42', 'password', 429) | 115 | await registerUser(server.url, 'test42', 'password', HttpStatusCode.TOO_MANY_REQUESTS_429) |
115 | }) | 116 | }) |
116 | 117 | ||
117 | it('Should not rate limit failed signup', async function () { | 118 | it('Should not rate limit failed signup', async function () { |
@@ -120,10 +121,10 @@ describe('Test application behind a reverse proxy', function () { | |||
120 | await wait(7000) | 121 | await wait(7000) |
121 | 122 | ||
122 | for (let i = 0; i < 3; i++) { | 123 | for (let i = 0; i < 3; i++) { |
123 | await registerUser(server.url, 'test' + i, 'password', 409) | 124 | await registerUser(server.url, 'test' + i, 'password', HttpStatusCode.CONFLICT_409) |
124 | } | 125 | } |
125 | 126 | ||
126 | await registerUser(server.url, 'test43', 'password', 204) | 127 | await registerUser(server.url, 'test43', 'password', HttpStatusCode.NO_CONTENT_204) |
127 | 128 | ||
128 | }) | 129 | }) |
129 | 130 | ||
@@ -140,7 +141,7 @@ describe('Test application behind a reverse proxy', function () { | |||
140 | } | 141 | } |
141 | } | 142 | } |
142 | 143 | ||
143 | await getVideo(server.url, videoId, 429) | 144 | await getVideo(server.url, videoId, HttpStatusCode.TOO_MANY_REQUESTS_429) |
144 | }) | 145 | }) |
145 | 146 | ||
146 | after(async function () { | 147 | after(async function () { |
diff --git a/server/tests/api/videos/multiple-servers.ts b/server/tests/api/videos/multiple-servers.ts index fdd5e33f3..f754df04e 100644 --- a/server/tests/api/videos/multiple-servers.ts +++ b/server/tests/api/videos/multiple-servers.ts | |||
@@ -41,6 +41,7 @@ import { | |||
41 | findCommentId | 41 | findCommentId |
42 | } from '../../../../shared/extra-utils/videos/video-comments' | 42 | } from '../../../../shared/extra-utils/videos/video-comments' |
43 | import { waitJobs } from '../../../../shared/extra-utils/server/jobs' | 43 | import { waitJobs } from '../../../../shared/extra-utils/server/jobs' |
44 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
44 | 45 | ||
45 | const expect = chai.expect | 46 | const expect = chai.expect |
46 | 47 | ||
@@ -999,7 +1000,7 @@ describe('Test multiple servers', function () { | |||
999 | expect(res.body.downloadEnabled).to.be.false | 1000 | expect(res.body.downloadEnabled).to.be.false |
1000 | 1001 | ||
1001 | const text = 'my super forbidden comment' | 1002 | const text = 'my super forbidden comment' |
1002 | await addVideoCommentThread(server.url, server.accessToken, videoUUID, text, 409) | 1003 | await addVideoCommentThread(server.url, server.accessToken, videoUUID, text, HttpStatusCode.CONFLICT_409) |
1003 | } | 1004 | } |
1004 | }) | 1005 | }) |
1005 | }) | 1006 | }) |
@@ -1021,7 +1022,7 @@ describe('Test multiple servers', function () { | |||
1021 | const filePath = join(__dirname, '..', '..', 'fixtures', 'video_short.webm') | 1022 | const filePath = join(__dirname, '..', '..', 'fixtures', 'video_short.webm') |
1022 | 1023 | ||
1023 | await req.attach('videofile', filePath) | 1024 | await req.attach('videofile', filePath) |
1024 | .expect(200) | 1025 | .expect(HttpStatusCode.OK_200) |
1025 | 1026 | ||
1026 | await waitJobs(servers) | 1027 | await waitJobs(servers) |
1027 | 1028 | ||
diff --git a/server/tests/api/videos/video-change-ownership.ts b/server/tests/api/videos/video-change-ownership.ts index dee6575b9..fad4c8b1f 100644 --- a/server/tests/api/videos/video-change-ownership.ts +++ b/server/tests/api/videos/video-change-ownership.ts | |||
@@ -23,6 +23,7 @@ import { | |||
23 | import { waitJobs } from '../../../../shared/extra-utils/server/jobs' | 23 | import { waitJobs } from '../../../../shared/extra-utils/server/jobs' |
24 | import { User } from '../../../../shared/models/users' | 24 | import { User } from '../../../../shared/models/users' |
25 | import { VideoDetails } from '../../../../shared/models/videos' | 25 | import { VideoDetails } from '../../../../shared/models/videos' |
26 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
26 | 27 | ||
27 | const expect = chai.expect | 28 | const expect = chai.expect |
28 | 29 | ||
@@ -140,7 +141,7 @@ describe('Test video change ownership - nominal', function () { | |||
140 | it('Should not be possible to refuse the change of ownership from first user', async function () { | 141 | it('Should not be possible to refuse the change of ownership from first user', async function () { |
141 | this.timeout(10000) | 142 | this.timeout(10000) |
142 | 143 | ||
143 | await refuseChangeOwnership(servers[0].url, firstUserAccessToken, lastRequestChangeOwnershipId, 403) | 144 | await refuseChangeOwnership(servers[0].url, firstUserAccessToken, lastRequestChangeOwnershipId, HttpStatusCode.FORBIDDEN_403) |
144 | }) | 145 | }) |
145 | 146 | ||
146 | it('Should be possible to refuse the change of ownership from second user', async function () { | 147 | it('Should be possible to refuse the change of ownership from second user', async function () { |
@@ -177,7 +178,7 @@ describe('Test video change ownership - nominal', function () { | |||
177 | const secondUserInformationResponse = await getMyUserInformation(servers[0].url, secondUserAccessToken) | 178 | const secondUserInformationResponse = await getMyUserInformation(servers[0].url, secondUserAccessToken) |
178 | const secondUserInformation: User = secondUserInformationResponse.body | 179 | const secondUserInformation: User = secondUserInformationResponse.body |
179 | const channelId = secondUserInformation.videoChannels[0].id | 180 | const channelId = secondUserInformation.videoChannels[0].id |
180 | await acceptChangeOwnership(servers[0].url, firstUserAccessToken, lastRequestChangeOwnershipId, channelId, 403) | 181 | await acceptChangeOwnership(servers[0].url, firstUserAccessToken, lastRequestChangeOwnershipId, channelId, HttpStatusCode.FORBIDDEN_403) |
181 | }) | 182 | }) |
182 | 183 | ||
183 | it('Should be possible to accept the change of ownership from second user', async function () { | 184 | it('Should be possible to accept the change of ownership from second user', async function () { |
@@ -294,7 +295,14 @@ describe('Test video change ownership - quota too small', function () { | |||
294 | const secondUserInformationResponse = await getMyUserInformation(server.url, secondUserAccessToken) | 295 | const secondUserInformationResponse = await getMyUserInformation(server.url, secondUserAccessToken) |
295 | const secondUserInformation: User = secondUserInformationResponse.body | 296 | const secondUserInformation: User = secondUserInformationResponse.body |
296 | const channelId = secondUserInformation.videoChannels[0].id | 297 | const channelId = secondUserInformation.videoChannels[0].id |
297 | await acceptChangeOwnership(server.url, secondUserAccessToken, lastRequestChangeOwnershipId, channelId, 403) | 298 | |
299 | await acceptChangeOwnership( | ||
300 | server.url, | ||
301 | secondUserAccessToken, | ||
302 | lastRequestChangeOwnershipId, | ||
303 | channelId, | ||
304 | HttpStatusCode.PAYLOAD_TOO_LARGE_413 | ||
305 | ) | ||
298 | }) | 306 | }) |
299 | 307 | ||
300 | after(async function () { | 308 | after(async function () { |
diff --git a/server/tests/api/videos/video-hls.ts b/server/tests/api/videos/video-hls.ts index 3a65cc1d2..f3dbbb114 100644 --- a/server/tests/api/videos/video-hls.ts +++ b/server/tests/api/videos/video-hls.ts | |||
@@ -26,6 +26,7 @@ import { | |||
26 | import { VideoDetails } from '../../../../shared/models/videos' | 26 | import { VideoDetails } from '../../../../shared/models/videos' |
27 | import { VideoStreamingPlaylistType } from '../../../../shared/models/videos/video-streaming-playlist.type' | 27 | import { VideoStreamingPlaylistType } from '../../../../shared/models/videos/video-streaming-playlist.type' |
28 | import { DEFAULT_AUDIO_RESOLUTION } from '../../../initializers/constants' | 28 | import { DEFAULT_AUDIO_RESOLUTION } from '../../../initializers/constants' |
29 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
29 | 30 | ||
30 | const expect = chai.expect | 31 | const expect = chai.expect |
31 | 32 | ||
@@ -57,8 +58,8 @@ async function checkHlsPlaylist (servers: ServerInfo[], videoUUID: string, hlsOn | |||
57 | ) | 58 | ) |
58 | expect(file.resolution.label).to.equal(resolution + 'p') | 59 | expect(file.resolution.label).to.equal(resolution + 'p') |
59 | 60 | ||
60 | await makeRawRequest(file.torrentUrl, 200) | 61 | await makeRawRequest(file.torrentUrl, HttpStatusCode.OK_200) |
61 | await makeRawRequest(file.fileUrl, 200) | 62 | await makeRawRequest(file.fileUrl, HttpStatusCode.OK_200) |
62 | 63 | ||
63 | const torrent = await webtorrentAdd(file.magnetUri, true) | 64 | const torrent = await webtorrentAdd(file.magnetUri, true) |
64 | expect(torrent.files).to.be.an('array') | 65 | expect(torrent.files).to.be.an('array') |
@@ -144,8 +145,8 @@ describe('Test HLS videos', function () { | |||
144 | await waitJobs(servers) | 145 | await waitJobs(servers) |
145 | 146 | ||
146 | for (const server of servers) { | 147 | for (const server of servers) { |
147 | await getVideo(server.url, videoUUID, 404) | 148 | await getVideo(server.url, videoUUID, HttpStatusCode.NOT_FOUND_404) |
148 | await getVideo(server.url, videoAudioUUID, 404) | 149 | await getVideo(server.url, videoAudioUUID, HttpStatusCode.NOT_FOUND_404) |
149 | } | 150 | } |
150 | }) | 151 | }) |
151 | 152 | ||
diff --git a/server/tests/api/videos/video-playlists.ts b/server/tests/api/videos/video-playlists.ts index 7d1215990..0a96ea9a0 100644 --- a/server/tests/api/videos/video-playlists.ts +++ b/server/tests/api/videos/video-playlists.ts | |||
@@ -61,6 +61,7 @@ import { | |||
61 | removeServerFromAccountBlocklist, | 61 | removeServerFromAccountBlocklist, |
62 | removeServerFromServerBlocklist | 62 | removeServerFromServerBlocklist |
63 | } from '../../../../shared/extra-utils/users/blocklist' | 63 | } from '../../../../shared/extra-utils/users/blocklist' |
64 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
64 | 65 | ||
65 | const expect = chai.expect | 66 | const expect = chai.expect |
66 | 67 | ||
@@ -1091,7 +1092,7 @@ describe('Test video playlists', function () { | |||
1091 | await waitJobs(servers) | 1092 | await waitJobs(servers) |
1092 | 1093 | ||
1093 | for (const server of servers) { | 1094 | for (const server of servers) { |
1094 | await getVideoPlaylist(server.url, videoPlaylistIds.uuid, 200) | 1095 | await getVideoPlaylist(server.url, videoPlaylistIds.uuid, HttpStatusCode.OK_200) |
1095 | } | 1096 | } |
1096 | 1097 | ||
1097 | const playlistAttrs = { privacy: VideoPlaylistPrivacy.PRIVATE } | 1098 | const playlistAttrs = { privacy: VideoPlaylistPrivacy.PRIVATE } |
@@ -1100,11 +1101,11 @@ describe('Test video playlists', function () { | |||
1100 | await waitJobs(servers) | 1101 | await waitJobs(servers) |
1101 | 1102 | ||
1102 | for (const server of [ servers[1], servers[2] ]) { | 1103 | for (const server of [ servers[1], servers[2] ]) { |
1103 | await getVideoPlaylist(server.url, videoPlaylistIds.uuid, 404) | 1104 | await getVideoPlaylist(server.url, videoPlaylistIds.uuid, HttpStatusCode.NOT_FOUND_404) |
1104 | } | 1105 | } |
1105 | await getVideoPlaylist(servers[0].url, videoPlaylistIds.uuid, 401) | 1106 | await getVideoPlaylist(servers[0].url, videoPlaylistIds.uuid, HttpStatusCode.UNAUTHORIZED_401) |
1106 | 1107 | ||
1107 | await getVideoPlaylistWithToken(servers[0].url, servers[0].accessToken, videoPlaylistIds.uuid, 200) | 1108 | await getVideoPlaylistWithToken(servers[0].url, servers[0].accessToken, videoPlaylistIds.uuid, HttpStatusCode.OK_200) |
1108 | }) | 1109 | }) |
1109 | }) | 1110 | }) |
1110 | 1111 | ||
@@ -1118,7 +1119,7 @@ describe('Test video playlists', function () { | |||
1118 | await waitJobs(servers) | 1119 | await waitJobs(servers) |
1119 | 1120 | ||
1120 | for (const server of servers) { | 1121 | for (const server of servers) { |
1121 | await getVideoPlaylist(server.url, playlistServer1UUID, 404) | 1122 | await getVideoPlaylist(server.url, playlistServer1UUID, HttpStatusCode.NOT_FOUND_404) |
1122 | } | 1123 | } |
1123 | }) | 1124 | }) |
1124 | 1125 | ||
@@ -1178,7 +1179,7 @@ describe('Test video playlists', function () { | |||
1178 | expect(res3.body.displayName).to.equal('channel playlist') | 1179 | expect(res3.body.displayName).to.equal('channel playlist') |
1179 | expect(res3.body.privacy.id).to.equal(VideoPlaylistPrivacy.PRIVATE) | 1180 | expect(res3.body.privacy.id).to.equal(VideoPlaylistPrivacy.PRIVATE) |
1180 | 1181 | ||
1181 | await getVideoPlaylist(servers[1].url, videoPlaylistUUID, 404) | 1182 | await getVideoPlaylist(servers[1].url, videoPlaylistUUID, HttpStatusCode.NOT_FOUND_404) |
1182 | }) | 1183 | }) |
1183 | 1184 | ||
1184 | it('Should delete an account and delete its playlists', async function () { | 1185 | it('Should delete an account and delete its playlists', async function () { |
diff --git a/server/tests/api/videos/video-privacy.ts b/server/tests/api/videos/video-privacy.ts index 38e93bbe6..f25d75af4 100644 --- a/server/tests/api/videos/video-privacy.ts +++ b/server/tests/api/videos/video-privacy.ts | |||
@@ -18,6 +18,7 @@ import { createUser } from '../../../../shared/extra-utils/users/users' | |||
18 | import { getMyVideos, getVideo, getVideoWithToken, updateVideo } from '../../../../shared/extra-utils/videos/videos' | 18 | import { getMyVideos, getVideo, getVideoWithToken, updateVideo } from '../../../../shared/extra-utils/videos/videos' |
19 | import { waitJobs } from '../../../../shared/extra-utils/server/jobs' | 19 | import { waitJobs } from '../../../../shared/extra-utils/server/jobs' |
20 | import { Video } from '@shared/models' | 20 | import { Video } from '@shared/models' |
21 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | ||
21 | 22 | ||
22 | const expect = chai.expect | 23 | const expect = chai.expect |
23 | 24 | ||
@@ -110,8 +111,8 @@ describe('Test video privacy', function () { | |||
110 | }) | 111 | }) |
111 | 112 | ||
112 | it('Should not be able to watch the private/internal video with non authenticated user', async function () { | 113 | it('Should not be able to watch the private/internal video with non authenticated user', async function () { |
113 | await getVideo(servers[0].url, privateVideoUUID, 401) | 114 | await getVideo(servers[0].url, privateVideoUUID, HttpStatusCode.UNAUTHORIZED_401) |
114 | await getVideo(servers[0].url, internalVideoUUID, 401) | 115 | await getVideo(servers[0].url, internalVideoUUID, HttpStatusCode.UNAUTHORIZED_401) |
115 | }) | 116 | }) |
116 | 117 | ||
117 | it('Should not be able to watch the private video with another user', async function () { | 118 | it('Should not be able to watch the private video with another user', async function () { |
@@ -124,15 +125,15 @@ describe('Test video privacy', function () { | |||
124 | await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password }) | 125 | await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password }) |
125 | 126 | ||
126 | anotherUserToken = await userLogin(servers[0], user) | 127 | anotherUserToken = await userLogin(servers[0], user) |
127 | await getVideoWithToken(servers[0].url, anotherUserToken, privateVideoUUID, 403) | 128 | await getVideoWithToken(servers[0].url, anotherUserToken, privateVideoUUID, HttpStatusCode.FORBIDDEN_403) |
128 | }) | 129 | }) |
129 | 130 | ||
130 | it('Should be able to watch the internal video with another user', async function () { | 131 | it('Should be able to watch the internal video with another user', async function () { |
131 | await getVideoWithToken(servers[0].url, anotherUserToken, internalVideoUUID, 200) | 132 | await getVideoWithToken(servers[0].url, anotherUserToken, internalVideoUUID, HttpStatusCode.OK_200) |
132 | }) | 133 | }) |
133 | 134 | ||
134 | it('Should be able to watch the private video with the correct user', async function () { | 135 | it('Should be able to watch the private video with the correct user', async function () { |
135 | await getVideoWithToken(servers[0].url, servers[0].accessToken, privateVideoUUID, 200) | 136 | await getVideoWithToken(servers[0].url, servers[0].accessToken, privateVideoUUID, HttpStatusCode.OK_200) |
136 | }) | 137 | }) |
137 | 138 | ||
138 | it('Should upload an unlisted video on server 2', async function () { | 139 | it('Should upload an unlisted video on server 2', async function () { |
@@ -202,7 +203,7 @@ describe('Test video privacy', function () { | |||
202 | }) | 203 | }) |
203 | 204 | ||
204 | it('Should not be able to get non-federated unlisted video from federated server', async function () { | 205 | it('Should not be able to get non-federated unlisted video from federated server', async function () { |
205 | await getVideo(servers[1].url, nonFederatedUnlistedVideoUUID, 404) | 206 | await getVideo(servers[1].url, nonFederatedUnlistedVideoUUID, HttpStatusCode.NOT_FOUND_404) |
206 | }) | 207 | }) |
207 | 208 | ||
208 | it('Should update the private and internal videos to public on server 1', async function () { | 209 | it('Should update the private and internal videos to public on server 1', async function () { |
diff --git a/server/tests/api/videos/videos-history.ts b/server/tests/api/videos/videos-history.ts index 6f90e9a57..661d603cb 100644 --- a/server/tests/api/videos/videos-history.ts +++ b/server/tests/api/videos/videos-history.ts | |||
@@ -20,6 +20,7 @@ import { | |||
20 | } from '../../../../shared/extra-utils' | 20 | } from '../../../../shared/extra-utils' |
21 | import { Video, VideoDetails } from '../../../../shared/models/videos' | 21 | import { Video, VideoDetails } from '../../../../shared/models/videos' |
22 | import { listMyVideosHistory, removeMyVideosHistory, userWatchVideo } from '../../../../shared/extra-utils/videos/video-history' | 22 | import { listMyVideosHistory, removeMyVideosHistory, userWatchVideo } from '../../../../shared/extra-utils/videos/video-history' |
23 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
23 | 24 | ||
24 | const expect = chai.expect | 25 | const expect = chai.expect |
25 | 26 | ||
@@ -171,7 +172,7 @@ describe('Test videos history', function () { | |||
171 | videosHistoryEnabled: false | 172 | videosHistoryEnabled: false |
172 | }) | 173 | }) |
173 | 174 | ||
174 | await userWatchVideo(server.url, server.accessToken, video2UUID, 8, 409) | 175 | await userWatchVideo(server.url, server.accessToken, video2UUID, 8, HttpStatusCode.CONFLICT_409) |
175 | }) | 176 | }) |
176 | 177 | ||
177 | it('Should re-enable videos history', async function () { | 178 | it('Should re-enable videos history', async function () { |
diff --git a/server/tests/cli/reset-password.ts b/server/tests/cli/reset-password.ts index 6abb6738f..a84463b33 100644 --- a/server/tests/cli/reset-password.ts +++ b/server/tests/cli/reset-password.ts | |||
@@ -10,6 +10,7 @@ import { | |||
10 | ServerInfo, | 10 | ServerInfo, |
11 | setAccessTokensToServers | 11 | setAccessTokensToServers |
12 | } from '../../../shared/extra-utils' | 12 | } from '../../../shared/extra-utils' |
13 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | ||
13 | 14 | ||
14 | describe('Test reset password scripts', function () { | 15 | describe('Test reset password scripts', function () { |
15 | let server: ServerInfo | 16 | let server: ServerInfo |
@@ -28,7 +29,7 @@ describe('Test reset password scripts', function () { | |||
28 | const env = getEnvCli(server) | 29 | const env = getEnvCli(server) |
29 | await execCLI(`echo coucou | ${env} npm run reset-password -- -u user_1`) | 30 | await execCLI(`echo coucou | ${env} npm run reset-password -- -u user_1`) |
30 | 31 | ||
31 | await login(server.url, server.client, { username: 'user_1', password: 'coucou' }, 200) | 32 | await login(server.url, server.client, { username: 'user_1', password: 'coucou' }, HttpStatusCode.OK_200) |
32 | }) | 33 | }) |
33 | 34 | ||
34 | after(async function () { | 35 | after(async function () { |
diff --git a/server/tests/feeds/feeds.ts b/server/tests/feeds/feeds.ts index 92a468192..f1055ea44 100644 --- a/server/tests/feeds/feeds.ts +++ b/server/tests/feeds/feeds.ts | |||
@@ -31,6 +31,7 @@ import { | |||
31 | import { waitJobs } from '../../../shared/extra-utils/server/jobs' | 31 | import { waitJobs } from '../../../shared/extra-utils/server/jobs' |
32 | import { addVideoCommentThread } from '../../../shared/extra-utils/videos/video-comments' | 32 | import { addVideoCommentThread } from '../../../shared/extra-utils/videos/video-comments' |
33 | import { User } from '../../../shared/models/users' | 33 | import { User } from '../../../shared/models/users' |
34 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | ||
34 | 35 | ||
35 | chai.use(require('chai-xml')) | 36 | chai.use(require('chai-xml')) |
36 | chai.use(require('chai-json-schema')) | 37 | chai.use(require('chai-json-schema')) |
@@ -330,11 +331,16 @@ describe('Test syndication feeds', () => { | |||
330 | }) | 331 | }) |
331 | 332 | ||
332 | it('Should fail with an invalid token', async function () { | 333 | it('Should fail with an invalid token', async function () { |
333 | await getJSONfeed(servers[0].url, 'subscriptions', { accountId: feeduserAccountId, token: 'toto' }, 403) | 334 | await getJSONfeed(servers[0].url, 'subscriptions', { accountId: feeduserAccountId, token: 'toto' }, HttpStatusCode.FORBIDDEN_403) |
334 | }) | 335 | }) |
335 | 336 | ||
336 | it('Should fail with a token of another user', async function () { | 337 | it('Should fail with a token of another user', async function () { |
337 | await getJSONfeed(servers[0].url, 'subscriptions', { accountId: feeduserAccountId, token: userFeedToken }, 403) | 338 | await getJSONfeed( |
339 | servers[0].url, | ||
340 | 'subscriptions', | ||
341 | { accountId: feeduserAccountId, token: userFeedToken }, | ||
342 | HttpStatusCode.FORBIDDEN_403 | ||
343 | ) | ||
338 | }) | 344 | }) |
339 | 345 | ||
340 | it('Should list no videos for a user with videos but no subscriptions', async function () { | 346 | it('Should list no videos for a user with videos but no subscriptions', async function () { |
@@ -382,7 +388,12 @@ describe('Test syndication feeds', () => { | |||
382 | it('Should renew the token, and so have an invalid old token', async function () { | 388 | it('Should renew the token, and so have an invalid old token', async function () { |
383 | await renewUserScopedTokens(servers[0].url, userAccessToken) | 389 | await renewUserScopedTokens(servers[0].url, userAccessToken) |
384 | 390 | ||
385 | await getJSONfeed(servers[0].url, 'subscriptions', { accountId: userAccountId, token: userFeedToken, version: 3 }, 403) | 391 | await getJSONfeed( |
392 | servers[0].url, | ||
393 | 'subscriptions', | ||
394 | { accountId: userAccountId, token: userFeedToken, version: 3 }, | ||
395 | HttpStatusCode.FORBIDDEN_403 | ||
396 | ) | ||
386 | }) | 397 | }) |
387 | 398 | ||
388 | it('Should succeed with the new token', async function () { | 399 | it('Should succeed with the new token', async function () { |
diff --git a/server/tests/plugins/filter-hooks.ts b/server/tests/plugins/filter-hooks.ts index 2441940c3..cdde6cd30 100644 --- a/server/tests/plugins/filter-hooks.ts +++ b/server/tests/plugins/filter-hooks.ts | |||
@@ -31,6 +31,7 @@ import { cleanupTests, flushAndRunMultipleServers, ServerInfo } from '../../../s | |||
31 | import { getGoodVideoUrl, getMyVideoImports, importVideo } from '../../../shared/extra-utils/videos/video-imports' | 31 | import { getGoodVideoUrl, getMyVideoImports, importVideo } from '../../../shared/extra-utils/videos/video-imports' |
32 | import { VideoDetails, VideoImport, VideoImportState, VideoPrivacy } from '../../../shared/models/videos' | 32 | import { VideoDetails, VideoImport, VideoImportState, VideoPrivacy } from '../../../shared/models/videos' |
33 | import { VideoCommentThreadTree } from '../../../shared/models/videos/video-comment.model' | 33 | import { VideoCommentThreadTree } from '../../../shared/models/videos/video-comment.model' |
34 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | ||
34 | 35 | ||
35 | const expect = chai.expect | 36 | const expect = chai.expect |
36 | 37 | ||
@@ -127,7 +128,7 @@ describe('Test plugin filter hooks', function () { | |||
127 | }) | 128 | }) |
128 | 129 | ||
129 | it('Should run filter:api.video.upload.accept.result', async function () { | 130 | it('Should run filter:api.video.upload.accept.result', async function () { |
130 | await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video with bad word' }, 403) | 131 | await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video with bad word' }, HttpStatusCode.FORBIDDEN_403) |
131 | }) | 132 | }) |
132 | 133 | ||
133 | it('Should run filter:api.live-video.create.accept.result', async function () { | 134 | it('Should run filter:api.live-video.create.accept.result', async function () { |
@@ -137,7 +138,7 @@ describe('Test plugin filter hooks', function () { | |||
137 | channelId: servers[0].videoChannel.id | 138 | channelId: servers[0].videoChannel.id |
138 | } | 139 | } |
139 | 140 | ||
140 | await createLive(servers[0].url, servers[0].accessToken, attributes, 403) | 141 | await createLive(servers[0].url, servers[0].accessToken, attributes, HttpStatusCode.FORBIDDEN_403) |
141 | }) | 142 | }) |
142 | 143 | ||
143 | it('Should run filter:api.video.pre-import-url.accept.result', async function () { | 144 | it('Should run filter:api.video.pre-import-url.accept.result', async function () { |
@@ -147,7 +148,7 @@ describe('Test plugin filter hooks', function () { | |||
147 | channelId: servers[0].videoChannel.id, | 148 | channelId: servers[0].videoChannel.id, |
148 | targetUrl: getGoodVideoUrl() + 'bad' | 149 | targetUrl: getGoodVideoUrl() + 'bad' |
149 | } | 150 | } |
150 | await importVideo(servers[0].url, servers[0].accessToken, baseAttributes, 403) | 151 | await importVideo(servers[0].url, servers[0].accessToken, baseAttributes, HttpStatusCode.FORBIDDEN_403) |
151 | }) | 152 | }) |
152 | 153 | ||
153 | it('Should run filter:api.video.pre-import-torrent.accept.result', async function () { | 154 | it('Should run filter:api.video.pre-import-torrent.accept.result', async function () { |
@@ -157,7 +158,7 @@ describe('Test plugin filter hooks', function () { | |||
157 | channelId: servers[0].videoChannel.id, | 158 | channelId: servers[0].videoChannel.id, |
158 | torrentfile: 'video-720p.torrent' as any | 159 | torrentfile: 'video-720p.torrent' as any |
159 | } | 160 | } |
160 | await importVideo(servers[0].url, servers[0].accessToken, baseAttributes, 403) | 161 | await importVideo(servers[0].url, servers[0].accessToken, baseAttributes, HttpStatusCode.FORBIDDEN_403) |
161 | }) | 162 | }) |
162 | 163 | ||
163 | it('Should run filter:api.video.post-import-url.accept.result', async function () { | 164 | it('Should run filter:api.video.post-import-url.accept.result', async function () { |
@@ -219,15 +220,22 @@ describe('Test plugin filter hooks', function () { | |||
219 | }) | 220 | }) |
220 | 221 | ||
221 | it('Should run filter:api.video-thread.create.accept.result', async function () { | 222 | it('Should run filter:api.video-thread.create.accept.result', async function () { |
222 | await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'comment with bad word', 403) | 223 | await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'comment with bad word', HttpStatusCode.FORBIDDEN_403) |
223 | }) | 224 | }) |
224 | 225 | ||
225 | it('Should run filter:api.video-comment-reply.create.accept.result', async function () { | 226 | it('Should run filter:api.video-comment-reply.create.accept.result', async function () { |
226 | const res = await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'thread') | 227 | const res = await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'thread') |
227 | threadId = res.body.comment.id | 228 | threadId = res.body.comment.id |
228 | 229 | ||
229 | await addVideoCommentReply(servers[0].url, servers[0].accessToken, videoUUID, threadId, 'comment with bad word', 403) | 230 | await addVideoCommentReply( |
230 | await addVideoCommentReply(servers[0].url, servers[0].accessToken, videoUUID, threadId, 'comment with good word', 200) | 231 | servers[0].url, |
232 | servers[0].accessToken, | ||
233 | videoUUID, | ||
234 | threadId, | ||
235 | 'comment with bad word', | ||
236 | HttpStatusCode.FORBIDDEN_403 | ||
237 | ) | ||
238 | await addVideoCommentReply(servers[0].url, servers[0].accessToken, videoUUID, threadId, 'comment with good word', HttpStatusCode.OK_200) | ||
231 | }) | 239 | }) |
232 | 240 | ||
233 | it('Should run filter:api.video-threads.list.params', async function () { | 241 | it('Should run filter:api.video-threads.list.params', async function () { |
@@ -326,7 +334,7 @@ describe('Test plugin filter hooks', function () { | |||
326 | }) | 334 | }) |
327 | 335 | ||
328 | it('Should not allow a signup', async function () { | 336 | it('Should not allow a signup', async function () { |
329 | const res = await registerUser(servers[0].url, 'jma', 'password', 403) | 337 | const res = await registerUser(servers[0].url, 'jma', 'password', HttpStatusCode.FORBIDDEN_403) |
330 | 338 | ||
331 | expect(res.body.error).to.equal('No jma') | 339 | expect(res.body.error).to.equal('No jma') |
332 | }) | 340 | }) |
diff --git a/server/tests/plugins/video-constants.ts b/server/tests/plugins/video-constants.ts index fec9196e2..5ee41fee1 100644 --- a/server/tests/plugins/video-constants.ts +++ b/server/tests/plugins/video-constants.ts | |||
@@ -16,6 +16,7 @@ import { | |||
16 | uploadVideo | 16 | uploadVideo |
17 | } from '../../../shared/extra-utils' | 17 | } from '../../../shared/extra-utils' |
18 | import { VideoDetails, VideoPlaylistPrivacy } from '../../../shared/models/videos' | 18 | import { VideoDetails, VideoPlaylistPrivacy } from '../../../shared/models/videos' |
19 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | ||
19 | 20 | ||
20 | const expect = chai.expect | 21 | const expect = chai.expect |
21 | 22 | ||
@@ -89,12 +90,17 @@ describe('Test plugin altering video constants', function () { | |||
89 | 90 | ||
90 | it('Should not be able to create a video with this privacy', async function () { | 91 | it('Should not be able to create a video with this privacy', async function () { |
91 | const attrs = { name: 'video', privacy: 2 } | 92 | const attrs = { name: 'video', privacy: 2 } |
92 | await uploadVideo(server.url, server.accessToken, attrs, 400) | 93 | await uploadVideo(server.url, server.accessToken, attrs, HttpStatusCode.BAD_REQUEST_400) |
93 | }) | 94 | }) |
94 | 95 | ||
95 | it('Should not be able to create a video with this privacy', async function () { | 96 | it('Should not be able to create a video with this privacy', async function () { |
96 | const attrs = { displayName: 'video playlist', privacy: VideoPlaylistPrivacy.PRIVATE } | 97 | const attrs = { displayName: 'video playlist', privacy: VideoPlaylistPrivacy.PRIVATE } |
97 | await createVideoPlaylist({ url: server.url, token: server.accessToken, playlistAttrs: attrs, expectedStatus: 400 }) | 98 | await createVideoPlaylist({ |
99 | url: server.url, | ||
100 | token: server.accessToken, | ||
101 | playlistAttrs: attrs, | ||
102 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
103 | }) | ||
98 | }) | 104 | }) |
99 | 105 | ||
100 | it('Should be able to upload a video with these values', async function () { | 106 | it('Should be able to upload a video with these values', async function () { |
diff --git a/server/tools/peertube-redundancy.ts b/server/tools/peertube-redundancy.ts index 1ab58a438..fe482daf4 100644 --- a/server/tools/peertube-redundancy.ts +++ b/server/tools/peertube-redundancy.ts | |||
@@ -7,6 +7,7 @@ import * as program from 'commander' | |||
7 | import { getAdminTokenOrDie, getServerCredentials } from './cli' | 7 | import { getAdminTokenOrDie, getServerCredentials } from './cli' |
8 | import { VideoRedundanciesTarget, VideoRedundancy } from '@shared/models' | 8 | import { VideoRedundanciesTarget, VideoRedundancy } from '@shared/models' |
9 | import { addVideoRedundancy, listVideoRedundancies, removeVideoRedundancy } from '@shared/extra-utils/server/redundancy' | 9 | import { addVideoRedundancy, listVideoRedundancies, removeVideoRedundancy } from '@shared/extra-utils/server/redundancy' |
10 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | ||
10 | import validator from 'validator' | 11 | import validator from 'validator' |
11 | import * as CliTable3 from 'cli-table3' | 12 | import * as CliTable3 from 'cli-table3' |
12 | import { URL } from 'url' | 13 | import { URL } from 'url' |
@@ -124,9 +125,9 @@ async function addRedundancyCLI (options: { videoId: number }) { | |||
124 | 125 | ||
125 | process.exit(0) | 126 | process.exit(0) |
126 | } catch (err) { | 127 | } catch (err) { |
127 | if (err.message.includes(409)) { | 128 | if (err.message.includes(HttpStatusCode.CONFLICT_409)) { |
128 | console.error('This video is already duplicated by your instance.') | 129 | console.error('This video is already duplicated by your instance.') |
129 | } else if (err.message.includes(404)) { | 130 | } else if (err.message.includes(HttpStatusCode.NOT_FOUND_404)) { |
130 | console.error('This video id does not exist.') | 131 | console.error('This video id does not exist.') |
131 | } else { | 132 | } else { |
132 | console.error(err) | 133 | console.error(err) |
diff --git a/shared/core-utils/miscs/http-error-codes.ts b/shared/core-utils/miscs/http-error-codes.ts index 8c8b87ba0..9ac8a6c83 100644 --- a/shared/core-utils/miscs/http-error-codes.ts +++ b/shared/core-utils/miscs/http-error-codes.ts | |||
@@ -1,6 +1,8 @@ | |||
1 | /** | 1 | /** |
2 | * Hypertext Transfer Protocol (HTTP) response status codes. | 2 | * Hypertext Transfer Protocol (HTTP) response status codes. |
3 | * @see {@link https://en.wikipedia.org/wiki/List_of_HTTP_status_codes} | 3 | * @see {@link https://en.wikipedia.org/wiki/List_of_HTTP_status_codes} |
4 | * | ||
5 | * WebDAV and other codes useless with regards to PeerTube are not listed. | ||
4 | */ | 6 | */ |
5 | export enum HttpStatusCode { | 7 | export enum HttpStatusCode { |
6 | 8 | ||
@@ -48,15 +50,6 @@ export enum HttpStatusCode { | |||
48 | ACCEPTED_202 = 202, | 50 | ACCEPTED_202 = 202, |
49 | 51 | ||
50 | /** | 52 | /** |
51 | * Official Documentation @ https://tools.ietf.org/html/rfc7231#section-6.3.4 | ||
52 | * | ||
53 | * SINCE HTTP/1.1 | ||
54 | * The server is a transforming proxy that received a 200 OK from its origin, | ||
55 | * but is returning a modified version of the origin's response. | ||
56 | */ | ||
57 | NON_AUTHORITATIVE_INFORMATION_203 = 203, | ||
58 | |||
59 | /** | ||
60 | * Official Documentation @ https://tools.ietf.org/html/rfc7231#section-6.3.5 | 53 | * Official Documentation @ https://tools.ietf.org/html/rfc7231#section-6.3.5 |
61 | * | 54 | * |
62 | * There is no content to send for this request, but the headers may be useful. | 55 | * There is no content to send for this request, but the headers may be useful. |
@@ -78,18 +71,6 @@ export enum HttpStatusCode { | |||
78 | PARTIAL_CONTENT_206 = 206, | 71 | PARTIAL_CONTENT_206 = 206, |
79 | 72 | ||
80 | /** | 73 | /** |
81 | * The message body that follows is an XML message and can contain a number of separate response codes, | ||
82 | * depending on how many sub-requests were made. | ||
83 | */ | ||
84 | MULTI_STATUS_207 = 207, | ||
85 | |||
86 | /** | ||
87 | * The server has fulfilled a request for the resource, | ||
88 | * and the response is a representation of the result of one or more instance-manipulations applied to the current instance. | ||
89 | */ | ||
90 | IM_USED_226 = 226, | ||
91 | |||
92 | /** | ||
93 | * Indicates multiple options for the resource from which the client may choose (via agent-driven content negotiation). | 74 | * Indicates multiple options for the resource from which the client may choose (via agent-driven content negotiation). |
94 | * For example, this code could be used to present multiple video format options, | 75 | * For example, this code could be used to present multiple video format options, |
95 | * to list files with different filename extensions, or to suggest word-sense disambiguation. | 76 | * to list files with different filename extensions, or to suggest word-sense disambiguation. |
@@ -129,20 +110,6 @@ export enum HttpStatusCode { | |||
129 | NOT_MODIFIED_304 = 304, | 110 | NOT_MODIFIED_304 = 304, |
130 | 111 | ||
131 | /** | 112 | /** |
132 | * @deprecated | ||
133 | * SINCE HTTP/1.1 | ||
134 | * The requested resource is available only through a proxy, the address for which is provided in the response. | ||
135 | * Many HTTP clients (such as Mozilla and Internet Explorer) do not correctly handle responses with this status | ||
136 | * code, primarily for security reasons. | ||
137 | */ | ||
138 | USE_PROXY_305 = 305, | ||
139 | |||
140 | /** | ||
141 | * No longer used. Originally meant "Subsequent requests should use the specified proxy." | ||
142 | */ | ||
143 | SWITCH_PROXY_306 = 306, | ||
144 | |||
145 | /** | ||
146 | * SINCE HTTP/1.1 | 113 | * SINCE HTTP/1.1 |
147 | * In this case, the request should be repeated with another URI; however, future requests should still use the original URI. | 114 | * In this case, the request should be repeated with another URI; however, future requests should still use the original URI. |
148 | * In contrast to how 302 was historically implemented, the request method is not allowed to be changed when reissuing the | 115 | * In contrast to how 302 was historically implemented, the request method is not allowed to be changed when reissuing the |
@@ -175,6 +142,8 @@ export enum HttpStatusCode { | |||
175 | UNAUTHORIZED_401 = 401, | 142 | UNAUTHORIZED_401 = 401, |
176 | 143 | ||
177 | /** | 144 | /** |
145 | * Official Documentation @ https://tools.ietf.org/html/rfc7231#section-6.5.2 | ||
146 | * | ||
178 | * Reserved for future use. The original intention was that this code might be used as part of some form of digital | 147 | * Reserved for future use. The original intention was that this code might be used as part of some form of digital |
179 | * cash or micro payment scheme, but that has not happened, and this code is not usually used. | 148 | * cash or micro payment scheme, but that has not happened, and this code is not usually used. |
180 | * Google Developers API uses this status if a particular developer has exceeded the daily limit on requests. | 149 | * Google Developers API uses this status if a particular developer has exceeded the daily limit on requests. |
@@ -211,21 +180,20 @@ export enum HttpStatusCode { | |||
211 | NOT_ACCEPTABLE_406 = 406, | 180 | NOT_ACCEPTABLE_406 = 406, |
212 | 181 | ||
213 | /** | 182 | /** |
214 | * The client must first authenticate itself with the proxy. | ||
215 | */ | ||
216 | PROXY_AUTHENTICATION_REQUIRED_407 = 407, | ||
217 | |||
218 | /** | ||
219 | * Official Documentation @ https://tools.ietf.org/html/rfc7231#section-6.5.7 | 183 | * Official Documentation @ https://tools.ietf.org/html/rfc7231#section-6.5.7 |
220 | * | 184 | * |
221 | * This response is sent on an idle connection by some servers, even without any previous request by the client. | 185 | * This response is sent on an idle connection by some servers, even without any previous request by the client. |
222 | * It means that the server would like to shut down this unused connection. This response is used much more since | 186 | * It means that the server would like to shut down this unused connection. This response is used much more since |
223 | * some browsers, like Chrome, Firefox 27+, or IE9, use HTTP pre-connection mechanisms to speed up surfing. Also | 187 | * some browsers, like Chrome, Firefox 27+, or IE9, use HTTP pre-connection mechanisms to speed up surfing. Also |
224 | * note that some servers merely shut down the connection without sending this message. | 188 | * note that some servers merely shut down the connection without sending this message. |
189 | * | ||
190 | * @ | ||
225 | */ | 191 | */ |
226 | REQUEST_TIMEOUT_408 = 408, | 192 | REQUEST_TIMEOUT_408 = 408, |
227 | 193 | ||
228 | /** | 194 | /** |
195 | * Official Documentation @ https://tools.ietf.org/html/rfc7231#section-6.5.8 | ||
196 | * | ||
229 | * Indicates that the request could not be processed because of conflict in the request, | 197 | * Indicates that the request could not be processed because of conflict in the request, |
230 | * such as an edit conflict between multiple simultaneous updates. | 198 | * such as an edit conflict between multiple simultaneous updates. |
231 | */ | 199 | */ |
@@ -284,11 +252,13 @@ export enum HttpStatusCode { | |||
284 | RANGE_NOT_SATISFIABLE_416 = 416, | 252 | RANGE_NOT_SATISFIABLE_416 = 416, |
285 | 253 | ||
286 | /** | 254 | /** |
287 | * The server cannot meet the requirements of the Expect request-header field. | 255 | * The server cannot meet the requirements of the `Expect` request-header field. |
288 | */ | 256 | */ |
289 | EXPECTATION_FAILED_417 = 417, | 257 | EXPECTATION_FAILED_417 = 417, |
290 | 258 | ||
291 | /** | 259 | /** |
260 | * Official Documentation @ https://tools.ietf.org/html/rfc2324 | ||
261 | * | ||
292 | * This code was defined in 1998 as one of the traditional IETF April Fools' jokes, in RFC 2324, Hyper Text Coffee Pot Control Protocol, | 262 | * This code was defined in 1998 as one of the traditional IETF April Fools' jokes, in RFC 2324, Hyper Text Coffee Pot Control Protocol, |
293 | * and is not expected to be implemented by actual HTTP servers. The RFC specifies this code should be returned by | 263 | * and is not expected to be implemented by actual HTTP servers. The RFC specifies this code should be returned by |
294 | * teapots requested to brew coffee. This HTTP status is used as an Easter egg in some websites, including PeerTube instances ;-). | 264 | * teapots requested to brew coffee. This HTTP status is used as an Easter egg in some websites, including PeerTube instances ;-). |
@@ -296,41 +266,26 @@ export enum HttpStatusCode { | |||
296 | I_AM_A_TEAPOT_418 = 418, | 266 | I_AM_A_TEAPOT_418 = 418, |
297 | 267 | ||
298 | /** | 268 | /** |
299 | * The request was directed at a server that is not able to produce a response (for example because a connection reuse). | ||
300 | */ | ||
301 | MISDIRECTED_REQUEST_421 = 421, | ||
302 | |||
303 | /** | ||
304 | * Official Documentation @ https://tools.ietf.org/html/rfc2518#section-10.3 | 269 | * Official Documentation @ https://tools.ietf.org/html/rfc2518#section-10.3 |
305 | * | 270 | * |
306 | * The request was well-formed but was unable to be followed due to semantic errors. | 271 | * The request was well-formed but was unable to be followed due to semantic errors. |
272 | * | ||
273 | * @see HttpStatusCode.UNSUPPORTED_MEDIA_TYPE_415 if the `Content-Type` was not supported. | ||
274 | * @see HttpStatusCode.BAD_REQUEST_400 if the request was not parsable (broken JSON, XML) | ||
307 | */ | 275 | */ |
308 | UNPROCESSABLE_ENTITY_422 = 422, | 276 | UNPROCESSABLE_ENTITY_422 = 422, |
309 | 277 | ||
310 | /** | 278 | /** |
311 | * The resource that is being accessed is locked. | 279 | * Official Documentation @ https://tools.ietf.org/html/rfc4918#section-11.3 |
280 | * | ||
281 | * The resource that is being accessed is locked. WebDAV-specific but used by some HTTP services. | ||
282 | * | ||
283 | * @deprecated use `If-Match` / `If-None-Match` instead | ||
284 | * @see {@link https://evertpot.com/http/423-locked} | ||
312 | */ | 285 | */ |
313 | LOCKED_423 = 423, | 286 | LOCKED_423 = 423, |
314 | 287 | ||
315 | /** | 288 | /** |
316 | * The request failed due to failure of a previous request (e.g., a PROPPATCH). | ||
317 | */ | ||
318 | FAILED_DEPENDENCY_424 = 424, | ||
319 | |||
320 | /** | ||
321 | * The client should switch to a different protocol such as TLS/1.0, given in the Upgrade header field. | ||
322 | */ | ||
323 | UPGRADE_REQUIRED_426 = 426, | ||
324 | |||
325 | /** | ||
326 | * The origin server requires the request to be conditional. | ||
327 | * Intended to prevent "the 'lost update' problem, where a client | ||
328 | * GETs a resource's state, modifies it, and PUTs it back to the server, | ||
329 | * when meanwhile a third party has modified the state on the server, leading to a conflict." | ||
330 | */ | ||
331 | PRECONDITION_REQUIRED_428 = 428, | ||
332 | |||
333 | /** | ||
334 | * Official Documentation @ https://tools.ietf.org/html/rfc6585#section-4 | 289 | * Official Documentation @ https://tools.ietf.org/html/rfc6585#section-4 |
335 | * | 290 | * |
336 | * The user has sent too many requests in a given amount of time. Intended for use with rate-limiting schemes. | 291 | * The user has sent too many requests in a given amount of time. Intended for use with rate-limiting schemes. |
@@ -359,6 +314,8 @@ export enum HttpStatusCode { | |||
359 | INTERNAL_SERVER_ERROR_500 = 500, | 314 | INTERNAL_SERVER_ERROR_500 = 500, |
360 | 315 | ||
361 | /** | 316 | /** |
317 | * Official Documentation @ https://tools.ietf.org/html/rfc7231#section-6.6.2 | ||
318 | * | ||
362 | * The server either does not recognize the request method, or it lacks the ability to fulfill the request. | 319 | * The server either does not recognize the request method, or it lacks the ability to fulfill the request. |
363 | * Usually this implies future availability (e.g., a new feature of a web-service API). | 320 | * Usually this implies future availability (e.g., a new feature of a web-service API). |
364 | */ | 321 | */ |
@@ -386,34 +343,14 @@ export enum HttpStatusCode { | |||
386 | HTTP_VERSION_NOT_SUPPORTED_505 = 505, | 343 | HTTP_VERSION_NOT_SUPPORTED_505 = 505, |
387 | 344 | ||
388 | /** | 345 | /** |
389 | * Transparent content negotiation for the request results in a circular reference. | ||
390 | */ | ||
391 | VARIANT_ALSO_NEGOTIATES_506 = 506, | ||
392 | |||
393 | /** | ||
394 | * Official Documentation @ https://tools.ietf.org/html/rfc2518#section-10.6 | 346 | * Official Documentation @ https://tools.ietf.org/html/rfc2518#section-10.6 |
395 | * | 347 | * |
396 | * The 507 (Insufficient Storage) status code means the method could not be performed on the resource because the | 348 | * The 507 (Insufficient Storage) status code means the method could not be performed on the resource because the |
397 | * server is unable to store the representation needed to successfully complete the request. This condition is | 349 | * server is unable to store the representation needed to successfully complete the request. This condition is |
398 | * considered to be temporary. If the request which received this status code was the result of a user action, | 350 | * considered to be temporary. If the request which received this status code was the result of a user action, |
399 | * the request MUST NOT be repeated until it is requested by a separate user action. | 351 | * the request MUST NOT be repeated until it is requested by a separate user action. |
352 | * | ||
353 | * @see HttpStatusCode.PAYLOAD_TOO_LARGE_413 for quota errors | ||
400 | */ | 354 | */ |
401 | INSUFFICIENT_STORAGE_507 = 507, | 355 | INSUFFICIENT_STORAGE_507 = 507, |
402 | |||
403 | /** | ||
404 | * The server detected an infinite loop while processing the request. | ||
405 | */ | ||
406 | LOOP_DETECTED_508 = 508, | ||
407 | |||
408 | /** | ||
409 | * Further extensions to the request are required for the server to fulfill it. | ||
410 | */ | ||
411 | NOT_EXTENDED_510 = 510, | ||
412 | |||
413 | /** | ||
414 | * The client needs to authenticate to gain network access. | ||
415 | * Intended for use by intercepting proxies used to control access to the network (e.g., "captive portals" used | ||
416 | * to require agreement to Terms of Service before granting full Internet access via a Wi-Fi hotspot). | ||
417 | */ | ||
418 | NETWORK_AUTHENTICATION_REQUIRED_511 = 511 | ||
419 | } | 356 | } |
diff --git a/shared/extra-utils/server/activitypub.ts b/shared/extra-utils/server/activitypub.ts index eccb198ca..cf967ed7d 100644 --- a/shared/extra-utils/server/activitypub.ts +++ b/shared/extra-utils/server/activitypub.ts | |||
@@ -1,6 +1,7 @@ | |||
1 | import * as request from 'supertest' | 1 | import * as request from 'supertest' |
2 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | ||
2 | 3 | ||
3 | function makeActivityPubGetRequest (url: string, path: string, expectedStatus = 200) { | 4 | function makeActivityPubGetRequest (url: string, path: string, expectedStatus = HttpStatusCode.OK_200) { |
4 | return request(url) | 5 | return request(url) |
5 | .get(path) | 6 | .get(path) |
6 | .set('Accept', 'application/activity+json,text/html;q=0.9,\\*/\\*;q=0.8') | 7 | .set('Accept', 'application/activity+json,text/html;q=0.9,\\*/\\*;q=0.8') |
diff --git a/shared/extra-utils/server/redundancy.ts b/shared/extra-utils/server/redundancy.ts index 3aca4ebfd..b83815a37 100644 --- a/shared/extra-utils/server/redundancy.ts +++ b/shared/extra-utils/server/redundancy.ts | |||
@@ -2,7 +2,13 @@ import { makeDeleteRequest, makeGetRequest, makePostBodyRequest, makePutBodyRequ | |||
2 | import { VideoRedundanciesTarget } from '@shared/models' | 2 | import { VideoRedundanciesTarget } from '@shared/models' |
3 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | 3 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' |
4 | 4 | ||
5 | function updateRedundancy (url: string, accessToken: string, host: string, redundancyAllowed: boolean, expectedStatus = 204) { | 5 | function updateRedundancy ( |
6 | url: string, | ||
7 | accessToken: string, | ||
8 | host: string, | ||
9 | redundancyAllowed: boolean, | ||
10 | expectedStatus = HttpStatusCode.NO_CONTENT_204 | ||
11 | ) { | ||
6 | const path = '/api/v1/server/redundancy/' + host | 12 | const path = '/api/v1/server/redundancy/' + host |
7 | 13 | ||
8 | return makePutBodyRequest({ | 14 | return makePutBodyRequest({ |
diff --git a/shared/extra-utils/users/login.ts b/shared/extra-utils/users/login.ts index 275bb0826..39e1a2747 100644 --- a/shared/extra-utils/users/login.ts +++ b/shared/extra-utils/users/login.ts | |||
@@ -2,12 +2,13 @@ import * as request from 'supertest' | |||
2 | 2 | ||
3 | import { ServerInfo } from '../server/servers' | 3 | import { ServerInfo } from '../server/servers' |
4 | import { getClient } from '../server/clients' | 4 | import { getClient } from '../server/clients' |
5 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | ||
5 | 6 | ||
6 | type Client = { id: string, secret: string } | 7 | type Client = { id: string, secret: string } |
7 | type User = { username: string, password: string } | 8 | type User = { username: string, password: string } |
8 | type Server = { url: string, client: Client, user: User } | 9 | type Server = { url: string, client: Client, user: User } |
9 | 10 | ||
10 | function login (url: string, client: Client, user: User, expectedStatus = 200) { | 11 | function login (url: string, client: Client, user: User, expectedStatus = HttpStatusCode.OK_200) { |
11 | const path = '/api/v1/users/token' | 12 | const path = '/api/v1/users/token' |
12 | 13 | ||
13 | const body = { | 14 | const body = { |
@@ -27,7 +28,7 @@ function login (url: string, client: Client, user: User, expectedStatus = 200) { | |||
27 | .expect(expectedStatus) | 28 | .expect(expectedStatus) |
28 | } | 29 | } |
29 | 30 | ||
30 | function logout (url: string, token: string, expectedStatus = 200) { | 31 | function logout (url: string, token: string, expectedStatus = HttpStatusCode.OK_200) { |
31 | const path = '/api/v1/users/revoke-token' | 32 | const path = '/api/v1/users/revoke-token' |
32 | 33 | ||
33 | return request(url) | 34 | return request(url) |
@@ -38,12 +39,12 @@ function logout (url: string, token: string, expectedStatus = 200) { | |||
38 | } | 39 | } |
39 | 40 | ||
40 | async function serverLogin (server: Server) { | 41 | async function serverLogin (server: Server) { |
41 | const res = await login(server.url, server.client, server.user, 200) | 42 | const res = await login(server.url, server.client, server.user, HttpStatusCode.OK_200) |
42 | 43 | ||
43 | return res.body.access_token as string | 44 | return res.body.access_token as string |
44 | } | 45 | } |
45 | 46 | ||
46 | function refreshToken (server: ServerInfo, refreshToken: string, expectedStatus = 200) { | 47 | function refreshToken (server: ServerInfo, refreshToken: string, expectedStatus = HttpStatusCode.OK_200) { |
47 | const path = '/api/v1/users/token' | 48 | const path = '/api/v1/users/token' |
48 | 49 | ||
49 | const body = { | 50 | const body = { |
@@ -61,7 +62,7 @@ function refreshToken (server: ServerInfo, refreshToken: string, expectedStatus | |||
61 | .expect(expectedStatus) | 62 | .expect(expectedStatus) |
62 | } | 63 | } |
63 | 64 | ||
64 | async function userLogin (server: Server, user: User, expectedStatus = 200) { | 65 | async function userLogin (server: Server, user: User, expectedStatus = HttpStatusCode.OK_200) { |
65 | const res = await login(server.url, server.client, user, expectedStatus) | 66 | const res = await login(server.url, server.client, user, expectedStatus) |
66 | 67 | ||
67 | return res.body.access_token as string | 68 | return res.body.access_token as string |
@@ -95,7 +96,7 @@ function setAccessTokensToServers (servers: ServerInfo[]) { | |||
95 | return Promise.all(tasks) | 96 | return Promise.all(tasks) |
96 | } | 97 | } |
97 | 98 | ||
98 | function loginUsingExternalToken (server: Server, username: string, externalAuthToken: string, expectedStatus = 200) { | 99 | function loginUsingExternalToken (server: Server, username: string, externalAuthToken: string, expectedStatus = HttpStatusCode.OK_200) { |
99 | const path = '/api/v1/users/token' | 100 | const path = '/api/v1/users/token' |
100 | 101 | ||
101 | const body = { | 102 | const body = { |
diff --git a/shared/extra-utils/videos/video-history.ts b/shared/extra-utils/videos/video-history.ts index 2d751cf14..0dd3afb24 100644 --- a/shared/extra-utils/videos/video-history.ts +++ b/shared/extra-utils/videos/video-history.ts | |||
@@ -1,7 +1,13 @@ | |||
1 | import { makeGetRequest, makePostBodyRequest, makePutBodyRequest } from '../requests/requests' | 1 | import { makeGetRequest, makePostBodyRequest, makePutBodyRequest } from '../requests/requests' |
2 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | 2 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' |
3 | 3 | ||
4 | function userWatchVideo (url: string, token: string, videoId: number | string, currentTime: number, statusCodeExpected = 204) { | 4 | function userWatchVideo ( |
5 | url: string, | ||
6 | token: string, | ||
7 | videoId: number | string, | ||
8 | currentTime: number, | ||
9 | statusCodeExpected = HttpStatusCode.NO_CONTENT_204 | ||
10 | ) { | ||
5 | const path = '/api/v1/videos/' + videoId + '/watching' | 11 | const path = '/api/v1/videos/' + videoId + '/watching' |
6 | const fields = { currentTime } | 12 | const fields = { currentTime } |
7 | 13 | ||
diff --git a/shared/extra-utils/videos/videos.ts b/shared/extra-utils/videos/videos.ts index a4b9d688e..a2438d712 100644 --- a/shared/extra-utils/videos/videos.ts +++ b/shared/extra-utils/videos/videos.ts | |||
@@ -155,7 +155,7 @@ function getVideosListWithToken (url: string, token: string, query: { nsfw?: boo | |||
155 | .set('Authorization', 'Bearer ' + token) | 155 | .set('Authorization', 'Bearer ' + token) |
156 | .query(immutableAssign(query, { sort: 'name' })) | 156 | .query(immutableAssign(query, { sort: 'name' })) |
157 | .set('Accept', 'application/json') | 157 | .set('Accept', 'application/json') |
158 | .expect(200) | 158 | .expect(HttpStatusCode.OK_200) |
159 | .expect('Content-Type', /json/) | 159 | .expect('Content-Type', /json/) |
160 | } | 160 | } |
161 | 161 | ||
@@ -166,7 +166,7 @@ function getLocalVideos (url: string) { | |||
166 | .get(path) | 166 | .get(path) |
167 | .query({ sort: 'name', filter: 'local' }) | 167 | .query({ sort: 'name', filter: 'local' }) |
168 | .set('Accept', 'application/json') | 168 | .set('Accept', 'application/json') |
169 | .expect(200) | 169 | .expect(HttpStatusCode.OK_200) |
170 | .expect('Content-Type', /json/) | 170 | .expect('Content-Type', /json/) |
171 | } | 171 | } |
172 | 172 | ||
diff --git a/support/doc/api/openapi.yaml b/support/doc/api/openapi.yaml index 2d6b4df27..ba420b4a9 100644 --- a/support/doc/api/openapi.yaml +++ b/support/doc/api/openapi.yaml | |||
@@ -1312,20 +1312,24 @@ paths: | |||
1312 | application/json: | 1312 | application/json: |
1313 | schema: | 1313 | schema: |
1314 | $ref: '#/components/schemas/VideoUploadResponse' | 1314 | $ref: '#/components/schemas/VideoUploadResponse' |
1315 | '400': | ||
1316 | description: invalid file field, schedule date or parameter | ||
1315 | '403': | 1317 | '403': |
1316 | description: user video quota is exceeded with this video | 1318 | description: video didn't pass upload filter |
1317 | '408': | 1319 | '408': |
1318 | description: upload has timed out | 1320 | description: upload has timed out |
1319 | '413': | 1321 | '413': |
1320 | description: video file too large | 1322 | description: video file too large, due to quota or max body size limit set by the reverse-proxy |
1321 | headers: | 1323 | headers: |
1322 | X-File-Maximum-Size: | 1324 | X-File-Maximum-Size: |
1323 | schema: | 1325 | schema: |
1324 | type: string | 1326 | type: string |
1325 | format: Nginx size | 1327 | format: Nginx size |
1326 | description: Maximum file size for the video | 1328 | description: Maximum file size for the video |
1329 | '415': | ||
1330 | description: video type unsupported | ||
1327 | '422': | 1331 | '422': |
1328 | description: invalid input file | 1332 | description: video unreadable |
1329 | requestBody: | 1333 | requestBody: |
1330 | content: | 1334 | content: |
1331 | multipart/form-data: | 1335 | multipart/form-data: |
@@ -1534,10 +1538,12 @@ paths: | |||
1534 | application/json: | 1538 | application/json: |
1535 | schema: | 1539 | schema: |
1536 | $ref: '#/components/schemas/VideoUploadResponse' | 1540 | $ref: '#/components/schemas/VideoUploadResponse' |
1537 | '409': | ||
1538 | description: HTTP or Torrent/magnetURI import not enabled | ||
1539 | '400': | 1541 | '400': |
1540 | description: '`magnetUri` or `targetUrl` or a torrent file missing' | 1542 | description: '`magnetUri` or `targetUrl` or a torrent file missing' |
1543 | '403': | ||
1544 | description: video didn't pass pre-import filter | ||
1545 | '409': | ||
1546 | description: HTTP or Torrent/magnetURI import not enabled | ||
1541 | 1547 | ||
1542 | /videos/live: | 1548 | /videos/live: |
1543 | post: | 1549 | post: |
@@ -3572,7 +3578,7 @@ components: | |||
3572 | name: name | 3578 | name: name |
3573 | in: path | 3579 | in: path |
3574 | required: true | 3580 | required: true |
3575 | description: The name of the account | 3581 | description: The username or handle of the account |
3576 | schema: | 3582 | schema: |
3577 | type: string | 3583 | type: string |
3578 | example: chocobozzz | chocobozzz@example.org | 3584 | example: chocobozzz | chocobozzz@example.org |
@@ -5175,7 +5181,7 @@ components: | |||
5175 | properties: | 5181 | properties: |
5176 | name: | 5182 | name: |
5177 | type: string | 5183 | type: string |
5178 | description: The name for the default channel | 5184 | description: The username for the default channel |
5179 | pattern: '/^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\\-_.:]+$/' | 5185 | pattern: '/^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\\-_.:]+$/' |
5180 | displayName: | 5186 | displayName: |
5181 | type: string | 5187 | type: string |