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

Merge branch 'master' into reactify-admin/security

WESEEK Kaito 6 лет назад
Родитель
Сommit
6169198205

+ 8 - 0
CHANGES.md

@@ -14,10 +14,18 @@ Upgrading Guide: https://docs.growi.org/en/admin-guide/upgrading/36x.html
 ### Updates
 
 * Improvement: Drop unnecessary MongoDB collection indexes
+* Fix: Appending tag is failed by wrong index of PageTagRelation
+    * Introduced by 3.5.20
 * Support: Support Node.js v12
 * Support: Upgrade libs
     * growi-commons
 
+
+
+## 3.5.23
+
+* Fix: Healthcheck API with `?connectToMiddlewares` returns error
+
 ## 3.5.22
 
 * Improvement: Add `FILE_UPLOAD_DISABLED` env var

+ 1 - 1
README.md

@@ -130,7 +130,7 @@ Environment Variables
         * `mongodb` : MongoDB GridFS (Setting-less)
         * `local` : Server's Local file system (Setting-less)
         * `none` : Disable file uploading
-    * FILE_UPLOAD_DISABLED: If `true`, disabled file upload. However can view files. default: `false`
+    * FILE_UPLOAD_DISABLED: If `true`, file uploading will be disabled. However, the files can be still viewed. Default: `false`
     * MAX_FILE_SIZE: The maximum file size limit for uploads (bytes). default: `Infinity`
     * FILE_UPLOAD_TOTAL_LIMIT: Total capacity limit for uploads (bytes). default: `Infinity`
     * GCS_API_KEY_JSON_PATH: Path of the JSON file that contains [service account key to authenticate to GCP API](https://cloud.google.com/iam/docs/creating-managing-service-account-keys)

+ 33 - 0
src/migrations/20191127023815-drop-wrong-index-of-page-tag-relation.js

@@ -0,0 +1,33 @@
+require('module-alias/register');
+const logger = require('@alias/logger')('growi:migrate:drop-wrong-index-of-page-tag-relation');
+
+const mongoose = require('mongoose');
+const config = require('@root/config/migrate');
+
+async function dropIndexIfExists(db, collectionName, indexName) {
+  // check existence of the collection
+  const items = await db.listCollections({ name: collectionName }, { nameOnly: true }).toArray();
+  if (items.length === 0) {
+    return;
+  }
+
+  const collection = await db.collection(collectionName);
+  if (await collection.indexExists(indexName)) {
+    await collection.dropIndex(indexName);
+  }
+}
+
+module.exports = {
+  async up(db) {
+    logger.info('Apply migration');
+    mongoose.connect(config.mongoUri, config.mongodb.options);
+
+    await dropIndexIfExists(db, 'pagetagrelations', 'page_1_user_1');
+
+    logger.info('Migration has successfully applied');
+  },
+
+  down(db) {
+    // do not rollback
+  },
+};

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

@@ -27,7 +27,7 @@ const schema = new mongoose.Schema({
   },
 });
 // define unique compound index
-schema.index({ page: 1, user: 1 }, { unique: true });
+schema.index({ relatedPage: 1, relatedTag: 1 }, { unique: true });
 schema.plugin(mongoosePaginate);
 schema.plugin(uniqueValidator);
 

+ 5 - 6
src/server/routes/apiv3/healthcheck.js

@@ -25,7 +25,7 @@ module.exports = (crowi) => {
    *      parameters:
    *        - name: connectToMiddlewares
    *          in: query
-   *          description: Check also MongoDB and Elasticsearch
+   *          description: Check also MongoDB and SearchService
    *          schema:
    *            type: boolean
    *      responses:
@@ -38,14 +38,13 @@ module.exports = (crowi) => {
    *                  mongo:
    *                    type: string
    *                    description: 'OK'
-   *                  esInfo:
+   *                  searchInfo:
    *                    type: object
-   *                    description: A result of `client.info()` of Elasticsearch Info API
    */
   router.get('/', helmet.noCache(), async(req, res) => {
     const connectToMiddlewares = req.query.connectToMiddlewares;
 
-    // return 200 w/o connecting to MongoDB and Elasticsearch
+    // return 200 w/o connecting to MongoDB and SearchService
     if (connectToMiddlewares == null) {
       res.status(200).send({ status: 'OK' });
       return;
@@ -57,9 +56,9 @@ module.exports = (crowi) => {
       await Config.findOne({});
       // connect to Elasticsearch
       const search = crowi.getSearcher();
-      const esInfo = await search.getInfo();
+      const searchInfo = await search.getInfo();
 
-      res.status(200).send({ mongo: 'OK', esInfo });
+      res.status(200).send({ mongo: 'OK', searchInfo });
     }
     catch (err) {
       res.status(503).send({ err });

+ 1 - 0
src/server/service/global-notification/global-notification-mail.js

@@ -11,6 +11,7 @@ class GlobalNotificationMailService {
     this.mailer = crowi.getMailer();
     this.type = crowi.model('GlobalNotificationSetting').TYPE.MAIL;
     this.event = crowi.model('GlobalNotificationSetting').EVENT;
+    this.defaultLang = crowi.configManager.getConfig('crowi', 'app:globalLang');
   }
 
   /**

+ 24 - 13
src/server/service/search-delegator/elasticsearch.js

@@ -21,12 +21,8 @@ class ElasticsearchDelegator {
     this.configManager = configManager;
     this.searchEvent = searchEvent;
 
-    this.esNodeName = '-';
-    this.esNodeNames = [];
     this.esVersion = 'unknown';
-    this.esVersions = [];
-    this.esPlugin = [];
-    this.esPlugins = [];
+    this.esNodeInfos = {};
 
     this.client = null;
 
@@ -72,6 +68,13 @@ class ElasticsearchDelegator {
     this.indexName = indexName;
   }
 
+  getInfo() {
+    return {
+      esVersion: this.esVersion,
+      esNodeInfos: this.esNodeInfos,
+    };
+  }
+
   /**
    * return information object to connect to ES
    * @return {object} { host, httpAuth, indexName}
@@ -158,18 +161,26 @@ class ElasticsearchDelegator {
    */
   async checkESVersion() {
     try {
-      const nodes = await this.client.nodes.info();
-      if (!nodes._nodes || !nodes.nodes) {
+      const info = await this.client.nodes.info();
+      if (!info._nodes || !info.nodes) {
         throw new Error('no nodes info');
       }
 
-      for (const [nodeName, nodeInfo] of Object.entries(nodes.nodes)) {
-        this.esNodeName = nodeName;
-        this.esNodeNames.push(nodeName);
+      for (const [nodeName, nodeInfo] of Object.entries(info.nodes)) {
         this.esVersion = nodeInfo.version;
-        this.esVersions.push(nodeInfo.version);
-        this.esPlugin = nodeInfo.plugins;
-        this.esPlugins.push(nodeInfo.plugins);
+
+        const filteredInfo = {
+          name: nodeInfo.name,
+          version: nodeInfo.version,
+          plugins: nodeInfo.plugins.map((pluginInfo) => {
+            return {
+              name: pluginInfo.name,
+              version: pluginInfo.version,
+            };
+          }),
+        };
+
+        this.esNodeInfos[nodeName] = filteredInfo;
       }
     }
     catch (error) {

+ 1 - 1
src/server/service/search.js

@@ -65,7 +65,7 @@ class SearchService {
   }
 
   getInfo() {
-    return this.delegator.client.info({});
+    return this.delegator.getInfo();
   }
 
   async buildIndex() {