Przeglądaj źródła

Merge pull request #9125 from weseek/fix/153813-153818-the-issue-where-all-descendant-pages'-scopes-are-overwritten-during-an-update,-making-the-descendant-pages-inaccessible

fix: Make it impossible to overwrite grants on descendant pages when 'anyone with the link' is selected.
mergify[bot] 1 rok temu
rodzic
commit
e899315d1c

+ 1 - 0
apps/app/public/static/locales/en_US/translation.json

@@ -64,6 +64,7 @@
   "Presentation Mode": "Presentation",
   "Not available for guest": "Not available for guest",
   "Not available in this version": "Not available in this version",
+  "Not available when \"anyone with the link\" is selected": "If \"anyone with the link\" is selected, the scope cannot be overridden.",
   "No users have liked this yet": "No users have liked this yet",
   "No users have liked this yet.": "No users have liked this yet.",
   "No users have bookmarked yet": "No users have bookmarked yet",

+ 1 - 0
apps/app/public/static/locales/fr_FR/translation.json

@@ -64,6 +64,7 @@
   "Presentation Mode": "Mode présentation",
   "Not available for guest": "Indisponible pour les invités",
   "Not available in this version": "Indisponible dans cette version",
+  "Not available when \"anyone with the link\" is selected": "Si \"Tous les utilisateurs disposant du lien\" est sélectionné, la portée ne peut pas être modifiée",
   "No users have liked this yet": "Aucun utilisateur n'a aimé cette page",
   "No users have liked this yet.": "Aucun utilisateur n'a aimé cette page.",
   "No users have bookmarked yet": "Aucun utilisateur n'a mis en favoris cette page",

+ 1 - 0
apps/app/public/static/locales/ja_JP/translation.json

@@ -61,6 +61,7 @@
   "Presentation Mode": "プレゼンテーション",
   "Not available for guest": "ゲストユーザーは利用できません",
   "Not available in this version": "このバージョンでは利用できません",
+  "Not available when \"anyone with the link\" is selected": "「リンクを知っている人のみ」を選択している場合はスコープを上書きできません。",
   "No users have liked this yet": "いいねをしているユーザーはいません",
   "No users have bookmarked yet": "ブックマークしているユーザーはいません",
   "Create Archive Page": "アーカイブページの作成",

+ 1 - 0
apps/app/public/static/locales/zh_CN/translation.json

@@ -61,6 +61,7 @@
   "Presentation Mode": "演示文稿",
   "Not available for guest": "不提供给客人",
   "Not available in this version": "此版本中不提供",
+  "Not available when \"anyone with the link\" is selected": "如果选择“任何人”,则无法覆盖范围",
   "No users have liked this yet": "还没有用户喜欢这个",
   "No users have bookmarked yet": "还没有用户加入书签",
   "Create Archive Page": "创建归档页",

+ 2 - 1
apps/app/src/client/components/NotAvailable.tsx

@@ -1,7 +1,8 @@
 import React from 'react';
 
 import { Disable } from 'react-disable';
-import { UncontrolledTooltip, UncontrolledTooltipProps } from 'reactstrap';
+import type { UncontrolledTooltipProps } from 'reactstrap';
+import { UncontrolledTooltip } from 'reactstrap';
 
 type NotAvailableProps = {
   children: JSX.Element

+ 23 - 7
apps/app/src/client/components/SavePageControls.tsx

@@ -2,6 +2,7 @@ import React, { useCallback, useState, useEffect } from 'react';
 
 import type EventEmitter from 'events';
 
+import { PageGrant } from '@growi/core';
 import { isTopPage, isUsersProtectedPages } from '@growi/core/dist/utils/page-path-utils';
 import { LoadingSpinner } from '@growi/ui/dist/components';
 import { useTranslation } from 'next-i18next';
@@ -17,9 +18,10 @@ import {
 import { useEditorMode } from '~/stores-universal/ui';
 import { useWaitingSaveProcessing, useSWRxSlackChannels, useIsSlackEnabled } from '~/stores/editor';
 import { useSWRxCurrentPage, useCurrentPagePath } from '~/stores/page';
-import { useIsDeviceLargerThanMd } from '~/stores/ui';
+import { useIsDeviceLargerThanMd, useSelectedGrant } from '~/stores/ui';
 import loggerFactory from '~/utils/logger';
 
+import { NotAvailable } from './NotAvailable';
 import { GrantSelector } from './SavePageControls/GrantSelector';
 import { SlackNotification } from './SlackNotification';
 
@@ -38,6 +40,7 @@ const SavePageButton = (props: {slackChannels: string, isSlackEnabled?: boolean,
   const { t } = useTranslation();
   const { data: _isWaitingSaveProcessing } = useWaitingSaveProcessing();
   const [isSavePageModalShown, setIsSavePageModalShown] = useState<boolean>(false);
+  const { data: selectedGrant } = useSelectedGrant();
 
   const { slackChannels, isSlackEnabled, isDeviceLargerThanMd } = props;
 
@@ -63,6 +66,7 @@ const SavePageButton = (props: {slackChannels: string, isSlackEnabled?: boolean,
   const labelSubmitButton = t('Update');
   const labelOverwriteScopes = t('page_edit.overwrite_scopes', { operation: labelSubmitButton });
   const labelUnpublishPage = t('wip_page.save_as_wip');
+  const restrictedGrantOverrideErrorTitle = t('Not available when "anyone with the link" is selected');
 
   return (
     <>
@@ -85,9 +89,15 @@ const SavePageButton = (props: {slackChannels: string, isSlackEnabled?: boolean,
             <>
               <DropdownToggle caret color="primary" disabled={isWaitingSaveProcessing} />
               <DropdownMenu container="body" end>
-                <DropdownItem onClick={saveAndOverwriteScopesOfDescendants}>
-                  {labelOverwriteScopes}
-                </DropdownItem>
+                <NotAvailable
+                  isDisabled={selectedGrant?.grant === PageGrant.GRANT_RESTRICTED}
+                  classNamePrefix="grw-not-available-when-grant-restricted-is-selected"
+                  title={restrictedGrantOverrideErrorTitle}
+                >
+                  <DropdownItem onClick={saveAndOverwriteScopesOfDescendants}>
+                    {labelOverwriteScopes}
+                  </DropdownItem>
+                </NotAvailable>
                 <DropdownItem onClick={saveAndMakeWip}>
                   {labelUnpublishPage}
                 </DropdownItem>
@@ -102,9 +112,15 @@ const SavePageButton = (props: {slackChannels: string, isSlackEnabled?: boolean,
                 toggle={() => setIsSavePageModalShown(false)}
               >
                 <div className="d-flex flex-column pt-4 pb-3 px-4 gap-4">
-                  <button type="button" className="btn btn-primary" onClick={() => { setIsSavePageModalShown(false); saveAndOverwriteScopesOfDescendants() }}>
-                    {labelOverwriteScopes}
-                  </button>
+                  <NotAvailable
+                    isDisabled={selectedGrant?.grant === PageGrant.GRANT_RESTRICTED}
+                    classNamePrefix="grw-not-available-when-grant-restricted-is-selected"
+                    title={restrictedGrantOverrideErrorTitle}
+                  >
+                    <button type="button" className="btn btn-primary" onClick={() => { setIsSavePageModalShown(false); saveAndOverwriteScopesOfDescendants() }}>
+                      {labelOverwriteScopes}
+                    </button>
+                  </NotAvailable>
                   <button type="button" className="btn btn-primary" onClick={() => { setIsSavePageModalShown(false); saveAndMakeWip() }}>
                     {labelUnpublishPage}
                   </button>

+ 1 - 1
apps/app/src/server/service/page/index.ts

@@ -4109,7 +4109,7 @@ class PageService implements IPageService {
     }
 
     // 3. Update scopes for descendants
-    if (options.overwriteScopesOfDescendants) {
+    if (options.overwriteScopesOfDescendants && shouldBeOnTree) {
       await this.applyScopesToDescendantsWithStream(currentPage, user);
     }