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

Merge branch 'feat/enhanced-link-edit-modal-for-master-merge' into feat/refactor-permalink-in-linker

yusuketk 5 лет назад
Родитель
Сommit
5de09bcf0e

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

@@ -341,7 +341,8 @@
     "activate_user_success": "Succeeded to activating {{username}}",
     "deactivate_user_success": "Succeeded to deactivate {{username}}",
     "remove_user_success": "Succeeded to removing {{username}} ",
-    "remove_external_user_success": "Succeeded to remove {{accountId}} "
+    "remove_external_user_success": "Succeeded to remove {{accountId}} ",
+    "failed_to_reset_password":"Failed to reset password"
   },
   "template": {
     "modal_label": {

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

@@ -342,7 +342,8 @@
     "activate_user_success": "{{username}}を有効化しました",
     "deactivate_user_success": "{{username}}を無効化しました",
     "remove_user_success": "{{username}}を削除しました",
-    "remove_external_user_success": "{{accountId}}を削除しました"
+    "remove_external_user_success": "{{accountId}}を削除しました",
+    "failed_to_reset_password":"パスワードのリセットに失敗しました"
   },
   "template": {
     "modal_label": {

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

@@ -339,8 +339,9 @@
 		"activate_user_success": "Succeeded to activating {{username}}",
 		"deactivate_user_success": "Succeeded to deactivate {{username}}",
 		"remove_user_success": "Succeeded to removing {{username}} ",
-		"remove_external_user_success": "Succeeded to remove {{accountId}} "
-	},
+    "remove_external_user_success": "Succeeded to remove {{accountId}} ",
+    "failed_to_reset_password":"Failed to reset password"
+  },
 	"template": {
 		"modal_label": {
 			"Create/Edit Template Page": "创建/编辑模板页",
@@ -721,4 +722,4 @@
 		"complete_to_install2": "完成安装GROWI!请先检查此页上的每个设置。",
 		"failed_to_create_admin_user": "无法创建管理用户。{{errMessage}"
 	}
-}
+}

+ 34 - 26
src/client/js/components/Admin/Users/PasswordResetModal.jsx

@@ -23,14 +23,14 @@ class PasswordResetModal extends React.Component {
   }
 
   async resetPassword() {
-    const { appContainer, userForPasswordResetModal } = this.props;
-
-    const res = await appContainer.apiPost('/admin/users.resetPassword', { user_id: userForPasswordResetModal._id });
-    if (res.ok) {
-      this.setState({ temporaryPassword: res.newPassword, isPasswordResetDone: true });
+    const { t, appContainer, userForPasswordResetModal } = this.props;
+    try {
+      const res = await appContainer.apiv3Put('/users/reset-password', { id: userForPasswordResetModal._id });
+      const { newPassword } = res.data;
+      this.setState({ temporaryPassword: newPassword, isPasswordResetDone: true });
     }
-    else {
-      toastError('Failed to reset password');
+    catch (err) {
+      toastError(err, t('toaster.failed_to_reset_password'));
     }
   }
 
@@ -38,15 +38,15 @@ class PasswordResetModal extends React.Component {
     const { t, userForPasswordResetModal } = this.props;
 
     return (
-      <div>
-        <p className="alert alert-danger">{t('admin:user_management.reset_password_modal.password_reset_message')}</p>
+      <>
         <p>
-          {t('admin:user_management.reset_password_modal.target_user')}: <code>{userForPasswordResetModal.email}</code>
+          {t('admin:user_management.reset_password_modal.password_never_seen')}<br />
+          <span className="text-danger">{t('admin:user_management.reset_password_modal.send_new_password')}</span>
         </p>
         <p>
-          {t('admin:user_management.reset_password_modal.new_password')}: <code>{this.state.temporaryPassword}</code>
+          {t('admin:user_management.reset_password_modal.target_user')}: <code>{userForPasswordResetModal.email}</code>
         </p>
-      </div>
+      </>
     );
   }
 
@@ -54,26 +54,34 @@ class PasswordResetModal extends React.Component {
     const { t, userForPasswordResetModal } = this.props;
 
     return (
-      <div>
+      <>
+        <p className="alert alert-danger">{t('admin:user_management.reset_password_modal.password_reset_message')}</p>
         <p>
-          {t('admin:user_management.reset_password_modal.password_never_seen')}<br />
-          <span className="text-danger">{t('admin:user_management.reset_password_modal.send_new_password')}</span>
+          {t('admin:user_management.reset_password_modal.target_user')}: <code>{userForPasswordResetModal.email}</code>
         </p>
         <p>
-          {t('admin:user_management.reset_password_modal.target_user')}: <code>{userForPasswordResetModal.email}</code>
+          {t('admin:user_management.reset_password_modal.new_password')}: <code>{this.state.temporaryPassword}</code>
         </p>
-        <button type="submit" className="btn btn-primary" onClick={this.resetPassword}>
-          {t('admin:user_management.reset_password')}
-        </button>
-      </div>
+      </>
+    );
+  }
+
+  returnModalFooterBeforeReset() {
+    const { t } = this.props;
+    return (
+      <button type="submit" className="btn btn-danger" onClick={this.resetPassword}>
+        {t('admin:user_management.reset_password')}
+      </button>
     );
   }
 
-  returnModalFooter() {
+  returnModalFooterAfterReset() {
+    const { t } = this.props;
+
     return (
-      <div>
-        <button type="submit" className="btn btn-primary" onClick={this.props.onClose}>OK</button>
-      </div>
+      <button type="submit" className="btn btn-primary" onClick={this.props.onClose}>
+        {t('Close')}
+      </button>
     );
   }
 
@@ -87,10 +95,10 @@ class PasswordResetModal extends React.Component {
           {t('admin:user_management.reset_password') }
         </ModalHeader>
         <ModalBody>
-          {this.state.isPasswordResetDone ? this.renderModalBodyBeforeReset() : this.returnModalBodyAfterReset()}
+          {this.state.isPasswordResetDone ? this.returnModalBodyAfterReset() : this.renderModalBodyBeforeReset()}
         </ModalBody>
         <ModalFooter>
-          {this.state.isPasswordResetDone && this.returnModalFooter()}
+          {this.state.isPasswordResetDone ? this.returnModalFooterAfterReset() : this.returnModalFooterBeforeReset()}
         </ModalFooter>
       </Modal>
     );

+ 47 - 0
src/server/routes/apiv3/users.js

@@ -597,5 +597,52 @@ module.exports = (crowi) => {
     }
   });
 
+  /**
+   * @swagger
+   *
+   *  paths:
+   *    /users/reset-password:
+   *      put:
+   *        tags: [Users]
+   *        operationId: resetPassword
+   *        summary: /users/reset-password
+   *        description: update imageUrlCache
+   *        requestBody:
+   *          content:
+   *            application/json:
+   *              schema:
+   *                properties:
+   *                  id:
+   *                    type: string
+   *                    description: user id for reset password
+   *        responses:
+   *          200:
+   *            description: success resrt password
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    newPassword:
+   *                      type: string
+   *                    user:
+   *                      type: object
+   *                      description: Target user
+   */
+  router.put('/reset-password', loginRequiredStrictly, adminRequired, csrf, async(req, res) => {
+    const { id } = req.body;
+
+    try {
+      const [newPassword, user] = await Promise.all([
+        await User.resetPasswordByRandomString(id),
+        await User.findById(id)]);
+
+      return res.apiv3({ newPassword, user });
+    }
+    catch (err) {
+      logger.error('Error', err);
+      return res.apiv3Err(new ErrorV3(err));
+    }
+  });
+
   return router;
 };