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

Merge pull request #7356 from weseek/fix/114374-114406-disable-to-show-password-reset-info

imprv: Add send email to user feat to `/reset-password` endpoint v6
Yuki Takei 3 лет назад
Родитель
Сommit
f2c8c76a5b

+ 3 - 3
packages/app/public/static/locales/en_US/admin.json

@@ -741,9 +741,9 @@
     },
     "reset_password": "Reset Password",
     "reset_password_modal": {
-      "password_never_seen": "The temporary password can never be retrieved after this screen is closed.",
-      "password_reset_message": "Let the user know the new password below and strongly recommend to change another one immediately.",
-      "send_new_password": "Please send the new password to the user.",
+      "reset_password_info": "When a password is reset, a newly password is sent to the target user.",
+      "password_reset_message": "The temporary password was sent to the below user and strongly recommend to change another one immediately.",
+      "reset_password_alert": "If the e-mail transmission fails, please make sure that e-mail settings are correct and reset password again.",
       "target_user": "Target User",
       "new_password": "New Password"
     },

+ 3 - 3
packages/app/public/static/locales/ja_JP/admin.json

@@ -749,9 +749,9 @@
     },
     "reset_password": "パスワードのリセット",
     "reset_password_modal": {
-      "password_never_seen": "表示されたパスワードはこの画面を閉じると二度と表示できませんのでご注意ください。",
-      "password_reset_message": "対象ユーザーに下記のパスワードを伝え、すぐに新しく別のパスワードを設定するよう伝えてください。",
-      "send_new_password": "新規発行したパスワードを、対象ユーザーへ連絡してください。",
+      "reset_password_info": "パスワードをリセットすると新規発行したパスワードを対象ユーザーに送信します。",
+      "password_reset_message": "対象ユーザーに一時的なパスワードを送信しました。新しく別のパスワードを設定するよう伝えてください。",
+      "reset_password_alert": "送信に失敗した場合はメール設定が正しいことを確認し再度パスワードのリセットを行ってください",
       "target_user": "対象ユーザー",
       "new_password": "新しいパスワード"
     },

+ 3 - 3
packages/app/public/static/locales/zh_CN/admin.json

@@ -749,9 +749,9 @@
     },
     "reset_password": "重置密码",
     "reset_password_modal": {
-      "password_never_seen": "The temporary password can never be retrieved after this screen is closed.",
-      "password_reset_message": "Let the user know the new password below and strongly recommend to change another one immediately.",
-      "send_new_password": "Please send the new password to the user.",
+      "reset_password_info": "When a password is reset, a newly password is sent to the target user.",
+      "password_reset_message": "The temporary password was sent to the below user and strongly recommend to change another one immediately.",
+      "reset_password_alert": "If the e-mail transmission fails, please make sure that e-mail settings are correct and reset password again.",
       "target_user": "Target User",
       "new_password": "New Password"
     },

+ 11 - 0
packages/app/resource/locales/en_US/admin/userResetPassword.txt

@@ -0,0 +1,11 @@
+Hi, <%- email -%>
+
+Your password has been reset by the administrator, you can log in with following account:
+
+Email: <%- email -%>
+New Password: <%- password -%>
+(This password was auto generated. Update required at the first time you logging in)
+
+--
+<%- appTitle -%>
+<%- url -%>

+ 11 - 0
packages/app/resource/locales/ja_JP/admin/userResetPassword.txt

@@ -0,0 +1,11 @@
+Hi, <%- email -%>
+
+Your password has been reset by the administrator, you can log in with following account:
+
+Email: <%- email -%>
+New Password: <%- password -%>
+(This password was auto generated. Update required at the first time you logging in)
+
+--
+<%- appTitle -%>
+<%- url -%>

+ 11 - 0
packages/app/resource/locales/zh_CN/admin/userResetPassword.txt

@@ -0,0 +1,11 @@
+Hi, <%- email -%>
+
+Your password has been reset by the administrator, you can log in with following account:
+
+Email: <%- email -%>
+New Password: <%- password -%>
+(This password was auto generated. Update required at the first time you logging in)
+
+--
+<%- appTitle -%>
+<%- url -%>

+ 4 - 10
packages/app/src/components/Admin/Users/PasswordResetModal.jsx

@@ -9,7 +9,6 @@ import {
 import { toastError } from '~/client/util/apiNotification';
 import { apiv3Put } from '~/client/util/apiv3-client';
 
-import { withUnstatedContainers } from '../../UnstatedUtils';
 
 class PasswordResetModal extends React.Component {
 
@@ -17,7 +16,6 @@ class PasswordResetModal extends React.Component {
     super(props);
 
     this.state = {
-      temporaryPassword: [],
       isPasswordResetDone: false,
     };
 
@@ -27,9 +25,8 @@ class PasswordResetModal extends React.Component {
   async resetPassword() {
     const { t, userForPasswordResetModal } = this.props;
     try {
-      const res = await apiv3Put('/users/reset-password', { id: userForPasswordResetModal._id });
-      const { newPassword } = res.data;
-      this.setState({ temporaryPassword: newPassword, isPasswordResetDone: true });
+      await apiv3Put('/users/reset-password', { id: userForPasswordResetModal._id });
+      this.setState({ isPasswordResetDone: true });
     }
     catch (err) {
       toastError(err, t('toaster.failed_to_reset_password'));
@@ -42,8 +39,8 @@ class PasswordResetModal extends React.Component {
     return (
       <>
         <p>
-          {t('user_management.reset_password_modal.password_never_seen')}<br />
-          <span className="text-danger">{t('user_management.reset_password_modal.send_new_password')}</span>
+          {t('user_management.reset_password_modal.reset_password_info')}<br />
+          <span className="text-danger">{t('user_management.reset_password_modal.reset_password_alert')}</span>
         </p>
         <p>
           {t('user_management.reset_password_modal.target_user')}: <code>{userForPasswordResetModal.email}</code>
@@ -61,9 +58,6 @@ class PasswordResetModal extends React.Component {
         <p>
           {t('user_management.reset_password_modal.target_user')}: <code>{userForPasswordResetModal.email}</code>
         </p>
-        <p>
-          {t('user_management.reset_password_modal.new_password')}: <code>{this.state.temporaryPassword}</code>
-        </p>
       </>
     );
   }

+ 28 - 6
packages/app/src/server/routes/apiv3/users.js

@@ -845,27 +845,49 @@ module.exports = (crowi) => {
    *              application/json:
    *                schema:
    *                  properties:
-   *                    newPassword:
-   *                      type: string
    *                    user:
    *                      type: object
    *                      description: Target user
    */
   router.put('/reset-password', loginRequiredStrictly, adminRequired, addActivity, async(req, res) => {
+    const { appService, mailService } = crowi;
     const { id } = req.body;
 
+    let newPassword;
+    let user;
+
     try {
-      const [newPassword, user] = await Promise.all([
+      [newPassword, user] = await Promise.all([
         await User.resetPasswordByRandomString(id),
         await User.findById(id)]);
 
       activityEvent.emit('update', res.locals.activity._id, { action: SupportedAction.ACTION_ADMIN_USERS_PASSWORD_RESET });
+    }
+    catch (err) {
+      const msg = 'Error occurred during password reset request procedure.';
+      logger.error(err);
+      return res.apiv3Err(`${msg} Cause: ${err}`);
+    }
+
+    try {
+      await mailService.send({
+        to: user.email,
+        subject: 'Your password has been reset by the administrator',
+        template: path.join(crowi.localeDir, 'en_US/admin/userResetPassword.txt'),
+        vars: {
+          email: user.email,
+          password: newPassword,
+          url: crowi.appService.getSiteUrl(),
+          appTitle: appService.getAppTitle(),
+        },
+      });
 
-      return res.apiv3({ newPassword, user });
+      return res.apiv3({});
     }
     catch (err) {
-      logger.error('Error', err);
-      return res.apiv3Err(new ErrorV3(err));
+      const msg = 'Error occurred during password reset send e-mail.';
+      logger.error(err);
+      return res.apiv3Err(`${msg} Cause: ${err}`);
     }
   });