From 01de67b9a4fcdf01102ccc3cb7dc24beebf6c7ea Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 3 Jan 2018 11:10:40 +0100 Subject: Add avatar max size limit --- .../account-settings.component.html | 3 +- .../account-settings.component.scss | 10 +- .../account-settings/account-settings.component.ts | 14 ++- client/src/app/core/server/server.service.ts | 11 ++ package.json | 1 + server.ts | 2 +- server/controllers/api/config.ts | 15 ++- .../helpers/custom-validators/activitypub/actor.ts | 4 +- .../helpers/custom-validators/activitypub/misc.ts | 2 +- server/initializers/constants.ts | 12 +- server/middlewares/validators/users.ts | 11 +- server/models/activitypub/actor.ts | 16 +-- server/models/server/server.ts | 2 +- server/tests/api/check-params/users.ts | 8 ++ server/tests/api/fixtures/avatar-big.png | Bin 0 -> 146585 bytes shared/models/server-config.model.ts | 13 ++ yarn.lock | 132 ++++++++++++++++++++- 17 files changed, 226 insertions(+), 30 deletions(-) create mode 100644 server/tests/api/fixtures/avatar-big.png diff --git a/client/src/app/account/account-settings/account-settings.component.html b/client/src/app/account/account-settings/account-settings.component.html index fe345207a..0d1637c40 100644 --- a/client/src/app/account/account-settings/account-settings.component.html +++ b/client/src/app/account/account-settings/account-settings.component.html @@ -9,8 +9,9 @@
Change your avatar - +
+
(extensions: {{ avatarExtensions }}, max size: {{ maxAvatarSize | bytes }})
Account settings
diff --git a/client/src/app/account/account-settings/account-settings.component.scss b/client/src/app/account/account-settings/account-settings.component.scss index accd65214..c8a27dbcd 100644 --- a/client/src/app/account/account-settings/account-settings.component.scss +++ b/client/src/app/account/account-settings/account-settings.component.scss @@ -22,11 +22,19 @@ } .button-file { - @include peertube-button-file(auto); + @include peertube-button-file(160px); margin-top: 10px; } +.file-max-size { + display: inline-block; + font-size: 13px; + + position: relative; + top: -10px; +} + .account-title { text-transform: uppercase; color: $orange-color; diff --git a/client/src/app/account/account-settings/account-settings.component.ts b/client/src/app/account/account-settings/account-settings.component.ts index 3e03085ce..d5f5ff30f 100644 --- a/client/src/app/account/account-settings/account-settings.component.ts +++ b/client/src/app/account/account-settings/account-settings.component.ts @@ -1,9 +1,8 @@ -import { HttpEventType, HttpResponse } from '@angular/common/http' import { Component, OnInit, ViewChild } from '@angular/core' import { NotificationsService } from 'angular2-notifications' -import { VideoPrivacy } from '../../../../../shared/models/videos' -import { User } from '../../shared' import { AuthService } from '../../core' +import { ServerService } from '../../core/server' +import { User } from '../../shared' import { UserService } from '../../shared/users' @Component({ @@ -19,6 +18,7 @@ export class AccountSettingsComponent implements OnInit { constructor ( private userService: UserService, private authService: AuthService, + private serverService: ServerService, private notificationsService: NotificationsService ) {} @@ -47,4 +47,12 @@ export class AccountSettingsComponent implements OnInit { err => this.notificationsService.error('Error', err.message) ) } + + get maxAvatarSize () { + return this.serverService.getConfig().avatar.file.size.max + } + + get avatarExtensions () { + return this.serverService.getConfig().avatar.file.extensions.join(',') + } } diff --git a/client/src/app/core/server/server.service.ts b/client/src/app/core/server/server.service.ts index a5be9e199..45f68b434 100644 --- a/client/src/app/core/server/server.service.ts +++ b/client/src/app/core/server/server.service.ts @@ -21,6 +21,17 @@ export class ServerService { }, transcoding: { enabledResolutions: [] + }, + avatar: { + file: { + size: { max: 0 }, + extensions: [] + } + }, + video: { + file: { + extensions: [] + } } } private videoCategories: Array<{ id: number, label: string }> = [] diff --git a/package.json b/package.json index f6e10d709..adaccaf37 100644 --- a/package.json +++ b/package.json @@ -86,6 +86,7 @@ "scripty": "^1.5.0", "sequelize": "4.25.2", "sequelize-typescript": "^0.6.1", + "sharp": "^0.18.4", "ts-node": "^3.3.0", "typescript": "^2.5.2", "uuid": "^3.1.0", diff --git a/server.ts b/server.ts index 05fc39acb..e46ff85c7 100644 --- a/server.ts +++ b/server.ts @@ -164,7 +164,7 @@ function onDatabaseInitDone () { .then(() => { // ----------- Make the server listening ----------- server.listen(port, () => { - VideosPreviewCache.Instance.init(CONFIG.CACHE.PREVIEWS.SIZE) + VideosPreviewCache.Instance.init(CONFIG.CACHE.PREVIEWS.FILE_SIZE) activitypubHttpJobScheduler.activate() transcodingJobScheduler.activate() diff --git a/server/controllers/api/config.ts b/server/controllers/api/config.ts index 2f1132904..35c89835b 100644 --- a/server/controllers/api/config.ts +++ b/server/controllers/api/config.ts @@ -1,7 +1,7 @@ import * as express from 'express' import { isSignupAllowed } from '../../helpers/utils' -import { CONFIG } from '../../initializers' +import { CONFIG, CONSTRAINTS_FIELDS } from '../../initializers' import { asyncMiddleware } from '../../middlewares' import { ServerConfig } from '../../../shared' @@ -24,6 +24,19 @@ async function getConfig (req: express.Request, res: express.Response, next: exp }, transcoding: { enabledResolutions + }, + avatar: { + file: { + size: { + max: CONSTRAINTS_FIELDS.ACTORS.AVATAR.FILE_SIZE.max + }, + extensions: CONSTRAINTS_FIELDS.ACTORS.AVATAR.EXTNAME + } + }, + video: { + file: { + extensions: CONSTRAINTS_FIELDS.VIDEOS.EXTNAME + } } } diff --git a/server/helpers/custom-validators/activitypub/actor.ts b/server/helpers/custom-validators/activitypub/actor.ts index 630bace30..700e06007 100644 --- a/server/helpers/custom-validators/activitypub/actor.ts +++ b/server/helpers/custom-validators/activitypub/actor.ts @@ -24,7 +24,7 @@ function isActorPublicKeyValid (publicKey: string) { typeof publicKey === 'string' && publicKey.startsWith('-----BEGIN PUBLIC KEY-----') && publicKey.indexOf('-----END PUBLIC KEY-----') !== -1 && - validator.isLength(publicKey, CONSTRAINTS_FIELDS.ACTOR.PUBLIC_KEY) + validator.isLength(publicKey, CONSTRAINTS_FIELDS.ACTORS.PUBLIC_KEY) } const actorNameRegExp = new RegExp('[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_]+') @@ -42,7 +42,7 @@ function isActorPrivateKeyValid (privateKey: string) { privateKey.startsWith('-----BEGIN RSA PRIVATE KEY-----') && // Sometimes there is a \n at the end, so just assert the string contains the end mark privateKey.indexOf('-----END RSA PRIVATE KEY-----') !== -1 && - validator.isLength(privateKey, CONSTRAINTS_FIELDS.ACTOR.PRIVATE_KEY) + validator.isLength(privateKey, CONSTRAINTS_FIELDS.ACTORS.PRIVATE_KEY) } function isRemoteActorValid (remoteActor: any) { diff --git a/server/helpers/custom-validators/activitypub/misc.ts b/server/helpers/custom-validators/activitypub/misc.ts index aa6ffc9bd..75d308e9d 100644 --- a/server/helpers/custom-validators/activitypub/misc.ts +++ b/server/helpers/custom-validators/activitypub/misc.ts @@ -17,7 +17,7 @@ function isActivityPubUrlValid (url: string) { isURLOptions.require_tld = false } - return exists(url) && validator.isURL('' + url, isURLOptions) && validator.isLength('' + url, CONSTRAINTS_FIELDS.ACTOR.URL) + return exists(url) && validator.isURL('' + url, isURLOptions) && validator.isLength('' + url, CONSTRAINTS_FIELDS.ACTORS.URL) } function isBaseActivityValid (activity: any, type: string) { diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 31bb6c981..aefb91537 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -133,9 +133,6 @@ const CONFIG = { } } -const AVATARS_DIR = { - ACCOUNT: join(CONFIG.STORAGE.AVATARS_DIR, 'account') -} // --------------------------------------------------------------------------- const CONSTRAINTS_FIELDS = { @@ -169,12 +166,15 @@ const CONSTRAINTS_FIELDS = { FILE_SIZE: { min: 10 }, URL: { min: 3, max: 2000 } // Length }, - ACTOR: { + ACTORS: { PUBLIC_KEY: { min: 10, max: 5000 }, // Length PRIVATE_KEY: { min: 10, max: 5000 }, // Length URL: { min: 3, max: 2000 }, // Length AVATAR: { - EXTNAME: [ '.png', '.jpeg', '.jpg' ] + EXTNAME: [ '.png', '.jpeg', '.jpg' ], + FILE_SIZE: { + max: 2 * 1024 * 1024 // 2MB + } } }, VIDEO_EVENTS: { @@ -345,6 +345,7 @@ if (isTestInstance() === true) { REMOTE_SCHEME.WS = 'ws' STATIC_MAX_AGE = '0' ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE = 2 + CONSTRAINTS_FIELDS.ACTORS.AVATAR.FILE_SIZE.max = 100 * 1024 // 100KB } CONFIG.WEBSERVER.URL = sanitizeUrl(CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT) @@ -372,7 +373,6 @@ export { PREVIEWS_SIZE, REMOTE_SCHEME, FOLLOW_STATES, - AVATARS_DIR, SERVER_ACTOR_NAME, PRIVATE_RSA_KEY_SIZE, SORTABLE_COLUMNS, diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts index 7c77e9a39..7de3e442c 100644 --- a/server/middlewares/validators/users.ts +++ b/server/middlewares/validators/users.ts @@ -12,6 +12,7 @@ import { isSignupAllowed } from '../../helpers/utils' import { CONSTRAINTS_FIELDS } from '../../initializers' import { UserModel } from '../../models/account/user' import { areValidationErrors } from './utils' +import Multer = require('multer') const usersAddValidator = [ body('username').custom(isUserUsernameValid).withMessage('Should have a valid username (lowercase alphanumeric characters)'), @@ -100,7 +101,7 @@ const usersUpdateMeValidator = [ const usersUpdateMyAvatarValidator = [ body('avatarfile').custom((value, { req }) => isAvatarFile(req.files)).withMessage( 'This file is not supported. Please, make sure it is of the following type : ' - + CONSTRAINTS_FIELDS.ACTOR.AVATAR.EXTNAME.join(', ') + + CONSTRAINTS_FIELDS.ACTORS.AVATAR.EXTNAME.join(', ') ), (req: express.Request, res: express.Response, next: express.NextFunction) => { @@ -108,6 +109,14 @@ const usersUpdateMyAvatarValidator = [ 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() } ] diff --git a/server/models/activitypub/actor.ts b/server/models/activitypub/actor.ts index a12f3ec9e..ff5ab2e32 100644 --- a/server/models/activitypub/actor.ts +++ b/server/models/activitypub/actor.ts @@ -87,17 +87,17 @@ export class ActorModel extends Model { @AllowNull(false) @Is('ActorUrl', value => throwIfNotValid(value, isActivityPubUrlValid, 'url')) - @Column(DataType.STRING(CONSTRAINTS_FIELDS.ACTOR.URL.max)) + @Column(DataType.STRING(CONSTRAINTS_FIELDS.ACTORS.URL.max)) url: string @AllowNull(true) @Is('ActorPublicKey', value => throwIfNotValid(value, isActorPublicKeyValid, 'public key')) - @Column(DataType.STRING(CONSTRAINTS_FIELDS.ACTOR.PUBLIC_KEY.max)) + @Column(DataType.STRING(CONSTRAINTS_FIELDS.ACTORS.PUBLIC_KEY.max)) publicKey: string @AllowNull(true) @Is('ActorPublicKey', value => throwIfNotValid(value, isActorPrivateKeyValid, 'private key')) - @Column(DataType.STRING(CONSTRAINTS_FIELDS.ACTOR.PRIVATE_KEY.max)) + @Column(DataType.STRING(CONSTRAINTS_FIELDS.ACTORS.PRIVATE_KEY.max)) privateKey: string @AllowNull(false) @@ -112,27 +112,27 @@ export class ActorModel extends Model { @AllowNull(false) @Is('ActorInboxUrl', value => throwIfNotValid(value, isActivityPubUrlValid, 'inbox url')) - @Column(DataType.STRING(CONSTRAINTS_FIELDS.ACTOR.URL.max)) + @Column(DataType.STRING(CONSTRAINTS_FIELDS.ACTORS.URL.max)) inboxUrl: string @AllowNull(false) @Is('ActorOutboxUrl', value => throwIfNotValid(value, isActivityPubUrlValid, 'outbox url')) - @Column(DataType.STRING(CONSTRAINTS_FIELDS.ACTOR.URL.max)) + @Column(DataType.STRING(CONSTRAINTS_FIELDS.ACTORS.URL.max)) outboxUrl: string @AllowNull(false) @Is('ActorSharedInboxUrl', value => throwIfNotValid(value, isActivityPubUrlValid, 'shared inbox url')) - @Column(DataType.STRING(CONSTRAINTS_FIELDS.ACTOR.URL.max)) + @Column(DataType.STRING(CONSTRAINTS_FIELDS.ACTORS.URL.max)) sharedInboxUrl: string @AllowNull(false) @Is('ActorFollowersUrl', value => throwIfNotValid(value, isActivityPubUrlValid, 'followers url')) - @Column(DataType.STRING(CONSTRAINTS_FIELDS.ACTOR.URL.max)) + @Column(DataType.STRING(CONSTRAINTS_FIELDS.ACTORS.URL.max)) followersUrl: string @AllowNull(false) @Is('ActorFollowingUrl', value => throwIfNotValid(value, isActivityPubUrlValid, 'following url')) - @Column(DataType.STRING(CONSTRAINTS_FIELDS.ACTOR.URL.max)) + @Column(DataType.STRING(CONSTRAINTS_FIELDS.ACTORS.URL.max)) followingUrl: string @CreatedAt diff --git a/server/models/server/server.ts b/server/models/server/server.ts index d35aa0ca4..122e5f74f 100644 --- a/server/models/server/server.ts +++ b/server/models/server/server.ts @@ -27,7 +27,7 @@ export class ServerModel extends Model { @AllowNull(false) @Default(SERVERS_SCORE.BASE) @IsInt - @Max(SERVERS_SCORE.MAX) + @Max(SERVERS_SCORE.max) @Column score: number diff --git a/server/tests/api/check-params/users.ts b/server/tests/api/check-params/users.ts index 33d92ac24..14fcf8703 100644 --- a/server/tests/api/check-params/users.ts +++ b/server/tests/api/check-params/users.ts @@ -276,6 +276,14 @@ describe('Test users API validators', function () { await makePostUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches }) }) + it('Should fail with a big file', async function () { + const fields = {} + const attaches = { + 'avatarfile': join(__dirname, '..', 'fixtures', 'avatar-big.png') + } + await makePostUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches }) + }) + it('Should succeed with the correct params', async function () { const fields = {} const attaches = { diff --git a/server/tests/api/fixtures/avatar-big.png b/server/tests/api/fixtures/avatar-big.png new file mode 100644 index 000000000..e593e40da Binary files /dev/null and b/server/tests/api/fixtures/avatar-big.png differ diff --git a/shared/models/server-config.model.ts b/shared/models/server-config.model.ts index 8de808e60..d0b2e40de 100644 --- a/shared/models/server-config.model.ts +++ b/shared/models/server-config.model.ts @@ -5,4 +5,17 @@ export interface ServerConfig { transcoding: { enabledResolutions: number[] } + avatar: { + file: { + size: { + max: number + }, + extensions: string[] + } + } + video: { + file: { + extensions: string[] + } + } } diff --git a/yarn.lock b/yarn.lock index 101428df8..67337c08b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -756,6 +756,15 @@ caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" +caw@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/caw/-/caw-2.0.1.tgz#6c3ca071fc194720883c2dc5da9b074bfc7e9e95" + dependencies: + get-proxy "^2.0.0" + isurl "^1.0.0-alpha5" + tunnel-agent "^0.6.0" + url-to-options "^1.0.1" + chai@^4.1.1: version "4.1.2" resolved "https://registry.yarnpkg.com/chai/-/chai-4.1.2.tgz#0f64584ba642f0f2ace2806279f4f06ca23ad73c" @@ -878,16 +887,30 @@ code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" -color-convert@^1.9.0: +color-convert@^1.9.0, color-convert@^1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" dependencies: color-name "^1.1.1" -color-name@^1.1.1: +color-name@^1.0.0, color-name@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" +color-string@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.2.tgz#26e45814bc3c9a7cbd6751648a41434514a773a9" + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color/-/color-2.0.1.tgz#e4ed78a3c4603d0891eba5430b04b86314f4c839" + dependencies: + color-convert "^1.9.1" + color-string "^1.5.2" + colors@1.0.x: version "1.0.3" resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" @@ -945,6 +968,13 @@ concurrently@^3.1.0: supports-color "^3.2.3" tree-kill "^1.1.0" +config-chain@^1.1.11: + version "1.1.11" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.11.tgz#aba09747dfbe4c3e70e766a6e41586e1859fc6f2" + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + config@^1.14.0: version "1.28.1" resolved "https://registry.yarnpkg.com/config/-/config-1.28.1.tgz#7625d2a1e4c90f131d8a73347982d93c3873282d" @@ -1161,6 +1191,10 @@ destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" +detect-libc@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-0.2.0.tgz#47fdf567348a17ec25fcbf0b9e446348a76f9fb5" + detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" @@ -1887,6 +1921,12 @@ get-func-name@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" +get-proxy@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/get-proxy/-/get-proxy-2.1.0.tgz#349f2b4d91d44c4d4d4e9cba2ad90143fac5ef93" + dependencies: + npm-conf "^1.1.0" + get-stdin@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" @@ -2016,6 +2056,16 @@ has-flag@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" +has-symbol-support-x@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.1.tgz#66ec2e377e0c7d7ccedb07a3a84d77510ff1bc4c" + +has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + dependencies: + has-symbol-support-x "^1.4.1" + has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -2196,6 +2246,10 @@ is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" +is-arrayish@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.1.tgz#c2dfc386abaa0c3e33c48db3fe87059e69065efd" + is-ascii@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-ascii/-/is-ascii-1.0.0.tgz#f02ad0259a0921cd199ff21ce1b09e0f6b4e3929" @@ -2300,6 +2354,10 @@ is-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" +is-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" + is-path-cwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" @@ -2380,6 +2438,13 @@ isstream@0.1.x, isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" +isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + js-string-escape@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" @@ -2779,6 +2844,18 @@ minimist@^1.1.0, minimist@^1.1.1, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" +minipass@^2.0.2, minipass@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.2.1.tgz#5ada97538b1027b4cf7213432428578cb564011f" + dependencies: + yallist "^3.0.0" + +minizlib@^1.0.3: + version "1.1.0" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" + dependencies: + minipass "^2.2.1" + mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" @@ -2867,7 +2944,7 @@ nan@2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45" -nan@^2.3.0, nan@^2.7.0: +nan@^2.3.0, nan@^2.6.2, nan@^2.7.0: version "2.8.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a" @@ -2969,6 +3046,13 @@ normalize-path@^2.0.0, normalize-path@^2.0.1: dependencies: remove-trailing-separator "^1.0.1" +npm-conf@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9" + dependencies: + config-chain "^1.1.11" + pify "^3.0.0" + npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -3399,6 +3483,10 @@ promisify-any@2.0.1: co-bluebird "^1.1.0" is-generator "^1.0.2" +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + proxy-addr@~2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec" @@ -3828,6 +3916,18 @@ setprototypeof@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" +sharp@^0.18.4: + version "0.18.4" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.18.4.tgz#fe329c0f06896c28aa24376df1fff02ae57f2d34" + dependencies: + caw "^2.0.0" + color "^2.0.0" + detect-libc "^0.2.0" + nan "^2.6.2" + semver "^5.3.0" + simple-get "^2.7.0" + tar "^3.1.5" + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -3866,7 +3966,7 @@ simple-get@^1.4.2: unzip-response "^1.0.0" xtend "^4.0.0" -simple-get@^2.0.0, simple-get@^2.2.1: +simple-get@^2.0.0, simple-get@^2.2.1, simple-get@^2.7.0: version "2.7.0" resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.7.0.tgz#ad37f926d08129237ff08c4f2edfd6f10e0380b5" dependencies: @@ -3890,6 +3990,12 @@ simple-sha1@^2.0.0, simple-sha1@^2.0.8, simple-sha1@^2.1.0: dependencies: rusha "^0.8.1" +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + dependencies: + is-arrayish "^0.3.1" + simple-websocket@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/simple-websocket/-/simple-websocket-5.1.0.tgz#9fc2e4127f217ace4871f10c56bd21c85ecca21d" @@ -4209,6 +4315,16 @@ tar@^2.2.1: fstream "^1.0.2" inherits "2" +tar@^3.1.5: + version "3.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-3.2.1.tgz#9aa8e41c88f09e76c166075bc71f93d5166e61b1" + dependencies: + chownr "^1.0.1" + minipass "^2.0.2" + minizlib "^1.0.3" + mkdirp "^0.5.0" + yallist "^3.0.2" + term-size@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" @@ -4459,6 +4575,10 @@ url-parse-lax@^1.0.0: dependencies: prepend-http "^1.0.1" +url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + user-home@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" @@ -4674,6 +4794,10 @@ yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" +yallist@^3.0.0, yallist@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" + yargs-parser@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.0.0.tgz#21d476330e5a82279a4b881345bf066102e219c6" -- cgit v1.2.3