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

Change error messages by Error object for login action

Shun Miyazawa 1 год назад
Родитель
Сommit
9a2a6f9eb4

+ 6 - 11
apps/app/src/components/LoginForm/LoginForm.tsx

@@ -231,6 +231,7 @@ export const LoginForm = (props: LoginFormProps): JSX.Element => {
               placeholder="Password"
               onChange={(e) => { setPasswordForLogin(e.target.value) }}
               name="passwordForLogin"
+              minLength={minPasswordLength}
             />
           </div>
 
@@ -255,15 +256,8 @@ export const LoginForm = (props: LoginFormProps): JSX.Element => {
       </>
     );
   }, [
-    props,
-    separateErrorsBasedOnErrorCode,
-    loginErrors,
-    generateDangerouslySetErrors,
-    generateSafelySetErrors,
-    isLdapSetupFailed,
-    t,
-    handleLoginWithLocalSubmit,
-    isLoading,
+    props, separateErrorsBasedOnErrorCode, loginErrors, generateDangerouslySetErrors, generateSafelySetErrors,
+    isLdapSetupFailed, t, handleLoginWithLocalSubmit, minPasswordLength, isLoading,
   ]);
 
 
@@ -457,13 +451,13 @@ export const LoginForm = (props: LoginFormProps): JSX.Element => {
                 </span>
                 {/* Password */}
                 <input
-                  minLength={minPasswordLength}
                   type="password"
                   className="form-control rounded ms-2"
                   onChange={(e) => { setPasswordForRegister(e.target.value) }}
                   placeholder={t('Password')}
                   name="password"
                   required
+                  minLength={minPasswordLength}
                 />
               </div>
             </div>
@@ -505,7 +499,8 @@ export const LoginForm = (props: LoginFormProps): JSX.Element => {
     );
   }, [
     t, isEmailAuthenticationEnabled, registrationMode, isMailerSetup, registerErrors, isSuccessToRagistration, emailForRegistrationOrder,
-    props.username, props.name, props.email, registrationWhitelist, isLoading, switchForm, tWithOpt, handleRegisterFormSubmit]);
+    props.username, props.name, props.email, registrationWhitelist, minPasswordLength, isLoading, switchForm, tWithOpt, handleRegisterFormSubmit,
+  ]);
 
   if (registrationMode === RegistrationMode.RESTRICTED && isSuccessToRagistration && !isEmailAuthenticationEnabled) {
     return <CompleteUserRegistration />;

+ 10 - 5
apps/app/src/server/middlewares/login-form-validator.ts

@@ -1,7 +1,12 @@
-import { body, validationResult } from 'express-validator';
+import { ErrorV3 } from '@growi/core/dist/models';
+import { body, validationResult, type ValidationChain } from 'express-validator';
+
+const DEFAULT_PASSOWRD_MINIMUM_NUMBER = 8;
 
 // form rules
-export const loginRules = () => {
+export const loginRules = (minPasswordLength?: number): ValidationChain[] => {
+  const fixedMinPasswordLength = minPasswordLength ?? DEFAULT_PASSOWRD_MINIMUM_NUMBER;
+
   return [
     body('loginForm.username')
       .matches(/^[\da-zA-Z\-_.+@]+$/)
@@ -12,8 +17,8 @@ export const loginRules = () => {
     body('loginForm.password')
       .matches(/^[\x20-\x7F]*$/)
       .withMessage('message.Password has invalid character')
-      .isLength({ min: 6 })
-      .withMessage('message.Password minimum character should be more than 6 characters')
+      .isLength({ min: fixedMinPasswordLength })
+      .withMessage(new ErrorV3('message.Password minimum character should be more than n characters', undefined, undefined, { number: fixedMinPasswordLength }))
       .not()
       .isEmpty()
       .withMessage('message.Password field is required'),
@@ -21,7 +26,7 @@ export const loginRules = () => {
 };
 
 // validation action
-export const loginValidation = (req, res, next) => {
+export const loginValidation = (req, res, next): ValidationChain[] => {
   const form = req.body;
 
   const errors = validationResult(req);

+ 1 - 1
apps/app/src/server/routes/apiv3/index.js

@@ -55,7 +55,7 @@ module.exports = (crowi, app) => {
   const login = require('../login')(crowi, app);
   const loginPassport = require('../login-passport')(crowi, app);
 
-  routerForAuth.post('/login', applicationInstalled, loginFormValidator.loginRules(), loginFormValidator.loginValidation,
+  routerForAuth.post('/login', applicationInstalled, loginFormValidator.loginRules(minPasswordLength), loginFormValidator.loginValidation,
     addActivity, loginPassport.injectRedirectTo, loginPassport.isEnableLoginWithLocalOrLdap, loginPassport.loginWithLocal, loginPassport.loginWithLdap,
     loginPassport.cannotLoginErrorHadnler, loginPassport.loginFailure);
 

+ 3 - 1
apps/app/src/server/routes/index.js

@@ -52,6 +52,8 @@ module.exports = function(crowi, app) {
   const unavailableWhenMaintenanceMode = generateUnavailableWhenMaintenanceModeMiddleware(crowi);
   const unavailableWhenMaintenanceModeForApi = generateUnavailableWhenMaintenanceModeMiddlewareForApi(crowi);
 
+  const minPasswordLength = crowi.configManager.getConfig('crowi', 'app:minPasswordLength');
+
 
   /* eslint-disable max-len, comma-spacing, no-multi-spaces */
 
@@ -96,7 +98,7 @@ module.exports = function(crowi, app) {
   app.get('/passport/oidc/callback'               , loginPassport.injectRedirectTo, loginPassport.loginPassportOidcCallback     , loginPassport.loginFailureForExternalAccount);
   app.post('/passport/saml/callback'              , addActivity, loginPassport.injectRedirectTo, loginPassport.loginPassportSamlCallback, loginPassport.loginFailureForExternalAccount);
 
-  app.post('/_api/login/testLdap'    , loginRequiredStrictly , loginFormValidator.loginRules() , loginFormValidator.loginValidation , loginPassport.testLdapCredentials);
+  app.post('/_api/login/testLdap'    , loginRequiredStrictly , loginFormValidator.loginRules(minPasswordLength) , loginFormValidator.loginValidation , loginPassport.testLdapCredentials);
 
   // importer management for admin
   app.post('/_api/admin/settings/importerEsa'   , loginRequiredStrictly , adminRequired , csrfProtection, addActivity, admin.importer.api.validators.importer.esa(),admin.api.importerSettingEsa);