]> git.immae.eu Git - github/shaarli/Shaarli.git/commitdiff
Merge pull request #1520 from ArthurHoaro/fix/jp-language
authorArthurHoaro <arthur@hoa.ro>
Thu, 3 Sep 2020 06:46:47 +0000 (08:46 +0200)
committerGitHub <noreply@github.com>
Thu, 3 Sep 2020 06:46:47 +0000 (08:46 +0200)
16 files changed:
application/bookmark/BookmarkArray.php
application/bookmark/BookmarkFileService.php
application/bookmark/BookmarkServiceInterface.php
application/feed/FeedBuilder.php
application/front/ShaarliMiddleware.php
application/legacy/LegacyController.php
application/render/PageBuilder.php
application/security/SessionManager.php
assets/default/js/base.js
assets/default/scss/shaarli.scss
index.php
tests/feed/FeedBuilderTest.php
tests/legacy/LegacyControllerTest.php
tests/security/SessionManagerTest.php
tpl/default/linklist.paging.html
yarn.lock

index d87d43b41ae41a3753aff732aa3989636728c4b4..3bd5eb20f64bebe26d6306ba3590190eb90ec55b 100644 (file)
@@ -234,16 +234,17 @@ class BookmarkArray implements \Iterator, \Countable, \ArrayAccess
      *
      * Also update the urls and ids mapping arrays.
      *
-     * @param string $order ASC|DESC
+     * @param string $order        ASC|DESC
+     * @param bool   $ignoreSticky If set to true, sticky bookmarks won't be first
      */
-    public function reorder($order = 'DESC')
+    public function reorder(string $order = 'DESC', bool $ignoreSticky = false): void
     {
         $order = $order === 'ASC' ? -1 : 1;
         // Reorder array by dates.
-        usort($this->bookmarks, function ($a, $b) use ($order) {
+        usort($this->bookmarks, function ($a, $b) use ($order, $ignoreSticky) {
             /** @var $a Bookmark */
             /** @var $b Bookmark */
-            if ($a->isSticky() !== $b->isSticky()) {
+            if (false === $ignoreSticky && $a->isSticky() !== $b->isSticky()) {
                 return $a->isSticky() ? -1 : 1;
             }
             return $a->getCreated() < $b->getCreated() ? 1 * $order : -1 * $order;
index b3a90ed4623beecc7c75d96be635e33decfd6aed..e3a611461a7aae9ecd3f0070a3341aa872aa737d 100644 (file)
@@ -114,8 +114,13 @@ class BookmarkFileService implements BookmarkServiceInterface
     /**
      * @inheritDoc
      */
-    public function search($request = [], $visibility = null, $caseSensitive = false, $untaggedOnly = false)
-    {
+    public function search(
+        $request = [],
+        $visibility = null,
+        $caseSensitive = false,
+        $untaggedOnly = false,
+        bool $ignoreSticky = false
+    ) {
         if ($visibility === null) {
             $visibility = $this->isLoggedIn ? BookmarkFilter::$ALL : BookmarkFilter::$PUBLIC;
         }
@@ -124,6 +129,10 @@ class BookmarkFileService implements BookmarkServiceInterface
         $searchtags = isset($request['searchtags']) ? $request['searchtags'] : '';
         $searchterm = isset($request['searchterm']) ? $request['searchterm'] : '';
 
+        if ($ignoreSticky) {
+            $this->bookmarks->reorder('DESC', true);
+        }
+
         return $this->bookmarkFilter->filter(
             BookmarkFilter::$FILTER_TAG | BookmarkFilter::$FILTER_TEXT,
             [$searchtags, $searchterm],
index ce8bd912bf6b5a8d086646a9f1fd4f8fd297fe62..b9b483eb8ae14ae70582ec5589eb67fd9f066558 100644 (file)
@@ -49,10 +49,17 @@ interface BookmarkServiceInterface
      * @param string $visibility
      * @param bool   $caseSensitive
      * @param bool   $untaggedOnly
+     * @param bool   $ignoreSticky
      *
      * @return Bookmark[]
      */
-    public function search($request = [], $visibility = null, $caseSensitive = false, $untaggedOnly = false);
+    public function search(
+        $request = [],
+        $visibility = null,
+        $caseSensitive = false,
+        $untaggedOnly = false,
+        bool $ignoreSticky = false
+    );
 
     /**
      * Get a single bookmark by its ID.
index 269ad87722cfc5888070ce05dc5c730149a9129b..3653c32f981b360d52d556e4ea48e5ee6c1e4ab3 100644 (file)
@@ -102,7 +102,7 @@ class FeedBuilder
         }
 
         // Optionally filter the results:
-        $linksToDisplay = $this->linkDB->search($userInput);
+        $linksToDisplay = $this->linkDB->search($userInput, null, false, false, true);
 
         $nblinksToDisplay = $this->getNbLinks(count($linksToDisplay), $userInput);
 
index c015c0c6f0284fcfb9802a9938494c60763f721e..d1aa139989e2689ee61df29f47c2cd08bd2d9999 100644 (file)
@@ -94,7 +94,7 @@ class ShaarliMiddleware
             && $this->container->conf->get('privacy.force_login')
             // and the current page isn't already the login page
             // and the user is not requesting a feed (which would lead to a different content-type as expected)
-            && !in_array($next->getName(), ['login', 'atom', 'rss'], true)
+            && !in_array($next->getName(), ['login', 'processLogin', 'atom', 'rss'], true)
         ) {
             throw new UnauthorizedException();
         }
index 26465d2cf56fcf78fb91f7ec608ede92a8c97d9e..e16dd0f43effa6921b6238f0546e7357c9cea188 100644 (file)
@@ -40,28 +40,33 @@ class LegacyController extends ShaarliVisitorController
     public function post(Request $request, Response $response): Response
     {
         $parameters = count($request->getQueryParams()) > 0 ? '?' . http_build_query($request->getQueryParams()) : '';
+        $route = '/admin/shaare';
 
         if (!$this->container->loginManager->isLoggedIn()) {
-            return $this->redirect($response, '/login' . $parameters);
+            return $this->redirect($response, '/login?returnurl='. $this->getBasePath() . $route . $parameters);
         }
 
-        return $this->redirect($response, '/admin/shaare' . $parameters);
+        return $this->redirect($response, $route . $parameters);
     }
 
     /** Legacy route: ?addlink= */
     protected function addlink(Request $request, Response $response): Response
     {
+        $route = '/admin/add-shaare';
+
         if (!$this->container->loginManager->isLoggedIn()) {
-            return $this->redirect($response, '/login');
+            return $this->redirect($response, '/login?returnurl=' . $this->getBasePath() . $route);
         }
 
-        return $this->redirect($response, '/admin/add-shaare');
+        return $this->redirect($response, $route);
     }
 
     /** Legacy route: ?do=login */
     protected function login(Request $request, Response $response): Response
     {
-        return $this->redirect($response, '/login');
+        $returnUrl = $request->getQueryParam('returnurl');
+
+        return $this->redirect($response, '/login' . ($returnUrl ? '?returnurl=' . $returnUrl : ''));
     }
 
     /** Legacy route: ?do=logout */
@@ -127,4 +132,21 @@ class LegacyController extends ShaarliVisitorController
 
         return $this->redirect($response, '/feed/' . $feedType . $parameters);
     }
+
+    /** Legacy route: ?do=configure */
+    protected function configure(Request $request, Response $response): Response
+    {
+        $route = '/admin/configure';
+
+        if (!$this->container->loginManager->isLoggedIn()) {
+            return $this->redirect($response, '/login?returnurl=' . $this->getBasePath() . $route);
+        }
+
+        return $this->redirect($response, $route);
+    }
+
+    protected function getBasePath(): string
+    {
+        return $this->container->basePath ?: '';
+    }
 }
index 7a7166732392a5726227bd33d769f0dd8abbc96e..c52e3b76143530343f5da67ce32e9f74a805d236 100644 (file)
@@ -149,6 +149,8 @@ class PageBuilder
 
         $this->tpl->assign('formatter', $this->conf->get('formatter', 'default'));
 
+        $this->tpl->assign('links_per_page', $this->session['LINKS_PER_PAGE']);
+
         // To be removed with a proper theme configuration.
         $this->tpl->assign('conf', $this->conf);
     }
index 76b0afe84283b05a6fe2d17ebc4642eecfbbf11c..36df8c1c9bc823b369f7422a76c63e1f3dd6676b 100644 (file)
@@ -183,7 +183,6 @@ class SessionManager
             unset($this->session['expires_on']);
             unset($this->session['username']);
             unset($this->session['visibility']);
-            unset($this->session['untaggedonly']);
         }
     }
 
index 0f29799d148d8f864ff009ef2f7034aa5bbf07c3..2793882349ad9fd1503eef0bf5baf5681f9f2b0f 100644 (file)
@@ -25,16 +25,18 @@ function findParent(element, tagName, attributes) {
 /**
  * Ajax request to refresh the CSRF token.
  */
-function refreshToken(basePath) {
-  console.log('refresh');
+function refreshToken(basePath, callback) {
   const xhr = new XMLHttpRequest();
   xhr.open('GET', `${basePath}/admin/token`);
   xhr.onload = () => {
     const elements = document.querySelectorAll('input[name="token"]');
     [...elements].forEach((element) => {
-      console.log(element);
       element.setAttribute('value', xhr.responseText);
     });
+
+    if (callback) {
+      callback(xhr.response);
+    }
   };
   xhr.send();
 }
@@ -622,4 +624,15 @@ function init(description) {
   [...autocompleteFields].forEach((autocompleteField) => {
     awesomepletes.push(createAwesompleteInstance(autocompleteField));
   });
+
+  const exportForm = document.querySelector('#exportform');
+  if (exportForm != null) {
+    exportForm.addEventListener('submit', (event) => {
+      event.preventDefault();
+
+      refreshToken(basePath, () => {
+        event.target.submit();
+      });
+    });
+  }
 })();
index 759dff29828f9bce824d7f5f9e185a23c6b70458..7ab09d3f2e313657f6682bf211b7d9462c6a88e7 100644 (file)
@@ -616,6 +616,11 @@ body,
     padding: 5px;
     text-decoration: none;
     color: $dark-grey;
+
+    &.selected {
+      background: var(--main-color);
+      color: $white;
+     }
   }
 
   input {
index e7471823252494c594be9b67eb835f26b290979d..869f42de1352eafb5ec95bf44de6ca2c1b29855e 100644 (file)
--- a/index.php
+++ b/index.php
@@ -95,7 +95,7 @@ $app->group('', function () {
     $this->get('/add-tag/{newTag}', '\Shaarli\Front\Controller\Visitor\TagController:addTag');
     $this->get('/remove-tag/{tag}', '\Shaarli\Front\Controller\Visitor\TagController:removeTag');
     $this->get('/links-per-page', '\Shaarli\Front\Controller\Visitor\PublicSessionFilterController:linksPerPage');
-    $this->get('/untagged-only', '\Shaarli\Front\Controller\Admin\PublicSessionFilterController:untaggedOnly');
+    $this->get('/untagged-only', '\Shaarli\Front\Controller\Visitor\PublicSessionFilterController:untaggedOnly');
 })->add('\Shaarli\Front\ShaarliMiddleware');
 
 $app->group('/admin', function () {
index 5c2aaedb30f131f9689c14afd03300b459a7d0e2..fe37d5f23a08068ddb2e8e91f77c872225173deb 100644 (file)
@@ -87,7 +87,7 @@ class FeedBuilderTest extends \PHPUnit\Framework\TestCase
         $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
 
         // Test first not pinned link (note link)
-        $link = $data['links'][array_keys($data['links'])[2]];
+        $link = $data['links'][array_keys($data['links'])[0]];
         $this->assertEquals(41, $link['id']);
         $this->assertEquals(DateTime::createFromFormat(Bookmark::LINK_DATE_FORMAT, '20150310_114651'), $link['created']);
         $this->assertEquals('http://host.tld/shaare/WDWyig', $link['guid']);
@@ -128,7 +128,7 @@ class FeedBuilderTest extends \PHPUnit\Framework\TestCase
         $data = $feedBuilder->buildData(FeedBuilder::$FEED_ATOM, null);
         $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
         $this->assertRegExp('/2016-08-03T09:30:33\+\d{2}:\d{2}/', $data['last_update']);
-        $link = $data['links'][array_keys($data['links'])[2]];
+        $link = $data['links'][array_keys($data['links'])[0]];
         $this->assertRegExp('/2015-03-10T11:46:51\+\d{2}:\d{2}/', $link['pub_iso_date']);
         $this->assertRegExp('/2016-08-03T09:30:33\+\d{2}:\d{2}/', $data['links'][8]['up_iso_date']);
     }
@@ -173,7 +173,7 @@ class FeedBuilderTest extends \PHPUnit\Framework\TestCase
         $feedBuilder->setLocale(self::$LOCALE);
         $data = $feedBuilder->buildData(FeedBuilder::$FEED_ATOM, $criteria);
         $this->assertEquals(3, count($data['links']));
-        $link = $data['links'][array_keys($data['links'])[2]];
+        $link = $data['links'][array_keys($data['links'])[0]];
         $this->assertEquals(41, $link['id']);
         $this->assertEquals(DateTime::createFromFormat(Bookmark::LINK_DATE_FORMAT, '20150310_114651'), $link['created']);
     }
@@ -195,7 +195,7 @@ class FeedBuilderTest extends \PHPUnit\Framework\TestCase
         $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
         $this->assertTrue($data['usepermalinks']);
         // First link is a permalink
-        $link = $data['links'][array_keys($data['links'])[2]];
+        $link = $data['links'][array_keys($data['links'])[0]];
         $this->assertEquals(41, $link['id']);
         $this->assertEquals(DateTime::createFromFormat(Bookmark::LINK_DATE_FORMAT, '20150310_114651'), $link['created']);
         $this->assertEquals('http://host.tld/shaare/WDWyig', $link['guid']);
@@ -203,7 +203,7 @@ class FeedBuilderTest extends \PHPUnit\Framework\TestCase
         $this->assertContains('Direct link', $link['description']);
         $this->assertContains('http://host.tld/shaare/WDWyig', $link['description']);
         // Second link is a direct link
-        $link = $data['links'][array_keys($data['links'])[3]];
+        $link = $data['links'][array_keys($data['links'])[1]];
         $this->assertEquals(8, $link['id']);
         $this->assertEquals(DateTime::createFromFormat(Bookmark::LINK_DATE_FORMAT, '20150310_114633'), $link['created']);
         $this->assertEquals('http://host.tld/shaare/RttfEw', $link['guid']);
@@ -270,7 +270,7 @@ class FeedBuilderTest extends \PHPUnit\Framework\TestCase
         );
 
         // Test first link (note link)
-        $link = $data['links'][array_keys($data['links'])[2]];
+        $link = $data['links'][array_keys($data['links'])[0]];
         $this->assertEquals('http://host.tld:8080/~user/shaarli/shaare/WDWyig', $link['guid']);
         $this->assertEquals('http://host.tld:8080/~user/shaarli/shaare/WDWyig', $link['url']);
         $this->assertContains('http://host.tld:8080/~user/shaarli/./add-tag/hashtag', $link['description']);
index 759a5b2a5d6269c133bed96e53cf1c886e23a80a..4e52f3e186597375b351d575c1067b9a7dbd7573 100644 (file)
@@ -66,11 +66,11 @@ class LegacyControllerTest extends TestCase
     {
         return [
             ['post', [], '/admin/shaare', true],
-            ['post', [], '/login', false],
+            ['post', [], '/login?returnurl=/subfolder/admin/shaare', false],
             ['post', ['title' => 'test'], '/admin/shaare?title=test', true],
-            ['post', ['title' => 'test'], '/login?title=test', false],
+            ['post', ['title' => 'test'], '/login?returnurl=/subfolder/admin/shaare?title=test', false],
             ['addlink', [], '/admin/add-shaare', true],
-            ['addlink', [], '/login', false],
+            ['addlink', [], '/login?returnurl=/subfolder/admin/add-shaare', false],
             ['login', [], '/login', true],
             ['login', [], '/login', false],
             ['logout', [], '/admin/logout', true],
@@ -94,6 +94,8 @@ class LegacyControllerTest extends TestCase
             ['opensearch', [], '/open-search', true],
             ['dailyrss', [], '/daily-rss', false],
             ['dailyrss', [], '/daily-rss', true],
+            ['configure', [], '/login?returnurl=/subfolder/admin/configure', false],
+            ['configure', [], '/admin/configure', true],
         ];
     }
 }
index 60695dcf944de720ac8e16163ef7df346f434513..11a59f9c6e06b846623f02d465206220b807f085 100644 (file)
@@ -207,15 +207,16 @@ class SessionManagerTest extends TestCase
             'expires_on' => time() + 1000,
             'username' => 'johndoe',
             'visibility' => 'public',
-            'untaggedonly' => false,
+            'untaggedonly' => true,
         ];
         $this->sessionManager->logout();
 
-        $this->assertFalse(isset($this->session['ip']));
-        $this->assertFalse(isset($this->session['expires_on']));
-        $this->assertFalse(isset($this->session['username']));
-        $this->assertFalse(isset($this->session['visibility']));
-        $this->assertFalse(isset($this->session['untaggedonly']));
+        $this->assertArrayNotHasKey('ip', $this->session);
+        $this->assertArrayNotHasKey('expires_on', $this->session);
+        $this->assertArrayNotHasKey('username', $this->session);
+        $this->assertArrayNotHasKey('visibility', $this->session);
+        $this->assertArrayHasKey('untaggedonly', $this->session);
+        $this->assertTrue($this->session['untaggedonly']);
     }
 
     /**
index 7b320eaff226a99b523209dc90dc6096d32174b3..aa637868eb94e2a91cb9e8a5af22011cb6bbc77f 100644 (file)
@@ -1,27 +1,29 @@
 <div class="linklist-paging">
   <div class="paging pure-g">
     <div class="linklist-filters pure-u-1-3">
-      {if="$is_logged_in or !empty($action_plugin)"}
-        <span class="linklist-filters-text pure-u-0 pure-u-lg-visible">
-          {'Filters'|t}
-        </span>
-        {if="$is_logged_in"}
-        <a href="{$base_path}/admin/visibility/private" aria-label="{'Only display private links'|t}" title="{'Only display private links'|t}"
-           class="{if="$visibility==='private'"}filter-on{else}filter-off{/if}"
-        ><i class="fa fa-user-secret" aria-hidden="true"></i></a>
-        <a href="{$base_path}/admin/visibility/public" aria-label="{'Only display public links'|t}" title="{'Only display public links'|t}"
-           class="{if="$visibility==='public'"}filter-on{else}filter-off{/if}"
-        ><i class="fa fa-globe" aria-hidden="true"></i></a>
-        {/if}
-        <a href="{$base_path}/untagged-only" aria-label="{'Filter untagged links'|t}" title="{'Filter untagged links'|t}"
-           class={if="$untaggedonly"}"filter-on"{else}"filter-off"{/if}
-        ><i class="fa fa-tag" aria-hidden="true"></i></a>
-        <a href="#" aria-label="{'Select all'|t}" title="{'Select all'|t}"
-           class="filter-off select-all-button pure-u-0 pure-u-lg-visible"
-        ><i class="fa fa-check-square-o" aria-hidden="true"></i></a>
-        <a href="#" class="filter-off fold-all pure-u-lg-0" aria-label="{'Fold all'|t}" title="{'Fold all'|t}">
-          <i class="fa fa-chevron-up" aria-hidden="true"></i>
-        </a>
+      <span class="linklist-filters-text pure-u-0 pure-u-lg-visible">
+        {'Filters'|t}
+      </span>
+      {if="$is_logged_in"}
+      <a href="{$base_path}/admin/visibility/private" aria-label="{'Only display private links'|t}" title="{'Only display private links'|t}"
+         class="{if="$visibility==='private'"}filter-on{else}filter-off{/if}"
+      ><i class="fa fa-user-secret" aria-hidden="true"></i></a>
+      <a href="{$base_path}/admin/visibility/public" aria-label="{'Only display public links'|t}" title="{'Only display public links'|t}"
+         class="{if="$visibility==='public'"}filter-on{else}filter-off{/if}"
+      ><i class="fa fa-globe" aria-hidden="true"></i></a>
+      {/if}
+      <a href="{$base_path}/untagged-only" aria-label="{'Filter untagged links'|t}" title="{'Filter untagged links'|t}"
+         class={if="$untaggedonly"}"filter-on"{else}"filter-off"{/if}
+      ><i class="fa fa-tag" aria-hidden="true"></i></a>
+      {if="$is_logged_in"}
+      <a href="#" aria-label="{'Select all'|t}" title="{'Select all'|t}"
+         class="filter-off select-all-button pure-u-0 pure-u-lg-visible"
+      ><i class="fa fa-check-square-o" aria-hidden="true"></i></a>
+      {/if}
+      <a href="#" class="filter-off fold-all pure-u-lg-0" aria-label="{'Fold all'|t}" title="{'Fold all'|t}">
+        <i class="fa fa-chevron-up" aria-hidden="true"></i>
+      </a>
+      {if="!empty($action_plugin)"}
         {loop="$action_plugin"}
           {$value.attr.class=isset($value.attr.class) ? $value.attr.class : ''}
           {$value.attr.class=!empty($value.on) ? $value.attr.class .' filter-on' : $value.attr.class .' filter-off'}
 
     <div class="linksperpage pure-u-1-3">
       <div class="pure-u-0 pure-u-lg-visible">{'Links per page'|t}</div>
-      <a href="{$base_path}/links-per-page?nb=20">20</a>
-      <a href="{$base_path}/links-per-page?nb=50">50</a>
-      <a href="{$base_path}/links-per-page?nb=100">100</a>
+      <a href="{$base_path}/links-per-page?nb=20"
+                       {if="$links_per_page == 20"}class="selected"{/if}>20</a>
+      <a href="{$base_path}/links-per-page?nb=50"
+                       {if="$links_per_page == 50"}class="selected"{/if}>50</a>
+      <a href="{$base_path}/links-per-page?nb=100"
+                       {if="$links_per_page == 100"}class="selected"{/if}>100</a>
       <form method="GET" class="pure-u-0 pure-u-lg-visible" action="{$base_path}/links-per-page">
-        <input type="text" name="nb" placeholder="133">
+        <input type="text" name="nb" placeholder="133"
+                       {if="$links_per_page != 20 && $links_per_page != 50 && $links_per_page != 100"}
+                               value="{$links_per_page}"{/if}>
       </form>
       <a href="#" class="filter-off fold-all pure-u-0 pure-u-lg-visible" aria-label="{'Fold all'|t}" title="{'Fold all'|t}">
         <i class="fa fa-chevron-up" aria-hidden="true"></i>
index 96f854c19da45502496763dfae89722ac9ee86d7..df6479505770634460f8b5c5ddc6e12eba09f3af 100644 (file)
--- a/yarn.lock
+++ b/yarn.lock
@@ -1065,9 +1065,9 @@ block-stream@*:
     inherits "~2.0.0"
 
 bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0:
-  version "4.11.8"
-  resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
-  integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==
+  version "4.11.9"
+  resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828"
+  integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==
 
 brace-expansion@^1.1.7:
   version "1.1.11"
@@ -1886,9 +1886,9 @@ electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.47:
   integrity sha512-xXLNstRdVsisPF3pL3H9TVZo2XkMILfqtD6RiWIUmDK2sFX1Bjwqmd8LBp0Kuo2FgKO63JXPoEVGm8WyYdwP0Q==
 
 elliptic@^6.0.0:
-  version "6.4.1"
-  resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a"
-  integrity sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==
+  version "6.5.3"
+  resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6"
+  integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==
   dependencies:
     bn.js "^4.4.0"
     brorand "^1.0.1"
@@ -2856,16 +2856,21 @@ inflight@^1.0.4:
     once "^1.3.0"
     wrappy "1"
 
-inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
-  integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
+inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3:
+  version "2.0.4"
+  resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
+  integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
 
 inherits@2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
   integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=
 
+inherits@2.0.3:
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
+  integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
+
 ini@~1.3.0:
   version "1.3.5"
   resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
@@ -3428,9 +3433,9 @@ lodash.uniq@^4.5.0:
   integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
 
 lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.3.0, lodash@~4.17.10:
-  version "4.17.15"
-  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
-  integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
+  version "4.17.19"
+  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
+  integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
 
 longest@^1.0.1:
   version "1.0.1"