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

Merge branch 'master' into feat/export-single-page-for-merge

yusuketk 5 лет назад
Родитель
Сommit
b7aa77ef81

+ 7 - 5
CHANGES.md

@@ -1,6 +1,10 @@
 # CHANGES
 
-## v4.0.9-RC
+## v4.0.10-RC
+
+* Fix: Fail to rename/delete a page set as "Anyone with the link"
+
+## v4.0.9
 
 * Feature: Detailed configurations for OpenID Connect
     * Authorization Endpoint
@@ -10,10 +14,6 @@
     * UserInfo Endpoint
     * Registration Endpoint
     * JSON Web Key Set URI
-
-
-## v4.0.8
-
 * Improvement: Navigations
     * New floating subnavigation
     * New open drawer button
@@ -26,6 +26,8 @@
 * Fix: Unable to create page with original path after emptying trash
 * I18n: Support zh-CN
 
+## v4.0.8  (Missing number)
+
 ## v4.0.7
 
 * Feature: Set request timeout for Elasticsearch with env var `ELASTICSEARCH_REQUEST_TIMEOUT`

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "growi",
-  "version": "4.0.9-RC",
+  "version": "4.0.10-RC",
   "description": "Team collaboration software using markdown",
   "tags": [
     "wiki",

+ 1 - 3
src/client/js/components/PageManagement/ApiErrorMessage.jsx

@@ -42,12 +42,10 @@ const ApiErrorMessage = (props) => {
         return (
           <strong><i className="icon-fw icon-ban"></i> Invalid path</strong>
         );
-      case 'unknown':
+      default:
         return (
           <strong><i className="icon-fw icon-ban"></i> Unknown error occured</strong>
         );
-      default:
-        return null;
     }
   }
 

+ 11 - 8
src/client/js/services/EditorContainer.js

@@ -57,16 +57,19 @@ export default class EditorContainer extends Container {
    * initialize state for page permission
    */
   initStateGrant() {
-    const elem = document.getElementById('save-page-controls');
+    const mainContent = document.getElementById('content-main');
 
-    if (elem) {
-      this.state.grant = +elem.dataset.grant;
+    if (mainContent == null) {
+      logger.debug('#content-main element is not exists');
+      return;
+    }
 
-      const grantGroupId = elem.dataset.grantGroup;
-      if (grantGroupId != null && grantGroupId.length > 0) {
-        this.state.grantGroupId = grantGroupId;
-        this.state.grantGroupName = elem.dataset.grantGroupName;
-      }
+    this.state.grant = +mainContent.getAttribute('data-page-grant');
+
+    const grantGroupId = mainContent.getAttribute('data-page-grant-group');
+    if (grantGroupId != null && grantGroupId.length > 0) {
+      this.state.grantGroupId = grantGroupId;
+      this.state.grantGroupName = mainContent.getAttribute('data-page-grant-group-name');
     }
   }
 

+ 33 - 22
src/server/models/page.js

@@ -693,7 +693,7 @@ module.exports = function(crowi) {
   /**
    * find pages that is match with `path` and its descendants
    */
-  pageSchema.statics.findListWithDescendants = async function(path, user, option) {
+  pageSchema.statics.findListWithDescendants = async function(path, user, option = {}) {
     const builder = new PageQueryBuilder(this.find());
     builder.addConditionToListWithDescendants(path, option);
 
@@ -1094,21 +1094,18 @@ module.exports = function(crowi) {
       throw new Error('This method does NOT supports deleting trashed pages.');
     }
 
-    const findOpts = { includeRedirect: true };
-    const result = await this.findListWithDescendants(targetPage.path, user, findOpts);
+    // find descendants (this array does not include GRANT_RESTRICTED)
+    const result = await this.findListWithDescendants(targetPage.path, user);
     const pages = result.pages;
+    // add targetPage if 'grant' is GRANT_RESTRICTED
+    //  because findListWithDescendants excludes GRANT_RESTRICTED pages
+    if (targetPage.grant === GRANT_RESTRICTED) {
+      pages.push(targetPage);
+    }
 
-    let updatedPage = null;
     await Promise.all(pages.map((page) => {
-      const isParent = (page.path === targetPage.path);
-      const p = this.deletePage(page, user, options);
-      if (isParent) {
-        updatedPage = p;
-      }
-      return p;
+      return this.deletePage(page, user, options);
     }));
-
-    return updatedPage;
   };
 
   pageSchema.statics.revertDeletedPage = async function(page, user, options = {}) {
@@ -1135,7 +1132,7 @@ module.exports = function(crowi) {
   };
 
   pageSchema.statics.revertDeletedPageRecursively = async function(targetPage, user, options = {}) {
-    const findOpts = { includeRedirect: true, includeTrashed: true };
+    const findOpts = { includeTrashed: true };
     const result = await this.findListWithDescendants(targetPage.path, user, findOpts);
     const pages = result.pages;
 
@@ -1185,17 +1182,23 @@ module.exports = function(crowi) {
   /**
    * Delete Bookmarks, Attachments, Revisions, Pages and emit delete
    */
-  pageSchema.statics.completelyDeletePageRecursively = async function(pagePath, user, options = {}) {
+  pageSchema.statics.completelyDeletePageRecursively = async function(targetPage, user, options = {}) {
+    const pagePath = targetPage.path;
 
-    const findOpts = { includeRedirect: true, includeTrashed: true };
+    const findOpts = { includeTrashed: true };
+
+    // find descendants (this array does not include GRANT_RESTRICTED)
     const result = await this.findListWithDescendants(pagePath, user, findOpts);
     const pages = result.pages;
+    // add targetPage if 'grant' is GRANT_RESTRICTED
+    //  because findListWithDescendants excludes GRANT_RESTRICTED pages
+    if (targetPage.grant === GRANT_RESTRICTED) {
+      pages.push(targetPage);
+    }
 
     await Promise.all(pages.map((page) => {
       return this.completelyDeletePage(page, user, options);
     }));
-
-    return pagePath;
   };
 
   pageSchema.statics.removeByPath = function(path) {
@@ -1263,22 +1266,30 @@ module.exports = function(crowi) {
     return updatedPageData;
   };
 
-  pageSchema.statics.renameRecursively = async function(pageData, newPagePathPrefix, user, options) {
+  pageSchema.statics.renameRecursively = async function(targetPage, newPagePathPrefix, user, options) {
     validateCrowi();
 
-    const path = pageData.path;
+    const path = targetPage.path;
     const pathRegExp = new RegExp(`^${escapeStringRegexp(path)}`, 'i');
 
     // sanitize path
     newPagePathPrefix = crowi.xss.process(newPagePathPrefix); // eslint-disable-line no-param-reassign
 
+    // find descendants (this array does not include GRANT_RESTRICTED)
     const result = await this.findListWithDescendants(path, user, options);
-    await Promise.all(result.pages.map((page) => {
+    const pages = result.pages;
+    // add targetPage if 'grant' is GRANT_RESTRICTED
+    //  because findListWithDescendants excludes GRANT_RESTRICTED pages
+    if (targetPage.grant === GRANT_RESTRICTED) {
+      pages.push(targetPage);
+    }
+
+    await Promise.all(pages.map((page) => {
       const newPagePath = page.path.replace(pathRegExp, newPagePathPrefix);
       return this.rename(page, newPagePath, user, options);
     }));
-    pageData.path = newPagePathPrefix;
-    return pageData;
+    targetPage.path = newPagePathPrefix;
+    return targetPage;
   };
 
   pageSchema.statics.handlePrivatePagesForDeletedGroup = async function(deletedGroup, action, transferToUserGroupId) {

+ 6 - 6
src/server/routes/page.js

@@ -1268,7 +1268,7 @@ module.exports = function(crowi, app) {
 
     const options = { socketClientId };
 
-    let page = await Page.findByIdAndViewer(pageId, req.user);
+    const page = await Page.findByIdAndViewer(pageId, req.user);
 
     if (page == null) {
       return res.json(ApiResponse.error(`Page '${pageId}' is not found or forbidden`, 'notfound_or_forbidden'));
@@ -1282,10 +1282,10 @@ module.exports = function(crowi, app) {
           return res.json(ApiResponse.error('You can not delete completely', 'user_not_admin'));
         }
         if (isRecursively) {
-          await Page.completelyDeletePageRecursively(page.path, req.user, options);
+          await Page.completelyDeletePageRecursively(page, req.user, options);
         }
         else {
-          page = await Page.completelyDeletePage(page, req.user, options);
+          await Page.completelyDeletePage(page, req.user, options);
         }
       }
       else {
@@ -1294,16 +1294,16 @@ module.exports = function(crowi, app) {
         }
 
         if (isRecursively) {
-          page = await Page.deletePageRecursively(page, req.user, options);
+          await Page.deletePageRecursively(page, req.user, options);
         }
         else {
-          page = await Page.deletePage(page, req.user, options);
+          await Page.deletePage(page, req.user, options);
         }
       }
     }
     catch (err) {
       logger.error('Error occured while get setting', err);
-      return res.json(ApiResponse.error('Failed to delete page.', 'unknown'));
+      return res.json(ApiResponse.error('Failed to delete page.', err.message));
     }
 
     debug('Page deleted', page.path);

+ 0 - 15
src/server/views/_form.html

@@ -10,20 +10,5 @@
 {% endif %}
 
 <div id="page-editor-navbar-bottom-container" class="d-none d-edit-block"></div>
-{#
-<div class="page-editor-footer d-flex flex-row align-items-center justify-content-between">
-
-  <div>
-    <div id="page-editor-options-selector" class="d-none d-md-block"></div>
-  </div>
-
-  <div id="save-page-controls"
-    data-grant="{{ grant }}"
-    data-grant-group="{{ grantedGroupId }}"
-    data-grant-group-name="{{ grantedGroupName }}">
-  </div>
-
-</div>
-#}
 
 <div class="file-module hidden"></div>

+ 3 - 0
src/server/views/widget/page_content.html

@@ -9,6 +9,9 @@
   data-page-revision-id-hackmd-synced="{% if revisionHackmdSynced %}{{ revisionHackmdSynced.toString() }}{% endif %}"
   data-page-id-on-hackmd="{% if pageIdOnHackmd %}{{ pageIdOnHackmd.toString() }}{% endif %}"
   data-page-has-draft-on-hackmd="{% if hasDraftOnHackmd %}{{ hasDraftOnHackmd.toString() }}{% endif %}"
+  data-page-grant="{{ grant }}"
+  data-page-grant-group="{{ grantedGroupId }}"
+  data-page-grant-group-name="{{ grantedGroupName }}"
   data-page-is-liked="{% if user %}{{ page.isLiked(user) }}{% else %}false{% endif %}"
   data-page-is-seen="{% if page and page.isSeenUser(user) %}1{% else %}0{% endif %}"
   data-page-is-forbidden="{% if forbidden %}true{% else %}false{% endif %}"