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

Merge pull request #2589 from weseek/feat/initialize-mail-setting-for-merge

Feat/initialize mail setting for merge
yusuketk 5 лет назад
Родитель
Сommit
43af67f920

+ 4 - 1
resource/locales/en_US/admin/admin.json

@@ -26,7 +26,7 @@
     "enable_files_except_image": "Enabling this option will allow upload of any file type. Without this option, only image file upload is supported.",
     "attach_enable": "You can attach files other than image files if you enable this option.",
     "update": "Update",
-    "mail_settings": "Mail settings",
+    "mail_settings": "E-mail Settings",
     "smtp_used": "If you have SMTP settings, it will be used.",
     "smtp_but_aws": "If you do not have SMTP settings but AWS settings,  e-mails will be sent by SES.",
     "neihter_of": "If neither is selected, then no email will be sent.",
@@ -35,6 +35,9 @@
     "host": "Host",
     "port": "Port",
     "user": "User",
+    "initialize_mail_settings": "initialize e-mail settings",
+    "initialize_mail_modal_header": "Initialize e-mail settings",
+    "confirm_to_initialize_mail_settings": "You can't restore to the current settings. Are you sure you want to initialize e-mail settings?",
     "aws_settings": "AWS settings",
     "aws_access": "This is for AWS settings. If you complete AWS settings, file upload function, profile picture function etc will be enabled.",
     "no_smtp_setting": "If you do not have SMTP settings, e-mails will be sent via SES. You need to verify from e-mail address and production settings.",

+ 1 - 0
resource/locales/en_US/translation.json

@@ -336,6 +336,7 @@
   },
   "toaster": {
     "update_successed": "Succeeded to update {{target}}",
+    "initialize_successed": "Succeeded to initialize {{target}}",
     "give_user_admin": "Succeeded to give {{username}} admin",
     "remove_user_admin": "Succeeded to remove {{username}} admin ",
     "activate_user_success": "Succeeded to activating {{username}}",

+ 3 - 0
resource/locales/ja_JP/admin/admin.json

@@ -35,6 +35,9 @@
     "host": "ホスト",
     "port": "ポート",
     "user": "ユーザー",
+    "initialize_mail_settings": "設定を初期化",
+    "initialize_mail_modal_header": "メール設定の初期化",
+    "confirm_to_initialize_mail_settings": "一度初期化した設定は戻せません。本当に初期化しますか?",
     "aws_settings": "AWS設定",
     "aws_access": "AWS にアクセスするための設定を行います。AWS の設定を完了させると、ファイルアップロード機能、プロフィール写真機能などが有効になります。",
     "no_smtp_setting": "また、SMTP の設定が無い場合、SES を利用したメール送信が行われます。FromメールアドレスのVerify、プロダクション利用設定をする必要があります。",

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

@@ -30,6 +30,7 @@
   "User": "ユーザー",
   "status": "ステータス",
   "account_id": "アカウントID",
+  "Initialize": "初期化",
   "Update": "更新",
   "Update Page": "ページを更新",
   "Warning": "注意",
@@ -337,6 +338,7 @@
   },
   "toaster": {
     "update_successed": "{{target}}を更新しました",
+    "initialize_successed": "{{target}}を初期化しました",
     "give_user_admin": "{{username}}を管理者に設定しました",
     "remove_user_admin": "{{username}}を管理者から外しました",
     "activate_user_success": "{{username}}を有効化しました",

+ 4 - 1
resource/locales/zh_CN/admin/admin.json

@@ -35,6 +35,9 @@
 		"host": "服务器",
 		"port": "端口号",
 		"user": "用户名",
+    "initialize_mail_settings": "初始化邮件设置",
+    "initialize_mail_modal_header": "初始化邮件设置",
+    "confirm_to_initialize_mail_settings": "You can't restore to the current settings. Are you sure you want to initialize e-mail settings?",
 		"aws_settings": "AWS设置",
 		"aws_access": "这是用于AWS设置的。如果您完成了AWS设置,文件上传功能,个人资料图片功能等将被启用。",
 		"no_smtp_setting": "如果您没有SMTP设置,电子邮件将通过SES发送。您需要从电子邮件地址和生产设置进行验证。",
@@ -315,4 +318,4 @@
 			"transfer_pages": "转移到另一组"
 		}
 	}
-}
+}

+ 3 - 1
resource/locales/zh_CN/translation.json

@@ -31,7 +31,8 @@
 	"User": "用户",
 	"status": "状态",
 	"account_id": "用户Id",
-	"Update": "更新",
+	"Initialize": "初始化",
+  "Update": "更新",
 	"Update Page": "更新本页",
 	"Warning": "警告",
 	"Sign in": "登录",
@@ -333,6 +334,7 @@
 	},
 	"toaster": {
 		"update_successed": "Succeeded to update {{target}}",
+    "initialize_successed": "Succeeded to initialize {{target}}",
 		"give_user_admin": "Succeeded to give {{username}} admin",
 		"remove_user_admin": "Succeeded to remove {{username}} admin ",
 		"activate_user_success": "Succeeded to activating {{username}}",

+ 65 - 2
src/client/js/components/Admin/App/MailSetting.jsx

@@ -3,12 +3,12 @@ import PropTypes from 'prop-types';
 import { withTranslation } from 'react-i18next';
 import loggerFactory from '@alias/logger';
 
+import { Modal, ModalHeader, ModalBody } from 'reactstrap';
 import { withUnstatedContainers } from '../../UnstatedUtils';
 import { toastSuccess, toastError } from '../../../util/apiNotification';
 
 import AppContainer from '../../../services/AppContainer';
 import AdminAppContainer from '../../../services/AdminAppContainer';
-import AdminUpdateButtonRow from '../Common/AdminUpdateButtonRow';
 
 const logger = loggerFactory('growi:appSettings');
 
@@ -17,7 +17,22 @@ class MailSetting extends React.Component {
   constructor(props) {
     super(props);
 
+    this.state = {
+      isInitializeValueModalOpen: false,
+    };
+
+    this.openInitializeValueModal = this.openInitializeValueModal.bind(this);
+    this.closeInitializeValueModal = this.closeInitializeValueModal.bind(this);
     this.submitHandler = this.submitHandler.bind(this);
+    this.initialize = this.initialize.bind(this);
+  }
+
+  openInitializeValueModal() {
+    this.setState({ isInitializeValueModalOpen: true });
+  }
+
+  closeInitializeValueModal() {
+    this.setState({ isInitializeValueModalOpen: false });
   }
 
   async submitHandler() {
@@ -33,6 +48,20 @@ class MailSetting extends React.Component {
     }
   }
 
+  async initialize() {
+    const { t, adminAppContainer } = this.props;
+
+    try {
+      await adminAppContainer.initializeMailSettingHandler();
+      toastSuccess(t('toaster.initialize_successed', { target: t('admin:app_setting.mail_settings') }));
+      this.closeInitializeValueModal();
+    }
+    catch (err) {
+      toastError(err);
+      logger.error(err);
+    }
+  }
+
   render() {
     const { t, adminAppContainer } = this.props;
 
@@ -94,7 +123,41 @@ class MailSetting extends React.Component {
           </div>
         </div>
 
-        <AdminUpdateButtonRow onClick={this.submitHandler} disabled={adminAppContainer.state.retrieveError != null} />
+        <div className="row my-3">
+          <div className="offset-5">
+            <button type="button" className="btn btn-primary" onClick={this.submitHandler} disabled={adminAppContainer.state.retrieveError != null}>
+              { t('Update') }
+            </button>
+          </div>
+          <div className="offset-1">
+            <button
+              type="button"
+              className="btn btn-secondary"
+              onClick={this.openInitializeValueModal}
+              disabled={adminAppContainer.state.retrieveError != null}
+            >
+              {t('admin:app_setting.initialize_mail_settings')}
+            </button>
+          </div>
+        </div>
+        <Modal isOpen={this.state.isInitializeValueModalOpen} toggle={this.closeInitializeValueModal} className="initialize-mail-settings">
+          <ModalHeader tag="h4" toggle={this.closeInitializeValueModal} className="bg-danger text-light">
+            {t('admin:app_setting.initialize_mail_modal_header')}
+          </ModalHeader>
+          <ModalBody>
+            <div className="text-center mb-4">
+              {t('admin:app_setting.confirm_to_initialize_mail_settings')}
+            </div>
+            <div className="text-center my-2">
+              <button type="button" className="btn btn-outline-secondary mr-4" onClick={this.closeInitializeValueModal}>
+                {t('Cancel')}
+              </button>
+              <button type="button" className="btn btn-danger" onClick={this.initialize}>
+                {t('Initialize')}
+              </button>
+            </div>
+          </ModalBody>
+        </Modal>
       </React.Fragment>
     );
   }

+ 13 - 0
src/client/js/services/AdminAppContainer.js

@@ -265,6 +265,19 @@ export default class AdminAppContainer extends Container {
     return mailSettingParams;
   }
 
+  /**
+   * Initialize mail setting
+   * @memberOf AdminAppContainer
+   * @return {Array} Appearance
+   */
+  async initializeMailSettingHandler() {
+    const response = await this.appContainer.apiv3.delete('/app-settings/mail-setting', {});
+    const {
+      mailSettingParams,
+    } = response.data;
+    this.setState(mailSettingParams);
+  }
+
   /**
    * Update AWS setting
    * @memberOf AdminAppContainer

+ 65 - 16
src/server/routes/apiv3/app-settings.js

@@ -320,6 +320,27 @@ module.exports = (crowi) => {
     await sendMailPromiseWrapper(smtpClient, mailOptions);
   }
 
+  const updateMailSettinConfig = async function(requestMailSettingParams) {
+    const {
+      configManager,
+      mailService,
+    } = crowi;
+
+    // update config without publishing S2sMessage
+    await configManager.updateConfigsInTheSameNamespace('crowi', requestMailSettingParams, true);
+
+    await mailService.initialize();
+    mailService.publishUpdatedMessage();
+
+    return {
+      fromAddress: configManager.getConfig('crowi', 'mail:from'),
+      smtpHost: configManager.getConfig('crowi', 'mail:smtpHost'),
+      smtpPort: configManager.getConfig('crowi', 'mail:smtpPort'),
+      smtpUser: configManager.getConfig('crowi', 'mail:smtpUser'),
+      smtpPassword: configManager.getConfig('crowi', 'mail:smtpPassword'),
+    };
+  };
+
   /**
    * @swagger
    *
@@ -327,7 +348,7 @@ module.exports = (crowi) => {
    *      put:
    *        tags: [AppSettings]
    *        operationId: updateAppSettingMailSetting
-   *        summary: /app-settings/site-url-setting
+   *        summary: /app-settings/mail-setting
    *        description: Update mail setting
    *        requestBody:
    *          required: true
@@ -364,21 +385,7 @@ module.exports = (crowi) => {
     };
 
     try {
-      const { configManager, mailService } = crowi;
-
-      // update config without publishing S2sMessage
-      await configManager.updateConfigsInTheSameNamespace('crowi', requestMailSettingParams, true);
-
-      await mailService.initialize();
-      mailService.publishUpdatedMessage();
-
-      const mailSettingParams = {
-        fromAddress: configManager.getConfig('crowi', 'mail:from'),
-        smtpHost: configManager.getConfig('crowi', 'mail:smtpHost'),
-        smtpPort: configManager.getConfig('crowi', 'mail:smtpPort'),
-        smtpUser: configManager.getConfig('crowi', 'mail:smtpUser'),
-        smtpPassword: configManager.getConfig('crowi', 'mail:smtpPassword'),
-      };
+      const mailSettingParams = await updateMailSettinConfig(requestMailSettingParams);
       return res.apiv3({ mailSettingParams });
     }
     catch (err) {
@@ -388,6 +395,48 @@ module.exports = (crowi) => {
     }
   });
 
+  /**
+   * @swagger
+   *
+   *    /app-settings/mail-setting:
+   *      delete:
+   *        tags: [AppSettings]
+   *        operationId: deleteAppSettingMailSetting
+   *        summary: /app-settings/mail-setting
+   *        description: delete mail setting
+   *        requestBody:
+   *          required: true
+   *          content:
+   *            application/json:
+   *              schema:
+   *                $ref: '#/components/schemas/MailSettingParams'
+   *        responses:
+   *          200:
+   *            description: Succeeded to delete mail setting
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  $ref: '#/components/schemas/MailSettingParams'
+   */
+  router.delete('/mail-setting', loginRequiredStrictly, adminRequired, csrf, async(req, res) => {
+    const requestMailSettingParams = {
+      'mail:from': null,
+      'mail:smtpHost': null,
+      'mail:smtpPort': null,
+      'mail:smtpUser': null,
+      'mail:smtpPassword': null,
+    };
+    try {
+      const mailSettingParams = await updateMailSettinConfig(requestMailSettingParams);
+      return res.apiv3({ mailSettingParams });
+    }
+    catch (err) {
+      const msg = 'Error occurred in initializing mail setting';
+      logger.error('Error', err);
+      return res.apiv3Err(new ErrorV3(msg, 'initialize-mailSetting-failed'));
+    }
+  });
+
   /**
    * @swagger
    *