Fix images size limit
This commit is contained in:
parent
c4082b8b4e
commit
0c237b19fd
|
@ -50,6 +50,10 @@ export class MyAccountSettingsComponent implements OnInit {
|
||||||
|
|
||||||
changeAvatar () {
|
changeAvatar () {
|
||||||
const avatarfile = this.avatarfileInput.nativeElement.files[ 0 ]
|
const avatarfile = this.avatarfileInput.nativeElement.files[ 0 ]
|
||||||
|
if (avatarfile.size > this.maxAvatarSize) {
|
||||||
|
this.notificationsService.error('Error', 'This image is too large.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('avatarfile', avatarfile)
|
formData.append('avatarfile', avatarfile)
|
||||||
|
@ -59,7 +63,7 @@ export class MyAccountSettingsComponent implements OnInit {
|
||||||
data => {
|
data => {
|
||||||
this.notificationsService.success(this.i18n('Success'), this.i18n('Avatar changed.'))
|
this.notificationsService.success(this.i18n('Success'), this.i18n('Avatar changed.'))
|
||||||
|
|
||||||
this.user.account.avatar = data.avatar
|
this.user.updateAccountAvatar(data.avatar)
|
||||||
},
|
},
|
||||||
|
|
||||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
import { NSFWPolicyType } from '../../../../../shared/models/videos/nsfw-policy.type'
|
import { NSFWPolicyType } from '../../../../../shared/models/videos/nsfw-policy.type'
|
||||||
import { Actor } from '@app/shared/actor/actor.model'
|
import { Actor } from '@app/shared/actor/actor.model'
|
||||||
import { Account } from '@app/shared/account/account.model'
|
import { Account } from '@app/shared/account/account.model'
|
||||||
|
import { Avatar } from '../../../../../shared/models/avatars/avatar.model'
|
||||||
|
|
||||||
export type UserConstructorHash = {
|
export type UserConstructorHash = {
|
||||||
id: number,
|
id: number,
|
||||||
|
@ -84,6 +85,12 @@ export class User implements UserServerModel {
|
||||||
this.updateComputedAttributes()
|
this.updateComputedAttributes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateAccountAvatar (newAccountAvatar: Avatar) {
|
||||||
|
this.account.avatar = newAccountAvatar
|
||||||
|
|
||||||
|
this.updateComputedAttributes()
|
||||||
|
}
|
||||||
|
|
||||||
private updateComputedAttributes () {
|
private updateComputedAttributes () {
|
||||||
this.accountAvatarUrl = Actor.GET_ACTOR_AVATAR_URL(this.account)
|
this.accountAvatarUrl = Actor.GET_ACTOR_AVATAR_URL(this.account)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ import { Component, forwardRef, Input } from '@angular/core'
|
||||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
|
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
|
||||||
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'
|
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'
|
||||||
import { ServerService } from '@app/core'
|
import { ServerService } from '@app/core'
|
||||||
|
import { NotificationsService } from 'angular2-notifications'
|
||||||
|
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-video-image',
|
selector: 'my-video-image',
|
||||||
|
@ -27,7 +29,9 @@ export class VideoImageComponent implements ControlValueAccessor {
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private sanitizer: DomSanitizer,
|
private sanitizer: DomSanitizer,
|
||||||
private serverService: ServerService
|
private serverService: ServerService,
|
||||||
|
private notificationsService: NotificationsService,
|
||||||
|
private i18n: I18n
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
get videoImageExtensions () {
|
get videoImageExtensions () {
|
||||||
|
@ -42,6 +46,11 @@ export class VideoImageComponent implements ControlValueAccessor {
|
||||||
if (event.target.files && event.target.files.length) {
|
if (event.target.files && event.target.files.length) {
|
||||||
const [ file ] = event.target.files
|
const [ file ] = event.target.files
|
||||||
|
|
||||||
|
if (file.size > this.maxVideoImageSize) {
|
||||||
|
this.notificationsService.error(this.i18n('Error'), this.i18n('This image is too large.'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
this.file = file
|
this.file = file
|
||||||
this.propagateChange(this.file)
|
this.propagateChange(this.file)
|
||||||
this.updatePreview()
|
this.updatePreview()
|
||||||
|
|
|
@ -45,6 +45,7 @@ function isFileValid (
|
||||||
files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[],
|
files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[],
|
||||||
mimeTypeRegex: string,
|
mimeTypeRegex: string,
|
||||||
field: string,
|
field: string,
|
||||||
|
maxSize: number,
|
||||||
optional = false
|
optional = false
|
||||||
) {
|
) {
|
||||||
// Should have files
|
// Should have files
|
||||||
|
@ -61,6 +62,9 @@ function isFileValid (
|
||||||
const file = fileArray[ 0 ]
|
const file = fileArray[ 0 ]
|
||||||
if (!file || !file.originalname) return false
|
if (!file || !file.originalname) return false
|
||||||
|
|
||||||
|
// Check size
|
||||||
|
if (maxSize && file.size > maxSize) return false
|
||||||
|
|
||||||
return new RegExp(`^${mimeTypeRegex}$`, 'i').test(file.mimetype)
|
return new RegExp(`^${mimeTypeRegex}$`, 'i').test(file.mimetype)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import 'express-validator'
|
||||||
import * as validator from 'validator'
|
import * as validator from 'validator'
|
||||||
import { UserRole } from '../../../shared'
|
import { UserRole } from '../../../shared'
|
||||||
import { CONSTRAINTS_FIELDS, NSFW_POLICY_TYPES } from '../../initializers'
|
import { CONSTRAINTS_FIELDS, NSFW_POLICY_TYPES } from '../../initializers'
|
||||||
|
|
||||||
import { exists, isFileValid } from './misc'
|
import { exists, isFileValid } from './misc'
|
||||||
import { values } from 'lodash'
|
import { values } from 'lodash'
|
||||||
|
|
||||||
|
@ -52,7 +51,7 @@ const avatarMimeTypes = CONSTRAINTS_FIELDS.ACTORS.AVATAR.EXTNAME
|
||||||
.join('|')
|
.join('|')
|
||||||
const avatarMimeTypesRegex = `image/(${avatarMimeTypes})`
|
const avatarMimeTypesRegex = `image/(${avatarMimeTypes})`
|
||||||
function isAvatarFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
|
function isAvatarFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
|
||||||
return isFileValid(files, avatarMimeTypesRegex, 'avatarfile')
|
return isFileValid(files, avatarMimeTypesRegex, 'avatarfile', CONSTRAINTS_FIELDS.ACTORS.AVATAR.FILE_SIZE.max)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
|
@ -86,7 +86,7 @@ const videoFileTypes = Object.keys(VIDEO_MIMETYPE_EXT).map(m => `(${m})`)
|
||||||
const videoFileTypesRegex = videoFileTypes.join('|')
|
const videoFileTypesRegex = videoFileTypes.join('|')
|
||||||
|
|
||||||
function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
|
function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
|
||||||
return isFileValid(files, videoFileTypesRegex, 'videofile')
|
return isFileValid(files, videoFileTypesRegex, 'videofile', null)
|
||||||
}
|
}
|
||||||
|
|
||||||
const videoImageTypes = CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME
|
const videoImageTypes = CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME
|
||||||
|
@ -95,7 +95,7 @@ const videoImageTypes = CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME
|
||||||
const videoImageTypesRegex = `image/(${videoImageTypes})`
|
const videoImageTypesRegex = `image/(${videoImageTypes})`
|
||||||
|
|
||||||
function isVideoImage (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], field: string) {
|
function isVideoImage (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], field: string) {
|
||||||
return isFileValid(files, videoImageTypesRegex, field, true)
|
return isFileValid(files, videoImageTypesRegex, field, CONSTRAINTS_FIELDS.VIDEOS.IMAGE.FILE_SIZE.max, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
function isVideoPrivacyValid (value: number) {
|
function isVideoPrivacyValid (value: number) {
|
||||||
|
|
|
@ -118,7 +118,7 @@ const usersUpdateMeValidator = [
|
||||||
|
|
||||||
const usersUpdateMyAvatarValidator = [
|
const usersUpdateMyAvatarValidator = [
|
||||||
body('avatarfile').custom((value, { req }) => isAvatarFile(req.files)).withMessage(
|
body('avatarfile').custom((value, { req }) => isAvatarFile(req.files)).withMessage(
|
||||||
'This file is not supported. Please, make sure it is of the following type : '
|
'This file is not supported or too large. Please, make sure it is of the following type : '
|
||||||
+ CONSTRAINTS_FIELDS.ACTORS.AVATAR.EXTNAME.join(', ')
|
+ CONSTRAINTS_FIELDS.ACTORS.AVATAR.EXTNAME.join(', ')
|
||||||
),
|
),
|
||||||
|
|
||||||
|
@ -127,14 +127,6 @@ const usersUpdateMyAvatarValidator = [
|
||||||
|
|
||||||
if (areValidationErrors(req, res)) return
|
if (areValidationErrors(req, res)) return
|
||||||
|
|
||||||
const imageFile = req.files['avatarfile'][0] as Express.Multer.File
|
|
||||||
if (imageFile.size > CONSTRAINTS_FIELDS.ACTORS.AVATAR.FILE_SIZE.max) {
|
|
||||||
res.status(400)
|
|
||||||
.send({ error: `The size of the avatar is too big (>${CONSTRAINTS_FIELDS.ACTORS.AVATAR.FILE_SIZE.max}).` })
|
|
||||||
.end()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -38,18 +38,21 @@ import { authenticate } from '../oauth'
|
||||||
import { areValidationErrors } from './utils'
|
import { areValidationErrors } from './utils'
|
||||||
|
|
||||||
const videosAddValidator = [
|
const videosAddValidator = [
|
||||||
body('videofile').custom((value, { req }) => isVideoFile(req.files)).withMessage(
|
body('videofile')
|
||||||
'This file is not supported. Please, make sure it is of the following type : '
|
.custom((value, { req }) => isVideoFile(req.files)).withMessage(
|
||||||
+ CONSTRAINTS_FIELDS.VIDEOS.EXTNAME.join(', ')
|
'This file is not supported or too large. Please, make sure it is of the following type : '
|
||||||
),
|
+ CONSTRAINTS_FIELDS.VIDEOS.EXTNAME.join(', ')
|
||||||
body('thumbnailfile').custom((value, { req }) => isVideoImage(req.files, 'thumbnailfile')).withMessage(
|
),
|
||||||
'This thumbnail file is not supported. Please, make sure it is of the following type : '
|
body('thumbnailfile')
|
||||||
+ CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME.join(', ')
|
.custom((value, { req }) => isVideoImage(req.files, 'thumbnailfile')).withMessage(
|
||||||
),
|
'This thumbnail file is not supported or too large. Please, make sure it is of the following type : '
|
||||||
body('previewfile').custom((value, { req }) => isVideoImage(req.files, 'previewfile')).withMessage(
|
+ CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME.join(', ')
|
||||||
'This preview file is not supported. Please, make sure it is of the following type : '
|
),
|
||||||
+ CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME.join(', ')
|
body('previewfile')
|
||||||
),
|
.custom((value, { req }) => isVideoImage(req.files, 'previewfile')).withMessage(
|
||||||
|
'This preview file is not supported or too large. Please, make sure it is of the following type : '
|
||||||
|
+ CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME.join(', ')
|
||||||
|
),
|
||||||
body('name').custom(isVideoNameValid).withMessage('Should have a valid name'),
|
body('name').custom(isVideoNameValid).withMessage('Should have a valid name'),
|
||||||
body('category')
|
body('category')
|
||||||
.optional()
|
.optional()
|
||||||
|
@ -147,14 +150,16 @@ const videosAddValidator = [
|
||||||
|
|
||||||
const videosUpdateValidator = [
|
const videosUpdateValidator = [
|
||||||
param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
|
param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
|
||||||
body('thumbnailfile').custom((value, { req }) => isVideoImage(req.files, 'thumbnailfile')).withMessage(
|
body('thumbnailfile')
|
||||||
'This thumbnail file is not supported. Please, make sure it is of the following type : '
|
.custom((value, { req }) => isVideoImage(req.files, 'thumbnailfile')).withMessage(
|
||||||
+ CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME.join(', ')
|
'This thumbnail file is not supported or too large. Please, make sure it is of the following type : '
|
||||||
),
|
+ CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME.join(', ')
|
||||||
body('previewfile').custom((value, { req }) => isVideoImage(req.files, 'previewfile')).withMessage(
|
),
|
||||||
'This preview file is not supported. Please, make sure it is of the following type : '
|
body('previewfile')
|
||||||
+ CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME.join(', ')
|
.custom((value, { req }) => isVideoImage(req.files, 'previewfile')).withMessage(
|
||||||
),
|
'This preview file is not supported or too large. Please, make sure it is of the following type : '
|
||||||
|
+ CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME.join(', ')
|
||||||
|
),
|
||||||
body('name')
|
body('name')
|
||||||
.optional()
|
.optional()
|
||||||
.custom(isVideoNameValid).withMessage('Should have a valid name'),
|
.custom(isVideoNameValid).withMessage('Should have a valid name'),
|
||||||
|
|
|
@ -326,7 +326,7 @@ describe('Test videos API validator', function () {
|
||||||
const fields = baseCorrectParams
|
const fields = baseCorrectParams
|
||||||
const attaches = {
|
const attaches = {
|
||||||
'thumbnailfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png'),
|
'thumbnailfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png'),
|
||||||
'videofile': join(__dirname, '..', '..', 'fixtures', 'video_short_fake.webm')
|
'videofile': join(__dirname, '..', '..', 'fixtures', 'video_short.mp4')
|
||||||
}
|
}
|
||||||
|
|
||||||
await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
||||||
|
@ -336,7 +336,7 @@ describe('Test videos API validator', function () {
|
||||||
const fields = baseCorrectParams
|
const fields = baseCorrectParams
|
||||||
const attaches = {
|
const attaches = {
|
||||||
'thumbnailfile': join(__dirname, '..', '..', 'fixtures', 'avatar-big.png'),
|
'thumbnailfile': join(__dirname, '..', '..', 'fixtures', 'avatar-big.png'),
|
||||||
'videofile': join(__dirname, '..', '..', 'fixtures', 'video_short_fake.webm')
|
'videofile': join(__dirname, '..', '..', 'fixtures', 'video_short.mp4')
|
||||||
}
|
}
|
||||||
|
|
||||||
await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
||||||
|
@ -346,7 +346,7 @@ describe('Test videos API validator', function () {
|
||||||
const fields = baseCorrectParams
|
const fields = baseCorrectParams
|
||||||
const attaches = {
|
const attaches = {
|
||||||
'previewfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png'),
|
'previewfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png'),
|
||||||
'videofile': join(__dirname, '..', '..', 'fixtures', 'video_short_fake.webm')
|
'videofile': join(__dirname, '..', '..', 'fixtures', 'video_short.mp4')
|
||||||
}
|
}
|
||||||
|
|
||||||
await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
||||||
|
@ -356,7 +356,7 @@ describe('Test videos API validator', function () {
|
||||||
const fields = baseCorrectParams
|
const fields = baseCorrectParams
|
||||||
const attaches = {
|
const attaches = {
|
||||||
'previewfile': join(__dirname, '..', '..', 'fixtures', 'avatar-big.png'),
|
'previewfile': join(__dirname, '..', '..', 'fixtures', 'avatar-big.png'),
|
||||||
'videofile': join(__dirname, '..', '..', 'fixtures', 'video_short_fake.webm')
|
'videofile': join(__dirname, '..', '..', 'fixtures', 'video_short.mp4')
|
||||||
}
|
}
|
||||||
|
|
||||||
await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
||||||
|
|
Loading…
Reference in New Issue