Browse Source

Merge pull request #1408 from weseek/dev/3.5.x

release v3.5.23
Yuki Takei 6 years ago
parent
commit
cfc3ae562d

+ 10 - 0
CHANGES.md

@@ -14,6 +14,16 @@ Upgrading Guide: https://docs.growi.org/en/admin-guide/upgrading/36x.html
 
 
 * Improvement: Drop unnecessary MongoDB collection indexes
 * Improvement: Drop unnecessary MongoDB collection indexes
 
 
+
+
+## 3.5.23-RC
+
+* Fix: Global Notification failed to send e-mail
+* Fix: Pagination is not working for trash list
+* Fix: Healthcheck API with `?connectToMiddlewares` returns error
+* Support: Upgrade libs
+    * growi-commons
+
 ## 3.5.22
 ## 3.5.22
 
 
 * Improvement: Add `FILE_UPLOAD_DISABLED` env var
 * Improvement: Add `FILE_UPLOAD_DISABLED` env var

+ 2 - 2
package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "growi",
   "name": "growi",
-  "version": "3.5.22-RC",
+  "version": "3.5.23-RC",
   "description": "Team collaboration software using markdown",
   "description": "Team collaboration software using markdown",
   "tags": [
   "tags": [
     "wiki",
     "wiki",
@@ -101,7 +101,7 @@
     "express-validator": "^6.1.1",
     "express-validator": "^6.1.1",
     "express-webpack-assets": "^0.1.0",
     "express-webpack-assets": "^0.1.0",
     "graceful-fs": "^4.1.11",
     "graceful-fs": "^4.1.11",
-    "growi-commons": "^4.0.7",
+    "growi-commons": "^4.0.8",
     "helmet": "^3.13.0",
     "helmet": "^3.13.0",
     "i18next": "^19.0.0",
     "i18next": "^19.0.0",
     "i18next-express-middleware": "^1.4.1",
     "i18next-express-middleware": "^1.4.1",

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

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

+ 7 - 10
src/server/routes/page.js

@@ -72,9 +72,6 @@ module.exports = function(crowi, app) {
   }
   }
 
 
   function generatePager(offset, limit, totalCount) {
   function generatePager(offset, limit, totalCount) {
-    let next = null;
-
-
     let prev = null;
     let prev = null;
 
 
     if (offset > 0) {
     if (offset > 0) {
@@ -84,12 +81,10 @@ module.exports = function(crowi, app) {
       }
       }
     }
     }
 
 
-    if (totalCount < limit) {
+    let next = offset + limit;
+    if (totalCount < next) {
       next = null;
       next = null;
     }
     }
-    else {
-      next = offset + limit;
-    }
 
 
     return {
     return {
       prev,
       prev,
@@ -164,7 +159,7 @@ module.exports = function(crowi, app) {
 
 
     const queryOptions = {
     const queryOptions = {
       offset,
       offset,
-      limit: limit + 1,
+      limit,
       includeTrashed: path.startsWith('/trash/'),
       includeTrashed: path.startsWith('/trash/'),
       isRegExpEscapedFromPath,
       isRegExpEscapedFromPath,
     };
     };
@@ -469,13 +464,15 @@ module.exports = function(crowi, app) {
   };
   };
 
 
   actions.deletedPageListShow = async function(req, res) {
   actions.deletedPageListShow = async function(req, res) {
-    const path = `/trash${getPathFromRequest(req)}`;
+    // normalizePath makes '/trash/' -> '/trash'
+    const path = pathUtils.normalizePath(`/trash${getPathFromRequest(req)}`);
+
     const limit = 50;
     const limit = 50;
     const offset = parseInt(req.query.offset) || 0;
     const offset = parseInt(req.query.offset) || 0;
 
 
     const queryOptions = {
     const queryOptions = {
       offset,
       offset,
-      limit: limit + 1,
+      limit,
       includeTrashed: true,
       includeTrashed: true,
     };
     };
 
 

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

@@ -47,12 +47,13 @@ class GlobalNotificationMailService {
    * @return  {{ subject: string, template: string, vars: object }}
    * @return  {{ subject: string, template: string, vars: object }}
    */
    */
   generateOption(event, path, triggeredBy, { comment, oldPath }) {
   generateOption(event, path, triggeredBy, { comment, oldPath }) {
+    const defaultLang = this.crowi.configManager.getConfig('crowi', 'app:globalLang');
     // validate for all events
     // validate for all events
     if (event == null || path == null || triggeredBy == null) {
     if (event == null || path == null || triggeredBy == null) {
       throw new Error(`invalid vars supplied to GlobalNotificationMailService.generateOption for event ${event}`);
       throw new Error(`invalid vars supplied to GlobalNotificationMailService.generateOption for event ${event}`);
     }
     }
 
 
-    const template = nodePath.join(this.crowi.localeDir, `${this.defaultLang}/notifications/${event}.txt`);
+    const template = nodePath.join(this.crowi.localeDir, `${defaultLang}/notifications/${event}.txt`);
     let subject;
     let subject;
     let vars = {
     let vars = {
       appTitle: this.crowi.appService.getAppTitle(),
       appTitle: this.crowi.appService.getAppTitle(),

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

@@ -21,12 +21,8 @@ class ElasticsearchDelegator {
     this.configManager = configManager;
     this.configManager = configManager;
     this.searchEvent = searchEvent;
     this.searchEvent = searchEvent;
 
 
-    this.esNodeName = '-';
-    this.esNodeNames = [];
     this.esVersion = 'unknown';
     this.esVersion = 'unknown';
-    this.esVersions = [];
-    this.esPlugin = [];
-    this.esPlugins = [];
+    this.esNodeInfos = {};
 
 
     this.client = null;
     this.client = null;
 
 
@@ -72,6 +68,13 @@ class ElasticsearchDelegator {
     this.indexName = indexName;
     this.indexName = indexName;
   }
   }
 
 
+  getInfo() {
+    return {
+      esVersion: this.esVersion,
+      esNodeInfos: this.esNodeInfos,
+    };
+  }
+
   /**
   /**
    * return information object to connect to ES
    * return information object to connect to ES
    * @return {object} { host, httpAuth, indexName}
    * @return {object} { host, httpAuth, indexName}
@@ -158,18 +161,26 @@ class ElasticsearchDelegator {
    */
    */
   async checkESVersion() {
   async checkESVersion() {
     try {
     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');
         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.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) {
     catch (error) {

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

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

+ 1 - 1
src/server/util/swigFunctions.js

@@ -156,7 +156,7 @@ module.exports = function(crowi, req, locals) {
 
 
   locals.isTrashPage = function() {
   locals.isTrashPage = function() {
     const path = req.path || '';
     const path = req.path || '';
-    if (path.match(/^\/trash\/.*/)) {
+    if (path.match(/^\/trash(\/.*)?$/)) {
       return true;
       return true;
     }
     }
 
 

+ 4 - 4
yarn.lock

@@ -5758,10 +5758,10 @@ grapheme-splitter@^1.0.4:
   resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e"
   resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e"
   integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==
   integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==
 
 
-growi-commons@^4.0.7:
-  version "4.0.7"
-  resolved "https://registry.yarnpkg.com/growi-commons/-/growi-commons-4.0.7.tgz#f9ff9c2f6afe3a9982b689d368e8e7a000d137e8"
-  integrity sha512-Ipku+WlfXsSqS+2fuDRfOeCP5Q8dBo/8XYlcjsPFdCvKa9lBr2OsSN2ac9dAXaL9bH4wc+Kz7UR/OLjAMlx0Iw==
+growi-commons@^4.0.8:
+  version "4.0.8"
+  resolved "https://registry.yarnpkg.com/growi-commons/-/growi-commons-4.0.8.tgz#3040f2759f5eb13084b101e303c11028af2a8faf"
+  integrity sha512-AL/vm3R3LqiWwCbuEHPsDP8hapiz7ulKZXyW4399WHorx/7oEkSWb6sGdkvJiqSnRWxEcdPkfw6K0kgzilMpig==
 
 
 growly@^1.3.0:
 growly@^1.3.0:
   version "1.3.0"
   version "1.3.0"