Ver Fonte

Merge remote-tracking branch 'origin/dev/4.0.x' into support/apply-bootstrap4

itizawa há 6 anos atrás
pai
commit
7bfea4deb4

+ 10 - 1
CHANGES.md

@@ -5,10 +5,19 @@
 * Support: Upgrade libs
     * bootstrap
 
-## v3.7.5
+## v3.7.6
 
 *
 
+## v3.7.5
+
+* Fix: Draw.io diagrams rendered twice
+* Fix: Behavior of password reset modal is strange
+* Fix: Import GROWI Archive doesn't restore some data correctly
+* Fix: Attachments list on root page and users top pages
+* Fix: Trash page shouldn't be editable
+* Fix: Rendering Timeline on /trash
+
 ## v3.7.4
 
 * Fix: Broken by displaying user image

+ 2 - 2
bin/github-actions/update-readme.sh

@@ -2,5 +2,5 @@
 
 cd docker
 
-sed -i -e "s/^\([*] \[\`\)[^\`]\+\(\`, \`3\.6\`, .\+\]\)\(.\+\/blob\/v\).\+\(\/docker\/Dockerfile.\+\)$/\1${RELEASE_VERSION}\2\3${RELEASE_VERSION}\4/" README.md
-sed -i -e "s/^\([*] \[\`\)[^\`]\+\(\`, \`3\.6-nocdn\`, .\+\]\)\(.\+\/blob\/v\).\+\(\/docker\/Dockerfile.\+\)$/\1${RELEASE_VERSION}-nocdn\2\3${RELEASE_VERSION}\4/" README.md
+sed -i -e "s/^\([*] \[\`\)[^\`]\+\(\`, \`3\.7\`, .\+\]\)\(.\+\/blob\/v\).\+\(\/docker\/Dockerfile.\+\)$/\1${RELEASE_VERSION}\2\3${RELEASE_VERSION}\4/" README.md
+sed -i -e "s/^\([*] \[\`\)[^\`]\+\(\`, \`3\.7-nocdn\`, .\+\]\)\(.\+\/blob\/v\).\+\(\/docker\/Dockerfile.\+\)$/\1${RELEASE_VERSION}-nocdn\2\3${RELEASE_VERSION}\4/" README.md

+ 4 - 6
docker/README.md

@@ -10,12 +10,10 @@ GROWI Official docker image
 Supported tags and respective Dockerfile links
 ------------------------------------------------
 
-* [`3.6.0`, `3.6`, `3`, `latest`, (Dockerfile)](https://github.com/weseek/growi/blob/v3.6.0/docker/Dockerfile)
-* [`3.6.0-nocdn`, `3.6-nocdn`, `3-nocdn`, `latest-nocdn`, (Dockerfile)](https://github.com/weseek/growi/blob/v3.6.0/docker/Dockerfile)
-* [`3.5.25`, `3.5`, `3`, (Dockerfile)](https://github.com/weseek/growi-docker/blob/v3.5.25/Dockerfile)
-* [`3.5.25-nocdn`, `3.5-nocdn`, `3-nocdn` (Dockerfile)](https://github.com/weseek/growi-docker/blob/v3.5.25/nocdn/Dockerfile)
-* [`3.4.7`, `3.4`, `3`, (Dockerfile)](https://github.com/weseek/growi-docker/blob/v3.4.7/Dockerfile)
-* [`3.4.7-nocdn`, `3.4-nocdn`, `3-nocdn` (Dockerfile)](https://github.com/weseek/growi-docker/blob/v3.4.7/nocdn/Dockerfile)
+* [`3.7.0`, `3.7`, `3`, `latest` (Dockerfile)](https://github.com/weseek/growi/blob/v3.7.0/docker/Dockerfile)
+* [`3.7.0-nocdn`, `3.7-nocdn`, `3-nocdn`, `latest-nocdn` (Dockerfile)](https://github.com/weseek/growi/blob/v3.7.0/docker/Dockerfile)
+* [`3.6.10`, `3.6` (Dockerfile)](https://github.com/weseek/growi/blob/v3.6.10/docker/Dockerfile)
+* [`3.6.10-nocdn`, `3.6-nocdn` (Dockerfile)](https://github.com/weseek/growi/blob/v3.6.10/docker/Dockerfile)
 
 
 What is GROWI?

+ 2 - 0
resource/locales/en-US/translation.json

@@ -189,9 +189,11 @@
   "Update API Token": "Update API Token",
   "header_search_box": {
     "label": {
+      "All pages": "All pages",
       "This tree": "This tree"
     },
     "item_label": {
+      "All pages": "All pages",
       "This tree": "Only children of this tree"
     }
   },

+ 2 - 0
resource/locales/ja/translation.json

@@ -188,9 +188,11 @@
   "Update API Token": "API Tokenを更新",
   "header_search_box": {
     "label": {
+      "All pages": "全てのページ",
       "This tree": "この階層"
     },
     "item_label": {
+      "All pages": "全てのページ",
       "This tree": "この階層下の子ページのみ"
     }
   },

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

@@ -75,8 +75,8 @@ Object.assign(componentMappings, {
   'page-status-alert': <PageStatusAlert />,
   'save-page-controls': <SavePageControls />,
 
-  'user-created-list': <RecentCreated />,
-  'user-draft-list': <MyDraftList />,
+  'page-timeline': <PageTimeline />,
+
   'personal-setting': <PersonalSettings crowi={personalContainer} />,
 });
 
@@ -86,13 +86,15 @@ if (pageContainer.state.pageId != null) {
     'page-editor-with-hackmd': <PageEditorByHackmd />,
     'page-comments-list': <PageComments />,
     'page-attachment': <PageAttachment />,
-    'page-timeline': <PageTimeline />,
     'page-comment-write': <CommentEditorLazyRenderer />,
     'revision-toc': <TableOfContents />,
     'seen-user-list': <UserPictureList userIds={pageContainer.state.seenUserIds} />,
     'liker-list': <UserPictureList userIds={pageContainer.state.likerUserIds} />,
     'rename-page-name-input': <PagePathAutoComplete crowi={appContainer} initializedPath={pageContainer.state.path} />,
     'duplicate-page-name-input': <PagePathAutoComplete crowi={appContainer} initializedPath={pageContainer.state.path} />,
+
+    'user-created-list': <RecentCreated />,
+    'user-draft-list': <MyDraftList />,
   });
 }
 if (pageContainer.state.path != null) {

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

@@ -60,7 +60,7 @@ class HeaderSearchBox extends React.Component {
     const { t, appContainer } = this.props;
     const scopeLabel = this.state.isScopeChildren
       ? t('header_search_box.label.This tree')
-      : 'All pages';
+      : t('header_search_box.label.All pages');
 
     const config = appContainer.getConfig();
     const isReachable = config.isSearchServiceReachable;
@@ -73,7 +73,7 @@ class HeaderSearchBox extends React.Component {
               {scopeLabel}
             </button>
             <div className="dropdown-menu">
-              <button className="dropdown-item" type="button" onClick={this.onClickAllPages}>All pages</button>
+              <button className="dropdown-item" type="button" onClick={this.onClickAllPages}>{ t('header_search_box.item_label.All pages') }</button>
               <button className="dropdown-item" type="button" onClick={this.onClickChildren}>{ t('header_search_box.item_label.This tree') }</button>
             </div>
           </div>

+ 0 - 30
src/client/js/components/Page/PagePath.jsx

@@ -1,30 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-export default class PagePath extends React.Component {
-
-  linkPath(path) {
-    return path;
-  }
-
-  render() {
-    const page = this.props.page;
-    const shortPath = this.getShortPath(page.path);
-    const pathPrefix = page.path.replace(new RegExp(`${shortPath}(/)?$`), '');
-
-    return (
-      <span className="page-path">
-        {pathPrefix}
-        <strong>{shortPath}</strong>
-      </span>
-    );
-  }
-
-}
-
-PagePath.propTypes = {
-  page: PropTypes.object.isRequired,
-};
-
-PagePath.defaultProps = {
-};

+ 11 - 5
src/migrations/20191102223901-drop-pages-indices.js

@@ -4,7 +4,14 @@ const logger = require('@alias/logger')('growi:migrate:drop-pages-indices');
 const mongoose = require('mongoose');
 const config = require('@root/config/migrate');
 
-async function dropIndexIfExists(collection, indexName) {
+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);
   }
@@ -15,10 +22,9 @@ module.exports = {
     logger.info('Apply migration');
     mongoose.connect(config.mongoUri, config.mongodb.options);
 
-    const collection = db.collection('pages');
-    await dropIndexIfExists(collection, 'lastUpdateUser_1');
-    await dropIndexIfExists(collection, 'liker_1');
-    await dropIndexIfExists(collection, 'seenUsers_1');
+    await dropIndexIfExists(db, 'pages', 'lastUpdateUser_1');
+    await dropIndexIfExists(db, 'pages', 'liker_1');
+    await dropIndexIfExists(db, 'pages', 'seenUsers_1');
 
     logger.info('Migration has successfully applied');
   },

+ 3 - 2
src/server/crowi/express-init.js

@@ -97,15 +97,16 @@ module.exports = function(crowi, app) {
   app.use(cookieParser());
 
   // configure express-session
+  const sessionMiddleware = expressSession(crowi.sessionConfig);
   app.use((req, res, next) => {
-    // test whether the route is listed in avoidSessionTroutes
+    // test whether the route is listed in avoidSessionRoutes
     for (const regex of avoidSessionRoutes) {
       if (regex.test(req.path)) {
         return next();
       }
     }
 
-    expressSession(crowi.sessionConfig)(req, res, next);
+    sessionMiddleware(req, res, next);
   });
 
   // passport

+ 13 - 14
src/server/service/import.js

@@ -97,28 +97,27 @@ class ImportService {
    * @param {any} value value from imported document
    * @param {{ document: object, schema: object, propertyName: string }}
    * @return {any} new value for the document
+   *
+   * @see https://mongoosejs.com/docs/api/schematype.html#schematype_SchemaType-cast
    */
   keepOriginal(value, { document, schema, propertyName }) {
-    let _value = value;
+    // Model
+    if (schema != null && schema.path(propertyName) != null) {
+      const schemaType = schema.path(propertyName);
+      return schemaType.cast(value);
+    }
 
     // _id
     if (propertyName === '_id' && ObjectId.isValid(value)) {
-      _value = ObjectId(value);
-    }
-    // Date
-    else if (isIsoDate(value)) {
-      _value = parseISO(value);
+      return ObjectId(value);
     }
 
-    // Model
-    if (schema != null) {
-      // ObjectID
-      if (schema[propertyName] != null && schema[propertyName].instance === 'ObjectID' && ObjectId.isValid(value)) {
-        _value = ObjectId(value);
-      }
+    // Date
+    if (isIsoDate(value)) {
+      return parseISO(value);
     }
 
-    return _value;
+    return value;
   }
 
   /**
@@ -409,7 +408,7 @@ class ImportService {
    */
   convertDocuments(collectionName, document, overwriteParams) {
     const Model = this.growiBridgeService.getModelFromCollectionName(collectionName);
-    const schema = (Model != null) ? Model.schema.paths : null;
+    const schema = (Model != null) ? Model.schema : null;
     const convertMap = this.convertMap[collectionName];
 
     const _document = {};

+ 1 - 1
src/server/views/layout-growi/page_list.html

@@ -42,7 +42,7 @@
 {% endblock %}
 
 
-{% block content_footer %}
+{% block content_main_after %}
   {% if page %}
     {% include '../widget/page_attachments.html' %}
   {% endif %}

+ 4 - 0
src/server/views/layout-growi/user_page.html

@@ -73,4 +73,8 @@
 
 {% block content_main_after %}
   {% include 'widget/comments.html' %}
+
+  {% if page %}
+    {% include '../widget/page_attachments.html' %}
+  {% endif %}
 {% endblock %}

+ 1 - 1
src/server/views/layout-kibela/page_list.html

@@ -40,7 +40,7 @@
 {% endblock %}
 
 
-{% block content_footer %}
+{% block content_main_after %}
   {% if page %}
     {% include '../widget/page_attachments.html' %}
   {% endif%}

+ 4 - 0
src/server/views/layout-kibela/user_page.html

@@ -64,4 +64,8 @@
 
 {% block content_main_after %}
   {% include 'widget/comments.html' %}
+
+  {% if page %}
+    {% include '../widget/page_attachments.html' %}
+  {% endif %}
 {% endblock %}

+ 2 - 0
src/server/views/modal/rename.html

@@ -29,6 +29,7 @@
 
           <hr>
 
+          {% if page.grant != 2 %}
           <div class="custom-control custom-checkbox custom-checkbox-warning">
             <input class="custom-control-input" name="recursively" id="cbRenameRecursively" value="1" type="checkbox" checked >
             <label class="custom-control-label" for="cbRenameRecursively">
@@ -36,6 +37,7 @@
               <p class="form-text text-muted mt-0">{{ t('modal_rename.help.recursive', page.path) }}</p>
             </label>
           </div>
+          {% endif %}
 
           <div class="custom-control custom-checkbox custom-checkbox-success">
             <input class="custom-control-input" name="create_redirect" id="cbRenameRedirect" value="1" type="checkbox">

+ 1 - 1
src/server/views/widget/page_content.html

@@ -50,7 +50,7 @@
       </div>
     {% endif %}
 
-    {% if not page.isDeleted() %}
+    {% if !isTrashPage() %}
       {# edit form #}
       <div class="tab-pane" id="edit">
         <div id="page-editor">{% if pageForm.body %}{{ pageForm.body }}{% endif %}</div>