Просмотр исходного кода

Merge branch 'master' into rc/1.0.x

Yuki Takei 9 лет назад
Родитель
Сommit
6109711ddc

+ 20 - 8
README.md

@@ -12,7 +12,7 @@ crowi-plus [![Chat on Slack](https://crowi-plus-slackin.weseek.co.jp/badge.svg)]
 [![dependencies status](https://david-dm.org/weseek/crowi-plus.svg)](https://david-dm.org/weseek/crowi-plus)
 [![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)
 
-This is **crowi-plus** that is the fork of [Crowi](https://github.com/crowi/crowi), is [perfectly compatible with official](https://github.com/weseek/crowi-plus/wiki/Question-and-Answers#does-crowi-plus-have-compatibility-with-official-crowi), and has been enhanced with the following points:
+This is **crowi-plus** that is the fork of [Crowi](https://github.com/crowi/crowi), is [perfectly compatible with official](https://github.com/weseek/crowi-plus/wiki/Questions-and-Answers#does-crowi-plus-have-compatibility-with-official-crowi), and has been enhanced with the following points:
 
 * Pluggable
   * Find plugins from [npm](https://www.npmjs.com/browse/keyword/crowi-plugin) or [github](https://github.com/search?q=topic%3Acrowi-plugin)!
@@ -33,6 +33,12 @@ This is **crowi-plus** that is the fork of [Crowi](https://github.com/crowi/crow
 Quick Start for Production
 ===========================
 
+Using Heroku
+------------
+
+1. go to https://heroku.com/deploy
+1. input INSTALL_PLUGINS to install plugins
+
 Using docker-compose
 ---------------------
 
@@ -44,14 +50,17 @@ docker-compose up
 
 see also [weseek/crowi-plus-docker-compose](https://github.com/weseek/crowi-plus-docker-compose)
 
-Using Heroku
-------------
-
-(TBD)
-
 On-premise
 ----------
 
+## Dependencies
+
+- node 6.x (DON'T USE 7.x)
+- npm 4.x
+- yarn
+
+### Start
+
 ```bash
 git clone https://github.com/weseek/crowi-plus.git
 cd crowi-plus
@@ -81,8 +90,11 @@ Getting Started to Develop
 ==========================
 
 ## Dependencies
-What you need to run this app:
-* `node` and `npm` (`brew install node`)
+
+- node 6.x (DON'T USE 7.x)
+- npm 4.x
+- yarn
+
 * following environment is confirmed to work
 
     ```bash

+ 0 - 1
bin/search.js

@@ -1,6 +1,5 @@
 
 var program = require('commander')
-  , sprintf = require('sprintf')
   , debug = require('debug')('crowi:console:search-util')
   , colors = require('colors')
   , crowi = new (require('../lib/crowi'))(__dirname + '/../', process.env)

+ 0 - 1
bin/util.js

@@ -1,5 +1,4 @@
 var program = require('commander')
-  , sprintf = require('sprintf')
   , debug = require('debug')('crowi:console:util')
   , colors = require('colors')
   , crowi = new (require('../lib/crowi'))(__dirname + '/../', process.env)

+ 0 - 1
lib/events/page.js

@@ -1,7 +1,6 @@
 var debug = require('debug')('crowi:events:page');
 var util = require('util');
 var events = require('events');
-var sprintf = require('sprintf');
 
 function PageEvent(crowi) {
   this.crowi = crowi;

+ 1 - 2
lib/events/user.js

@@ -1,7 +1,6 @@
 var debug = require('debug')('crowi:events:user');
 var util = require('util');
 var events = require('events');
-var sprintf = require('sprintf');
 
 function UserEvent(crowi) {
   this.crowi = crowi;
@@ -19,7 +18,7 @@ UserEvent.prototype.onActivated = function(user) {
   .then(function(page) {
     // do nothing because user page is already exists.
   }).catch(function(err) {
-    var body = sprintf('# %s\nThis is %s\'s page', user.username, user.username)
+    var body = `# ${user.username}\nThis is ${user.username}\'s page`;
     // create user page
     Page.create(userPagePath, body, user, {})
     .then(function(page) {

+ 1 - 0
lib/form/index.js

@@ -7,6 +7,7 @@ module.exports = {
   me: {
     user: require('./me/user'),
     password: require('./me/password'),
+    imagetype: require('./me/imagetype'),
     apiToken: require('./me/apiToken'),
   },
   admin: {

+ 8 - 0
lib/form/me/imagetype.js

@@ -0,0 +1,8 @@
+'use strict';
+
+var form = require('express-form')
+  , field = form.field;
+
+module.exports = form(
+  field('imagetypeForm.isGravatarEnabled').required()
+);

+ 11 - 1
lib/models/user.js

@@ -11,7 +11,7 @@ module.exports = function(crowi) {
     , STATUS_SUSPENDED  = 3
     , STATUS_DELETED    = 4
     , STATUS_INVITED    = 5
-    , USER_PUBLIC_FIELDS = '_id image googleId name username email introduction status lang createdAt admin' // TODO: どこか別の場所へ...
+    , USER_PUBLIC_FIELDS = '_id image isGravatarEnabled googleId name username email introduction status lang createdAt admin' // TODO: どこか別の場所へ...
 
     , LANG_EN    = 'en'
     , LANG_EN_US = 'en-US'
@@ -27,6 +27,7 @@ module.exports = function(crowi) {
   userSchema = new mongoose.Schema({
     userId: String,
     image: String,
+    isGravatarEnabled: { type: Boolean, default: false },
     googleId: String,
     name: { type: String },
     username: { type: String, index: true },
@@ -137,6 +138,13 @@ module.exports = function(crowi) {
     });
   };
 
+  userSchema.methods.updateIsGravatarEnabled = function(isGravatarEnabled, callback) {
+    this.isGravatarEnabled = isGravatarEnabled;
+    this.save(function(err, userData) {
+      return callback(err, userData);
+    });
+  };
+
   userSchema.methods.updatePassword = function(password, callback) {
     this.setPassword(password);
     this.save(function(err, userData) {
@@ -573,6 +581,7 @@ module.exports = function(crowi) {
 
           newUser.email = email;
           newUser.setPassword(password);
+          newUser.isGravatarEnabled = true;   // Gravatar enabled in default
           newUser.createdAt = Date.now();
           newUser.status = STATUS_INVITED;
 
@@ -649,6 +658,7 @@ module.exports = function(crowi) {
     newUser.email = email;
     newUser.setPassword(password);
     newUser.lang = lang;
+    newUser.isGravatarEnabled = true;   // Gravatar enabled in default
     newUser.createdAt = Date.now();
     newUser.status = decideUserStatusOnRegistration();
 

+ 1 - 0
lib/routes/index.js

@@ -83,6 +83,7 @@ module.exports = function(crowi, app) {
   app.get('/me/apiToken'              , loginRequired(crowi, app) , me.apiToken);
   app.post('/me'                      , form.me.user              , loginRequired(crowi, app) , me.index);
   app.post('/me/password'             , form.me.password          , loginRequired(crowi, app) , me.password);
+  app.post('/me/imagetype'            , form.me.imagetype         , loginRequired(crowi, app) , me.imagetype);
   app.post('/me/apiToken'             , form.me.apiToken          , loginRequired(crowi, app) , me.apiToken);
   app.post('/me/picture/delete'       , loginRequired(crowi, app) , me.deletePicture);
   app.post('/me/auth/google'          , loginRequired(crowi, app) , me.authGoogle);

+ 30 - 0
lib/routes/me.js

@@ -114,6 +114,36 @@ module.exports = function(crowi, app) {
     }
   };
 
+  actions.imagetype = function(req,res) {
+    if (req.method !== 'POST') {
+      // do nothing
+      return;
+    }
+    else if (!req.form.isValid) {
+      req.flash('errorMessage', req.form.errors.join('\n'));
+      return;
+    }
+
+    var imagetypeForm = req.body.imagetypeForm;
+    var userData = req.user;
+
+    var isGravatarEnabled = imagetypeForm.isGravatarEnabled;
+
+    userData.updateIsGravatarEnabled(isGravatarEnabled, function(err, userData) {
+      if (err) {
+        for (var e in err.errors) {
+          if (err.errors.hasOwnProperty(e)) {
+            req.form.errors.push(err.errors[e].message);
+          }
+        }
+        return res.render('me/index', {});
+      }
+
+      req.flash('successMessage', req.t('Updated'));
+      return res.redirect('/me');
+    });
+  }
+
   actions.password = function(req, res) {
     var passwordForm = req.body.mePassword;
     var userData = req.user;

+ 2 - 4
lib/routes/page.js

@@ -9,8 +9,6 @@ module.exports = function(crowi, app) {
     , ApiResponse = require('../util/apiResponse')
     , interceptorManager = crowi.getInterceptorManager()
 
-    , sprintf = require('sprintf')
-
     , actions = {};
 
   // register page events
@@ -823,13 +821,13 @@ module.exports = function(crowi, app) {
     var page = {};
 
     if (!Page.isCreatableName(newPagePath)) {
-      return res.json(ApiResponse.error(sprintf('このページ名は作成できません (%s)', newPagePath)));
+      return res.json(ApiResponse.error(`このページ名は作成できません (${newPagePath})`));
     }
 
     Page.findPageByPath(newPagePath)
     .then(function(page) {
       // if page found, cannot cannot rename to that path
-      return res.json(ApiResponse.error(sprintf('このページ名は作成できません (%s)。ページが存在します。', newPagePath)));
+      return res.json(ApiResponse.error(`このページ名は作成できません (${newPagePath})。ページが存在します。`));
     }).catch(function(err) {
 
       Page.findPageById(pageId)

+ 0 - 2
lib/routes/search.js

@@ -6,8 +6,6 @@ module.exports = function(crowi, app) {
     , User = crowi.model('User')
     , ApiResponse = require('../util/apiResponse')
 
-    , sprintf = require('sprintf')
-
     , actions = {};
   var api = actions.api = {};
 

+ 27 - 4
lib/util/middlewares.js

@@ -1,4 +1,5 @@
 var debug = require('debug')('crowi:lib:middlewares');
+var md5 = require('md5');
 
 exports.loginChecker = function(crowi, app) {
   return function(req, res, next) {
@@ -57,6 +58,24 @@ exports.swigFunctions = function(crowi, app) {
 };
 
 exports.swigFilters = function(app, swig) {
+
+  // define a function for Gravatar
+  const generateGravatarSrc = function(user) {
+    const hash = md5(user.email.trim().toLowerCase());
+    return `http://www.gravatar.com/avatar/${hash}`;
+  };
+
+  // define a function for uploaded picture
+  const getUploadedPictureSrc = function(user) {
+    if (user.image !== undefined) {
+      return user.image;
+    }
+    else {
+      return '/images/userpicture.png';
+    }
+  };
+
+
   return function(req, res, next) {
     swig.setFilter('path2name', function(string) {
       var name = string.replace(/(\/)$/, '');
@@ -131,15 +150,19 @@ exports.swigFilters = function(app, swig) {
         .replace(/\s(https?.+(jpe?g|png|gif))\s/, '\n\n\n![]($1)\n\n\n');
     });
 
+    swig.setFilter('gravatar', generateGravatarSrc);
+    swig.setFilter('uploadedpicture', getUploadedPictureSrc);
+
     swig.setFilter('picture', function(user) {
       if (!user) {
         return '';
       }
 
-      if (user.image && user.image != '/images/userpicture.png') {
-        return user.image;
-      } else {
-        return '/images/userpicture.png';
+      if (user.isGravatarEnabled === true) {
+        return generateGravatarSrc(user);
+      }
+      else {
+        return getUploadedPictureSrc(user);
       }
     });
 

+ 4 - 5
lib/util/slack.js

@@ -8,7 +8,6 @@ module.exports = function(crowi) {
   var debug = require('debug')('crowi:util:slack'),
     Config = crowi.model('Config'),
     Botkit = require('botkit'),
-    sprintf = require('sprintf'),
     bot = null,
     slack = {};
   slack.controller = undefined;
@@ -126,12 +125,12 @@ module.exports = function(crowi) {
       debug('diff line', line)
       var value = line.value.replace(/\r\n|\r/g, '\n');
       if (line.added) {
-        diffText += sprintf(':pencil2: ...\n%s', line.value);
+        diffText += `:pencil2: ...\n${line.value}`;
       } else if (line.removed) {
         // diffText += '-' + line.value.replace(/(.+)?\n/g, '- $1\n');
         // 1以下は無視
         if (line.count > 1) {
-          diffText += sprintf(':wastebasket: ... %s lines\n', line.count);
+          diffText += `:wastebasket: ... ${line.count} lines\n`;
         }
       } else {
         //diffText += '...\n';
@@ -182,9 +181,9 @@ module.exports = function(crowi) {
     var text;
 
     if (updateType == 'create') {
-      text = sprintf(':white_check_mark: %s created a new page! %s', user.username, path);
+      text = `:white_check_mark: ${user.username} created a new page! ${path}`;
     } else {
-      text = sprintf(':up: %s updated %s', user.username, path);
+      text = `:up: ${user.username} updated ${path}`;
     }
 
     return text;

+ 99 - 65
lib/views/me/index.html

@@ -94,81 +94,115 @@
   </div>
 
   <div class="form-box">
-    <fieldset>
-      <legend>{{ t('Set Profile Image') }}</legend>
-        <div class="form-group">
-          <div id="pictureUploadFormMessage"></div>
-          <label for="" class="col-sm-3 control-label">
-            {{ t('Current Image') }}
-          </label>
-          <div class="col-sm-9">
-            <p>
-            <img src="{{ user|picture }}" width="64" id="settingUserPicture"><br>
-            </p>
-            <p>
-            {% if user.image %}
-            <form action="/me/picture/delete" method="post" class="form-horizontal" role="form" onsubmit="return window.confirm('{{ t('Delete this image?') }}');">
-              <button type="submit" class="btn btn-danger">{{ t('Delete Image') }}</button>
-            </form>
-            {% endif %}
-            </p>
+    <form action="/me/imagetype" method="post" class="form" role="form">
+      <fieldset>
+
+        <legend>{{ t('Set Profile Image') }}</legend>
+
+        <div class="form-group col-sm-offset-1 col-sm-3">
+          <div class="radio">
+            <h4>
+              <input type="radio" name="imagetypeForm[isGravatarEnabled]" value="true" {% if user.isGravatarEnabled %}checked="checked"{% endif %}>
+              <img src="https://www.gravatar.com/avatar/00000000000000000000000000000000?s=24" /> Gravatar
+              <a href="https://gravatar.com/">
+                <small><i class="fa fa-external-link" aria-hidden="true"></i></small>
+              </a>
+            </h4>
+          </div>
+
+          <img src="{{ user|gravatar }}" width="64">
+        </div><!-- /.col-sm* -->
+
+        <div class="form-group col-sm-8">
+          <div class="radio">
+            <h4>
+              <input type="radio" name="imagetypeForm[isGravatarEnabled]" value="false" {% if !user.isGravatarEnabled  %}checked="checked"{% endif %}>{{ t('Upload Image') }}
+            </h4>
           </div>
-        </div> {# /.form-group# #}
+          <div class="form-group">
+            <div id="pictureUploadFormMessage"></div>
+            <label for="" class="col-sm-4 control-label">
+              {{ t('Current Image') }}
+            </label>
+            <div class="col-sm-8">
+              <p>
+              <img src="{{ user|uploadedpicture }}" width="64" id="settingUserPicture"><br>
+              </p>
+              <p>
+              {% if user.image %}
+              <form action="/me/picture/delete" method="post" class="form-horizontal" role="form" onsubmit="return window.confirm('{{ t('Delete this image?') }}');">
+                <button type="submit" class="btn btn-danger">{{ t('Delete Image') }}</button>
+              </form>
+              {% endif %}
+              </p>
+            </div>
+          </div><!-- /.form-group -->
+
+          <div class="form-group">
+            <label for="" class="col-sm-4 control-label">
+              {{ t('Upload new image') }}
+            </label>
+            <div class="col-sm-8">
+              {% if isUploadable() %}
+              <form action="/_api/me/picture/upload" id="pictureUploadForm" method="post" class="form-horizontal" role="form" enctype="multipart/form-data">
+                <input name="userPicture" type="file" accept="image/*">
+                <div id="pictureUploadFormProgress">
+                </div>
+              </form>
+              {% else %}
+              * {{ t('page_me.form_help.profile_image1') }}<br>
+              * {{ t('page_me.form_help.profile_image2') }}<br>
+              {% endif %}
+            </div>
+          </div><!-- /.form-group -->
+
+        </div><!-- /.col-sm- -->
 
         <div class="form-group">
-          <label for="" class="col-sm-3 control-label">
-            {{ t('Upload new image') }}
-          </label>
-          <div class="col-sm-9">
-            {% if isUploadable() %}
-            <form action="/_api/me/picture/upload" id="pictureUploadForm" method="post" class="form-horizontal" role="form" enctype="multipart/form-data">
-              <input name="userPicture" type="file" accept="image/*">
-              <div id="pictureUploadFormProgress">
-              </div>
-            </form>
-            {% else %}
-            * {{ t('page_me.form_help.profile_image1') }}<br>
-            * {{ t('page_me.form_help.profile_image2') }}<br>
-            {% endif %}
+          <div class="col-sm-offset-4 col-sm-6">
+            <button type="submit" class="btn btn-primary">{{ t('Update') }}</button>
           </div>
         </div>
+
       </fieldset>
-    </div>
-    <script>
-    $(function()
-    {
-      $("#pictureUploadForm input[name=userPicture]").on('change', function(){
-        var $form = $('#pictureUploadForm');
-        var fd = new FormData($form[0]);
-        if ($(this).val() == '') {
-          return false;
-        }
+    </form>
+  </div><!-- /.form-box -->
 
-        $('#pictureUploadFormProgress').html('<img src="/images/loading_s.gif"> アップロード中...');
-        $.ajax($form.attr("action"), {
-          type: 'post',
-          processData: false,
-          contentType: false,
-          data: fd,
-          dataType: 'json',
-          success: function(data){
-            if (data.status) {
-              $('#settingUserPicture').attr('src', data.url + '?time=' + (new Date()));
-              $('#pictureUploadFormMessage')
-                .addClass('alert alert-success')
-                .html('変更しました');
-            } else {
-              $('#pictureUploadFormMessage')
-                .addClass('alert alert-danger')
-                .html('変更中にエラーが発生しました。');
-            }
-            $('#pictureUploadFormProgress').html('');
-          }
-        });
+  <script>
+  $(function()
+  {
+    $("#pictureUploadForm input[name=userPicture]").on('change', function(){
+      var $form = $('#pictureUploadForm');
+      var fd = new FormData($form[0]);
+      if ($(this).val() == '') {
         return false;
+      }
+
+      $('#pictureUploadFormProgress').html('<img src="/images/loading_s.gif"> アップロード中...');
+      $.ajax($form.attr("action"), {
+        type: 'post',
+        processData: false,
+        contentType: false,
+        data: fd,
+        dataType: 'json',
+        success: function(data){
+          if (data.status) {
+            $('#settingUserPicture').attr('src', data.url + '?time=' + (new Date()));
+            $('#pictureUploadFormMessage')
+              .addClass('alert alert-success')
+              .html('変更しました');
+          } else {
+            $('#pictureUploadFormMessage')
+              .addClass('alert alert-danger')
+              .html('変更中にエラーが発生しました。');
+          }
+          $('#pictureUploadFormProgress').html('');
+        }
       });
+      return false;
     });
-    </script>
+  });
+  </script>
 
   <div class="row">
     {% if googleLoginEnabled() %}

+ 1 - 0
locales/en-US/translation.json

@@ -51,6 +51,7 @@
   "English": "English",
   "Japanese": "Japanese",
   "Set Profile Image": "Set Profile Image",
+  "Upload Image": "Upload Image",
   "Current Image": "Current Image",
   "Delete Image": "Delete Image",
   "Delete this image?": "Delete this image?",

+ 1 - 0
locales/ja/translation.json

@@ -51,6 +51,7 @@
   "English": "英語",
   "Japanese": "日本語",
   "Set Profile Image": "プロフィール画像の設定",
+  "Upload Image": "画像をアップロード",
   "Current Image": "現在の画像",
   "Delete Image": "画像を削除",
   "Delete this image?": "削除してよろしいですか?",

+ 9 - 9
package.json

@@ -45,15 +45,15 @@
   },
   "dependencies": {
     "assets-webpack-plugin": "~3.5.1",
-    "async": "~1.5.0",
+    "async": "^2.3.0",
     "aws-sdk": "~2.2.26",
-    "axios": "0.15.x",
+    "axios": "^0.16.1",
     "babel-core": "^6.24.0",
     "babel-loader": "^6.4.1",
     "babel-preset-es2015": "^6.24.0",
     "babel-preset-react": "^6.23.0",
     "basic-auth-connect": "~1.0.0",
-    "body-parser": "~1.14.1",
+    "body-parser": "^1.17.1",
     "bootstrap-sass": "~3.3.6",
     "botkit": "~0.1.1",
     "cli": "~1.0.1",
@@ -62,18 +62,18 @@
     "connect-flash": "~0.1.1",
     "connect-redis": "~2.1.0",
     "consolidate": "~0.14.0",
-    "cookie-parser": "~1.3.4",
+    "cookie-parser": "^1.4.3",
     "copy-webpack-plugin": "^4.0.0",
     "crowi-pluginkit": "^1.1.0",
     "csrf": "~3.0.3",
-    "css-loader": "^0.27.3",
+    "css-loader": "^0.28.0",
     "debug": "~2.6.0",
     "diff": "^3.2.0",
     "diff2html": "^2.3.0",
     "elasticsearch": "^12.1.3",
     "emojify.js": "^1.1.0",
     "env-cmd": "^5.0.0",
-    "errorhandler": "~1.3.4",
+    "errorhandler": "^1.5.0",
     "express": "~4.15.2",
     "express-form": "~0.12.0",
     "express-session": "~1.15.0",
@@ -89,10 +89,11 @@
     "inline-attachment": "git+https://github.com/Rovak/InlineAttachment.git#2.0.3",
     "jquery.cookie": "~1.4.1",
     "marked": "~0.3.6",
+    "md5": "^2.2.1",
     "method-override": "~2.3.1",
     "mkdirp": "~0.5.1",
     "moment": "^2.18.0",
-    "mongoose": "4.7.x",
+    "mongoose": "^4.9.4",
     "mongoose-paginate": "5.0.x",
     "morgan": "^1.8.0",
     "multer": "~1.3.0",
@@ -109,7 +110,6 @@
     "sass-loader": "^6.0.3",
     "socket.io": "~1.7.0",
     "socket.io-client": "~1.7.0",
-    "sprintf": "~0.1.5",
     "style-loader": "^0.16.1",
     "swig": "~1.4.0",
     "uglifycss": "^0.0.25",
@@ -123,7 +123,7 @@
     "easy-livereload": "^1.2.0",
     "mocha": "^3.2.0",
     "node-dev": "^3.1.3",
-    "proxyquire": "~1.4.0",
+    "proxyquire": "^1.7.11",
     "sinon": "^2.1.0",
     "sinon-chai": "^2.9.0"
   },

+ 15 - 4
resource/js/components/User/UserPicture.js

@@ -1,18 +1,29 @@
 import React from 'react';
+import md5 from 'md5';
 
 // TODO UserComponent?
 export default class UserPicture extends React.Component {
 
   getUserPicture(user) {
-    // from swig.setFilter('picture', function(user)
-
-    if (user.image && user.image != '/images/userpicture.png') {
+    // gravatar
+    if (user.isGravatarEnabled === true) {
+      console.log(user.username + ": isGravatarEnabled true");
+      return this.generateGravatarSrc(user);
+    }
+    // uploaded image
+    else if (user.image && user.image != '/images/userpicture.png') {
       return user.image;
-    } else {
+    }
+    else {
       return '/images/userpicture.png';
     }
   }
 
+  generateGravatarSrc(user) {
+    const hash = md5(user.email.trim().toLowerCase());
+    return `http://www.gravatar.com/avatar/${hash}`;
+  }
+
   getClassName() {
     let className = ['picture', 'picture-rounded'];
     if (this.props.size) {

+ 110 - 125
yarn.lock

@@ -13,13 +13,6 @@ accepts@1.3.3, accepts@~1.3.3:
     mime-types "~2.1.11"
     negotiator "0.6.1"
 
-accepts@~1.2.6:
-  version "1.2.13"
-  resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.2.13.tgz#e5f1f3928c6d95fd96558c36ec3d9d0de4a6ecea"
-  dependencies:
-    mime-types "~2.1.6"
-    negotiator "0.5.3"
-
 acorn-dynamic-import@^2.0.0:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz#c752bd210bef679501b6c6cb7fc84f8f47158cc4"
@@ -229,7 +222,7 @@ async@^0.9.0:
   version "0.9.2"
   resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d"
 
-async@^2.0.1, async@^2.1.2, async@^2.1.5:
+async@^2.0.1, async@^2.1.2, async@^2.1.5, async@^2.3.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/async/-/async-2.3.0.tgz#1013d1051047dd320fe24e494d5c66ecaf6147d9"
   dependencies:
@@ -247,10 +240,6 @@ async@~1.4.2:
   version "1.4.2"
   resolved "https://registry.yarnpkg.com/async/-/async-1.4.2.tgz#6c9edcb11ced4f0dd2f2d40db0d49a109c088aab"
 
-async@~1.5.0:
-  version "1.5.2"
-  resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
-
 async@~2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/async/-/async-2.0.1.tgz#b709cc0280a9c36f09f4536be823c838a9049e25"
@@ -288,11 +277,11 @@ aws4@^1.2.1:
   version "1.6.0"
   resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
 
-axios@0.15.x:
-  version "0.15.3"
-  resolved "https://registry.yarnpkg.com/axios/-/axios-0.15.3.tgz#2c9d638b2e191a08ea1d6cc988eadd6ba5bdc053"
+axios@^0.16.1:
+  version "0.16.1"
+  resolved "https://registry.yarnpkg.com/axios/-/axios-0.16.1.tgz#c0b6d26600842384b8f509e57111f0d2df8223ca"
   dependencies:
-    follow-redirects "1.0.0"
+    follow-redirects "^1.2.3"
 
 babel-code-frame@^6.11.0, babel-code-frame@^6.22.0:
   version "6.22.0"
@@ -874,20 +863,20 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0:
   version "4.11.6"
   resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215"
 
-body-parser@^1.14.2, body-parser@~1.14.1:
-  version "1.14.2"
-  resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.14.2.tgz#1015cb1fe2c443858259581db53332f8d0cf50f9"
+body-parser@^1.14.2, body-parser@^1.17.1:
+  version "1.17.1"
+  resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.17.1.tgz#75b3bc98ddd6e7e0d8ffe750dfaca5c66993fa47"
   dependencies:
-    bytes "2.2.0"
-    content-type "~1.0.1"
-    debug "~2.2.0"
+    bytes "2.4.0"
+    content-type "~1.0.2"
+    debug "2.6.1"
     depd "~1.1.0"
-    http-errors "~1.3.1"
-    iconv-lite "0.4.13"
+    http-errors "~1.6.1"
+    iconv-lite "0.4.15"
     on-finished "~2.3.0"
-    qs "5.2.0"
-    raw-body "~2.1.5"
-    type-is "~1.6.10"
+    qs "6.4.0"
+    raw-body "~2.2.0"
+    type-is "~1.6.14"
 
 boom@2.x.x:
   version "2.10.1"
@@ -1047,10 +1036,6 @@ busboy@^0.2.11:
     dicer "0.2.5"
     readable-stream "1.1.x"
 
-bytes@2.2.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.2.0.tgz#fd35464a403f6f9117c2de3609ecff9cae000588"
-
 bytes@2.4.0:
   version "2.4.0"
   resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339"
@@ -1148,6 +1133,10 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3:
     strip-ansi "^3.0.0"
     supports-color "^2.0.0"
 
+charenc@~0.0.1:
+  version "0.0.2"
+  resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
+
 chokidar@^1.4.3:
   version "1.6.1"
   resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2"
@@ -1455,7 +1444,7 @@ content-disposition@0.5.2:
   version "0.5.2"
   resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4"
 
-content-type@~1.0.1, content-type@~1.0.2:
+content-type@~1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed"
 
@@ -1463,21 +1452,17 @@ convert-source-map@^1.1.0:
   version "1.5.0"
   resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5"
 
-cookie-parser@~1.3.4:
-  version "1.3.5"
-  resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.3.5.tgz#9d755570fb5d17890771227a02314d9be7cf8356"
+cookie-parser@^1.4.3:
+  version "1.4.3"
+  resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.4.3.tgz#0fe31fa19d000b95f4aadf1f53fdc2b8a203baa5"
   dependencies:
-    cookie "0.1.3"
+    cookie "0.3.1"
     cookie-signature "1.0.6"
 
 cookie-signature@1.0.6:
   version "1.0.6"
   resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
 
-cookie@0.1.3:
-  version "0.1.3"
-  resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.1.3.tgz#e734a5c1417fce472d5aef82c381cabb64d1a435"
-
 cookie@0.3.1:
   version "0.3.1"
   resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
@@ -1560,6 +1545,10 @@ crowi-pluginkit@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/crowi-pluginkit/-/crowi-pluginkit-1.1.0.tgz#c423f812a1d5198f57ba0180230b6be53120595d"
 
+crypt@~0.0.1:
+  version "0.0.2"
+  resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
+
 cryptiles@2.x.x:
   version "2.0.5"
   resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
@@ -1593,9 +1582,9 @@ css-color-names@0.0.4:
   version "0.0.4"
   resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0"
 
-css-loader@^0.27.3:
-  version "0.27.3"
-  resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.27.3.tgz#69ab6f47b69bfb1b5acee61bac2aab14302ff0dc"
+css-loader@^0.28.0:
+  version "0.28.0"
+  resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.0.tgz#417cfa9789f8cde59a30ccbf3e4da7a806889bad"
   dependencies:
     babel-code-frame "^6.11.0"
     css-selector-tokenizer "^0.7.0"
@@ -1711,7 +1700,7 @@ debounce@^1.0.0:
   dependencies:
     date-now "1.0.1"
 
-debug@*, debug@2, debug@2.6.3, debug@^2.1.1, debug@^2.2.0, debug@~2.6.0:
+debug@*, debug@2, debug@2.6.3, debug@^2.1.1, debug@^2.2.0, debug@^2.4.5, debug@~2.6.0:
   version "2.6.3"
   resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.3.tgz#0f7eb8c30965ec08c72accfa0130c8b79984141d"
   dependencies:
@@ -1972,21 +1961,17 @@ error-ex@^1.2.0:
   dependencies:
     is-arrayish "^0.2.1"
 
-errorhandler@~1.3.4:
-  version "1.3.6"
-  resolved "https://registry.yarnpkg.com/errorhandler/-/errorhandler-1.3.6.tgz#a7cdc13854c2872315dbbdfe8ba9ac25c4ccf4c7"
+errorhandler@^1.5.0:
+  version "1.5.0"
+  resolved "https://registry.yarnpkg.com/errorhandler/-/errorhandler-1.5.0.tgz#eaba64ca5d542a311ac945f582defc336165d9f4"
   dependencies:
-    accepts "~1.2.6"
-    escape-html "1.0.1"
+    accepts "~1.3.3"
+    escape-html "~1.0.3"
 
 es6-promise@3.2.1:
   version "3.2.1"
   resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.2.1.tgz#ec56233868032909207170c39448e24449dd1fc4"
 
-escape-html@1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.1.tgz#181a286ead397a39a92857cfb1d43052e356bff0"
-
 escape-html@~1.0.3:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
@@ -2187,6 +2172,13 @@ filewatcher@~3.0.0:
   dependencies:
     debounce "^1.0.0"
 
+fill-keys@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/fill-keys/-/fill-keys-1.0.2.tgz#9a8fa36f4e8ad634e3bf6b4f3c8882551452eb20"
+  dependencies:
+    is-object "~1.0.1"
+    merge-descriptors "~1.0.0"
+
 fill-range@^2.1.0:
   version "2.2.3"
   resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723"
@@ -2255,11 +2247,11 @@ flatten@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
 
-follow-redirects@1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.0.0.tgz#8e34298cbd2e176f254effec75a1c78cc849fd37"
+follow-redirects@^1.2.3:
+  version "1.2.3"
+  resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.2.3.tgz#01abaeca85e3609837d9fcda3167a7e42fdaca21"
   dependencies:
-    debug "^2.2.0"
+    debug "^2.4.5"
 
 for-in@^0.1.3:
   version "0.1.8"
@@ -2634,9 +2626,9 @@ home-or-tmp@^2.0.0:
     os-homedir "^1.0.0"
     os-tmpdir "^1.0.1"
 
-hooks-fixed@1.2.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/hooks-fixed/-/hooks-fixed-1.2.0.tgz#0d2772d4d7d685ff9244724a9f0b5b2559aac96b"
+hooks-fixed@2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/hooks-fixed/-/hooks-fixed-2.0.0.tgz#a01d894d52ac7f6599bbb1f63dfc9c411df70cba"
 
 hosted-git-info@^2.1.4:
   version "2.4.2"
@@ -2646,13 +2638,6 @@ html-comment-regex@^1.1.0:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.1.tgz#668b93776eaae55ebde8f3ad464b307a4963625e"
 
-http-errors@~1.3.1:
-  version "1.3.1"
-  resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.3.1.tgz#197e22cdebd4198585e8694ef6786197b91ed942"
-  dependencies:
-    inherits "~2.0.1"
-    statuses "1"
-
 http-errors@~1.5.1:
   version "1.5.1"
   resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.5.1.tgz#788c0d2c1de2c81b9e6e8c01843b6b97eb920750"
@@ -2722,10 +2707,6 @@ i18next@~4.1.0:
   version "4.1.4"
   resolved "https://registry.yarnpkg.com/i18next/-/i18next-4.1.4.tgz#d9514fe51b43e9d80d55ca73072fe11564182dc8"
 
-iconv-lite@0.4.13:
-  version "0.4.13"
-  resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2"
-
 iconv-lite@0.4.15, iconv-lite@~0.4.13:
   version "0.4.15"
   resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb"
@@ -2823,7 +2804,7 @@ is-binary-path@^1.0.0:
   dependencies:
     binary-extensions "^1.0.0"
 
-is-buffer@^1.0.2:
+is-buffer@^1.0.2, is-buffer@~1.1.1:
   version "1.1.5"
   resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc"
 
@@ -2898,6 +2879,10 @@ is-object@~0.1.2:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/is-object/-/is-object-0.1.2.tgz#00efbc08816c33cfc4ac8251d132e10dc65098d7"
 
+is-object@~1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470"
+
 is-plain-obj@^1.0.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
@@ -3096,9 +3081,9 @@ jws@^3.0.0, jws@~3.0.0:
     base64url "~1.0.4"
     jwa "~1.0.0"
 
-kareem@1.2.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/kareem/-/kareem-1.2.0.tgz#59851e833feb1ce6cf60000e0c23acf75c8a3547"
+kareem@1.2.1:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/kareem/-/kareem-1.2.1.tgz#acdb8c8119845834abbfa58ade1cf9dea63dc752"
 
 keygrip@~1.0.0:
   version "1.0.1"
@@ -3464,6 +3449,14 @@ math-expression-evaluator@^1.2.14:
   version "1.2.16"
   resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.16.tgz#b357fa1ca9faefb8e48d10c14ef2bcb2d9f0a7c9"
 
+md5@^2.2.1:
+  version "2.2.1"
+  resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9"
+  dependencies:
+    charenc "~0.0.1"
+    crypt "~0.0.1"
+    is-buffer "~1.1.1"
+
 media-typer@0.3.0:
   version "0.3.0"
   resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
@@ -3499,7 +3492,7 @@ meow@~2.0.0:
     minimist "^1.1.0"
     object-assign "^1.0.0"
 
-merge-descriptors@1.0.1:
+merge-descriptors@1.0.1, merge-descriptors@~1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
 
@@ -3545,7 +3538,7 @@ mime-db@~1.27.0:
   version "1.27.0"
   resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1"
 
-mime-types@^2.1.11, mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.15, mime-types@~2.1.6, mime-types@~2.1.7:
+mime-types@^2.1.11, mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.15, mime-types@~2.1.7:
   version "2.1.15"
   resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed"
   dependencies:
@@ -3610,23 +3603,27 @@ mocha@^3.2.0:
     mkdirp "0.5.1"
     supports-color "3.1.2"
 
+module-not-found-error@^1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/module-not-found-error/-/module-not-found-error-1.0.1.tgz#cf8b4ff4f29640674d6cdd02b0e3bc523c2bbdc0"
+
 moment@^2.18.0:
   version "2.18.1"
   resolved "https://registry.yarnpkg.com/moment/-/moment-2.18.1.tgz#c36193dd3ce1c2eed2adb7c802dbbc77a81b1c0f"
 
-mongodb-core@2.1.7:
-  version "2.1.7"
-  resolved "https://registry.yarnpkg.com/mongodb-core/-/mongodb-core-2.1.7.tgz#6a27909b98142ef2508d924c274969008954fa29"
+mongodb-core@2.1.9:
+  version "2.1.9"
+  resolved "https://registry.yarnpkg.com/mongodb-core/-/mongodb-core-2.1.9.tgz#85aa71ee4fb716196e06b787557bf139f801daf5"
   dependencies:
     bson "~1.0.4"
     require_optional "~1.0.0"
 
-mongodb@2.2.22:
-  version "2.2.22"
-  resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-2.2.22.tgz#d67c588fc08f922db19754b1d2e03e2d7d1319fb"
+mongodb@2.2.25:
+  version "2.2.25"
+  resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-2.2.25.tgz#d3b25dad00eda2bdfcbc996210ba082ac686a6b6"
   dependencies:
     es6-promise "3.2.1"
-    mongodb-core "2.1.7"
+    mongodb-core "2.1.9"
     readable-stream "2.1.5"
 
 mongoose-paginate@5.0.x:
@@ -3635,20 +3632,20 @@ mongoose-paginate@5.0.x:
   dependencies:
     bluebird "3.0.5"
 
-mongoose@4.7.x:
-  version "4.7.9"
-  resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-4.7.9.tgz#7a860161d649789699b1363fb5d47ed957748200"
+mongoose@^4.9.4:
+  version "4.9.4"
+  resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-4.9.4.tgz#212be4597e2db57b05286cc53ee894f30f3d8fad"
   dependencies:
     async "2.1.4"
     bson "~1.0.4"
-    hooks-fixed "1.2.0"
-    kareem "1.2.0"
-    mongodb "2.2.22"
+    hooks-fixed "2.0.0"
+    kareem "1.2.1"
+    mongodb "2.2.25"
     mpath "0.2.1"
     mpromise "0.5.5"
-    mquery "2.0.0"
+    mquery "2.3.0"
     ms "0.7.2"
-    muri "1.2.0"
+    muri "1.2.1"
     regexp-clone "0.0.1"
     sliced "1.0.1"
 
@@ -3670,9 +3667,9 @@ mpromise@0.5.5:
   version "0.5.5"
   resolved "https://registry.yarnpkg.com/mpromise/-/mpromise-0.5.5.tgz#f5b24259d763acc2257b0a0c8c6d866fd51732e6"
 
-mquery@2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/mquery/-/mquery-2.0.0.tgz#b5abc850b90dffc3e10ae49b4b6e7a479752df22"
+mquery@2.3.0:
+  version "2.3.0"
+  resolved "https://registry.yarnpkg.com/mquery/-/mquery-2.3.0.tgz#3d1717ad8958d0c99e42ea2461a109f3e5f3e458"
   dependencies:
     bluebird "2.10.2"
     debug "2.2.0"
@@ -3704,9 +3701,9 @@ multer@~1.3.0:
     type-is "^1.6.4"
     xtend "^4.0.0"
 
-muri@1.2.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/muri/-/muri-1.2.0.tgz#b86383c902920b09ebe62af0e75c94de5f33cd3d"
+muri@1.2.1:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/muri/-/muri-1.2.1.tgz#ec7ea5ce6ca6a523eb1ab35bacda5fa816c9aa3c"
 
 mustache@^2.2.1:
   version "2.3.0"
@@ -3724,10 +3721,6 @@ native-promise-only@^0.8.1:
   version "0.8.1"
   resolved "https://registry.yarnpkg.com/native-promise-only/-/native-promise-only-0.8.1.tgz#20a318c30cb45f71fe7adfbf7b21c99c1472ef11"
 
-negotiator@0.5.3:
-  version "0.5.3"
-  resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.5.3.tgz#269d5c476810ec92edbe7b6c2f28316384f9a7e8"
-
 negotiator@0.6.1:
   version "0.6.1"
   resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
@@ -4512,9 +4505,13 @@ proxy-addr@~1.1.3:
     forwarded "~0.1.0"
     ipaddr.js "1.3.0"
 
-proxyquire@~1.4.0:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/proxyquire/-/proxyquire-1.4.0.tgz#bd1f641ae1ef3a5fd2a9faffba7dc410eebda92c"
+proxyquire@^1.7.11:
+  version "1.7.11"
+  resolved "https://registry.yarnpkg.com/proxyquire/-/proxyquire-1.7.11.tgz#13b494eb1e71fb21cc3ebe3699e637d3bec1af9e"
+  dependencies:
+    fill-keys "^1.0.2"
+    module-not-found-error "^1.0.0"
+    resolve "~1.1.7"
 
 prr@~0.0.0:
   version "0.0.0"
@@ -4546,10 +4543,6 @@ q@^1.1.2:
   version "1.5.0"
   resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1"
 
-qs@5.2.0:
-  version "5.2.0"
-  resolved "https://registry.yarnpkg.com/qs/-/qs-5.2.0.tgz#a9f31142af468cb72b25b30136ba2456834916be"
-
 qs@6.2.0, qs@~6.2.0:
   version "6.2.0"
   resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.0.tgz#3b7848c03c2dece69a9522b0fae8c4126d745f3b"
@@ -4596,12 +4589,12 @@ range-parser@~1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"
 
-raw-body@~2.1.5:
-  version "2.1.7"
-  resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.1.7.tgz#adfeace2e4fb3098058014d08c072dcc59758774"
+raw-body@~2.2.0:
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.2.0.tgz#994976cf6a5096a41162840492f0bdc5d6e7fb96"
   dependencies:
     bytes "2.4.0"
-    iconv-lite "0.4.13"
+    iconv-lite "0.4.15"
     unpipe "1.0.0"
 
 rc@^1.1.7:
@@ -4926,7 +4919,7 @@ resolve@^1.0.0:
   dependencies:
     path-parse "^1.0.5"
 
-resolve@~1.1.0:
+resolve@~1.1.0, resolve@~1.1.7:
   version "1.1.7"
   resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
 
@@ -5261,10 +5254,6 @@ sprintf-js@~1.0.2:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
 
-sprintf@~0.1.5:
-  version "0.1.5"
-  resolved "https://registry.yarnpkg.com/sprintf/-/sprintf-0.1.5.tgz#8f83e39a9317c1a502cb7db8050e51c679f6edcf"
-
 sshpk@^1.7.0:
   version "1.13.0"
   resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.0.tgz#ff2a3e4fd04497555fed97b39a0fd82fafb3a33c"
@@ -5280,7 +5269,7 @@ sshpk@^1.7.0:
     jsbn "~0.1.0"
     tweetnacl "~0.14.0"
 
-statuses@1, "statuses@>= 1.3.1 < 2", statuses@~1.3.1:
+"statuses@>= 1.3.1 < 2", statuses@~1.3.1:
   version "1.3.1"
   resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e"
 
@@ -5553,7 +5542,7 @@ type-detect@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.0.tgz#62053883542a321f2f7b25746dc696478b18ff6b"
 
-type-is@^1.6.4, type-is@~1.6.10, type-is@~1.6.14:
+type-is@^1.6.4, type-is@~1.6.14:
   version "1.6.15"
   resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410"
   dependencies:
@@ -5803,14 +5792,10 @@ window-size@^0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075"
 
-wordwrap@0.0.2:
+wordwrap@0.0.2, wordwrap@~0.0.2:
   version "0.0.2"
   resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f"
 
-wordwrap@~0.0.2:
-  version "0.0.3"
-  resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
-
 wordwrapjs@^1.2.0:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-1.2.1.tgz#754a5ea0664cfbff50540dc32d67bda3289fc34b"