Remove ng2 file upload module

Unmaintained and we don't need it anymore with httpclient
This commit is contained in:
Chocobozzz 2017-09-14 17:06:31 +02:00
parent d5050d1e09
commit bfb3a98fac
20 changed files with 188 additions and 162 deletions

View File

@ -61,7 +61,6 @@
"intl": "^1.2.4", "intl": "^1.2.4",
"json-loader": "^0.5.4", "json-loader": "^0.5.4",
"ng-router-loader": "^2.0.0", "ng-router-loader": "^2.0.0",
"ng2-file-upload": "^1.1.4-2",
"ngc-webpack": "3.2.2", "ngc-webpack": "3.2.2",
"ngx-bootstrap": "1.9.1", "ngx-bootstrap": "1.9.1",
"ngx-chips": "1.5.3", "ngx-chips": "1.5.3",

View File

@ -98,7 +98,7 @@ export class FriendAddComponent implements OnInit {
setTimeout(() => this.router.navigate([ '/admin/friends/list' ]), 1000) setTimeout(() => this.router.navigate([ '/admin/friends/list' ]), 1000)
}, },
err => this.notificationsService.error('Error', err) err => this.notificationsService.error('Error', err.message)
) )
} }
) )

View File

@ -40,7 +40,7 @@ export class FriendListComponent implements OnInit {
this.loadData() this.loadData()
}, },
err => this.notificationsService.error('Error', err) err => this.notificationsService.error('Error', err.message)
) )
} }
) )
@ -59,7 +59,7 @@ export class FriendListComponent implements OnInit {
this.loadData() this.loadData()
}, },
err => this.notificationsService.error('Error', err) err => this.notificationsService.error('Error', err.message)
) )
} }
) )
@ -72,7 +72,7 @@ export class FriendListComponent implements OnInit {
this.friends = resultList.data this.friends = resultList.data
}, },
err => this.notificationsService.error('Error', err) err => this.notificationsService.error('Error', err.message)
) )
} }
} }

View File

@ -57,7 +57,7 @@ export class RequestSchedulersStatsComponent implements OnInit, OnDestroy {
this.requestService.getStats().subscribe( this.requestService.getStats().subscribe(
stats => this.stats = stats, stats => this.stats = stats,
err => this.notificationsService.error('Error', err) err => this.notificationsService.error('Error', err.message)
) )
} }

View File

@ -47,7 +47,7 @@ export class UserListComponent extends RestTable implements OnInit {
this.loadData() this.loadData()
}, },
err => this.notificationsService.error('Error', err) err => this.notificationsService.error('Error', err.message)
) )
} }
) )
@ -65,7 +65,7 @@ export class UserListComponent extends RestTable implements OnInit {
this.totalRecords = resultList.total this.totalRecords = resultList.total
}, },
err => this.notificationsService.error('Error', err) err => this.notificationsService.error('Error', err.message)
) )
} }
} }

View File

@ -40,7 +40,7 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
this.totalRecords = resultList.total this.totalRecords = resultList.total
}, },
err => this.notificationsService.error('Error', err) err => this.notificationsService.error('Error', err.message)
) )
} }
} }

View File

@ -31,8 +31,7 @@ export class AppComponent implements OnInit {
private authService: AuthService, private authService: AuthService,
private configService: ConfigService, private configService: ConfigService,
private userService: UserService, private userService: UserService,
private videoService: VideoService, private videoService: VideoService
viewContainerRef: ViewContainerRef
) {} ) {}
ngOnInit () { ngOnInit () {

View File

@ -44,3 +44,10 @@ export const VIDEO_TAGS = {
'maxlength': 'A tag should be less than 10 characters long.' 'maxlength': 'A tag should be less than 10 characters long.'
} }
} }
export const VIDEO_FILE = {
VALIDATORS: [ Validators.required ],
MESSAGES: {
'required': 'Video file is required.'
}
}

View File

@ -40,19 +40,29 @@ export class RestExtractor {
handleError (err: HttpErrorResponse) { handleError (err: HttpErrorResponse) {
let errorMessage let errorMessage
console.log(err)
if (err.error instanceof Error) { if (err.error instanceof Error) {
// A client-side or network error occurred. Handle it accordingly. // A client-side or network error occurred. Handle it accordingly.
errorMessage = err.error.message errorMessage = err.error.message
console.error('An error occurred:', errorMessage) console.error('An error occurred:', errorMessage)
} else if (err.status !== undefined) { } else if (err.status !== undefined) {
// The backend returned an unsuccessful response code. const body = err.error
// The response body may contain clues as to what went wrong, errorMessage = body.error
errorMessage = err.error
console.error(`Backend returned code ${err.status}, body was: ${errorMessage}`) console.error(`Backend returned code ${err.status}, body was: ${errorMessage}`)
} else { } else {
errorMessage = err errorMessage = err
} }
return Observable.throw(errorMessage) const errorObj = {
message: errorMessage,
status: undefined
}
if (err.status) {
errorObj.status = err.status
}
return Observable.throw(errorObj)
} }
} }

View File

@ -10,7 +10,6 @@ import { BsDropdownModule } from 'ngx-bootstrap/dropdown'
import { ProgressbarModule } from 'ngx-bootstrap/progressbar' import { ProgressbarModule } from 'ngx-bootstrap/progressbar'
import { PaginationModule } from 'ngx-bootstrap/pagination' import { PaginationModule } from 'ngx-bootstrap/pagination'
import { ModalModule } from 'ngx-bootstrap/modal' import { ModalModule } from 'ngx-bootstrap/modal'
import { FileUploadModule } from 'ng2-file-upload/ng2-file-upload'
import { DataTableModule, SharedModule as PrimeSharedModule } from 'primeng/primeng' import { DataTableModule, SharedModule as PrimeSharedModule } from 'primeng/primeng'
import { AUTH_INTERCEPTOR_PROVIDER } from './auth' import { AUTH_INTERCEPTOR_PROVIDER } from './auth'
@ -32,8 +31,6 @@ import { VideoAbuseService } from './video-abuse'
PaginationModule.forRoot(), PaginationModule.forRoot(),
ProgressbarModule.forRoot(), ProgressbarModule.forRoot(),
FileUploadModule,
DataTableModule, DataTableModule,
PrimeSharedModule PrimeSharedModule
], ],
@ -52,7 +49,6 @@ import { VideoAbuseService } from './video-abuse'
HttpClientModule, HttpClientModule,
BsDropdownModule, BsDropdownModule,
FileUploadModule,
ModalModule, ModalModule,
PaginationModule, PaginationModule,
ProgressbarModule, ProgressbarModule,

View File

@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'
import { Observable } from 'rxjs/Observable' import { Observable } from 'rxjs/Observable'
import 'rxjs/add/operator/catch' import 'rxjs/add/operator/catch'
import 'rxjs/add/operator/map' import 'rxjs/add/operator/map'
import { HttpClient, HttpParams } from '@angular/common/http' import { HttpClient, HttpParams, HttpRequest } from '@angular/common/http'
import { Search } from '../../shared' import { Search } from '../../shared'
import { SortField } from './sort-field.type' import { SortField } from './sort-field.type'
@ -14,13 +14,14 @@ import {
import { Video } from './video.model' import { Video } from './video.model'
import { VideoPagination } from './video-pagination.model' import { VideoPagination } from './video-pagination.model'
import { import {
UserVideoRate, VideoCreate,
VideoRateType, UserVideoRate,
VideoUpdate, VideoRateType,
VideoAbuseCreate, VideoUpdate,
UserVideoRateUpdate, VideoAbuseCreate,
Video as VideoServerModel, UserVideoRateUpdate,
ResultList Video as VideoServerModel,
ResultList
} from '../../../../../shared' } from '../../../../../shared'
@Injectable() @Injectable()
@ -73,6 +74,14 @@ export class VideoService {
.catch(this.restExtractor.handleError) .catch(this.restExtractor.handleError)
} }
// uploadVideo (video: VideoCreate) {
uploadVideo (video: any) {
const req = new HttpRequest('POST', `${VideoService.BASE_VIDEO_URL}/upload`, video, { reportProgress: true })
return this.authHttp.request(req)
.catch(this.restExtractor.handleError)
}
getVideos (videoPagination: VideoPagination, sort: SortField) { getVideos (videoPagination: VideoPagination, sort: SortField) {
const pagination = this.videoPaginationToRestPagination(videoPagination) const pagination = this.videoPaginationToRestPagination(videoPagination)

View File

@ -3,7 +3,7 @@
<h3>Upload a video</h3> <h3>Upload a video</h3>
<div *ngIf="error" class="alert alert-danger">{{ error }}</div> <div *ngIf="error !== undefined" class="alert alert-danger">{{ error }}</div>
<form novalidate [formGroup]="form"> <form novalidate [formGroup]="form">
<div class="form-group"> <div class="form-group">
@ -62,7 +62,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="tags" class="label-tags">Tags</label> <span class="little-information">(press enter to add the tag)</span> <label class="label-tags">Tags</label> <span class="little-information">(press enter to add the tag)</span>
<tag-input <tag-input
[ngModel]="tags" [validators]="tagValidators" [errorMessages]="tagValidatorsMessages" [ngModel]="tags" [validators]="tagValidators" [errorMessages]="tagValidatorsMessages"
formControlName="tags" maxItems="3" modelAsStrings="true" formControlName="tags" maxItems="3" modelAsStrings="true"
@ -71,25 +71,22 @@
<div class="form-group"> <div class="form-group">
<label for="videofile">File</label> <label for="videofile">File</label>
<div class="btn btn-default btn-file" [ngClass]="{ 'disabled': filename !== null }" > <div class="btn btn-default btn-file">
<span>Select the video...</span> <span>Select the video...</span>
<input <input #videofileInput type="file" name="videofile" id="videofile" (change)="fileChange($event)" />
type="file" name="videofile" id="videofile" <input type="hidden" name="videofileHidden" formControlName="videofile"/>
ng2FileSelect [uploader]="uploader" [disabled]="filename !== null"
(change)="fileChanged()"
>
</div> </div>
</div> </div>
<div class="file-to-upload"> <div class="file-to-upload">
<div class="file" *ngIf="uploader.queue.length > 0"> <div class="file" *ngIf="filename">
<span class="filename">{{ filename }}</span> <span class="filename">{{ filename }}</span>
<span class="glyphicon glyphicon-remove" (click)="removeFile()"></span> <span class="glyphicon glyphicon-remove" (click)="removeFile()"></span>
</div> </div>
</div> </div>
<div *ngIf="fileError" class="alert alert-danger"> <div *ngIf="formErrors.videofile" class="alert alert-danger">
{{ fileError }} {{ formErrors.videofile }}
</div> </div>
<div class="form-group"> <div class="form-group">
@ -105,7 +102,7 @@
</div> </div>
<div class="progress"> <div class="progress">
<progressbar [value]="uploader.progress" max="100"></progressbar> <progressbar [value]="progressPercent" max="100"></progressbar>
</div> </div>
<div class="form-group"> <div class="form-group">

View File

@ -1,11 +1,9 @@
import { Component, ElementRef, OnInit } from '@angular/core' import { Component, OnInit, ViewChild } from '@angular/core'
import { FormBuilder, FormGroup } from '@angular/forms' import { FormBuilder, FormGroup } from '@angular/forms'
import { Router } from '@angular/router' import { Router } from '@angular/router'
import { FileUploader } from 'ng2-file-upload/ng2-file-upload'
import { NotificationsService } from 'angular2-notifications' import { NotificationsService } from 'angular2-notifications'
import { AuthService } from '../../core'
import { import {
FormReactive, FormReactive,
VIDEO_NAME, VIDEO_NAME,
@ -17,6 +15,8 @@ import {
} from '../../shared' } from '../../shared'
import { VideoService } from '../shared' import { VideoService } from '../shared'
import { VideoCreate } from '../../../../../shared' import { VideoCreate } from '../../../../../shared'
import { HttpEventType, HttpResponse } from '@angular/common/http'
import { VIDEO_FILE } from '../../shared/forms/form-validators/video'
@Component({ @Component({
selector: 'my-videos-add', selector: 'my-videos-add',
@ -25,8 +25,10 @@ import { VideoCreate } from '../../../../../shared'
}) })
export class VideoAddComponent extends FormReactive implements OnInit { export class VideoAddComponent extends FormReactive implements OnInit {
@ViewChild('videofileInput') videofileInput
progressPercent = 0
tags: string[] = [] tags: string[] = []
uploader: FileUploader
videoCategories = [] videoCategories = []
videoLicences = [] videoLicences = []
videoLanguages = [] videoLanguages = []
@ -34,29 +36,26 @@ export class VideoAddComponent extends FormReactive implements OnInit {
tagValidators = VIDEO_TAGS.VALIDATORS tagValidators = VIDEO_TAGS.VALIDATORS
tagValidatorsMessages = VIDEO_TAGS.MESSAGES tagValidatorsMessages = VIDEO_TAGS.MESSAGES
error: string = null error: string
form: FormGroup form: FormGroup
formErrors = { formErrors = {
name: '', name: '',
category: '', category: '',
licence: '', licence: '',
language: '', language: '',
description: '' description: '',
videofile: ''
} }
validationMessages = { validationMessages = {
name: VIDEO_NAME.MESSAGES, name: VIDEO_NAME.MESSAGES,
category: VIDEO_CATEGORY.MESSAGES, category: VIDEO_CATEGORY.MESSAGES,
licence: VIDEO_LICENCE.MESSAGES, licence: VIDEO_LICENCE.MESSAGES,
language: VIDEO_LANGUAGE.MESSAGES, language: VIDEO_LANGUAGE.MESSAGES,
description: VIDEO_DESCRIPTION.MESSAGES description: VIDEO_DESCRIPTION.MESSAGES,
videofile: VIDEO_FILE.MESSAGES
} }
// Special error messages
fileError = ''
constructor ( constructor (
private authService: AuthService,
private elementRef: ElementRef,
private formBuilder: FormBuilder, private formBuilder: FormBuilder,
private router: Router, private router: Router,
private notificationsService: NotificationsService, private notificationsService: NotificationsService,
@ -66,11 +65,7 @@ export class VideoAddComponent extends FormReactive implements OnInit {
} }
get filename () { get filename () {
if (this.uploader.queue.length === 0) { return this.form.value['videofile']
return null
}
return this.uploader.queue[0].file.name
} }
buildForm () { buildForm () {
@ -81,7 +76,8 @@ export class VideoAddComponent extends FormReactive implements OnInit {
licence: [ '', VIDEO_LICENCE.VALIDATORS ], licence: [ '', VIDEO_LICENCE.VALIDATORS ],
language: [ '', VIDEO_LANGUAGE.VALIDATORS ], language: [ '', VIDEO_LANGUAGE.VALIDATORS ],
description: [ '', VIDEO_DESCRIPTION.VALIDATORS ], description: [ '', VIDEO_DESCRIPTION.VALIDATORS ],
tags: [ ''] videofile: [ '', VIDEO_FILE.VALIDATORS ],
tags: [ '' ]
}) })
this.form.valueChanges.subscribe(data => this.onValueChanged(data)) this.form.valueChanges.subscribe(data => this.onValueChanged(data))
@ -92,14 +88,31 @@ export class VideoAddComponent extends FormReactive implements OnInit {
this.videoLicences = this.videoService.videoLicences this.videoLicences = this.videoService.videoLicences
this.videoLanguages = this.videoService.videoLanguages this.videoLanguages = this.videoService.videoLanguages
this.uploader = new FileUploader({ this.buildForm()
authToken: this.authService.getRequestHeaderValue(), }
queueLimit: 1,
url: API_URL + '/api/v1/videos/upload', // The goal is to keep reactive form validation (required field)
removeAfterUpload: true // https://stackoverflow.com/a/44238894
}) fileChange ($event) {
this.form.controls['videofile'].setValue($event.target.files[0].name)
}
removeFile () {
this.videofileInput.nativeElement.value = ''
this.form.controls['videofile'].setValue('')
}
checkForm () {
this.forceCheck()
return this.form.valid
}
upload () {
if (this.checkForm() === false) {
return
}
this.uploader.onBuildItemForm = (item, form: FormData) => {
const formValue: VideoCreate = this.form.value const formValue: VideoCreate = this.form.value
const name = formValue.name const name = formValue.name
@ -109,83 +122,40 @@ export class VideoAddComponent extends FormReactive implements OnInit {
const language = formValue.language const language = formValue.language
const description = formValue.description const description = formValue.description
const tags = formValue.tags const tags = formValue.tags
const videofile = this.videofileInput.nativeElement.files[0]
form.append('name', name) const formData = new FormData()
form.append('category', '' + category) formData.append('name', name)
form.append('nsfw', '' + nsfw) formData.append('category', '' + category)
form.append('licence', '' + licence) formData.append('nsfw', '' + nsfw)
formData.append('licence', '' + licence)
formData.append('videofile', videofile)
// Language is optional // Language is optional
if (language) { if (language) {
form.append('language', '' + language) formData.append('language', '' + language)
} }
form.append('description', description) formData.append('description', description)
for (let i = 0; i < tags.length; i++) { for (let i = 0; i < tags.length; i++) {
form.append(`tags[${i}]`, tags[i]) formData.append(`tags[${i}]`, tags[i])
}
} }
this.buildForm() this.videoService.uploadVideo(formData).subscribe(
} event => {
if (event.type === HttpEventType.UploadProgress) {
checkForm () { this.progressPercent = Math.round(100 * event.loaded / event.total)
this.forceCheck() } else if (event instanceof HttpResponse) {
if (this.filename === null) {
this.fileError = 'You did not add a file.'
}
return this.form.valid === true && this.fileError === ''
}
fileChanged () {
this.fileError = ''
}
removeFile () {
this.uploader.clearQueue()
}
upload () {
if (this.checkForm() === false) {
return
}
const item = this.uploader.queue[0]
// TODO: wait for https://github.com/valor-software/ng2-file-upload/pull/242
item.alias = 'videofile'
item.onSuccess = () => {
console.log('Video uploaded.') console.log('Video uploaded.')
this.notificationsService.success('Success', 'Video uploaded.') this.notificationsService.success('Success', 'Video uploaded.')
// Print all the videos once it's finished // Display all the videos once it's finished
this.router.navigate(['/videos/list']) this.router.navigate([ '/videos/list '])
} }
},
item.onError = (response: string, status: number) => { err => this.error = err.message
// We need to handle manually these cases because we use the FileUpload component
if (status === 400) {
this.error = response
} else if (status === 401) {
this.error = 'Access token was expired, refreshing token...'
this.authService.refreshAccessToken().subscribe(
() => {
// Update the uploader request header
this.uploader.authToken = this.authService.getRequestHeaderValue()
this.error += ' access token refreshed. Please retry your request.'
}
) )
} else if (status === 403) {
this.error = 'Your video quota is reached, you can\'t upload this video.'
} else {
this.error = 'Unknown error'
console.error(this.error)
}
}
this.uploader.uploadAll()
} }
} }

View File

@ -2,7 +2,6 @@ import { Component, ElementRef, OnInit } from '@angular/core'
import { FormBuilder, FormGroup } from '@angular/forms' import { FormBuilder, FormGroup } from '@angular/forms'
import { ActivatedRoute, Router } from '@angular/router' import { ActivatedRoute, Router } from '@angular/router'
import { FileUploader } from 'ng2-file-upload/ng2-file-upload'
import { NotificationsService } from 'angular2-notifications' import { NotificationsService } from 'angular2-notifications'
import { AuthService } from '../../core' import { AuthService } from '../../core'

View File

@ -63,7 +63,7 @@ export class VideoReportComponent extends FormReactive implements OnInit {
this.hide() this.hide()
}, },
err => this.notificationsService.error('Error', err) err => this.notificationsService.error('Error', err.message)
) )
} }
} }

View File

@ -158,7 +158,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
this.userRating = 'like' this.userRating = 'like'
}, },
err => this.notificationsService.error('Error', err) err => this.notificationsService.error('Error', err.message)
) )
} }
@ -175,7 +175,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
this.userRating = 'dislike' this.userRating = 'dislike'
}, },
err => this.notificationsService.error('Error', err) err => this.notificationsService.error('Error', err.message)
) )
} }
@ -275,7 +275,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
} }
}, },
err => this.notificationsService.error('Error', err) err => this.notificationsService.error('Error', err.message)
) )
} }

View File

@ -4436,10 +4436,6 @@ ng-router-loader@^2.0.0:
loader-utils "^0.2.16" loader-utils "^0.2.16"
recast "^0.11.20" recast "^0.11.20"
ng2-file-upload@^1.1.4-2:
version "1.2.1"
resolved "https://registry.yarnpkg.com/ng2-file-upload/-/ng2-file-upload-1.2.1.tgz#5563c5dfd6f43fbfbe815c206e343464a0a6a197"
ng2-material-dropdown@0.7.10: ng2-material-dropdown@0.7.10:
version "0.7.10" version "0.7.10"
resolved "https://registry.yarnpkg.com/ng2-material-dropdown/-/ng2-material-dropdown-0.7.10.tgz#093471f2a9cadd726cbcb120b0ad7818a54fa5ed" resolved "https://registry.yarnpkg.com/ng2-material-dropdown/-/ng2-material-dropdown-0.7.10.tgz#093471f2a9cadd726cbcb120b0ad7818a54fa5ed"

View File

@ -11,7 +11,11 @@ import { isTestInstance } from '../../helpers'
function makeFriendsValidator (req: express.Request, res: express.Response, next: express.NextFunction) { function makeFriendsValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
// Force https if the administrator wants to make friends // Force https if the administrator wants to make friends
if (isTestInstance() === false && CONFIG.WEBSERVER.SCHEME === 'http') { if (isTestInstance() === false && CONFIG.WEBSERVER.SCHEME === 'http') {
return res.status(400).send('Cannot make friends with a non HTTPS web server.') return res.status(400)
.json({
error: 'Cannot make friends with a non HTTPS web server.'
})
.end()
} }
req.checkBody('hosts', 'Should have an array of unique hosts').isEachUniqueHostValid() req.checkBody('hosts', 'Should have an array of unique hosts').isEachUniqueHostValid()

View File

@ -45,9 +45,13 @@ function usersRemoveValidator (req: express.Request, res: express.Response, next
return res.sendStatus(500) return res.sendStatus(500)
} }
if (user.username === 'root') return res.status(400).send('Cannot remove the root user') if (user.username === 'root') {
return res.status(400)
.send({ error: 'Cannot remove the root user' })
.end()
}
next() return next()
}) })
}) })
} }
@ -99,9 +103,13 @@ function usersVideoRatingValidator (req: express.Request, res: express.Response,
videoPromise videoPromise
.then(video => { .then(video => {
if (!video) return res.status(404).send('Video not found') if (!video) {
return res.status(404)
.json({ error: 'Video not found' })
.end()
}
next() return next()
}) })
.catch(err => { .catch(err => {
logger.error('Error in user request validator.', err) logger.error('Error in user request validator.', err)
@ -113,7 +121,9 @@ function usersVideoRatingValidator (req: express.Request, res: express.Response,
function ensureUserRegistrationAllowed (req: express.Request, res: express.Response, next: express.NextFunction) { function ensureUserRegistrationAllowed (req: express.Request, res: express.Response, next: express.NextFunction) {
isSignupAllowed().then(allowed => { isSignupAllowed().then(allowed => {
if (allowed === false) { if (allowed === false) {
return res.status(403).send('User registration is not enabled or user limit is reached.') return res.status(403)
.send({ error: 'User registration is not enabled or user limit is reached.' })
.end()
} }
return next() return next()
@ -138,10 +148,14 @@ export {
function checkUserExists (id: number, res: express.Response, callback: (err: Error, user: UserInstance) => void) { function checkUserExists (id: number, res: express.Response, callback: (err: Error, user: UserInstance) => void) {
db.User.loadById(id) db.User.loadById(id)
.then(user => { .then(user => {
if (!user) return res.status(404).send('User not found') if (!user) {
return res.status(404)
.send({ error: 'User not found' })
.end()
}
res.locals.user = user res.locals.user = user
callback(null, user) return callback(null, user)
}) })
.catch(err => { .catch(err => {
logger.error('Error in user request validator.', err) logger.error('Error in user request validator.', err)
@ -152,9 +166,13 @@ function checkUserExists (id: number, res: express.Response, callback: (err: Err
function checkUserDoesNotAlreadyExist (username: string, email: string, res: express.Response, callback: () => void) { function checkUserDoesNotAlreadyExist (username: string, email: string, res: express.Response, callback: () => void) {
db.User.loadByUsernameOrEmail(username, email) db.User.loadByUsernameOrEmail(username, email)
.then(user => { .then(user => {
if (user) return res.status(409).send('User already exists.') if (user) {
return res.status(409)
.send({ error: 'User already exists.' })
.end()
}
callback() return callback()
}) })
.catch(err => { .catch(err => {
logger.error('Error in usersAdd request validator.', err) logger.error('Error in usersAdd request validator.', err)

View File

@ -30,7 +30,9 @@ function videosAddValidator (req: express.Request, res: express.Response, next:
user.isAbleToUploadVideo(videoFile) user.isAbleToUploadVideo(videoFile)
.then(isAble => { .then(isAble => {
if (isAble === false) { if (isAble === false) {
res.status(403).send('The user video quota is exceeded with this video.') res.status(403)
.json({ error: 'The user video quota is exceeded with this video.' })
.end()
return undefined return undefined
} }
@ -38,17 +40,23 @@ function videosAddValidator (req: express.Request, res: express.Response, next:
return db.Video.getDurationFromFile(videoFile.path) return db.Video.getDurationFromFile(videoFile.path)
.catch(err => { .catch(err => {
logger.error('Invalid input file in videosAddValidator.', err) logger.error('Invalid input file in videosAddValidator.', err)
res.status(400).send('Invalid input file.') res.status(400)
.json({ error: 'Invalid input file.' })
.end()
return undefined return undefined
}) })
}) })
.then(duration => { .then(duration => {
// Previous test failed, abort // Previous test failed, abort
if (duration === undefined) return undefined if (duration === undefined) return
if (!isVideoDurationValid('' + duration)) { if (!isVideoDurationValid('' + duration)) {
return res.status(400).send('Duration of the video file is too big (max: ' + CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).') return res.status(400)
.json({
error: 'Duration of the video file is too big (max: ' + CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).'
})
.end()
} }
videoFile['duration'] = duration videoFile['duration'] = duration
@ -80,11 +88,15 @@ function videosUpdateValidator (req: express.Request, res: express.Response, nex
checkVideoExists(req.params.id, res, () => { checkVideoExists(req.params.id, res, () => {
// We need to make additional checks // We need to make additional checks
if (res.locals.video.isOwned() === false) { if (res.locals.video.isOwned() === false) {
return res.status(403).send('Cannot update video of another pod') return res.status(403)
.json({ error: 'Cannot update video of another pod' })
.end()
} }
if (res.locals.video.Author.userId !== res.locals.oauth.token.User.id) { if (res.locals.video.Author.userId !== res.locals.oauth.token.User.id) {
return res.status(403).send('Cannot update video of another user') return res.status(403)
.json({ error: 'Cannot update video of another user' })
.end()
} }
next() next()
@ -188,7 +200,11 @@ function checkVideoExists (id: string, res: express.Response, callback: () => vo
} }
promise.then(video => { promise.then(video => {
if (!video) return res.status(404).send('Video not found') if (!video) {
return res.status(404)
.json({ error: 'Video not found' })
.end()
}
res.locals.video = video res.locals.video = video
callback() callback()
@ -204,14 +220,18 @@ function checkUserCanDeleteVideo (userId: number, res: express.Response, callbac
db.User.loadById(userId) db.User.loadById(userId)
.then(user => { .then(user => {
if (res.locals.video.isOwned() === false) { if (res.locals.video.isOwned() === false) {
return res.status(403).send('Cannot remove video of another pod, blacklist it') return res.status(403)
.json({ error: 'Cannot remove video of another pod, blacklist it' })
.end()
} }
// Check if the user can delete the video // Check if the user can delete the video
// The user can delete it if s/he is an admin // The user can delete it if s/he is an admin
// Or if s/he is the video's author // Or if s/he is the video's author
if (user.isAdmin() === false && res.locals.video.Author.userId !== res.locals.oauth.token.User.id) { if (user.isAdmin() === false && res.locals.video.Author.userId !== res.locals.oauth.token.User.id) {
return res.status(403).send('Cannot remove video of another user') return res.status(403)
.json({ error: 'Cannot remove video of another user' })
.end()
} }
// If we reach this comment, we can delete the video // If we reach this comment, we can delete the video
@ -225,7 +245,9 @@ function checkUserCanDeleteVideo (userId: number, res: express.Response, callbac
function checkVideoIsBlacklistable (req: express.Request, res: express.Response, callback: () => void) { function checkVideoIsBlacklistable (req: express.Request, res: express.Response, callback: () => void) {
if (res.locals.video.isOwned() === true) { if (res.locals.video.isOwned() === true) {
return res.status(403).send('Cannot blacklist a local video') return res.status(403)
.json({ error: 'Cannot blacklist a local video' })
.end()
} }
callback() callback()