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

Merge branch 'master' into feat/show-tags-page

yusuketk 7 лет назад
Родитель
Сommit
974b96121b

+ 6 - 0
CHANGES.md

@@ -2,10 +2,16 @@
 
 ## 3.4.3-RC
 
+* Improvement: Add 'antarctic' theme
 * Support Apply eslint-config-airbnb based rules
 * Support Apply prettier and stylelint
 * Support: Upgrade libs
     * eslint
+    * googleapis
+    * i18next
+    * nodemailer
+    * react-i18next
+    * string-width
 
 ## 3.4.2
 

+ 0 - 2
config/webpack.common.js

@@ -82,8 +82,6 @@ module.exports = (options) => {
             exclude: [ // include as a result
               { test: helpers.root('node_modules', 'growi-plugin-') },
               helpers.root('node_modules/codemirror/src'),
-              helpers.root('node_modules/string-width'),
-              helpers.root('node_modules/is-fullwidth-code-point'), // depends from string-width
             ],
           },
           use: [{

+ 5 - 5
package.json

@@ -86,11 +86,11 @@
     "express-sanitizer": "^1.0.4",
     "express-session": "~1.15.0",
     "express-webpack-assets": "^0.1.0",
-    "googleapis": "^37.0.0",
+    "googleapis": "^39.1.0",
     "graceful-fs": "^4.1.11",
     "growi-pluginkit": "^1.1.0",
     "helmet": "^3.13.0",
-    "i18next": "=12.1.0",
+    "i18next": "^15.0.9",
     "i18next-express-middleware": "^1.4.1",
     "i18next-node-fs-backend": "^2.1.0",
     "i18next-sprintf-postprocessor": "^0.2.2",
@@ -105,7 +105,7 @@
     "mongoose-unique-validator": "^2.0.2",
     "multer": "~1.4.0",
     "multer-autoreap": "^1.0.3",
-    "nodemailer": "^5.1.1",
+    "nodemailer": "^6.0.0",
     "nodemailer-ses-transport": "~1.5.0",
     "npm-run-all": "^4.1.2",
     "passport": "^0.4.0",
@@ -119,7 +119,7 @@
     "slack-node": "^0.1.8",
     "socket.io": "^2.0.3",
     "stream-to-promise": "^2.2.0",
-    "string-width": "^3.0.0",
+    "string-width": "^4.1.0",
     "swig-templates": "^2.0.2",
     "uglifycss": "^0.0.29",
     "url-join": "^4.0.0",
@@ -200,7 +200,7 @@
     "react-dom": "^16.8.3",
     "react-dropzone": "=7.0.1",
     "react-frame-component": "^4.0.0",
-    "react-i18next": "=7.13.0",
+    "react-i18next": "^10.6.1",
     "react-waypoint": "^9.0.0",
     "replacestream": "^4.0.3",
     "reveal.js": "^3.5.0",

+ 3 - 3
src/client/js/app.js

@@ -291,7 +291,7 @@ if (!pageRevisionId && draft != null) {
  */
 const componentMappings = {
   'search-top': <I18nextProvider i18n={i18n}><HeaderSearchBox crowi={crowi} /></I18nextProvider>,
-  'search-sidebar': <HeaderSearchBox crowi={crowi} />,
+  'search-sidebar': <I18nextProvider i18n={i18n}><HeaderSearchBox crowi={crowi} /></I18nextProvider>,
   'search-page': <I18nextProvider i18n={i18n}><SearchPage crowi={crowi} crowiRenderer={crowiRenderer} /></I18nextProvider>,
 
   // 'revision-history': <PageHistory pageId={pageId} />,
@@ -374,7 +374,7 @@ if (savePageControlsElem) {
         onSubmit={saveWithSubmitButton}
         ref={(elem) => {
             if (savePageControls == null) {
-              savePageControls = elem.getWrappedInstance();
+              savePageControls = elem;
             }
           }}
         pageId={pageId}
@@ -510,7 +510,7 @@ if (pageStatusAlertElem) {
       <PageStatusAlert
         ref={(elem) => {
             if (pageStatusAlert == null) {
-              pageStatusAlert = elem.getWrappedInstance();
+              pageStatusAlert = elem;
             }
           }}
         revisionId={pageRevisionId}

+ 2 - 2
src/client/js/components/HeaderSearchBox.jsx

@@ -1,6 +1,6 @@
 import React from 'react';
 import PropTypes from 'prop-types';
-import { translate } from 'react-i18next';
+import { withTranslation } from 'react-i18next';
 
 import FormGroup from 'react-bootstrap/es/FormGroup';
 import Button from 'react-bootstrap/es/Button';
@@ -98,4 +98,4 @@ HeaderSearchBox.propTypes = {
   crowi: PropTypes.object.isRequired,
 };
 
-export default translate()(HeaderSearchBox);
+export default withTranslation()(HeaderSearchBox);

+ 2 - 2
src/client/js/components/InstallerForm.jsx

@@ -1,7 +1,7 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import i18next from 'i18next';
-import { translate } from 'react-i18next';
+import { withTranslation } from 'react-i18next';
 
 class InstallerForm extends React.Component {
 
@@ -153,4 +153,4 @@ InstallerForm.propTypes = {
   csrf: PropTypes.string,
 };
 
-export default translate()(InstallerForm);
+export default withTranslation()(InstallerForm);

+ 2 - 2
src/client/js/components/PageEditor/Cheatsheet.js

@@ -2,7 +2,7 @@
 
 import React from 'react';
 import PropTypes from 'prop-types';
-import { translate } from 'react-i18next';
+import { withTranslation } from 'react-i18next';
 
 class Cheatsheet extends React.Component {
 
@@ -103,4 +103,4 @@ Cheatsheet.propTypes = {
   t: PropTypes.func.isRequired, // i18next
 };
 
-export default translate()(Cheatsheet);
+export default withTranslation()(Cheatsheet);

+ 2 - 2
src/client/js/components/PageEditor/OptionsSelector.js

@@ -1,6 +1,6 @@
 import React from 'react';
 import PropTypes from 'prop-types';
-import { translate } from 'react-i18next';
+import { withTranslation } from 'react-i18next';
 
 import FormGroup from 'react-bootstrap/es/FormGroup';
 import FormControl from 'react-bootstrap/es/FormControl';
@@ -287,4 +287,4 @@ OptionsSelector.propTypes = {
   onChange: PropTypes.func.isRequired,
 };
 
-export default translate()(OptionsSelector);
+export default withTranslation()(OptionsSelector);

+ 2 - 2
src/client/js/components/PageEditor/SimpleCheatsheet.js

@@ -1,6 +1,6 @@
 import React from 'react';
 import PropTypes from 'prop-types';
-import { translate } from 'react-i18next';
+import { withTranslation } from 'react-i18next';
 
 class SimpleCheatsheet extends React.Component {
 
@@ -50,4 +50,4 @@ SimpleCheatsheet.propTypes = {
   t: PropTypes.func.isRequired, // i18next
 };
 
-export default translate()(SimpleCheatsheet);
+export default withTranslation()(SimpleCheatsheet);

+ 2 - 2
src/client/js/components/PageHistory.js

@@ -1,6 +1,6 @@
 import React from 'react';
 import PropTypes from 'prop-types';
-import { translate } from 'react-i18next';
+import { withTranslation } from 'react-i18next';
 
 import PageRevisionList from './PageHistory/PageRevisionList';
 
@@ -144,4 +144,4 @@ PageHistory.propTypes = {
   crowi: PropTypes.object.isRequired,
 };
 
-export default translate()(PageHistory);
+export default withTranslation()(PageHistory);

+ 2 - 2
src/client/js/components/PageStatusAlert.jsx

@@ -1,6 +1,6 @@
 import React from 'react';
 import PropTypes from 'prop-types';
-import { translate } from 'react-i18next';
+import { withTranslation } from 'react-i18next';
 
 /**
  *
@@ -142,4 +142,4 @@ PageStatusAlert.propTypes = {
 PageStatusAlert.defaultProps = {
 };
 
-export default translate()(PageStatusAlert);
+export default withTranslation(null, { withRef: true })(PageStatusAlert);

+ 3 - 3
src/client/js/components/SavePageControls.jsx

@@ -1,6 +1,6 @@
 import React from 'react';
 import PropTypes from 'prop-types';
-import { translate } from 'react-i18next';
+import { withTranslation } from 'react-i18next';
 
 import ButtonToolbar from 'react-bootstrap/es/ButtonToolbar';
 import SplitButton from 'react-bootstrap/es/SplitButton';
@@ -80,7 +80,7 @@ class SavePageControls extends React.PureComponent {
               crowi={this.props.crowi}
               ref={(elem) => {
                   if (this.grantSelector == null) {
-                    this.grantSelector = elem.getWrappedInstance();
+                    this.grantSelector = elem;
                   }
                 }}
               grant={this.props.grant}
@@ -124,4 +124,4 @@ SavePageControls.propTypes = {
   grantGroupName: PropTypes.string,
 };
 
-export default translate()(SavePageControls);
+export default withTranslation(null, { withRef: true })(SavePageControls);

+ 2 - 2
src/client/js/components/SavePageControls/GrantSelector.jsx

@@ -1,6 +1,6 @@
 import React from 'react';
 import PropTypes from 'prop-types';
-import { translate } from 'react-i18next';
+import { withTranslation } from 'react-i18next';
 
 import FormGroup from 'react-bootstrap/es/FormGroup';
 import FormControl from 'react-bootstrap/es/FormControl';
@@ -288,4 +288,4 @@ GrantSelector.propTypes = {
   grantGroupName: PropTypes.string,
 };
 
-export default translate()(GrantSelector);
+export default withTranslation(null, { withRef: true })(GrantSelector);

+ 2 - 2
src/client/js/components/SearchPage.js

@@ -2,7 +2,7 @@
 
 import React from 'react';
 import PropTypes from 'prop-types';
-import { translate } from 'react-i18next';
+import { withTranslation } from 'react-i18next';
 
 import SearchPageForm from './SearchPage/SearchPageForm';
 import SearchResult from './SearchPage/SearchResult';
@@ -121,4 +121,4 @@ SearchPage.defaultProps = {
   query: SearchPage.getQueryByLocation(window.location || {}),
 };
 
-export default translate()(SearchPage);
+export default withTranslation()(SearchPage);

+ 5 - 3
src/client/js/i18n.js

@@ -1,6 +1,6 @@
 import i18n from 'i18next';
 import LanguageDetector from 'i18next-browser-languagedetector';
-import { reactI18nextModule } from 'react-i18next';
+import { initReactI18next } from 'react-i18next';
 
 import resources from '@alias/locales';
 
@@ -16,9 +16,9 @@ export default (userlang) => {
     },
   });
 
-  return i18n
+  i18n
     .use(langDetector)
-    .use(reactI18nextModule) // if not using I18nextProvider
+    .use(initReactI18next) // if not using I18nextProvider
     .init({
       debug: (process.env.NODE_ENV !== 'production'),
       resources,
@@ -42,4 +42,6 @@ export default (userlang) => {
         nsMode: 'default',
       },
     });
+
+  return i18n;
 };

+ 3 - 3
src/client/js/legacy/crowi.js

@@ -683,7 +683,7 @@ $(() => {
 window.addEventListener('load', (e) => {
   // hash on page
   if (location.hash) {
-    if (location.hash === '#edit' || location.hash === '#edit-form') {
+    if ((location.hash === '#edit' || location.hash === '#edit-form') && $('.tab-pane#edit').length > 0) {
       $('a[data-toggle="tab"][href="#edit"]').tab('show');
       $('body').addClass('on-edit');
       $('body').addClass('builtin-editor');
@@ -691,12 +691,12 @@ window.addEventListener('load', (e) => {
       // focus
       Crowi.setCaretLineAndFocusToEditor();
     }
-    else if (location.hash === '#hackmd') {
+    else if (location.hash === '#hackmd' && $('.tab-pane#hackmd').length > 0) {
       $('a[data-toggle="tab"][href="#hackmd"]').tab('show');
       $('body').addClass('on-edit');
       $('body').addClass('hackmd');
     }
-    else if (location.hash === '#revision-history') {
+    else if (location.hash === '#revision-history' && $('.tab-pane#revision-history').length > 0) {
       $('a[data-toggle="tab"][href="#revision-history"]').tab('show');
     }
   }

+ 10 - 1
src/server/models/page.js

@@ -188,7 +188,16 @@ class PageQueryBuilder {
       ? escapeStringRegexp(path) // escape
       : pathSlashOmitted;
 
-    const queryReg = new RegExp(`^${pattern}`);
+    let queryReg;
+    try {
+      queryReg = new RegExp(`^${pattern}`);
+    }
+    // if regular expression is invalid
+    catch (e) {
+      // force to escape
+      queryReg = new RegExp(`^${escapeStringRegexp(pattern)}`);
+    }
+
     pathCondition.push({ path: queryReg });
 
     this.query = this.query

+ 6 - 3
src/server/routes/page.js

@@ -253,7 +253,7 @@ module.exports = function(crowi, app) {
     addRendarVarsForScope(renderVars, page);
 
     await addRenderVarsForSlack(renderVars, page);
-    await addRenderVarsForDescendants(renderVars, path, req.user, offset, limit);
+    await addRenderVarsForDescendants(renderVars, path, req.user, offset, limit, true);
 
     if (isUserPage(page.path)) {
       // change template
@@ -406,7 +406,10 @@ module.exports = function(crowi, app) {
     let view;
     const renderVars = { path };
 
-    if (!isCreatable || req.isForbidden) {
+    if (!isCreatable) {
+      view = 'customlayout-selector/not_creatable';
+    }
+    else if (req.isForbidden) {
       view = 'customlayout-selector/forbidden';
     }
     else {
@@ -429,7 +432,7 @@ module.exports = function(crowi, app) {
 
     const limit = 50;
     const offset = parseInt(req.query.offset) || 0;
-    await addRenderVarsForDescendants(renderVars, path, req.user, offset, limit);
+    await addRenderVarsForDescendants(renderVars, path, req.user, offset, limit, true);
 
     return res.render(view, renderVars);
   };

+ 7 - 0
src/server/views/customlayout-selector/not_creatable.html

@@ -0,0 +1,7 @@
+{% if !layoutType() || 'crowi' === layoutType() %}
+  {% include '../layout-crowi/not_creatable.html' %}
+{% elseif !layoutType() || 'kibela' === layoutType()%}
+  {% include '../layout-kibela/not_creatable.html' %}
+{% else %}
+  {% include '../layout-growi/not_creatable.html' %}
+{% endif %}

+ 41 - 0
src/server/views/layout-crowi/not_creatable.html

@@ -0,0 +1,41 @@
+{% extends 'base/layout.html' %}
+
+{% block content_header %}
+
+  {% block content_header_before %}
+  {% endblock %}
+
+  <div class="header-wrap">
+    <header id="page-header">
+      <div>
+        <div>
+          <h1 class="title" id="revision-path"></h1>
+          <div id="revision-url" class="url-line"></div>
+        </div>
+      </div>
+
+    </header>
+  </div>
+
+  {% block content_header_after %}
+  {% endblock %}
+
+{% endblock %} {# /content_head #}
+
+
+{% block content_main_before %}
+  {% include '../widget/page_alerts.html' %}
+{% endblock %}
+
+
+{% block content_main %}
+  {% include '../widget/not_creatable_content.html' %}
+{% endblock %}
+
+
+{% block content_main_after %}
+{% endblock %}
+
+
+{% block content_footer %}
+{% endblock %}

+ 25 - 0
src/server/views/layout-growi/not_creatable.html

@@ -0,0 +1,25 @@
+{% extends 'base/layout.html' %}
+
+
+{% block content_header %}
+  {% include 'widget/header.html' with {isCreatable: false} %}
+{% endblock %}
+
+
+{% block content_main_before %}
+  {% include '../widget/page_alerts.html' %}
+{% endblock %}
+
+
+{% block content_main %}
+  <div class="row">
+    <div class="col-lg-10 col-md-9">
+      {% include '../widget/not_creatable_content.html' %}
+    </div> {# /.col- #}
+  </div>
+{% endblock %}
+
+{% block body_end %}
+  <div id="crowi-modals">
+  </div>
+{% endblock %}

+ 25 - 0
src/server/views/layout-kibela/not_creatable.html

@@ -0,0 +1,25 @@
+{% extends 'base/layout.html' %}
+
+
+{% block content_header %}
+  {% include 'widget/header.html' %}
+{% endblock %}
+
+
+{% block content_main_before %}
+  {% include '../widget/page_alerts.html' %}
+{% endblock %}
+
+
+{% block content_main %}
+  <div class="row">
+    <div class="bg-white round-corner">
+      {% include '../widget/not_creatable_content.html' %}
+    </div> {# /.col- #}
+  </div>
+{% endblock %}
+
+{% block body_end %}
+  <div id="crowi-modals">
+  </div>
+{% endblock %}

+ 36 - 0
src/server/views/widget/not_creatable_content.html

@@ -0,0 +1,36 @@
+<div class="row not-found-message-row m-b-20">
+  <div class="col-md-12">
+    <h2 class="text-muted">
+      <i class="icon-ban" aria-hidden="true"></i>
+      Couldn't create path
+    </h2>
+  </div>
+</div>
+
+<div id="content-main" class="content-main content-main-not-found page-list"
+  data-path="{{ path | preventXss }}"
+  data-current-user="{% if user %}{{ user._id.toString() }}{% endif %}"
+  >
+
+  <ul class="nav nav-tabs hidden-print">
+    <li class="nav-main-left-tab active">
+      <a href="#revision-body" data-toggle="tab">
+        <i class="icon-notebook"></i> List
+      </a>
+    </li>
+  </ul>
+
+  <div class="tab-content">
+    {# list view #}
+    <div class="p-t-10 active tab-pane page-list-container" id="revision-body">
+      {% if pages.length == 0 %}
+        <div class="m-t-10">
+          There are no pages under <strong>{{ path }}</strong>.
+        </div>
+      {% endif  %}
+
+      {% include '../widget/page_list.html' with { pages: pages, pager: pager, viewConfig: viewConfig } %}
+    </div>
+
+  </div>
+</div>

+ 65 - 21
yarn.lock

@@ -73,6 +73,13 @@
   dependencies:
     regenerator-runtime "^0.12.0"
 
+"@babel/runtime@^7.3.1":
+  version "7.4.3"
+  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.3.tgz#79888e452034223ad9609187a0ad1fe0d2ad4bdc"
+  integrity sha512-9lsJwJLxDh/T3Q3SZszfWOTkk3pHbkmH+3KY+zwIDmsNlxsumuhS2TH3NIpktU4kNvfzy+k3eLT7aTJSPTo0OA==
+  dependencies:
+    regenerator-runtime "^0.13.2"
+
 "@babel/template@^7.1.0":
   version "7.4.0"
   resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.0.tgz#12474e9c077bae585c5d835a95c0b0b790c25c8b"
@@ -535,6 +542,11 @@ ansi-regex@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.0.0.tgz#70de791edf021404c3fd615aa89118ae0432e5a9"
 
+ansi-regex@^4.1.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
+  integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
+
 ansi-styles@^2.2.1:
   version "2.2.1"
   resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
@@ -3355,6 +3367,11 @@ emoji-regex@^7.0.1:
   version "7.0.1"
   resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.1.tgz#5a132b28ebf84a289ba692862f7d4206ebcd32d0"
 
+emoji-regex@^8.0.0:
+  version "8.0.0"
+  resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
+  integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
+
 emojis-list@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
@@ -4763,10 +4780,10 @@ googleapis@^16.0.0:
     google-auth-library "~0.10.0"
     string-template "~1.0.0"
 
-googleapis@^37.0.0:
-  version "37.2.0"
-  resolved "https://registry.yarnpkg.com/googleapis/-/googleapis-37.2.0.tgz#63bfcadaccc7cb8c1d8dff90573c48ca18132409"
-  integrity sha512-UenlZ0c4eaVAylIPvvsIlL/q5/3Xg8DuKug5aqdmRMk+tTVfJUmEKgp3s4ZSUOI5oKqO/+arIW5UnY2S62B13w==
+googleapis@^39.1.0:
+  version "39.1.0"
+  resolved "https://registry.yarnpkg.com/googleapis/-/googleapis-39.1.0.tgz#7a89092e9cc64b25dde4503db606032e3514444d"
+  integrity sha512-MRO9rW7izUIBZ4NJ67FNhBUw/Q3ki7hk149E9MhphJnLw1CStUAnm9nFD/IpNnx97qx2WBa7dLPjeXrJky6xlw==
   dependencies:
     google-auth-library "^3.0.0"
     googleapis-common "^0.7.0"
@@ -5036,10 +5053,6 @@ hogan.js@^3.0.2:
     mkdirp "0.3.0"
     nopt "1.0.10"
 
-hoist-non-react-statics@^2.3.1:
-  version "2.5.5"
-  resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47"
-
 home-or-tmp@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8"
@@ -5085,6 +5098,7 @@ html-comment-regex@^1.1.0:
 html-parse-stringify2@2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/html-parse-stringify2/-/html-parse-stringify2-2.0.1.tgz#dc5670b7292ca158b7bc916c9a6735ac8872834a"
+  integrity sha1-3FZwtyksoVi3vJFsmmc1rIhyg0o=
   dependencies:
     void-elements "^2.0.1"
 
@@ -5178,9 +5192,12 @@ i18next-sprintf-postprocessor@^0.2.2:
   version "0.2.2"
   resolved "https://registry.yarnpkg.com/i18next-sprintf-postprocessor/-/i18next-sprintf-postprocessor-0.2.2.tgz#2e409f1043579382698b6a2da70cdaa551d67ea4"
 
-i18next@=12.1.0:
-  version "12.1.0"
-  resolved "https://registry.yarnpkg.com/i18next/-/i18next-12.1.0.tgz#387bf4b94d05b0160b6a41d001a6b360e384bdb1"
+i18next@^15.0.9:
+  version "15.0.9"
+  resolved "https://registry.yarnpkg.com/i18next/-/i18next-15.0.9.tgz#42536407a921bb5a8535a4c090a26f16827a1884"
+  integrity sha512-IdVj7DqErUuMbGuj2dFT431T7zKlmDci63eae6pNA/bMwgBZKT74/KnwHXE0WH7ivo2EV/LNme4pP4Yw6vB79w==
+  dependencies:
+    "@babel/runtime" "^7.3.1"
 
 iconv-lite@0.4.19, iconv-lite@~0.4.13:
   version "0.4.19"
@@ -5561,6 +5578,11 @@ is-fullwidth-code-point@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
 
+is-fullwidth-code-point@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
+  integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
+
 is-glob@^2.0.0, is-glob@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863"
@@ -7271,10 +7293,10 @@ nodemailer-ses-transport@~1.5.0:
   dependencies:
     aws-sdk "^2.2.36"
 
-nodemailer@^5.1.1:
-  version "5.1.1"
-  resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-5.1.1.tgz#0c48d1ecab02e86d9ff6c620ee75ed944b763505"
-  integrity sha512-hKGCoeNdFL2W7S76J/Oucbw0/qRlfG815tENdhzcqTpSjKgAN91mFOqU2lQUflRRxFM7iZvCyaFcAR9noc/CqQ==
+nodemailer@^6.0.0:
+  version "6.0.0"
+  resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.0.0.tgz#d9761128771739dc87c1fdd747f569b7f135cb02"
+  integrity sha512-PMQJyLhoNAMoBU1hEh5aaUkpa/tcDNwzS7s7zow/myKfoEoZewMxUuWZqQ5yjYsAnvE484KSkYH5s6iPvcjhCg==
 
 nopt@1.0.10:
   version "1.0.10"
@@ -8508,7 +8530,7 @@ prop-types@^15.0.0, prop-types@^15.6.2:
     loose-envify "^1.3.1"
     object-assign "^4.1.1"
 
-prop-types@^15.5.0, prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.0:
+prop-types@^15.5.0, prop-types@^15.5.10, prop-types@^15.5.8:
   version "15.6.0"
   resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
   dependencies:
@@ -8766,13 +8788,13 @@ react-frame-component@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/react-frame-component/-/react-frame-component-4.0.0.tgz#57d51cdb2da3b204cc34577349f9f5bb84a76aac"
 
-react-i18next@=7.13.0:
-  version "7.13.0"
-  resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-7.13.0.tgz#a6f64fd749215ec70400f90da6cbde2a9c5b1588"
+react-i18next@^10.6.1:
+  version "10.6.1"
+  resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-10.6.1.tgz#044c39fb463a8d96cc548509187a1bb316e660fa"
+  integrity sha512-uuLksWCYR0i9tRZyKsQpcbJ0kiXYVDcaFXPVapZe8mYXReXvKsBgaOb6EwtqdXqiidO+HJAbyLOq9g3yzuZDEQ==
   dependencies:
-    hoist-non-react-statics "^2.3.1"
+    "@babel/runtime" "^7.3.1"
     html-parse-stringify2 "2.0.1"
-    prop-types "^15.6.0"
 
 react-is@^16.6.3:
   version "16.6.3"
@@ -9035,6 +9057,11 @@ regenerator-runtime@^0.12.0:
   resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de"
   integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==
 
+regenerator-runtime@^0.13.2:
+  version "0.13.2"
+  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447"
+  integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==
+
 regenerator-transform@^0.10.0:
   version "0.10.1"
   resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd"
@@ -10158,6 +10185,15 @@ string-width@^3.0.0:
     is-fullwidth-code-point "^2.0.0"
     strip-ansi "^5.0.0"
 
+string-width@^4.1.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.1.0.tgz#ba846d1daa97c3c596155308063e075ed1c99aff"
+  integrity sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ==
+  dependencies:
+    emoji-regex "^8.0.0"
+    is-fullwidth-code-point "^3.0.0"
+    strip-ansi "^5.2.0"
+
 string.prototype.padend@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz#f3aaef7c1719f170c5eab1c32bf780d96e21f2f0"
@@ -10225,6 +10261,13 @@ strip-ansi@^5.0.0:
   dependencies:
     ansi-regex "^4.0.0"
 
+strip-ansi@^5.2.0:
+  version "5.2.0"
+  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
+  integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
+  dependencies:
+    ansi-regex "^4.1.0"
+
 strip-bom@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e"
@@ -11147,6 +11190,7 @@ vm-browserify@0.0.4:
 void-elements@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
+  integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=
 
 warning@^3.0.0:
   version "3.0.0"