Răsfoiți Sursa

fix: create user should add limitation for username and password (#787)

Signed-off-by: ryjiang <jiangruiyi@gmail.com>
ryjiang 2 luni în urmă
părinte
comite
3097afb3ed

+ 12 - 11
client/src/i18n/cn/warning.ts

@@ -1,15 +1,16 @@
 const warningTrans = {
 const warningTrans = {
-  required: '{{name}} 是必需的',
-  requiredOnly: '必需的',
-  positive: '{{name}} 应为正数',
-  integer: '{{name}} 应为整数',
-  number: '{{name}} 应为数字',
-  bool: '{{name}} 应为布尔值`true`或`false`',
-  range: '范围是 {{min}} ~ {{max}}',
+  required: '{{name}} 是必填的。',
+  requiredOnly: '必填的。',
+  positive: '{{name}} 应为正数',
+  integer: '{{name}} 应为整数',
+  number: '{{name}} 应为数字',
+  bool: '{{name}} 应为布尔值`true`或`false`',
+  range: '范围是 {{min}} ~ {{max}}',
   specValueOrRange:
   specValueOrRange:
-    '{{name}} 应为 {{specValue}},或在范围 {{min}} ~ {{max}} 内',
-  noSupportIndexType:
-    'Attu 还不支持 {{type}}。请更换其他字段',
+    '{{name}} 应为 {{specValue}},或在范围 {{min}} ~ {{max}} 内。',
+  noSupportIndexType: 'Attu 还不支持 {{type}}。请更换其他字段。',
+  valueLength: '{{name}} 长度应在 {{min}} ~ {{max}} 之间。',
+  username: ' 用户名不能为空,长度不能超过32个字符。必须以字母开头,只能包含下划线、字母或数字。',
 };
 };
 
 
-export default warningTrans;
+export default warningTrans;

+ 11 - 9
client/src/i18n/en/warning.ts

@@ -1,15 +1,17 @@
 const warningTrans = {
 const warningTrans = {
-  required: '{{name}} is required',
-  requiredOnly: 'Required',
-  positive: '{{name}} should be positive',
-  integer: '{{name}} should be integers',
-  number: '{{name}} should be numbers',
-  bool: '{{name}} should be boolean value `true` or `false`',
-  range: 'Range is {{min}} ~ {{max}}',
+  required: '{{name}} is required.',
+  requiredOnly: 'Required.',
+  positive: '{{name}} should be positive.',
+  integer: '{{name}} should be integers.',
+  number: '{{name}} should be numbers.',
+  bool: '{{name}} should be boolean value `true` or `false`.',
+  range: 'Range is {{min}} ~ {{max}}.',
   specValueOrRange:
   specValueOrRange:
-    '{{name}} should be {{specValue}}, or in range {{min}} ~ {{max}}',
+    '{{name}} should be {{specValue}}, or in range {{min}} ~ {{max}}.',
   noSupportIndexType:
   noSupportIndexType:
-    'Attu has not supported {{type}} yet. Please change another field',
+    'Attu has not supported {{type}} yet. Please change another field.',
+  valueLength: '{{name}} length should be in {{min}} ~ {{max}}.',
+  username: ' Username must not be empty, and must not exceed 32 characters in length. It must start with a letter, and only contains underscores, letters, or numbers.',
 };
 };
 
 
 export default warningTrans;
 export default warningTrans;

+ 6 - 3
client/src/pages/user/User.tsx

@@ -1,4 +1,4 @@
-import React, { useContext, useEffect, useState } from 'react';
+import { useContext, useEffect, useState } from 'react';
 import { Theme } from '@mui/material';
 import { Theme } from '@mui/material';
 import { useTranslation } from 'react-i18next';
 import { useTranslation } from 'react-i18next';
 import { UserService } from '@/http';
 import { UserService } from '@/http';
@@ -7,7 +7,6 @@ import { ColDefinitionsType, ToolBarConfig } from '@/components/grid/Types';
 import {
 import {
   CreateUserParams,
   CreateUserParams,
   DeleteUserParams,
   DeleteUserParams,
-  UpdateUserParams,
   UpdateUserRoleParams,
   UpdateUserRoleParams,
 } from './Types';
 } from './Types';
 import DeleteTemplate from '@/components/customDialog/DeleteDialogTemplate';
 import DeleteTemplate from '@/components/customDialog/DeleteDialogTemplate';
@@ -72,7 +71,11 @@ const Users = () => {
   } = usePaginationHook(users || []);
   } = usePaginationHook(users || []);
 
 
   const handleCreate = async (data: CreateUserParams) => {
   const handleCreate = async (data: CreateUserParams) => {
-    await UserService.createUser(data);
+    const s: any = await UserService.createUser(data);
+    if (s.error_code !== 'Success') {
+      openSnackBar(s.reason, 'error');
+      return;
+    }
     // assign user role if
     // assign user role if
     await UserService.updateUserRole({
     await UserService.updateUserRole({
       username: data.username,
       username: data.username,

+ 16 - 0
client/src/pages/user/dialogs/CreateUserDialog.tsx

@@ -74,6 +74,10 @@ const CreateUser: FC<CreateUserProps> = ({
             name: attuTrans.username,
             name: attuTrans.username,
           }),
           }),
         },
         },
+        {
+          rule: 'username',
+          errorText: warningTrans('username'),
+        },
       ],
       ],
       defaultValue: form.username,
       defaultValue: form.username,
     },
     },
@@ -93,6 +97,18 @@ const CreateUser: FC<CreateUserProps> = ({
             name: attuTrans.password,
             name: attuTrans.password,
           }),
           }),
         },
         },
+        {
+          rule: 'valueLength',
+          errorText: warningTrans('valueLength', {
+            name: attuTrans.password,
+            min: 6,
+            max: 256,
+          }),
+          extraParam: {
+            min: 6,
+            max: 256,
+          },
+        },
       ],
       ],
       defaultValue: form.username,
       defaultValue: form.username,
     },
     },

+ 14 - 0
client/src/utils/Validation.ts

@@ -20,6 +20,8 @@ export type ValidType =
   | 'firstCharacter'
   | 'firstCharacter'
   | 'specValueOrRange'
   | 'specValueOrRange'
   | 'duplicate'
   | 'duplicate'
+  | 'valueLength'
+  | 'username'
   | 'custom';
   | 'custom';
 export interface ICheckMapParam {
 export interface ICheckMapParam {
   value: string;
   value: string;
@@ -222,6 +224,16 @@ export const checkNumber = (value: string): boolean => {
   return !isNaN(Number(value));
   return !isNaN(Number(value));
 };
 };
 
 
+export const checkValueLength = (value: string, min: number, max: number) => {
+  return value.length >= min && value.length <= max;
+};
+
+// Username must not be empty, and must not exceed 32 characters in length. It must start with a letter, and only contains underscores, letters, or numbers.
+export const checkUserName = (value: string): boolean => {
+  const re = /^[a-zA-Z][a-zA-Z0-9_]{0,31}$/;
+  return re.test(value);
+};
+
 export const getCheckResult = (param: ICheckMapParam): boolean => {
 export const getCheckResult = (param: ICheckMapParam): boolean => {
   const { value, extraParam = {}, rule } = param;
   const { value, extraParam = {}, rule } = param;
   const numberValue = Number(value);
   const numberValue = Number(value);
@@ -265,6 +277,8 @@ export const getCheckResult = (param: ICheckMapParam): boolean => {
       compareValue: Number(extraParam.compareValue) || 0,
       compareValue: Number(extraParam.compareValue) || 0,
     }),
     }),
     duplicate: checkDuplicate({ value, compare: extraParam.compareValue! }),
     duplicate: checkDuplicate({ value, compare: extraParam.compareValue! }),
+    valueLength: checkValueLength(value, extraParam.min!, extraParam.max!),
+    username: checkUserName(value),
     custom:
     custom:
       extraParam && typeof extraParam.compare === 'function'
       extraParam && typeof extraParam.compare === 'function'
         ? extraParam.compare(value)
         ? extraParam.compare(value)