فهرست منبع

Revert "Merge branch 'feat/4937-5495-implement-access-token-without-user' into feat/4937-5433-Discard-access-token"

This reverts commit 3b96bd277c268a8bf2b01b8e279da35cd3e7d236, reversing
changes made to 760e81a8f5d5353980270e779fa6eedbc20187cd.
itizawa 5 سال پیش
والد
کامیت
5db85b81c4

+ 1 - 9
CHANGES.md

@@ -2,15 +2,7 @@
 
 ## v4.2.14-RC
 
-* Support: Update libs
-    * bunyan
-    * browser-bunyan
-* Fix: Can create pages on the share route
-    * Introduced by v4.2.8
-* Fix: Group page is excluded by recurrence operation
-    * Introduced by v4.2.8
-* Fix: New path to rename and duplicate is considered as a child page
-    * Introduced by v4.2.8
+* 
 
 ## v4.2.13
 

+ 2 - 4
package.json

@@ -87,7 +87,7 @@
     "aws-sdk": "^2.88.0",
     "axios": "^0.21.1",
     "body-parser": "^1.18.2",
-    "bunyan": "^1.8.15",
+    "bunyan": "^1.8.12",
     "bunyan-format": "^0.2.1",
     "check-node-version": "^4.0.2",
     "connect-flash": "~0.1.1",
@@ -155,7 +155,6 @@
     "string-width": "^4.1.0",
     "swig-templates": "^2.0.2",
     "uglifycss": "^0.0.29",
-    "universal-bunyan": "^0.9.2",
     "unzipper": "^0.10.5",
     "url-join": "^4.0.0",
     "validator": "^12.0.0",
@@ -176,7 +175,6 @@
     "@babel/polyfill": "^7.4.4",
     "@babel/preset-env": "^7.4.5",
     "@babel/preset-react": "^7.0.0",
-    "@browser-bunyan/console-formatted-stream": "^1.6.2",
     "@handsontable/react": "=2.1.0",
     "autoprefixer": "^9.0.0",
     "babel-eslint": "^10.0.1",
@@ -184,7 +182,7 @@
     "babel-plugin-lodash": "^3.3.4",
     "babel-plugin-transform-imports": "^2.0.0",
     "bootstrap": "^4.5.0",
-    "browser-bunyan": "^1.6.3",
+    "browser-bunyan": "^1.3.0",
     "browser-sync": "^2.26.3",
     "bunyan-debug": "^2.0.0",
     "cli": "~1.0.1",

+ 3 - 1
src/client/styles/scss/theme/spring.scss

@@ -97,7 +97,7 @@ html[dark] {
   //Button
   // Outline buttons are applyed the accent color to this spring theme cuz the primary is too light and it looks like unable to click them.
   .btn.btn-outline-primary {
-    @include btn-page-editor-mode-manager(darken($primary, 50%), darken($primary, 50%), lighten($primary, 10%));
+    @include button-outline-variant($accentcolor, $accentcolor, lighten($accentcolor, 20%), $accentcolor);
   }
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
@@ -150,6 +150,8 @@ html[dark] {
 
   h1,
   h2 {
+    color: $subthemecolor;
+
     svg {
       fill: $subthemecolor;
     }

+ 1 - 3
src/lib/service/logger/alias-for-debug.js

@@ -1,5 +1,3 @@
-const generateBunyanLogger = require('./index');
-
 /**
  * return 'debug' method of bunyan logger
  *
@@ -8,6 +6,6 @@ const generateBunyanLogger = require('./index');
  * @param {string} name
  */
 module.exports = (name) => {
-  const bunyanLogger = generateBunyanLogger(name);
+  const bunyanLogger = require('./index')(name);
   return bunyanLogger.debug.bind(bunyanLogger);
 };

+ 63 - 11
src/lib/service/logger/index.js

@@ -1,16 +1,68 @@
-const { createLogger } = require('universal-bunyan');
+const bunyan = require('bunyan'); // will be replaced to browser-bunyan on browser by webpack
+const minimatch = require('minimatch');
 
-const configForDev = require('@root/config/logger/config.dev');
-const configForProd = require('@root/config/logger/config.prod');
+const isBrowser = typeof window !== 'undefined';
+const isProd = process.env.NODE_ENV === 'production';
 
-const isProduction = process.env.NODE_ENV === 'production';
-const config = isProduction ? configForProd : configForDev;
+const config = require('@root/config').logger;
+const stream = isProd ? require('./stream.prod') : require('./stream.dev');
 
-const loggerFactory = function(name) {
-  return createLogger({
-    name,
-    config,
-  });
+// logger store
+const loggers = {};
+
+
+// merge configuration from environment variables
+const envLevelMap = {
+  INFO:   'info',
+  DEBUG:  'debug',
+  WARN:   'warn',
+  TRACE:  'trace',
+  ERROR:  'error',
 };
+Object.keys(envLevelMap).forEach((envName) => { // ['INFO', 'DEBUG', ...].forEach
+  const envVars = process.env[envName]; // process.env.DEBUG should have a value like 'growi:routes:page,growi:models.page,...'
+  if (envVars != null) {
+    const level = envLevelMap[envName];
+    envVars.split(',').forEach((ns) => { // ['growi:routes:page', 'growi:models.page', ...].forEach
+      config[ns.trim()] = level;
+    });
+  }
+});
+
+
+/**
+ * determine logger level
+ * @param {string} name Logger name
+ */
+function determineLoggerLevel(name) {
+  if (isBrowser && isProd) {
+    return 'error';
+  }
+
+  let level = config.default;
 
-module.exports = loggerFactory;
+  /* eslint-disable array-callback-return, no-useless-return */
+  // retrieve configured level
+  Object.keys(config).some((key) => { //  breakable forEach
+    // test whether 'name' matches to 'key'(blob)
+    if (minimatch(name, key)) {
+      level = config[key];
+      return; //                          break if match
+    }
+  });
+
+  return level;
+}
+
+module.exports = (name) => {
+  // create logger instance if absent
+  if (loggers[name] == null) {
+    loggers[name] = bunyan.createLogger({
+      name,
+      stream,
+      level: determineLoggerLevel(name),
+    });
+  }
+
+  return loggers[name];
+};

+ 16 - 0
src/lib/service/logger/stream.dev.js

@@ -0,0 +1,16 @@
+const isBrowser = typeof window !== 'undefined';
+
+let stream;
+
+// browser settings
+if (isBrowser) {
+  const ConsoleFormattedStream = require('@browser-bunyan/console-formatted-stream').ConsoleFormattedStream;
+  stream = new ConsoleFormattedStream();
+}
+// node settings
+else {
+  const bunyanFormat = require('bunyan-format');
+  stream = bunyanFormat({ outputMode: 'short' });
+}
+
+module.exports = stream;

+ 25 - 0
src/lib/service/logger/stream.prod.js

@@ -0,0 +1,25 @@
+const { envUtils } = require('growi-commons');
+
+const isBrowser = typeof window !== 'undefined';
+
+let stream;
+
+// browser settings
+if (isBrowser) {
+  const ConsoleFormattedStream = require('@browser-bunyan/console-formatted-stream').ConsoleFormattedStream;
+  stream = new ConsoleFormattedStream();
+}
+// node settings
+else {
+  const isFormat = (process.env.FORMAT_NODE_LOG == null) || envUtils.toBoolean(process.env.FORMAT_NODE_LOG);
+
+  if (isFormat) {
+    const bunyanFormat = require('bunyan-format');
+    stream = bunyanFormat({ outputMode: 'long' });
+  }
+  else {
+    stream = process.stdout;
+  }
+}
+
+module.exports = stream;

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

@@ -533,7 +533,7 @@ module.exports = function(crowi) {
       /\s+\/\s+/, // avoid miss in renaming
       /.+\/edit$/,
       /.+\.md$/,
-      /^\/(installer|register|login|logout|admin|me|files|trash|paste|comments|tags|share)(\/.*|$)/,
+      /^\/(installer|register|login|logout|admin|me|files|trash|paste|comments|tags)(\/.*|$)/,
     ];
 
     let isCreatable = true;

+ 3 - 24
src/server/routes/apiv3/slack-bot.js

@@ -1,10 +1,6 @@
 
 const express = require('express');
 
-const loggerFactory = require('@alias/logger');
-
-const logger = loggerFactory('growi:routes:apiv3:slack-bot');
-
 const router = express.Router();
 
 module.exports = (crowi) => {
@@ -12,30 +8,13 @@ module.exports = (crowi) => {
   const { boltService } = crowi;
   const requestHandler = boltService.receiver.requestHandler.bind(boltService.receiver);
 
-
-  // Check if the access token is correct
-  function verificationAccessToken(req, res, next) {
-    const slackBotAccessToken = req.body.slack_bot_access_token || null;
-
-    if (slackBotAccessToken == null || slackBotAccessToken !== this.crowi.configManager.getConfig('crowi', 'slackbot:access-token')) {
-      logger.error('slack_bot_access_token is invalid.');
-      return res.send('*Access token is inValid*');
-    }
-
-    return next();
-  }
-
-  function verificationRequestUrl(req, res, next) {
+  router.post('/', async(req, res) => {
     // for verification request URL on Event Subscriptions
     if (req.body.type === 'url_verification') {
-      return res.send(req.body);
+      res.send(req.body);
+      return;
     }
 
-    return next();
-  }
-
-  router.post('/', verificationRequestUrl, verificationAccessToken, async(req, res) => {
-
     // Send response immediately to avoid opelation_timeout error
     // See https://api.slack.com/apis/connections/events-api#the-events-api__responding-to-events
     res.send();

+ 5 - 5
src/server/routes/apiv3/slack-integration.js

@@ -55,9 +55,9 @@ module.exports = (crowi) => {
   }
 
 
-  function generateAccessToken(user) {
-    const hasher = crypto.createHash('sha512');
-    hasher.update(new Date().getTime() + user._id);
+  function generateAccessToken() {
+    const hasher = crypto.createHash('sha256');
+    hasher.update(`${new Date().getTime()}`);
 
     return hasher.digest('base64');
   }
@@ -158,10 +158,10 @@ module.exports = (crowi) => {
    *          200:
    *            description: Succeeded to update access token for slack
    */
-  router.put('/access-token', loginRequiredStrictly, adminRequired, async(req, res) => {
+  router.put('/access-token', loginRequiredStrictly, adminRequired, csrf, async(req, res) => {
 
     try {
-      const accessToken = generateAccessToken(req.user);
+      const accessToken = generateAccessToken();
       await updateSlackBotSettings({ 'slackbot:access-token': accessToken });
 
       return res.apiv3({ accessToken });

+ 15 - 0
src/server/service/bolt.js

@@ -74,11 +74,26 @@ class BoltService {
     }
   }
 
+  verifyAccessToken(body, command) {
+    const slackBotAccessToken = body.slack_bot_access_token || null;
+    if (slackBotAccessToken == null || slackBotAccessToken !== this.crowi.configManager.getConfig('crowi', 'slackbot:access-token')) {
+      logger.error('slack_bot_access_token is inValid.');
+      this.client.chat.postEphemeral({
+        channel: command.channel_id,
+        user: command.user_id,
+        blocks: [this.generateMarkdownSectionBlock('*Access token is inValid*')],
+      });
+      throw new Error('slack_bot_access_token is inValid');
+    }
+  }
+
   init() {
     this.bolt.command('/growi', async({
       command, client, body, ack,
     }) => {
       await ack();
+      this.verifyAccessToken(body, command);
+
       const args = command.text.split(' ');
       const firstArg = args[0];
 

+ 13 - 32
src/server/service/page.js

@@ -5,7 +5,6 @@ const debug = require('debug')('growi:models:page');
 const { Writable } = require('stream');
 const { createBatchStream } = require('@server/util/batch-stream');
 const { isTrashPage } = require('@commons/util/path-utils');
-const streamToPromise = require('stream-to-promise');
 const { serializePageSecurely } = require('../models/serializers/page-serializer');
 
 const BULK_REINDEX_SIZE = 100;
@@ -58,10 +57,6 @@ class PageService {
     // sanitize path
     newPagePath = this.crowi.xss.process(newPagePath); // eslint-disable-line no-param-reassign
 
-    if (isRecursively) {
-      await this.renameDescendantsWithStream(page, newPagePath, user, options);
-    }
-
     const update = {};
     // update Page
     update.path = newPagePath;
@@ -79,6 +74,10 @@ class PageService {
       await Page.create(path, body, user, { redirectTo: newPagePath });
     }
 
+    if (isRecursively) {
+      this.renameDescendantsWithStream(page, newPagePath, user, options);
+    }
+
     this.pageEvent.emit('delete', page, user, socketClientId);
     this.pageEvent.emit('create', renamedPage, user, socketClientId);
 
@@ -142,9 +141,6 @@ class PageService {
    */
   async renameDescendantsWithStream(targetPage, newPagePath, user, options = {}) {
     const Page = this.crowi.model('Page');
-    const UserGroupRelation = this.crowi.model('UserGroupRelation');
-
-    const userGroups = await UserGroupRelation.findAllUserGroupIdsRelatedToUser(user);
     const newPagePathPrefix = newPagePath;
     const { PageQueryBuilder } = Page;
     const pathRegExp = new RegExp(`^${escapeStringRegexp(targetPage.path)}`, 'i');
@@ -152,7 +148,7 @@ class PageService {
     const readStream = new PageQueryBuilder(Page.find())
       .addConditionToExcludeRedirect()
       .addConditionToListOnlyDescendants(targetPage.path)
-      .addConditionToFilteringByViewer(user, userGroups)
+      .addConditionToFilteringByViewer(user)
       .query
       .lean()
       .cursor({ batchSize: BULK_REINDEX_SIZE });
@@ -186,8 +182,6 @@ class PageService {
     readStream
       .pipe(createBatchStream(BULK_REINDEX_SIZE))
       .pipe(writeStream);
-
-    return streamToPromise(writeStream);
   }
 
 
@@ -240,14 +234,14 @@ class PageService {
 
     newPagePath = this.crowi.xss.process(newPagePath); // eslint-disable-line no-param-reassign
 
-    if (isRecursively) {
-      await this.duplicateDescendantsWithStream(page, newPagePath, user);
-    }
-
     const createdPage = await Page.create(
       newPagePath, page.revision.body, user, options,
     );
 
+    if (isRecursively) {
+      this.duplicateDescendantsWithStream(page, newPagePath, user);
+    }
+
     // take over tags
     const originTags = await page.findRelatedTagsById();
     let savedTags = [];
@@ -348,9 +342,6 @@ class PageService {
 
   async duplicateDescendantsWithStream(page, newPagePath, user) {
     const Page = this.crowi.model('Page');
-    const UserGroupRelation = this.crowi.model('UserGroupRelation');
-
-    const userGroups = await UserGroupRelation.findAllUserGroupIdsRelatedToUser(user);
     const newPagePathPrefix = newPagePath;
     const pathRegExp = new RegExp(`^${escapeStringRegexp(page.path)}`, 'i');
 
@@ -359,7 +350,7 @@ class PageService {
     const readStream = new PageQueryBuilder(Page.find())
       .addConditionToExcludeRedirect()
       .addConditionToListOnlyDescendants(page.path)
-      .addConditionToFilteringByViewer(user, userGroups)
+      .addConditionToFilteringByViewer(user)
       .query
       .lean()
       .cursor({ batchSize: BULK_REINDEX_SIZE });
@@ -394,7 +385,6 @@ class PageService {
       .pipe(createBatchStream(BULK_REINDEX_SIZE))
       .pipe(writeStream);
 
-    return streamToPromise(writeStream);
   }
 
 
@@ -490,15 +480,12 @@ class PageService {
    */
   async deleteDescendantsWithStream(targetPage, user, options = {}) {
     const Page = this.crowi.model('Page');
-    const UserGroupRelation = this.crowi.model('UserGroupRelation');
-
-    const userGroups = await UserGroupRelation.findAllUserGroupIdsRelatedToUser(user);
     const { PageQueryBuilder } = Page;
 
     const readStream = new PageQueryBuilder(Page.find())
       .addConditionToExcludeRedirect()
       .addConditionToListOnlyDescendants(targetPage.path)
-      .addConditionToFilteringByViewer(user, userGroups)
+      .addConditionToFilteringByViewer(user)
       .query
       .lean()
       .cursor({ batchSize: BULK_REINDEX_SIZE });
@@ -569,15 +556,12 @@ class PageService {
    */
   async deleteCompletelyDescendantsWithStream(targetPage, user, options = {}) {
     const Page = this.crowi.model('Page');
-    const UserGroupRelation = this.crowi.model('UserGroupRelation');
-
-    const userGroups = await UserGroupRelation.findAllUserGroupIdsRelatedToUser(user);
     const { PageQueryBuilder } = Page;
 
     const readStream = new PageQueryBuilder(Page.find())
       .addConditionToExcludeRedirect()
       .addConditionToListOnlyDescendants(targetPage.path)
-      .addConditionToFilteringByViewer(user, userGroups)
+      .addConditionToFilteringByViewer(user)
       .query
       .lean()
       .cursor({ batchSize: BULK_REINDEX_SIZE });
@@ -698,15 +682,12 @@ class PageService {
    */
   async revertDeletedDescendantsWithStream(targetPage, user, options = {}) {
     const Page = this.crowi.model('Page');
-    const UserGroupRelation = this.crowi.model('UserGroupRelation');
-
-    const userGroups = await UserGroupRelation.findAllUserGroupIdsRelatedToUser(user);
     const { PageQueryBuilder } = Page;
 
     const readStream = new PageQueryBuilder(Page.find())
       .addConditionToExcludeRedirect()
       .addConditionToListOnlyDescendants(targetPage.path)
-      .addConditionToFilteringByViewer(user, userGroups)
+      .addConditionToFilteringByViewer(user)
       .query
       .lean()
       .cursor({ batchSize: BULK_REINDEX_SIZE });

+ 17 - 52
yarn.lock

@@ -1315,31 +1315,21 @@
   resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
   integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
 
-"@browser-bunyan/console-formatted-stream@^1.6.2":
-  version "1.6.2"
-  resolved "https://registry.yarnpkg.com/@browser-bunyan/console-formatted-stream/-/console-formatted-stream-1.6.2.tgz#e458a1913b952249afa4be3fde0d7b3068ab9507"
-  integrity sha512-RFY4VG5+ewPG5A4LC3uN4AC8MIXEjlUJ568VlXhdMDfV9/LUrUX1LUbf0UmFQ3OhI2jqbeC31XwP0gBIrwbXpw==
-  dependencies:
-    "@browser-bunyan/levels" "^1.6.0"
-
-"@browser-bunyan/console-plain-stream@^1.6.0":
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/@browser-bunyan/console-plain-stream/-/console-plain-stream-1.6.0.tgz#295404482150e7693846ccb07045676218bcc911"
-  integrity sha512-92j8/Lk7yD6F4JKygWd7g9++QoNiEIj1MAP5zMGVk0g1ssPs3vqK1F+HgWfzYaHccREJ6S553imX9Ll5OAn2nA==
+"@browser-bunyan/console-formatted-stream@^1.3.0":
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/@browser-bunyan/console-formatted-stream/-/console-formatted-stream-1.3.0.tgz#3dc059aa5c1b2a7a1f26e2706e2bdeb9a09bbe57"
   dependencies:
-    "@browser-bunyan/levels" "^1.6.0"
+    "@browser-bunyan/levels" "^1.3.0"
 
-"@browser-bunyan/console-raw-stream@^1.6.0":
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/@browser-bunyan/console-raw-stream/-/console-raw-stream-1.6.0.tgz#255f4734c064dc046fe7896353982c563e2ec150"
-  integrity sha512-OqPe4uy/rGOL8ZRiq3iwGM/YIGWKd2ne+8cxWSsMbcLL5hr66IOhzr3nwhyRsSo58JbWDC3K/IaJDyoOTcwrdA==
+"@browser-bunyan/console-raw-stream@^1.3.0":
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/@browser-bunyan/console-raw-stream/-/console-raw-stream-1.3.0.tgz#ccf24b56f2265058297c6517fbecea84ebb7818c"
   dependencies:
-    "@browser-bunyan/levels" "^1.6.0"
+    "@browser-bunyan/levels" "^1.3.0"
 
-"@browser-bunyan/levels@^1.6.0":
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/@browser-bunyan/levels/-/levels-1.6.0.tgz#3a50b8118254aa2ac26caf9d2aafa72d157e374b"
-  integrity sha512-wte6nXXZH62Y/RGysYRlOkKxuJn+4S8xEamMF0fDncxxy0SriCHYwGPyWGF0FWYWmRzbZuEkp7dNebBf9Xfeeg==
+"@browser-bunyan/levels@^1.3.0":
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/@browser-bunyan/levels/-/levels-1.3.0.tgz#a052303ae5d1a1f9b63eeb3a94495a2f429f4831"
 
 "@cnakazawa/watch@^1.0.3":
   version "1.0.3"
@@ -3443,15 +3433,13 @@ brorand@^1.0.1:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
 
-browser-bunyan@^1.6.3:
-  version "1.6.3"
-  resolved "https://registry.yarnpkg.com/browser-bunyan/-/browser-bunyan-1.6.3.tgz#0e58c51ff48507317ba8e5cf579e8b6bad7281e0"
-  integrity sha512-HRg+acpwO3dsY2RWgtjw2wPVHV+uzbCrdhUxD25+qo5NFSTpbfJekrRP0yFNypAhG5LwXFV1Dc5FIc8cxwU5rQ==
+browser-bunyan@^1.3.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/browser-bunyan/-/browser-bunyan-1.3.0.tgz#26378dc58d7a98002cc9bfcfba2ea5d712449992"
   dependencies:
-    "@browser-bunyan/console-formatted-stream" "^1.6.2"
-    "@browser-bunyan/console-plain-stream" "^1.6.0"
-    "@browser-bunyan/console-raw-stream" "^1.6.0"
-    "@browser-bunyan/levels" "^1.6.0"
+    "@browser-bunyan/console-formatted-stream" "^1.3.0"
+    "@browser-bunyan/console-raw-stream" "^1.3.0"
+    "@browser-bunyan/levels" "^1.3.0"
 
 browser-or-node@>=1.2.1:
   version "1.2.1"
@@ -3694,16 +3682,6 @@ bunyan@^1.8.12, bunyan@^1.8.3:
     mv "~2"
     safe-json-stringify "~1"
 
-bunyan@^1.8.15:
-  version "1.8.15"
-  resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.15.tgz#8ce34ca908a17d0776576ca1b2f6cbd916e93b46"
-  integrity sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig==
-  optionalDependencies:
-    dtrace-provider "~0.8"
-    moment "^2.19.3"
-    mv "~2"
-    safe-json-stringify "~1"
-
 busboy@^0.2.11:
   version "0.2.14"
   resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453"
@@ -10359,11 +10337,6 @@ moment@>=2.26.0:
   resolved "https://registry.yarnpkg.com/moment/-/moment-2.26.0.tgz#5e1f82c6bafca6e83e808b30c8705eed0dcbd39a"
   integrity sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw==
 
-moment@^2.19.3:
-  version "2.29.1"
-  resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
-  integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
-
 mongodb@3.6.2, mongodb@^3.1.0, mongodb@^3.6.2:
   version "3.6.2"
   resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-3.6.2.tgz#1154a4ac107bf1375112d83a29c5cf97704e96b6"
@@ -15940,14 +15913,6 @@ unist-util-visit@^1.1.0:
   dependencies:
     unist-util-visit-parents "^2.0.0"
 
-universal-bunyan@^0.9.2:
-  version "0.9.2"
-  resolved "https://registry.yarnpkg.com/universal-bunyan/-/universal-bunyan-0.9.2.tgz#4cf09dc34070390d8f5df4fe9af6a80fcd0dd574"
-  integrity sha512-MkyO17+5AVCpFfhMtYLODvSZmPxV8eHcoOAWobEXXzlXrSnf5YgCV5lBWcMV3VPaaKyZPQ0oG5PSWYmGSBGtIg==
-  dependencies:
-    bunyan-format "^0.2.1"
-    minimatch "^3.0.4"
-
 universalify@^0.1.0:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7"