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

Merge pull request #2725 from weseek/imprv/refactor-validation-for-smtp

Imprv/refactor validation for smtp
itizawa 5 лет назад
Родитель
Сommit
4ba8700dc0

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

@@ -32,9 +32,6 @@
     "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?",
     "ses_settings":"SES 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.",

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

@@ -32,9 +32,6 @@
     "host": "ホスト",
     "port": "ポート",
     "user": "ユーザー",
-    "initialize_mail_settings": "設定を初期化",
-    "initialize_mail_modal_header": "メール設定の初期化",
-    "confirm_to_initialize_mail_settings": "一度初期化した設定は戻せません。本当に初期化しますか?",
     "ses_settings":"SES設定",
     "aws_settings": "AWS設定",
     "aws_access": "AWS にアクセスするための設定を行います。AWS の設定を完了させると、ファイルアップロード機能、プロフィール写真機能などが有効になります。",

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

@@ -32,9 +32,6 @@
 		"host": "服务器",
 		"port": "端口号",
 		"user": "用户名",
-    "initialize_mail_settings": "重置邮件设置",
-    "initialize_mail_modal_header": "重置邮件设置",
-    "confirm_to_initialize_mail_settings": "当前设置将被清空且不可恢复。确认重置?",
     "ses_settings":"SES设置",
 		"aws_settings": "AWS设置",
 		"aws_access": "这是用于AWS设置的。如果您完成了AWS设置,文件上传功能,个人资料图片功能等将被启用。",

+ 3 - 75
src/client/js/components/Admin/App/SmtpSetting.jsx

@@ -1,12 +1,9 @@
 
-import React, { useState, useRef } from 'react';
+import React from 'react';
 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 { withLoadingSppiner } from '../../SuspenseUtils';
@@ -21,22 +18,6 @@ const logger = loggerFactory('growi:smtpSettings');
 function SmtpSetting(props) {
   const { adminAppContainer, t } = props;
 
-  const hostInput = useRef();
-  const portInput = useRef();
-  const userInput = useRef();
-  const passwordInput = useRef();
-
-  const [isInitializeValueModalOpen, setIsInitializeValueModalOpen] = useState(false);
-
-  function openInitializeValueModal() {
-    setIsInitializeValueModalOpen(true);
-
-  }
-
-  function closeInitializeValueModal() {
-    setIsInitializeValueModalOpen(false);
-  }
-
   async function submitHandler() {
     const { t, adminAppContainer } = props;
 
@@ -50,26 +31,6 @@ function SmtpSetting(props) {
     }
   }
 
-  async function initialize() {
-    const { t, adminAppContainer } = props;
-
-    try {
-      const mailSettingParams = await adminAppContainer.initializeSmtpSettingHandler();
-      toastSuccess(t('toaster.initialize_successed', { target: t('admin:app_setting.smtp_settings') }));
-      // convert values to '' if value is null for overwriting values of inputs with refs
-      hostInput.current.value = mailSettingParams.smtpHost || '';
-      portInput.current.value = mailSettingParams.smtpPort || '';
-      userInput.current.value = mailSettingParams.smtpUser || '';
-      passwordInput.current.value = mailSettingParams.smtpPassword || '';
-      closeInitializeValueModal();
-    }
-    catch (err) {
-      toastError(err);
-      logger.error(err);
-    }
-  }
-
-
   return (
     <React.Fragment>
       <div id="mail-smtp" className="tab-pane active mt-5">
@@ -80,7 +41,6 @@ function SmtpSetting(props) {
             <input
               className="form-control"
               type="text"
-              ref={hostInput}
               defaultValue={adminAppContainer.state.smtpHost || ''}
               onChange={(e) => { adminAppContainer.changeSmtpHost(e.target.value) }}
             />
@@ -89,7 +49,6 @@ function SmtpSetting(props) {
             <label>{t('admin:app_setting.port')}</label>
             <input
               className="form-control"
-              ref={portInput}
               defaultValue={adminAppContainer.state.smtpPort || ''}
               onChange={(e) => { adminAppContainer.changeSmtpPort(e.target.value) }}
             />
@@ -102,7 +61,6 @@ function SmtpSetting(props) {
             <input
               className="form-control"
               type="text"
-              ref={userInput}
               defaultValue={adminAppContainer.state.smtpUser || ''}
               onChange={(e) => { adminAppContainer.changeSmtpUser(e.target.value) }}
             />
@@ -112,7 +70,6 @@ function SmtpSetting(props) {
             <input
               className="form-control"
               type="password"
-              ref={passwordInput}
               defaultValue={adminAppContainer.state.smtpPassword || ''}
               onChange={(e) => { adminAppContainer.changeSmtpPassword(e.target.value) }}
             />
@@ -120,43 +77,14 @@ function SmtpSetting(props) {
         </div>
 
         <div className="row my-3">
-          <div className="offset-5">
+          <div className="mx-auto">
             <button type="button" className="btn btn-primary" onClick={submitHandler} disabled={adminAppContainer.state.retrieveError != null}>
               { t('Update') }
             </button>
           </div>
-          <div className="offset-1">
-            <button
-              type="button"
-              className="btn btn-secondary"
-              onClick={openInitializeValueModal}
-              disabled={adminAppContainer.state.retrieveError != null}
-            >
-              {t('admin:app_setting.initialize_mail_settings')}
-            </button>
-          </div>
         </div>
-      </div>
 
-
-      <Modal isOpen={isInitializeValueModalOpen} toggle={closeInitializeValueModal} className="initialize-mail-settings">
-        <ModalHeader tag="h4" toggle={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={closeInitializeValueModal}>
-              {t('Cancel')}
-            </button>
-            <button type="button" className="btn btn-danger" onClick={initialize}>
-              {t('Reset')}
-            </button>
-          </div>
-        </ModalBody>
-      </Modal>
+      </div>
 
     </React.Fragment>
   );

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

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

+ 41 - 49
src/server/routes/apiv3/app-settings.js

@@ -134,7 +134,7 @@ module.exports = (crowi) => {
     ],
     smtpSetting: [
       body('smtpHost').trim(),
-      body('smtpPort').trim().isPort(),
+      body('smtpPort').trim().if(value => value !== '').isPort(),
       body('smtpUser').trim(),
       body('smtpPassword').trim(),
     ],
@@ -313,8 +313,14 @@ module.exports = (crowi) => {
   /**
    * validate mail setting send test mail
    */
-  async function validateMailSetting(req) {
+  async function sendTestEmail(req) {
+
     const { configManager, mailService } = crowi;
+
+    if (!mailService.isMailerSetup) {
+      throw Error('mailService is not setup');
+    }
+
     const fromAddress = configManager.getConfig('crowi', 'mail:from');
     if (fromAddress == null) {
       throw Error('fromAddress is not setup');
@@ -360,6 +366,7 @@ module.exports = (crowi) => {
     mailService.publishUpdatedMessage();
 
     return {
+      isMailerSetup: mailService.isMailerSetup,
       smtpHost: configManager.getConfig('crowi', 'mail:smtpHost'),
       smtpPort: configManager.getConfig('crowi', 'mail:smtpPort'),
       smtpUser: configManager.getConfig('crowi', 'mail:smtpUser'),
@@ -394,7 +401,6 @@ module.exports = (crowi) => {
 
     try {
       const mailSettingParams = await updateMailSettinConfig({ 'mail:from': req.body.fromAddress });
-
       return res.apiv3({ mailSettingParams });
     }
     catch (err) {
@@ -429,17 +435,6 @@ module.exports = (crowi) => {
    *                  $ref: '#/components/schemas/SmtpSettingParams'
    */
   router.put('/smtp-setting', loginRequiredStrictly, adminRequired, csrf, validator.smtpSetting, apiV3FormValidator, async(req, res) => {
-    try {
-      await validateMailSetting(req);
-    }
-    catch (err) {
-      const msg = req.t('validation.failed_to_send_a_test_email');
-      logger.error('Error', err);
-      debug('Error validate mail setting: ', err);
-      return res.apiv3Err(new ErrorV3(msg, 'update-mailSetting-failed'));
-    }
-
-
     const requestMailSettingParams = {
       'mail:smtpHost': req.body.smtpHost,
       'mail:smtpPort': req.body.smtpPort,
@@ -458,6 +453,38 @@ module.exports = (crowi) => {
     }
   });
 
+  /**
+   * @swagger
+   *
+   *    /app-settings/smtp-test:
+   *      post:
+   *        tags: [AppSettings]
+   *        operationId: posyAppSettingSmtpTast
+   *        summary: /app-settings/smtp-setting
+   *        description: Send test mail for smtp
+   *        requestBody:
+   *          required: true
+   *          content:
+   *            application/json:
+   *              schema:
+   *                $ref: '#/components/schemas/SmtpSettingParams'
+   *        responses:
+   *          200:
+   *            description: Succeeded to send test mail for smtp
+   */
+  router.post('/smtp-test', loginRequiredStrictly, adminRequired, csrf, validator.smtpSetting, apiV3FormValidator, async(req, res) => {
+    try {
+      await sendTestEmail(req);
+      return res.apiv3({});
+    }
+    catch (err) {
+      const msg = req.t('validation.failed_to_send_a_test_email');
+      logger.error('Error', err);
+      debug('Error validate mail setting: ', err);
+      return res.apiv3Err(new ErrorV3(msg, 'update-mailSetting-failed'));
+    }
+  });
+
   /**
    * @swagger
    *
@@ -499,41 +526,6 @@ module.exports = (crowi) => {
     }
   });
 
-  /**
-   * @swagger
-   *
-   *    /app-settings/smtp-setting:
-   *      delete:
-   *        tags: [AppSettings]
-   *        operationId: deleteAppSettingSmtpSetting
-   *        summary: /app-settings/smtp-setting
-   *        description: delete smtp setting
-   *        responses:
-   *          200:
-   *            description: Succeeded to delete smtp setting
-   *            content:
-   *              application/json:
-   *                schema:
-   *                  $ref: '#/components/schemas/SmtpSettingParams'
-   */
-  router.delete('/smtp-setting', loginRequiredStrictly, adminRequired, csrf, async(req, res) => {
-    const requestMailSettingParams = {
-      '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 stmp setting';
-      logger.error('Error', err);
-      return res.apiv3Err(new ErrorV3(msg, 'initialize-smtpSetting-failed'));
-    }
-  });
-
   /**
    * @swagger
    *

+ 11 - 0
src/server/service/mail.js

@@ -20,6 +20,11 @@ class MailService extends S2sMessageHandlable {
     this.mailConfig = {};
     this.mailer = {};
 
+    /**
+     * the flag whether mailer is set up successfully
+     */
+    this.isMailerSetup = false;
+
     this.initialize();
   }
 
@@ -65,6 +70,8 @@ class MailService extends S2sMessageHandlable {
   initialize() {
     const { appService, configManager } = this;
 
+    this.isMailerSetup = false;
+
     if (!configManager.getConfig('crowi', 'mail:from')) {
       this.mailer = null;
       return;
@@ -74,9 +81,11 @@ class MailService extends S2sMessageHandlable {
 
     if (transmissionMethod === 'smtp') {
       this.mailer = this.createSMTPClient();
+      this.isMailerSetup = true;
     }
     else if (transmissionMethod === 'ses') {
       this.mailer = this.createSESClient();
+      this.isMailerSetup = true;
     }
     else {
       this.mailer = null;
@@ -113,6 +122,7 @@ class MailService extends S2sMessageHandlable {
     const client = nodemailer.createTransport(option);
 
     logger.debug('mailer set up for SMTP', client);
+
     return client;
   }
 
@@ -130,6 +140,7 @@ class MailService extends S2sMessageHandlable {
     const client = nodemailer.createTransport(ses(option));
 
     logger.debug('mailer set up for SES', client);
+
     return client;
   }