Sfoglia il codice sorgente

Support /forgot-password

Shun Miyazawa 3 anni fa
parent
commit
d59d612370

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

@@ -560,6 +560,8 @@
     "USER_LOGIN_WITH_BASIC": "Login with BASIC",
     "USER_LOGIN_WITH_BASIC": "Login with BASIC",
     "USER_LOGIN_FAILURE": "Login failure",
     "USER_LOGIN_FAILURE": "Login failure",
     "USER_LOGOUT": "Logout",
     "USER_LOGOUT": "Logout",
+    "USER_FOGOT_PASSWORD": "Request password reset",
+    "USER_RESET_PASSWORD": "Reset password",
     "USER_PERSONAL_SETTINGS_UPDATE": "User personal settings update",
     "USER_PERSONAL_SETTINGS_UPDATE": "User personal settings update",
     "USER_IMAGE_TYPE_UPDATE": "User image type update",
     "USER_IMAGE_TYPE_UPDATE": "User image type update",
     "USER_LDAP_ACCOUNT_ASSOCIATE": "LDAP account associate",
     "USER_LDAP_ACCOUNT_ASSOCIATE": "LDAP account associate",

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

@@ -559,6 +559,8 @@
     "USER_LOGIN_WITH_BASIC": "BASIC 認証でログイン",
     "USER_LOGIN_WITH_BASIC": "BASIC 認証でログイン",
     "USER_LOGIN_FAILURE": "ログイン失敗",
     "USER_LOGIN_FAILURE": "ログイン失敗",
     "USER_LOGOUT": "ログアウト",
     "USER_LOGOUT": "ログアウト",
+    "USER_FOGOT_PASSWORD": "パスワードリセットのリクエスト",
+    "USER_RESET_PASSWORD": "パスワードのリセット",
     "USER_PERSONAL_SETTINGS_UPDATE": "ユーザーの基本情報の更新",
     "USER_PERSONAL_SETTINGS_UPDATE": "ユーザーの基本情報の更新",
     "USER_IMAGE_TYPE_UPDATE": "プロフィール画像の変更",
     "USER_IMAGE_TYPE_UPDATE": "プロフィール画像の変更",
     "USER_LDAP_ACCOUNT_ASSOCIATE": "LDAP アカウントの追加",
     "USER_LDAP_ACCOUNT_ASSOCIATE": "LDAP アカウントの追加",

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

@@ -569,6 +569,8 @@
     "USER_LOGIN_WITH_BASIC": "使用 BASIC 登录",
     "USER_LOGIN_WITH_BASIC": "使用 BASIC 登录",
     "USER_LOGIN_FAILURE": "登录失败",
     "USER_LOGIN_FAILURE": "登录失败",
     "USER_LOGOUT": "注销",
     "USER_LOGOUT": "注销",
+    "USER_FOGOT_PASSWORD": "要求重置密码",
+    "USER_RESET_PASSWORD": "重置密码",
     "USER_PERSONAL_SETTINGS_UPDATE": "用户个人设置更新",
     "USER_PERSONAL_SETTINGS_UPDATE": "用户个人设置更新",
     "USER_IMAGE_TYPE_UPDATE": "用户图片类型更新",
     "USER_IMAGE_TYPE_UPDATE": "用户图片类型更新",
     "USER_LDAP_ACCOUNT_ASSOCIATE": "LDAP 帐户关联",
     "USER_LDAP_ACCOUNT_ASSOCIATE": "LDAP 帐户关联",

+ 6 - 0
packages/app/src/interfaces/activity.ts

@@ -19,6 +19,8 @@ const ACTION_USER_LOGIN_WITH_SAML = 'USER_LOGIN_WITH_SAML';
 const ACTION_USER_LOGIN_WITH_BASIC = 'USER_LOGIN_WITH_BASIC';
 const ACTION_USER_LOGIN_WITH_BASIC = 'USER_LOGIN_WITH_BASIC';
 const ACTION_USER_LOGIN_FAILURE = 'USER_LOGIN_FAILURE';
 const ACTION_USER_LOGIN_FAILURE = 'USER_LOGIN_FAILURE';
 const ACTION_USER_LOGOUT = 'USER_LOGOUT';
 const ACTION_USER_LOGOUT = 'USER_LOGOUT';
+const ACTION_USER_FOGOT_PASSWORD = 'USER_FOGOT_PASSWORD';
+const ACTION_USER_RESET_PASSWORD = 'USER_RESET_PASSWORD';
 const ACTION_USER_PERSONAL_SETTINGS_UPDATE = 'USER_PERSONAL_SETTINGS_UPDATE';
 const ACTION_USER_PERSONAL_SETTINGS_UPDATE = 'USER_PERSONAL_SETTINGS_UPDATE';
 const ACTION_USER_IMAGE_TYPE_UPDATE = 'USER_IMAGE_TYPE_UPDATE';
 const ACTION_USER_IMAGE_TYPE_UPDATE = 'USER_IMAGE_TYPE_UPDATE';
 const ACTION_USER_LDAP_ACCOUNT_ASSOCIATE = 'USER_LDAP_ACCOUNT_ASSOCIATE';
 const ACTION_USER_LDAP_ACCOUNT_ASSOCIATE = 'USER_LDAP_ACCOUNT_ASSOCIATE';
@@ -195,6 +197,8 @@ export const SupportedAction = {
   ACTION_USER_LOGIN_WITH_BASIC,
   ACTION_USER_LOGIN_WITH_BASIC,
   ACTION_USER_LOGIN_FAILURE,
   ACTION_USER_LOGIN_FAILURE,
   ACTION_USER_LOGOUT,
   ACTION_USER_LOGOUT,
+  ACTION_USER_FOGOT_PASSWORD,
+  ACTION_USER_RESET_PASSWORD,
   ACTION_USER_PERSONAL_SETTINGS_UPDATE,
   ACTION_USER_PERSONAL_SETTINGS_UPDATE,
   ACTION_USER_IMAGE_TYPE_UPDATE,
   ACTION_USER_IMAGE_TYPE_UPDATE,
   ACTION_USER_LDAP_ACCOUNT_ASSOCIATE,
   ACTION_USER_LDAP_ACCOUNT_ASSOCIATE,
@@ -376,6 +380,8 @@ export const SmallActionGroup = {
 export const MediumActionGroup = {
 export const MediumActionGroup = {
   ...SmallActionGroup,
   ...SmallActionGroup,
   ACTION_USER_REGISTRATION_SUCCESS,
   ACTION_USER_REGISTRATION_SUCCESS,
+  ACTION_USER_FOGOT_PASSWORD,
+  ACTION_USER_RESET_PASSWORD,
   ACTION_USER_PERSONAL_SETTINGS_UPDATE,
   ACTION_USER_PERSONAL_SETTINGS_UPDATE,
   ACTION_USER_IMAGE_TYPE_UPDATE,
   ACTION_USER_IMAGE_TYPE_UPDATE,
   ACTION_USER_LDAP_ACCOUNT_ASSOCIATE,
   ACTION_USER_LDAP_ACCOUNT_ASSOCIATE,

+ 13 - 2
packages/app/src/server/routes/apiv3/forgot-password.js

@@ -1,5 +1,7 @@
 import { format, subSeconds } from 'date-fns';
 import { format, subSeconds } from 'date-fns';
 
 
+import { SupportedAction } from '~/interfaces/activity';
+import { generateAddActivityMiddleware } from '~/server/middlewares/add-activity';
 import injectResetOrderByTokenMiddleware from '~/server/middlewares/inject-reset-order-by-token-middleware';
 import injectResetOrderByTokenMiddleware from '~/server/middlewares/inject-reset-order-by-token-middleware';
 import PasswordResetOrder from '~/server/models/password-reset-order';
 import PasswordResetOrder from '~/server/models/password-reset-order';
 import ErrorV3 from '~/server/models/vo/error-apiv3';
 import ErrorV3 from '~/server/models/vo/error-apiv3';
@@ -24,6 +26,9 @@ module.exports = (crowi) => {
   const User = crowi.model('User');
   const User = crowi.model('User');
   const path = require('path');
   const path = require('path');
   const csrf = require('../../middlewares/csrf')(crowi);
   const csrf = require('../../middlewares/csrf')(crowi);
+  const addActivity = generateAddActivityMiddleware(crowi);
+
+  const activityEvent = crowi.event('activity');
 
 
   const minPasswordLength = crowi.configManager.getConfig('crowi', 'app:minPasswordLength');
   const minPasswordLength = crowi.configManager.getConfig('crowi', 'app:minPasswordLength');
 
 
@@ -56,7 +61,7 @@ module.exports = (crowi) => {
     });
     });
   }
   }
 
 
-  router.post('/', checkPassportStrategyMiddleware, async(req, res) => {
+  router.post('/', checkPassportStrategyMiddleware, addActivity, async(req, res) => {
     const { email } = req.body;
     const { email } = req.body;
     const i18n = configManager.getConfig('crowi', 'app:globalLang');
     const i18n = configManager.getConfig('crowi', 'app:globalLang');
     const appUrl = appService.getSiteUrl();
     const appUrl = appService.getSiteUrl();
@@ -77,6 +82,9 @@ module.exports = (crowi) => {
       const expiredAt = subSeconds(passwordResetOrderData.expiredAt, grwTzoffsetSec);
       const expiredAt = subSeconds(passwordResetOrderData.expiredAt, grwTzoffsetSec);
       const formattedExpiredAt = format(expiredAt, 'yyyy/MM/dd HH:mm');
       const formattedExpiredAt = format(expiredAt, 'yyyy/MM/dd HH:mm');
       await sendPasswordResetEmail('passwordReset', i18n, email, oneTimeUrl, formattedExpiredAt);
       await sendPasswordResetEmail('passwordReset', i18n, email, oneTimeUrl, formattedExpiredAt);
+
+      activityEvent.emit('update', res.locals.activity._id, { action: SupportedAction.ACTION_USER_FOGOT_PASSWORD });
+
       return res.apiv3();
       return res.apiv3();
     }
     }
     catch (err) {
     catch (err) {
@@ -87,7 +95,7 @@ module.exports = (crowi) => {
   });
   });
 
 
   // eslint-disable-next-line max-len
   // eslint-disable-next-line max-len
-  router.put('/', checkPassportStrategyMiddleware, injectResetOrderByTokenMiddleware, csrf, validator.password, apiV3FormValidator, async(req, res) => {
+  router.put('/', checkPassportStrategyMiddleware, injectResetOrderByTokenMiddleware, csrf, validator.password, apiV3FormValidator, addActivity, async(req, res) => {
     const { passwordResetOrder } = req;
     const { passwordResetOrder } = req;
     const { email } = passwordResetOrder;
     const { email } = passwordResetOrder;
     const grobalLang = configManager.getConfig('crowi', 'app:globalLang');
     const grobalLang = configManager.getConfig('crowi', 'app:globalLang');
@@ -106,6 +114,9 @@ module.exports = (crowi) => {
       const serializedUserData = serializeUserSecurely(userData);
       const serializedUserData = serializeUserSecurely(userData);
       passwordResetOrder.revokeOneTimeToken();
       passwordResetOrder.revokeOneTimeToken();
       await sendPasswordResetEmail('passwordResetSuccessful', i18n, email);
       await sendPasswordResetEmail('passwordResetSuccessful', i18n, email);
+
+      activityEvent.emit('update', res.locals.activity._id, { action: SupportedAction.ACTION_USER_RESET_PASSWORD });
+
       return res.apiv3({ userData: serializedUserData });
       return res.apiv3({ userData: serializedUserData });
     }
     }
     catch (err) {
     catch (err) {