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

Merge branch 'master' into feat/update-documents-by-reinstall

jam411 3 лет назад
Родитель
Сommit
8044afc25f

+ 13 - 7
packages/app/src/client/services/AdminMarkDownContainer.js

@@ -29,7 +29,7 @@ export default class AdminMarkDownContainer extends Container {
       isEnabledXss: false,
       isEnabledXss: false,
       xssOption: '',
       xssOption: '',
       tagWhiteList: '',
       tagWhiteList: '',
-      attrWhiteList: '',
+      attrWhiteList: '{}',
     };
     };
 
 
     this.switchEnableXss = this.switchEnableXss.bind(this);
     this.switchEnableXss = this.switchEnableXss.bind(this);
@@ -119,19 +119,25 @@ export default class AdminMarkDownContainer extends Container {
    * Update Xss Setting
    * Update Xss Setting
    */
    */
   async updateXssSetting() {
   async updateXssSetting() {
-    let { tagWhiteList, attrWhiteList } = this.state;
+    let { tagWhiteList } = this.state;
+    const { attrWhiteList } = this.state;
 
 
     tagWhiteList = Array.isArray(tagWhiteList) ? tagWhiteList : tagWhiteList.split(',');
     tagWhiteList = Array.isArray(tagWhiteList) ? tagWhiteList : tagWhiteList.split(',');
-    attrWhiteList = Array.isArray(attrWhiteList) ? attrWhiteList : attrWhiteList.split(',');
 
 
-    const response = await apiv3Put('/markdown-setting/xss', {
+    try {
+      // Check if parsing is possible
+      JSON.parse(attrWhiteList);
+    }
+    catch (err) {
+      throw Error(err);
+    }
+
+    await apiv3Put('/markdown-setting/xss', {
       isEnabledXss: this.state.isEnabledXss,
       isEnabledXss: this.state.isEnabledXss,
       xssOption: this.state.xssOption,
       xssOption: this.state.xssOption,
       tagWhiteList,
       tagWhiteList,
-      attrWhiteList,
+      attrWhiteList: attrWhiteList ?? '{}',
     });
     });
-
-    return response;
   }
   }
 
 
   /**
   /**

+ 1 - 1
packages/app/src/components/PageEditor/Editor.tsx

@@ -246,7 +246,7 @@ const Editor: ForwardRefRenderFunction<IEditorMethods, EditorPropsType> = (props
     };
     };
 
 
     return (
     return (
-      <Modal isOpen={isCheatsheetModalShown} toggle={hideCheatsheetModal} className={`modal-gfm-cheatsheet ${styles['modal-gfm-cheatsheet']}`} >
+      <Modal isOpen={isCheatsheetModalShown} toggle={hideCheatsheetModal} className={`modal-gfm-cheatsheet ${styles['modal-gfm-cheatsheet']}`} size={'lg'} >
         <ModalHeader tag="h4" toggle={hideCheatsheetModal} className="bg-primary text-light">
         <ModalHeader tag="h4" toggle={hideCheatsheetModal} className="bg-primary text-light">
           <i className="icon-fw icon-question" />Markdown help
           <i className="icon-fw icon-question" />Markdown help
         </ModalHeader>
         </ModalHeader>

+ 7 - 2
packages/app/src/components/PageEditorByHackmd.tsx

@@ -259,6 +259,8 @@ export const PageEditorByHackmd = (): JSX.Element => {
       updateStateAfterSave?.();
       updateStateAfterSave?.();
       mutateTagsInfo();
       mutateTagsInfo();
 
 
+      mutateIsEnabledUnsavedWarning(false);
+
       logger.debug('success to save');
       logger.debug('success to save');
 
 
       toastSuccess(t('successfully_saved_the_page'));
       toastSuccess(t('successfully_saved_the_page'));
@@ -267,7 +269,8 @@ export const PageEditorByHackmd = (): JSX.Element => {
       logger.error('failed to save', error);
       logger.error('failed to save', error);
       toastError(error.message);
       toastError(error.message);
     }
     }
-  }, [currentPagePath, currentPathname, pageId, revisionIdHackmdSynced, optionsToSave, saveOrUpdate, mutatePageData, updateStateAfterSave, mutateTagsInfo, t]);
+  }, [currentPagePath, currentPathname, pageId, revisionIdHackmdSynced, optionsToSave,
+      saveOrUpdate, mutatePageData, updateStateAfterSave, mutateTagsInfo, mutateIsEnabledUnsavedWarning, t]);
 
 
   /**
   /**
    * onChange event of HackmdEditor handler
    * onChange event of HackmdEditor handler
@@ -283,13 +286,15 @@ export const PageEditorByHackmd = (): JSX.Element => {
       return;
       return;
     }
     }
 
 
+    mutateIsEnabledUnsavedWarning(true);
+
     try {
     try {
       await apiPost('/hackmd.saveOnHackmd', { pageId });
       await apiPost('/hackmd.saveOnHackmd', { pageId });
     }
     }
     catch (err) {
     catch (err) {
       logger.error(err);
       logger.error(err);
     }
     }
-  }, [pageId, revision?.body, hackmdUri]);
+  }, [hackmdUri, pageId, revision?.body, mutateIsEnabledUnsavedWarning]);
 
 
   const penpalErrorOccuredHandler = useCallback((error) => {
   const penpalErrorOccuredHandler = useCallback((error) => {
     toastError(error.message);
     toastError(error.message);

+ 3 - 1
packages/app/src/server/models/config.ts

@@ -147,12 +147,14 @@ export const defaultCrowiConfigs: { [key: string]: any } = {
 };
 };
 
 
 export const defaultMarkdownConfigs: { [key: string]: any } = {
 export const defaultMarkdownConfigs: { [key: string]: any } = {
+  // don't use it, but won't turn it off
   'markdown:xss:tagWhiteList': [],
   'markdown:xss:tagWhiteList': [],
   'markdown:xss:attrWhiteList': [],
   'markdown:xss:attrWhiteList': [],
+
   'markdown:rehypeSanitize:isEnabledPrevention': true,
   'markdown:rehypeSanitize:isEnabledPrevention': true,
   'markdown:rehypeSanitize:option': RehypeSanitizeOption.RECOMMENDED,
   'markdown:rehypeSanitize:option': RehypeSanitizeOption.RECOMMENDED,
   'markdown:rehypeSanitize:tagNames': [],
   'markdown:rehypeSanitize:tagNames': [],
-  'markdown:rehypeSanitize:attributes': {},
+  'markdown:rehypeSanitize:attributes': '{}',
   'markdown:isEnabledLinebreaks': false,
   'markdown:isEnabledLinebreaks': false,
   'markdown:isEnabledLinebreaksInComments': true,
   'markdown:isEnabledLinebreaksInComments': true,
   'markdown:adminPreferredIndentSize': 4,
   'markdown:adminPreferredIndentSize': 4,

+ 16 - 7
packages/app/src/server/routes/apiv3/markdown-setting.js

@@ -30,7 +30,7 @@ const validator = {
   xssSetting: [
   xssSetting: [
     body('isEnabledXss').isBoolean(),
     body('isEnabledXss').isBoolean(),
     body('tagWhiteList').isArray(),
     body('tagWhiteList').isArray(),
-    body('attrWhiteList').isArray(),
+    body('attrWhiteList').isString(),
   ],
   ],
 };
 };
 
 
@@ -127,8 +127,8 @@ module.exports = (crowi) => {
       pageBreakCustomSeparator: await crowi.configManager.getConfig('markdown', 'markdown:presentation:pageBreakCustomSeparator'),
       pageBreakCustomSeparator: await crowi.configManager.getConfig('markdown', 'markdown:presentation:pageBreakCustomSeparator'),
       isEnabledXss: await crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:isEnabledPrevention'),
       isEnabledXss: await crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:isEnabledPrevention'),
       xssOption: await crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:option'),
       xssOption: await crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:option'),
-      tagWhiteList: await crowi.configManager.getConfig('markdown', 'markdown:xss:tagWhiteList'),
-      attrWhiteList: await crowi.configManager.getConfig('markdown', 'markdown:xss:attrWhiteList'),
+      tagWhiteList: await crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:tagNames'),
+      attrWhiteList: await crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes'),
     };
     };
 
 
     return res.apiv3({ markdownParams });
     return res.apiv3({ markdownParams });
@@ -292,11 +292,20 @@ module.exports = (crowi) => {
       return res.apiv3Err(new ErrorV3('xss option is required'));
       return res.apiv3Err(new ErrorV3('xss option is required'));
     }
     }
 
 
+    try {
+      JSON.parse(req.body.attrWhiteList);
+    }
+    catch (err) {
+      const msg = 'Error occurred in updating xss';
+      logger.error('Error', err);
+      return res.apiv3Err(new ErrorV3(msg, 'update-xss-failed'));
+    }
+
     const reqestXssParams = {
     const reqestXssParams = {
       'markdown:rehypeSanitize:isEnabledPrevention': req.body.isEnabledXss,
       'markdown:rehypeSanitize:isEnabledPrevention': req.body.isEnabledXss,
       'markdown:rehypeSanitize:option': req.body.xssOption,
       'markdown:rehypeSanitize:option': req.body.xssOption,
-      'markdown:xss:tagWhiteList': req.body.tagWhiteList, // Todo: need to be changed at https://redmine.weseek.co.jp/issues/109763
-      'markdown:xss:attrWhiteList': req.body.attrWhiteList, // Todo: need to be changed at https://redmine.weseek.co.jp/issues/109763
+      'markdown:rehypeSanitize:tagNames': req.body.tagWhiteList,
+      'markdown:rehypeSanitize:attributes': req.body.attrWhiteList,
     };
     };
 
 
     try {
     try {
@@ -304,8 +313,8 @@ module.exports = (crowi) => {
       const xssParams = {
       const xssParams = {
         isEnabledXss: await crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:isEnabledPrevention'),
         isEnabledXss: await crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:isEnabledPrevention'),
         xssOption: await crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:option'),
         xssOption: await crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:option'),
-        tagWhiteList: await crowi.configManager.getConfig('markdown', 'markdown:xss:tagWhiteList'),
-        attrWhiteList: await crowi.configManager.getConfig('markdown', 'markdown:xss:attrWhiteList'),
+        tagWhiteList: await crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:tagNames'),
+        attrWhiteList: await crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes'),
       };
       };
 
 
       const parameters = { action: SupportedAction.ACTION_ADMIN_MARKDOWN_XSS_UPDATE };
       const parameters = { action: SupportedAction.ACTION_ADMIN_MARKDOWN_XSS_UPDATE };